From 4ac9e49abdf124628162e0a4bd036b7f28227955 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Fri, 2 Sep 2022 22:26:41 +0300 Subject: [PATCH] [K/N][codegen] Moved llvmContext from global scope to generationState --- .../jetbrains/kotlin/backend/konan/Boxing.kt | 9 +- .../kotlin/backend/konan/CAdapterGenerator.kt | 4 +- .../backend/konan/CheckExternalCalls.kt | 42 ++-- .../kotlin/backend/konan/CompilerOutput.kt | 6 +- .../backend/konan/NativeGenerationState.kt | 11 +- .../backend/konan/RuntimeLinkageStrategy.kt | 4 +- .../konan/descriptors/ClassLayoutBuilder.kt | 4 +- .../backend/konan/llvm/CodeGenerator.kt | 97 ++++---- .../kotlin/backend/konan/llvm/ContextUtils.kt | 222 +++++++++++------- .../kotlin/backend/konan/llvm/DataLayout.kt | 38 ++- .../kotlin/backend/konan/llvm/DebugUtils.kt | 47 ++-- .../kotlin/backend/konan/llvm/HashUtils.kt | 4 +- .../backend/konan/llvm/IntrinsicGenerator.kt | 80 +++---- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 183 +++++++-------- .../llvm/KotlinObjCClassInfoGenerator.kt | 38 +-- .../backend/konan/llvm/KotlinStaticData.kt | 26 +- .../backend/konan/llvm/LlvmDeclarations.kt | 20 +- .../backend/konan/llvm/LlvmLinkOptions.kt | 5 +- .../backend/konan/llvm/LlvmParamType.kt | 8 +- .../kotlin/backend/konan/llvm/LlvmUtils.kt | 124 ++-------- .../backend/konan/llvm/RTTIGenerator.kt | 128 +++++----- .../kotlin/backend/konan/llvm/Runtime.kt | 4 +- .../kotlin/backend/konan/llvm/StaticData.kt | 9 +- .../backend/konan/llvm/VariableManager.kt | 4 +- .../coverage/LLVMCoverageInstrumentation.kt | 10 +- .../kotlin/backend/konan/llvm/diagnostics.kt | 10 +- .../kotlin/backend/konan/llvm/linkModules.kt | 2 +- .../konan/llvm/objc/ObjCCodeGenerator.kt | 22 +- .../konan/llvm/objc/ObjCDataGenerator.kt | 36 +-- .../backend/konan/llvm/objc/linkObjC.kt | 17 +- .../llvm/objcexport/BlockPointerSupport.kt | 57 ++--- .../objcexport/ObjCExportCodeGenerator.kt | 173 +++++++------- .../backend/konan/optimizations/DataFlowIR.kt | 6 +- 33 files changed, 699 insertions(+), 751 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt index 8b6a65f663d..9f4080de247 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt @@ -186,8 +186,9 @@ private fun initCache(cache: BoxCache, context: Context, cacheName: String, val kotlinType = context.irBuiltIns.getKotlinClass(cache) val staticData = context.generationState.llvm.staticData - val llvmType = staticData.getLLVMType(kotlinType.defaultType) - val llvmBoxType = structType(context.generationState.llvm.runtime.objHeaderType, llvmType) + val llvm = context.generationState.llvm + val llvmType = kotlinType.defaultType.toLLVMType(llvm) + val llvmBoxType = llvm.structType(llvm.runtime.objHeaderType, llvmType) val (start, end) = context.config.target.getBoxCacheRange(cache) return if (declareOnly) { @@ -227,7 +228,9 @@ internal fun IrConstantPrimitive.toBoxCacheValue(context: Context): ConstValue? } val (start, end) = context.config.target.getBoxCacheRange(cacheType) return if (value in start..end) { - context.generationState.llvm.boxCacheGlobals[cacheType]?.pointer?.getElementPtr(value.toInt() - start)?.getElementPtr(0) + context.generationState.llvm.let { llvm -> + llvm.boxCacheGlobals[cacheType]?.pointer?.getElementPtr(llvm, value.toInt() - start)?.getElementPtr(llvm, 0) + } } else { null } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt index d400e101a46..596077c5149 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt @@ -249,8 +249,8 @@ private class ExportedElement(val kind: ElementKind, "${cname}_type", owner.kGetTypeFuncType ) - val builder = LLVMCreateBuilderInContext(llvmContext)!! - val bb = LLVMAppendBasicBlockInContext(llvmContext, getTypeFunction, "")!! + val builder = LLVMCreateBuilderInContext(llvm.llvmContext)!! + val bb = LLVMAppendBasicBlockInContext(llvm.llvmContext, getTypeFunction, "")!! LLVMPositionBuilderAtEnd(builder, bb) LLVMBuildRet(builder, irClass.typeInfoPtr.llvm) LLVMDisposeBuilder(builder) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt index 83afeb13fa5..0fb244300c1 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt @@ -20,7 +20,7 @@ private fun LLVMValueRef.isLLVMBuiltin(): Boolean { } -private class CallsChecker(val context: Context, goodFunctions: List) { +private class CallsChecker(context: Context, goodFunctions: List) { private val llvm = context.generationState.llvm private val goodFunctionsExact = goodFunctions.filterNot { it.endsWith("*") }.toSet() private val goodFunctionsByPrefix = goodFunctions.filter { it.endsWith("*") }.map { it.substring(0, it.length - 1) }.sorted() @@ -38,22 +38,22 @@ private class CallsChecker(val context: Context, goodFunctions: List) { val getMethodImpl = llvm.externalFunction(LlvmFunctionProto( "class_getMethodImplementation", - LlvmRetType(pointerType(functionType(voidType, false))), - listOf(LlvmParamType(int8TypePtr), LlvmParamType(int8TypePtr)), + LlvmRetType(pointerType(functionType(llvm.voidType, false))), + listOf(LlvmParamType(llvm.int8PtrType), LlvmParamType(llvm.int8PtrType)), origin = context.stdlibModule.llvmSymbolOrigin) ) val getClass = llvm.externalFunction(LlvmFunctionProto( "object_getClass", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), origin = context.stdlibModule.llvmSymbolOrigin) ) val getSuperClass = llvm.externalFunction(LlvmFunctionProto( "class_getSuperclass", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), origin = context.stdlibModule.llvmSymbolOrigin) ) @@ -69,7 +69,7 @@ private class CallsChecker(val context: Context, goodFunctions: List) { return when { LLVMIsAFunction(value) != null -> { val valueOrSpecial = value.takeIf { !it.isLLVMBuiltin() } - ?: LLVMConstIntToPtr(Int64(CALLED_LLVM_BUILTIN).llvm, int8TypePtr)!! + ?: LLVMConstIntToPtr(llvm.int64(CALLED_LLVM_BUILTIN), llvm.int8PtrType)!! ExternalCallInfo(value.name!!, valueOrSpecial).takeIf { value.isExternalFunction() } } LLVMIsACastInst(value) != null -> cleanCalledFunction(LLVMGetOperand(value, 0)!!) @@ -95,7 +95,7 @@ private class CallsChecker(val context: Context, goodFunctions: List) { val calls = getInstructions(block) .filter { it.isFunctionCall() } .toList() - val builder = LLVMCreateBuilderInContext(llvmContext) + val builder = LLVMCreateBuilderInContext(llvm.llvmContext) for (call in calls) { val calleeInfo = call.getPossiblyExternalCalledFunction() ?: continue @@ -111,13 +111,13 @@ private class CallsChecker(val context: Context, goodFunctions: List) { if (LLVMGetNumArgOperands(call) < 2) continue callSiteDescription = "$functionName (over objc_msgSend)" calledName = null - val firstArgI8Ptr = LLVMBuildBitCast(builder, LLVMGetArgOperand(call, 0), int8TypePtr, "") + val firstArgI8Ptr = LLVMBuildBitCast(builder, LLVMGetArgOperand(call, 0), llvm.int8PtrType, "") val firstArgClassPtr = LLVMBuildCall(builder, getClass.llvmValue, listOf(firstArgI8Ptr).toCValues(), 1, "") - val isNil = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntEQ, firstArgI8Ptr, LLVMConstNull(int8TypePtr), "") + val isNil = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntEQ, firstArgI8Ptr, LLVMConstNull(llvm.int8PtrType), "") val selector = LLVMGetArgOperand(call, 1) val calledPtrLlvmIfNotNilFunPtr = LLVMBuildCall(builder, getMethodImpl.llvmValue, listOf(firstArgClassPtr, selector).toCValues(), 2, "") - val calledPtrLlvmIfNotNil = LLVMBuildBitCast(builder, calledPtrLlvmIfNotNilFunPtr, int8TypePtr, "") - val calledPtrLlvmIfNil = LLVMConstIntToPtr(Int64(MSG_SEND_TO_NULL).llvm, int8TypePtr) + val calledPtrLlvmIfNotNil = LLVMBuildBitCast(builder, calledPtrLlvmIfNotNilFunPtr, llvm.int8PtrType, "") + val calledPtrLlvmIfNil = LLVMConstIntToPtr(llvm.int64(MSG_SEND_TO_NULL), llvm.int8PtrType) calledPtrLlvm = LLVMBuildSelect(builder, isNil, calledPtrLlvmIfNil, calledPtrLlvmIfNotNil, "") } "objc_msgSendSuper2" -> { @@ -125,24 +125,24 @@ private class CallsChecker(val context: Context, goodFunctions: List) { callSiteDescription = "$functionName (over objc_msgSendSuper2)" calledName = null val superStruct = LLVMGetArgOperand(call, 0) - val superClassPtrPtr = LLVMBuildGEP(builder, superStruct, listOf(Int32(0).llvm, Int32(1).llvm).toCValues(), 2, "") + val superClassPtrPtr = LLVMBuildGEP(builder, superStruct, listOf(llvm.int32(0), llvm.int32(1)).toCValues(), 2, "") val superClassPtr = LLVMBuildLoad(builder, superClassPtrPtr, "") val classPtr = LLVMBuildCall(builder, getSuperClass.llvmValue, listOf(superClassPtr).toCValues(), 1, "") val calledPtrLlvmFunPtr = LLVMBuildCall(builder, getMethodImpl.llvmValue, listOf(classPtr, LLVMGetArgOperand(call, 1)).toCValues(), 2, "") - calledPtrLlvm = LLVMBuildBitCast(builder, calledPtrLlvmFunPtr, int8TypePtr, "") + calledPtrLlvm = LLVMBuildBitCast(builder, calledPtrLlvmFunPtr, llvm.int8PtrType, "") } else -> { callSiteDescription = functionName calledName = calleeInfo.name calledPtrLlvm = when (val typeKind = LLVMGetTypeKind(calleeInfo.calledPtr.type)) { - LLVMTypeKind.LLVMPointerTypeKind -> LLVMBuildBitCast(builder, calleeInfo.calledPtr, int8TypePtr, "") - LLVMTypeKind.LLVMIntegerTypeKind -> LLVMBuildIntToPtr(builder, calleeInfo.calledPtr, int8TypePtr, "") + LLVMTypeKind.LLVMPointerTypeKind -> LLVMBuildBitCast(builder, calleeInfo.calledPtr, llvm.int8PtrType, "") + LLVMTypeKind.LLVMIntegerTypeKind -> LLVMBuildIntToPtr(builder, calleeInfo.calledPtr, llvm.int8PtrType, "") else -> TODO("Unsupported typeKind=${typeKind} of calledPtr=${llvm2string(calleeInfo.calledPtr)}") } } } val callSiteDescriptionLlvm = llvm.staticData.cStringLiteral(callSiteDescription).llvm - val calledNameLlvm = if (calledName == null) LLVMConstNull(int8TypePtr) else llvm.staticData.cStringLiteral(calledName).llvm + val calledNameLlvm = if (calledName == null) LLVMConstNull(llvm.int8PtrType) else llvm.staticData.cStringLiteral(calledName).llvm LLVMBuildCall(builder, checkerFunction, listOf(callSiteDescriptionLlvm, calledNameLlvm, calledPtrLlvm).toCValues(), 3, "") } LLVMDisposeBuilder(builder) @@ -194,14 +194,14 @@ internal fun addFunctionsListSymbolForChecker(context: Context) { val functions = getFunctions(llvm.module) .filter { !it.isExternalFunction() } - .map { constPointer(it).bitcast(int8TypePtr) } + .map { constPointer(it).bitcast(llvm.int8PtrType) } .toList() - val functionsArray = staticData.placeGlobalConstArray("", int8TypePtr, functions) + val functionsArray = staticData.placeGlobalConstArray("", llvm.int8PtrType, functions) staticData.getGlobal(functionListGlobal) ?.setInitializer(functionsArray) ?: throw IllegalStateException("$functionListGlobal global not found") staticData.getGlobal(functionListSizeGlobal) - ?.setInitializer(Int32(functions.size)) + ?.setInitializer(llvm.constInt32(functions.size)) ?: throw IllegalStateException("$functionListSizeGlobal global not found") context.verifyBitCode() } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt index 5baca71a6d9..267e08907cd 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt @@ -137,7 +137,7 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List): List = files.map { bitcodeFile -> - val parsedModule = parseBitcodeFile(bitcodeFile) + val parsedModule = parseBitcodeFile(context.generationState.llvmContext, bitcodeFile) if (!context.shouldUseDebugInfoFromNativeLibs()) { LLVMStripModuleDebugInfo(parsedModule) } @@ -280,7 +280,7 @@ internal fun produceOutput(context: Context) { } internal fun parseAndLinkBitcodeFile(context: Context, llvmModule: LLVMModuleRef, path: String) { - val parsedModule = parseBitcodeFile(path) + val parsedModule = parseBitcodeFile(context.generationState.llvmContext, path) if (!context.shouldUseDebugInfoFromNativeLibs()) { LLVMStripModuleDebugInfo(parsedModule) } @@ -308,5 +308,5 @@ private fun embedAppleLinkerOptionsToBitcode(llvm: Llvm, config: KonanConfig) { val optionsToEmbed = findEmbeddableOptions(config.platform.configurables.linkerKonanFlags) + llvm.allNativeDependencies.flatMap { findEmbeddableOptions(it.linkerOpts) } - embedLlvmLinkOptions(llvm.module, optionsToEmbed) + embedLlvmLinkOptions(llvm.llvmContext, llvm.module, optionsToEmbed) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt index cf601116a48..283e3ccd771 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt @@ -10,8 +10,6 @@ import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.DebugInfo import org.jetbrains.kotlin.backend.konan.llvm.Llvm import org.jetbrains.kotlin.backend.konan.llvm.LlvmDeclarations -import org.jetbrains.kotlin.backend.konan.llvm.llvmContext -import org.jetbrains.kotlin.backend.konan.llvm.tryDisposeLLVMContext import org.jetbrains.kotlin.backend.konan.llvm.verifyModule import org.jetbrains.kotlin.backend.konan.serialization.SerializedClassFields import org.jetbrains.kotlin.backend.konan.serialization.SerializedInlineFunctionReference @@ -56,14 +54,11 @@ internal class NativeGenerationState(private val context: Context) { getLocalClassName(source)?.let { name -> putLocalClassName(destination, name) } } - init { - llvmContext = LLVMContextCreate()!! - } - - private val runtimeDelegate = lazy { Runtime(config.distribution.compilerInterface(config.target)) } + private val runtimeDelegate = lazy { Runtime(llvmContext, config.distribution.compilerInterface(config.target)) } private val llvmDelegate = lazy { Llvm(context, LLVMModuleCreateWithNameInContext("out", llvmContext)!!) } private val debugInfoDelegate = lazy { DebugInfo(context) } + val llvmContext = LLVMContextCreate()!! val llvmImports = Llvm.ImportsImpl(context) val runtime by runtimeDelegate val llvm by llvmDelegate @@ -98,7 +93,7 @@ internal class NativeGenerationState(private val context: Context) { LLVMDisposeTargetData(runtime.targetData) LLVMDisposeModule(runtime.llvmModule) } - tryDisposeLLVMContext() + LLVMContextDispose(llvmContext) tempFiles.dispose() isDisposed = true diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/RuntimeLinkageStrategy.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/RuntimeLinkageStrategy.kt index a4ac3814d61..d7651ca5d9d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/RuntimeLinkageStrategy.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/RuntimeLinkageStrategy.kt @@ -7,9 +7,7 @@ package org.jetbrains.kotlin.backend.konan import llvm.LLVMModuleCreateWithNameInContext import llvm.LLVMModuleRef -import llvm.LLVMStripModuleDebugInfo import org.jetbrains.kotlin.backend.konan.llvm.* -import org.jetbrains.kotlin.backend.konan.llvm.llvmContext import org.jetbrains.kotlin.backend.konan.llvm.llvmLinkModules2 /** @@ -46,7 +44,7 @@ internal sealed class RuntimeLinkageStrategy { if (runtimeNativeLibraries.isEmpty()) { return emptyList() } - val runtimeModule = LLVMModuleCreateWithNameInContext("runtime", llvmContext)!! + val runtimeModule = LLVMModuleCreateWithNameInContext("runtime", context.generationState.llvmContext)!! runtimeNativeLibraries.forEach { val failed = llvmLinkModules2(context, runtimeModule, it) if (failed != 0) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassLayoutBuilder.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassLayoutBuilder.kt index b83c01f8397..20bfd347bf8 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassLayoutBuilder.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassLayoutBuilder.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionW import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName -import org.jetbrains.kotlin.backend.konan.llvm.getLLVMType +import org.jetbrains.kotlin.backend.konan.llvm.toLLVMType import org.jetbrains.kotlin.backend.konan.llvm.localHash import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget import org.jetbrains.kotlin.descriptors.Modality @@ -425,7 +425,7 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) { declaredFields else declaredFields.sortedByDescending { - with(context.generationState.llvm) { LLVMStoreSizeOfType(runtime.targetData, getLLVMType(it.type)) } + with(context.generationState.llvm) { LLVMStoreSizeOfType(runtime.targetData, it.type.toLLVMType(this)) } } val superFieldsCount = 1 /* First field is ObjHeader */ + superFields.size diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index c6546b7ca90..0d4b1d0d28f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -55,7 +55,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { function.llvmFunctionOrNull val llvmDeclarations = context.generationState.llvmDeclarations - val intPtrType = LLVMIntPtrTypeInContext(llvmContext, llvmTargetData)!! + val intPtrType = LLVMIntPtrTypeInContext(llvm.llvmContext, llvmTargetData)!! internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!! internal val immThreeIntPtrType = LLVMConstInt(intPtrType, 3, 1)!! // Keep in sync with OBJECT_TAG_MASK in C++. @@ -73,7 +73,6 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { private fun countParams(fn: IrFunction) = LLVMCountParams(fn.llvmFunction.llvmValue) fun functionEntryPointAddress(function: IrFunction) = function.entryPointAddress.llvm - fun functionHash(function: IrFunction): LLVMValueRef = function.computeFunctionName().localHash.llvm fun typeInfoForAllocation(constructedClass: IrClass): LLVMValueRef { assert(!constructedClass.isObjCClass()) @@ -289,7 +288,7 @@ internal class StackLocalsManagerImpl( val stackLocal = appendingTo(bbInitStackLocals) { val stackSlot = LLVMBuildAlloca(builder, type, "")!! - memset(bitcast(kInt8Ptr, stackSlot), 0, LLVMSizeOfTypeInBits(codegen.llvmTargetData, type).toInt() / 8) + memset(bitcast(llvm.int8PtrType, stackSlot), 0, LLVMSizeOfTypeInBits(codegen.llvmTargetData, type).toInt() / 8) val objectHeader = structGep(stackSlot, 0, "objHeader") val typeInfo = codegen.typeInfoForAllocation(irClass) @@ -321,18 +320,20 @@ internal class StackLocalsManagerImpl( } private val symbols = functionGenerationContext.context.ir.symbols + private val llvm = functionGenerationContext.llvm + // TODO: find better place? private val arrayToElementType = mapOf( - symbols.array to functionGenerationContext.kObjHeaderPtr, - symbols.byteArray to int8Type, - symbols.charArray to int16Type, - symbols.string to int16Type, - symbols.shortArray to int16Type, - symbols.intArray to int32Type, - symbols.longArray to int64Type, - symbols.floatArray to floatType, - symbols.doubleArray to doubleType, - symbols.booleanArray to int8Type + symbols.array to functionGenerationContext.kObjHeaderPtr, + symbols.byteArray to llvm.int8Type, + symbols.charArray to llvm.int16Type, + symbols.string to llvm.int16Type, + symbols.shortArray to llvm.int16Type, + symbols.intArray to llvm.int32Type, + symbols.longArray to llvm.int64Type, + symbols.floatArray to llvm.floatType, + symbols.doubleArray to llvm.doubleType, + symbols.booleanArray to llvm.int8Type ) override fun allocArray(irClass: IrClass, count: LLVMValueRef) = with(functionGenerationContext) { @@ -347,7 +348,7 @@ internal class StackLocalsManagerImpl( val sizeField = structGep(arrayHeaderSlot, 1, "count_") store(count, sizeField) - memset(bitcast(kInt8Ptr, structGep(arraySlot, 1, "arrayBody")), + memset(bitcast(llvm.int8PtrType, structGep(arraySlot, 1, "arrayBody")), 0, constCount * LLVMSizeOfTypeInBits(codegen.llvmTargetData, arrayToElementType[irClass.symbol]).toInt() / 8 ) @@ -389,7 +390,7 @@ internal class StackLocalsManagerImpl( val bodySize = LLVMSizeOfTypeInBits(codegen.llvmTargetData, type).toInt() / 8 val serviceInfoSize = runtime.pointerSize val serviceInfoSizeLlvm = LLVMConstInt(codegen.intPtrType, serviceInfoSize.toLong(), 1)!! - val bodyWithSkippedServiceInfoPtr = intToPtr(add(bodyPtr, serviceInfoSizeLlvm), kInt8Ptr) + val bodyWithSkippedServiceInfoPtr = intToPtr(add(bodyPtr, serviceInfoSizeLlvm), llvm.int8PtrType) memset(bodyWithSkippedServiceInfoPtr, 0, bodySize - serviceInfoSize) } } @@ -528,13 +529,13 @@ internal abstract class FunctionGenerationContext( } protected fun basicBlockInFunction(name: String, locationInfo: LocationInfo?): LLVMBasicBlockRef { - val bb = LLVMAppendBasicBlockInContext(llvmContext, function, name)!! + val bb = LLVMAppendBasicBlockInContext(llvm.llvmContext, function, name)!! update(bb, locationInfo) return bb } fun basicBlock(name: String = "label_", startLocationInfo: LocationInfo?, endLocationInfo: LocationInfo? = startLocationInfo): LLVMBasicBlockRef { - val result = LLVMInsertBasicBlockInContext(llvmContext, this.currentBlock, name)!! + val result = LLVMInsertBasicBlockInContext(llvm.llvmContext, this.currentBlock, name)!! update(result, startLocationInfo, endLocationInfo) LLVMMoveBasicBlockAfter(result, this.currentBlock) return result @@ -552,7 +553,7 @@ internal abstract class FunctionGenerationContext( fun alloca(type: LLVMTypeRef?, name: String = "", variableLocation: VariableDebugLocation? = null): LLVMValueRef { if (isObjectType(type!!)) { appendingTo(localsInitBb) { - val slotAddress = gep(slotsPhi!!, Int32(slotCount).llvm, name) + val slotAddress = gep(slotsPhi!!, llvm.int32(slotCount), name) variableLocation?.let { slotToVariableLocation[slotCount] = it } @@ -675,9 +676,9 @@ internal abstract class FunctionGenerationContext( fun memset(pointer: LLVMValueRef, value: Byte, size: Int, isVolatile: Boolean = false) = call(llvm.memsetFunction, listOf(pointer, - Int8(value).llvm, - Int32(size).llvm, - Int1(isVolatile).llvm)) + llvm.int8(value), + llvm.int32(size), + llvm.int1(isVolatile))) fun call(llvmCallable: LlvmCallable, args: List, resultLifetime: Lifetime = Lifetime.IRRELEVANT, @@ -918,7 +919,7 @@ internal abstract class FunctionGenerationContext( val personalityFunction = llvm.gxxPersonalityFunction.llvmValue // Type of `landingpad` instruction result (depends on personality function): - val landingpadType = structType(int8TypePtr, int32Type) + val landingpadType = llvm.structType(llvm.int8PtrType, llvm.int32Type) val landingpad = LLVMBuildLandingPad(builder, landingpadType, personalityFunction, numClauses, name)!! @@ -951,7 +952,7 @@ internal abstract class FunctionGenerationContext( if (wrapExceptionMode) { LLVMAddClause(landingpad, objcNSExceptionRtti.llvm) } - LLVMAddClause(landingpad, LLVMConstNull(kInt8Ptr)) + LLVMAddClause(landingpad, LLVMConstNull(llvm.int8PtrType)) val fatalForeignExceptionBlock = basicBlock("fatalForeignException", position()?.start) val forwardKotlinExceptionBlock = basicBlock("forwardKotlinException", position()?.start) @@ -1034,7 +1035,7 @@ internal abstract class FunctionGenerationContext( fun catchKotlinException(): LLVMValueRef { val landingpadResult = gxxLandingpad(numClauses = 1, name = "lp") - LLVMAddClause(landingpadResult, LLVMConstNull(kInt8Ptr)) + LLVMAddClause(landingpadResult, LLVMConstNull(llvm.int8PtrType)) // TODO: properly handle C++ exceptions: currently C++ exception can be thrown out from try-finally // bypassing the finally block. @@ -1173,7 +1174,7 @@ internal abstract class FunctionGenerationContext( fun fastPath(): LLVMValueRef { // The fastest optimistic version. - val interfaceTableIndex = and(interfaceTableSize, Int32(interfaceId).llvm) + val interfaceTableIndex = and(interfaceTableSize, llvm.int32(interfaceId)) return gep(interfaceTable, interfaceTableIndex) } @@ -1188,7 +1189,7 @@ internal abstract class FunctionGenerationContext( val fastPathBB = basicBlock("fast_path", startLocationInfo) val slowPathBB = basicBlock("slow_path", startLocationInfo) val takeResBB = basicBlock("take_res", startLocationInfo) - condBr(icmpGe(interfaceTableSize, kImmInt32Zero), fastPathBB, slowPathBB) + condBr(icmpGe(interfaceTableSize, llvm.kImmInt32Zero), fastPathBB, slowPathBB) positionAtEnd(takeResBB) val resultPhi = phi(pointerType(runtime.interfaceTableRecordType)) appendingTo(fastPathBB) { @@ -1197,9 +1198,9 @@ internal abstract class FunctionGenerationContext( addPhiIncoming(resultPhi, currentBlock to fastValue) } appendingTo(slowPathBB) { - val actualInterfaceTableSize = sub(kImmInt32Zero, interfaceTableSize) // -interfaceTableSize + val actualInterfaceTableSize = sub(llvm.kImmInt32Zero, interfaceTableSize) // -interfaceTableSize val slowValue = call(llvm.lookupInterfaceTableRecord, - listOf(interfaceTable, actualInterfaceTableSize, Int32(interfaceId).llvm)) + listOf(interfaceTable, actualInterfaceTableSize, llvm.int32(interfaceId))) br(takeResBB) addPhiIncoming(resultPhi, currentBlock to slowValue) } @@ -1229,9 +1230,9 @@ internal abstract class FunctionGenerationContext( !owner.isInterface -> { // If this is a virtual method of the class - we can call via vtable. val index = context.getLayoutBuilder(owner).vtableIndex(anyMethod ?: irFunction) - val vtablePlace = gep(typeInfoPtr, Int32(1).llvm) // typeInfoPtr + 1 - val vtable = bitcast(kInt8PtrPtr, vtablePlace) - val slot = gep(vtable, Int32(index).llvm) + val vtablePlace = gep(typeInfoPtr, llvm.int32(1)) // typeInfoPtr + 1 + val vtable = bitcast(llvm.int8PtrPtrType, vtablePlace) + val slot = gep(vtable, llvm.int32(index)) load(slot) } @@ -1239,7 +1240,7 @@ internal abstract class FunctionGenerationContext( // Essentially: typeInfo.itable[place(interfaceId)].vtable[method] val itablePlace = context.getLayoutBuilder(owner).itablePlace(irFunction) val interfaceTableRecord = lookupInterfaceTableRecord(typeInfoPtr, itablePlace.interfaceId) - load(gep(load(structGep(interfaceTableRecord, 2 /* vtable */)), Int32(itablePlace.methodIndex).llvm)) + load(gep(load(structGep(interfaceTableRecord, 2 /* vtable */)), llvm.int32(itablePlace.methodIndex))) } } val functionPtrType = pointerType(codegen.getLlvmFunctionType(irFunction)) @@ -1303,7 +1304,7 @@ internal abstract class FunctionGenerationContext( // If global object is imported - import it's storage directly. ObjectStorageKind.PERMANENT, ObjectStorageKind.SHARED -> { - val llvmType = getLLVMType(irClass.defaultType) + val llvmType = irClass.defaultType.toLLVMType(llvm) importGlobal( irClass.globalObjectStorageSymbolName, llvmType, @@ -1358,7 +1359,7 @@ internal abstract class FunctionGenerationContext( br(bbExit) positionAtEnd(bbExit) - val valuePhi = phi(codegen.getLLVMType(irClass.defaultType)) + val valuePhi = phi(irClass.defaultType.toLLVMType(llvm)) addPhiIncoming(valuePhi, bbCurrent to objectVal, bbInitResult to newValue) return valuePhi @@ -1372,7 +1373,7 @@ internal abstract class FunctionGenerationContext( val getterId = context.enumsSupport.enumEntriesMap(enumClass)[enumEntry.name]!!.getterId return call( context.enumsSupport.getValueGetter(enumClass).llvmFunction.llvmValue, - listOf(Int32(getterId).llvm), + listOf(llvm.int32(getterId)), Lifetime.GLOBAL, exceptionHandler ) @@ -1391,8 +1392,8 @@ internal abstract class FunctionGenerationContext( val getClass = llvm.externalFunction(LlvmFunctionProto( "object_getClass", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), origin = context.standardLlvmSymbolsOrigin )) call(getClass, listOf(objCClass), exceptionHandler = exceptionHandler) @@ -1409,7 +1410,7 @@ internal abstract class FunctionGenerationContext( val storedClass = this.load(classPointerGlobal) - val storedClassIsNotNull = this.icmpNe(storedClass, kNullInt8Ptr) + val storedClassIsNotNull = this.icmpNe(storedClass, llvm.kNullInt8Ptr) return this.ifThenElse(storedClassIsNotNull, storedClass) { call( @@ -1457,13 +1458,13 @@ internal abstract class FunctionGenerationContext( appendingTo(prologueBb) { val slots = if (needSlotsPhi || needCleanupLandingpadAndLeaveFrame) - LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!! + LLVMBuildArrayAlloca(builder, kObjHeaderPtr, llvm.int32(slotCount), "")!! else kNullObjHeaderPtrPtr if (needSlots || needCleanupLandingpadAndLeaveFrame) { check(!forbidRuntime) { "Attempt to start a frame where runtime usage is forbidden" } // Zero-init slots. - val slotsMem = bitcast(kInt8Ptr, slots) + val slotsMem = bitcast(llvm.int8PtrType, slots) memset(slotsMem, 0, slotCount * codegen.runtime.pointerSize) } addPhiIncoming(slotsPhi!!, prologueBb to slots) @@ -1514,7 +1515,7 @@ internal abstract class FunctionGenerationContext( switchThreadState(Runnable) } if (needSlots || needCleanupLandingpadAndLeaveFrame) { - call(llvm.enterFrameFunction, listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) + call(llvm.enterFrameFunction, listOf(slotsPhi!!, llvm.int32(vars.skipSlots), llvm.int32(slotCount))) } else { check(!setCurrentFrameIsCalled) } @@ -1587,16 +1588,16 @@ internal abstract class FunctionGenerationContext( private val kotlinExceptionRtti: ConstPointer get() = constPointer(importGlobal( "_ZTI18ExceptionObjHolder", // typeinfo for ObjHolder - int8TypePtr, + llvm.int8PtrType, origin = context.stdlibModule.llvmSymbolOrigin - )).bitcast(int8TypePtr) + )).bitcast(llvm.int8PtrType) private val objcNSExceptionRtti: ConstPointer by lazy { constPointer(importGlobal( "OBJC_EHTYPE_\$_NSException", // typeinfo for NSException* - int8TypePtr, + llvm.int8PtrType, origin = context.stdlibModule.llvmSymbolOrigin - )).bitcast(int8TypePtr) + )).bitcast(llvm.int8PtrType) } //-------------------------------------------------------------------------// @@ -1607,7 +1608,7 @@ internal abstract class FunctionGenerationContext( * This class is introduced to workaround unreachable code handling. */ inner class PositionHolder { - private val builder: LLVMBuilderRef = LLVMCreateBuilderInContext(llvmContext)!! + private val builder: LLVMBuilderRef = LLVMCreateBuilderInContext(llvm.llvmContext)!! fun getBuilder(): LLVMBuilderRef { @@ -1714,7 +1715,7 @@ internal abstract class FunctionGenerationContext( if (needCleanupLandingpadAndLeaveFrame || needSlots) { check(!forbidRuntime) { "Attempt to leave a frame where runtime usage is forbidden" } call(llvm.leaveFrameFunction, - listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) + listOf(slotsPhi!!, llvm.int32(vars.skipSlots), llvm.int32(slotCount))) } if (!stackLocalsManager.isEmpty() && context.memoryModel != MemoryModel.EXPERIMENTAL) { stackLocalsManager.clean(refsOnly = true) // Only bother about not leaving any dangling references. @@ -1762,7 +1763,7 @@ internal class DefaultFunctionGenerationContext( override fun processReturns() { appendingTo(epilogueBb) { when { - returnType == voidType -> { + returnType == llvm.voidType -> { retVoid() } returns.isNotEmpty() -> { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index ac646aaa7ef..ef789046321 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.konan.llvm +import kotlinx.cinterop.toCValues import kotlinx.cinterop.toKString import llvm.* import org.jetbrains.kotlin.backend.konan.* @@ -20,8 +21,6 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.uniqueName -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.cast import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty @@ -202,7 +201,7 @@ internal interface ContextUtils : RuntimeAware { */ val IrFunction.entryPointAddress: ConstPointer get() { - val result = LLVMConstBitCast(this.llvmFunction.llvmValue, int8TypePtr)!! + val result = LLVMConstBitCast(this.llvmFunction.llvmValue, llvm.int8PtrType)!! return constPointer(result) } @@ -236,15 +235,6 @@ internal interface ContextUtils : RuntimeAware { */ internal fun stringAsBytes(str: String) = str.toByteArray(Charsets.UTF_8) -internal val String.localHash: LocalHash - get() = LocalHash(localHash(stringAsBytes(this))) - -internal val Name.localHash: LocalHash - get() = this.toString().localHash - -internal val FqName.localHash: LocalHash - get() = this.toString().localHash - internal class InitializersGenerationState { val fileGlobalInitStates = mutableMapOf() val fileThreadLocalInitStates = mutableMapOf() @@ -271,7 +261,41 @@ internal class InitializersGenerationState { && moduleGlobalInitializers.isEmpty() && moduleThreadLocalInitializers.isEmpty() } -internal class Llvm(val context: Context, val module: LLVMModuleRef) : RuntimeAware { +internal class ConstInt1(llvm: Llvm, val value: Boolean) : ConstValue { + override val llvm = LLVMConstInt(llvm.int1Type, if (value) 1 else 0, 1)!! +} + +internal class ConstInt8(llvm: Llvm, val value: Byte) : ConstValue { + override val llvm = LLVMConstInt(llvm.int8Type, value.toLong(), 1)!! +} + +internal class ConstInt16(llvm: Llvm, val value: Short) : ConstValue { + override val llvm = LLVMConstInt(llvm.int16Type, value.toLong(), 1)!! +} + +internal class ConstChar16(llvm: Llvm, val value: Char) : ConstValue { + override val llvm = LLVMConstInt(llvm.int16Type, value.code.toLong(), 1)!! +} + +internal class ConstInt32(llvm: Llvm, val value: Int) : ConstValue { + override val llvm = LLVMConstInt(llvm.int32Type, value.toLong(), 1)!! +} + +internal class ConstInt64(llvm: Llvm, val value: Long) : ConstValue { + override val llvm = LLVMConstInt(llvm.int64Type, value, 1)!! +} + +internal class ConstFloat32(llvm: Llvm, val value: Float) : ConstValue { + override val llvm = LLVMConstReal(llvm.floatType, value.toDouble())!! +} + +internal class ConstFloat64(llvm: Llvm, val value: Double) : ConstValue { + override val llvm = LLVMConstReal(llvm.doubleType, value)!! +} + +@Suppress("FunctionName", "PropertyName", "PrivatePropertyName") +internal class Llvm(private val context: Context, val module: LLVMModuleRef) : RuntimeAware { + val llvmContext = context.generationState.llvmContext private fun importFunction(name: String, otherModule: LLVMModuleRef): LlvmCallable { if (LLVMGetNamedFunction(module, name) != null) { @@ -303,7 +327,7 @@ internal class Llvm(val context: Context, val module: LLVMModuleRef) : RuntimeAw } private fun importMemset(): LlvmCallable { - val functionType = functionType(voidType, false, int8TypePtr, int8Type, int32Type, int1Type) + val functionType = functionType(voidType, false, int8PtrType, int8Type, int32Type, int1Type) return llvmIntrinsic("llvm.memset.p0i8.i32", functionType) } @@ -440,7 +464,7 @@ internal class Llvm(val context: Context, val module: LLVMModuleRef) : RuntimeAw val additionalProducedBitcodeFiles = mutableListOf() - val staticData = KotlinStaticData(context, module) + val staticData = KotlinStaticData(context, this, module) private val target = context.config.target @@ -535,66 +559,6 @@ internal class Llvm(val context: Context, val module: LLVMModuleRef) : RuntimeAw } } - var tlsCount = 0 - - val tlsKey by lazy { - val global = LLVMAddGlobal(module, kInt8Ptr, "__KonanTlsKey")!! - LLVMSetLinkage(global, LLVMLinkage.LLVMInternalLinkage) - LLVMSetInitializer(global, LLVMConstNull(kInt8Ptr)) - global - } - - private val personalityFunctionName = when (target) { - KonanTarget.IOS_ARM32 -> "__gxx_personality_sj0" - KonanTarget.MINGW_X64 -> "__gxx_personality_seh0" - else -> "__gxx_personality_v0" - } - - val cxxStdTerminate = externalFunction(LlvmFunctionProto( - "_ZSt9terminatev", // mangled C++ 'std::terminate' - returnType = LlvmRetType(voidType), - functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), - origin = context.standardLlvmSymbolsOrigin - )) - - val gxxPersonalityFunction = externalFunction(LlvmFunctionProto( - personalityFunctionName, - returnType = LlvmRetType(int32Type), - functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), - isVararg = true, - origin = context.standardLlvmSymbolsOrigin - )) - - val cxaBeginCatchFunction = externalFunction(LlvmFunctionProto( - "__cxa_begin_catch", - returnType = LlvmRetType(int8TypePtr), - functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), - parameterTypes = listOf(LlvmParamType(int8TypePtr)), - origin = context.standardLlvmSymbolsOrigin - )) - - val cxaEndCatchFunction = externalFunction(LlvmFunctionProto( - "__cxa_end_catch", - returnType = LlvmRetType(voidType), - functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), - origin = context.standardLlvmSymbolsOrigin - )) - - val memsetFunction = importMemset() - //val memcpyFunction = importMemcpy() - - val llvmTrap = llvmIntrinsic( - "llvm.trap", - functionType(voidType, false), - "cold", "noreturn", "nounwind" - ) - - val llvmEhTypeidFor = llvmIntrinsic( - "llvm.eh.typeid.for", - functionType(int32Type, false, int8TypePtr), - "nounwind", "readnone" - ) - val usedFunctions = mutableListOf() val usedGlobals = mutableListOf() val compilerUsedGlobals = mutableListOf() @@ -629,14 +593,106 @@ internal class Llvm(val context: Context, val module: LLVMModuleRef) : RuntimeAw } } - val llvmInt1 = int1Type - val llvmInt8 = int8Type - val llvmInt16 = int16Type - val llvmInt32 = int32Type - val llvmInt64 = int64Type - val llvmFloat = floatType - val llvmDouble = doubleType - val llvmVector128 = vector128Type + val int1Type = LLVMInt1TypeInContext(llvmContext)!! + val int8Type = LLVMInt8TypeInContext(llvmContext)!! + val int16Type = LLVMInt16TypeInContext(llvmContext)!! + val int32Type = LLVMInt32TypeInContext(llvmContext)!! + val int64Type = LLVMInt64TypeInContext(llvmContext)!! + val floatType = LLVMFloatTypeInContext(llvmContext)!! + val doubleType = LLVMDoubleTypeInContext(llvmContext)!! + val vector128Type = LLVMVectorType(floatType, 4)!! + val voidType = LLVMVoidTypeInContext(llvmContext)!! + val int8PtrType = pointerType(int8Type) + val int8PtrPtrType = pointerType(int8PtrType) + + fun structType(vararg types: LLVMTypeRef): LLVMTypeRef = structType(types.toList()) + + fun struct(vararg elements: ConstValue) = Struct(structType(elements.map { it.llvmType }), *elements) + + private fun structType(types: List): LLVMTypeRef = + LLVMStructTypeInContext(llvmContext, types.toCValues(), types.size, 0)!! + + fun constInt1(value: Boolean) = ConstInt1(this, value) + fun constInt8(value: Byte) = ConstInt8(this, value) + fun constInt16(value: Short) = ConstInt16(this, value) + fun constChar16(value: Char) = ConstChar16(this, value) + fun constInt32(value: Int) = ConstInt32(this, value) + fun constInt64(value: Long) = ConstInt64(this, value) + fun constFloat32(value: Float) = ConstFloat32(this, value) + fun constFloat64(value: Double) = ConstFloat64(this, value) + + fun int1(value: Boolean): LLVMValueRef = constInt1(value).llvm + fun int8(value: Byte): LLVMValueRef = constInt8(value).llvm + fun int16(value: Short): LLVMValueRef = constInt16(value).llvm + fun char16(value: Char): LLVMValueRef = constChar16(value).llvm + fun int32(value: Int): LLVMValueRef = constInt32(value).llvm + fun int64(value: Long): LLVMValueRef = constInt64(value).llvm + fun float32(value: Float): LLVMValueRef = constFloat32(value).llvm + fun float64(value: Double): LLVMValueRef = constFloat64(value).llvm + + val kNullInt8Ptr by lazy { LLVMConstNull(int8PtrType)!! } + val kNullInt32Ptr by lazy { LLVMConstNull(pointerType(int32Type))!! } + val kImmInt32Zero by lazy { int32(0) } + val kImmInt32One by lazy { int32(1) } + + val memsetFunction = importMemset() + + val llvmTrap = llvmIntrinsic( + "llvm.trap", + functionType(voidType, false), + "cold", "noreturn", "nounwind" + ) + + val llvmEhTypeidFor = llvmIntrinsic( + "llvm.eh.typeid.for", + functionType(int32Type, false, int8PtrType), + "nounwind", "readnone" + ) + + var tlsCount = 0 + + val tlsKey by lazy { + val global = LLVMAddGlobal(module, int8PtrType, "__KonanTlsKey")!! + LLVMSetLinkage(global, LLVMLinkage.LLVMInternalLinkage) + LLVMSetInitializer(global, LLVMConstNull(int8PtrType)) + global + } + + private val personalityFunctionName = when (target) { + KonanTarget.IOS_ARM32 -> "__gxx_personality_sj0" + KonanTarget.MINGW_X64 -> "__gxx_personality_seh0" + else -> "__gxx_personality_v0" + } + + val cxxStdTerminate = externalFunction(LlvmFunctionProto( + "_ZSt9terminatev", // mangled C++ 'std::terminate' + returnType = LlvmRetType(voidType), + functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), + origin = context.standardLlvmSymbolsOrigin + )) + + val gxxPersonalityFunction = externalFunction(LlvmFunctionProto( + personalityFunctionName, + returnType = LlvmRetType(int32Type), + functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), + isVararg = true, + origin = context.standardLlvmSymbolsOrigin + )) + + val cxaBeginCatchFunction = externalFunction(LlvmFunctionProto( + "__cxa_begin_catch", + returnType = LlvmRetType(int8PtrType), + functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), + parameterTypes = listOf(LlvmParamType(int8PtrType)), + origin = context.standardLlvmSymbolsOrigin + )) + + val cxaEndCatchFunction = externalFunction(LlvmFunctionProto( + "__cxa_end_catch", + returnType = LlvmRetType(voidType), + functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), + origin = context.standardLlvmSymbolsOrigin + )) private fun getSizeOfReturnTypeInBits(functionPointer: LLVMValueRef): Long { // LLVMGetElementType is called because we need to dereference a pointer to function. diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt index 0481efd64b0..a9e8ccd5c8b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt @@ -7,37 +7,31 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.* -import org.jetbrains.kotlin.backend.konan.optimizations.DataFlowIR import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.types.isUnit -private fun RuntimeAware.getLlvmType(primitiveBinaryType: PrimitiveBinaryType?) = when (primitiveBinaryType) { - null -> this.kObjHeaderPtr +private fun PrimitiveBinaryType?.toLlvmType(llvm: Llvm) = when (this) { + null -> llvm.kObjHeaderPtr - PrimitiveBinaryType.BOOLEAN -> int1Type - PrimitiveBinaryType.BYTE -> int8Type - PrimitiveBinaryType.SHORT -> int16Type - PrimitiveBinaryType.INT -> int32Type - PrimitiveBinaryType.LONG -> int64Type - PrimitiveBinaryType.FLOAT -> floatType - PrimitiveBinaryType.DOUBLE -> doubleType + PrimitiveBinaryType.BOOLEAN -> llvm.int1Type + PrimitiveBinaryType.BYTE -> llvm.int8Type + PrimitiveBinaryType.SHORT -> llvm.int16Type + PrimitiveBinaryType.INT -> llvm.int32Type + PrimitiveBinaryType.LONG -> llvm.int64Type + PrimitiveBinaryType.FLOAT -> llvm.floatType + PrimitiveBinaryType.DOUBLE -> llvm.doubleType - PrimitiveBinaryType.VECTOR128 -> vector128Type - PrimitiveBinaryType.POINTER -> int8TypePtr + PrimitiveBinaryType.VECTOR128 -> llvm.vector128Type + PrimitiveBinaryType.POINTER -> llvm.int8PtrType } -internal fun RuntimeAware.getLLVMType(type: IrType): LLVMTypeRef = - runtime.calculatedLLVMTypes.getOrPut(type) { getLlvmType(type.computePrimitiveBinaryTypeOrNull()) } - -internal fun RuntimeAware.getLLVMType(type: DataFlowIR.Type) = - getLlvmType(type.primitiveBinaryType) +internal fun IrType.toLLVMType(llvm: Llvm): LLVMTypeRef = + llvm.runtime.calculatedLLVMTypes.getOrPut(this) { computePrimitiveBinaryTypeOrNull().toLlvmType(llvm) } internal fun IrType.isVoidAsReturnType() = isUnit() || isNothing() -internal fun RuntimeAware.getLLVMReturnType(type: IrType): LLVMTypeRef { - return when { - type.isVoidAsReturnType() -> voidType - else -> getLLVMType(type) - } +internal fun IrType.getLLVMReturnType(llvm: Llvm) = when { + isVoidAsReturnType() -> llvm.voidType + else -> toLLVMType(llvm) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt index b11fac07313..db6fadae790 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt @@ -25,10 +25,6 @@ import org.jetbrains.kotlin.konan.file.File internal object DWARF { val producer = "konanc ${CompilerVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}" - - /* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */ - val dwarfVersionMetaDataNodeName get() = "Dwarf Version".mdString() - val dwarfDebugInfoMetaDataNodeName get() = "Debug Info Version".mdString() const val debugInfoVersion = 3 /* TODO: configurable? */ /** @@ -110,9 +106,12 @@ internal class DebugInfo(override val context: Context) : ContextUtils { * !5 = !{i32 1, !"PIC Level", i32 2} * !6 = !{!"Apple LLVM version 8.0.0 (clang-800.0.38)"} */ - val llvmTwo = Int32(2).llvm - val dwarfVersion = node(llvmTwo, DWARF.dwarfVersionMetaDataNodeName, Int32(DWARF.dwarfVersion(config)).llvm) - val nodeDebugInfoVersion = node(llvmTwo, DWARF.dwarfDebugInfoMetaDataNodeName, Int32(DWARF.debugInfoVersion).llvm) + val llvmTwo = llvm.int32(2) + /* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */ + val dwarfVersionMetaDataNodeName = "Dwarf Version".mdString(llvm.llvmContext) + val dwarfDebugInfoMetaDataNodeName = "Debug Info Version".mdString(llvm.llvmContext) + val dwarfVersion = node(llvm.llvmContext, llvmTwo, dwarfVersionMetaDataNodeName, llvm.int32(DWARF.dwarfVersion(config))) + val nodeDebugInfoVersion = node(llvm.llvmContext, llvmTwo, dwarfDebugInfoMetaDataNodeName, llvm.int32(DWARF.debugInfoVersion)) val llvmModuleFlags = "llvm.module.flags" LLVMAddNamedMetadataOperand(llvm.module, llvmModuleFlags, dwarfVersion) LLVMAddNamedMetadataOperand(llvm.module, llvmModuleFlags, nodeDebugInfoVersion) @@ -142,17 +141,17 @@ internal class DebugInfo(override val context: Context) : ContextUtils { val types = mutableMapOf() private val llvmTypes = mapOf( - context.irBuiltIns.booleanType to llvm.llvmInt8, - context.irBuiltIns.byteType to llvm.llvmInt8, - context.irBuiltIns.charType to llvm.llvmInt16, - context.irBuiltIns.shortType to llvm.llvmInt16, - context.irBuiltIns.intType to llvm.llvmInt32, - context.irBuiltIns.longType to llvm.llvmInt64, - context.irBuiltIns.floatType to llvm.llvmFloat, - context.irBuiltIns.doubleType to llvm.llvmDouble) + context.irBuiltIns.booleanType to llvm.int8Type, + context.irBuiltIns.byteType to llvm.int8Type, + context.irBuiltIns.charType to llvm.int16Type, + context.irBuiltIns.shortType to llvm.int16Type, + context.irBuiltIns.intType to llvm.int32Type, + context.irBuiltIns.longType to llvm.int64Type, + context.irBuiltIns.floatType to llvm.floatType, + context.irBuiltIns.doubleType to llvm.doubleType) private val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap() private val llvmTypeAlignments = llvmTypes.map { it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value) }.toMap() - private val otherLlvmType = LLVMPointerType(int64Type, 0)!! + private val otherLlvmType = LLVMPointerType(llvm.int64Type, 0)!! private val otherTypeSize = LLVMSizeOfTypeInBits(llvmTargetData, otherLlvmType) private val otherTypeAlignment = LLVMPreferredAlignmentOfType(llvmTargetData, otherLlvmType) @@ -194,14 +193,14 @@ internal class DebugInfo(override val context: Context) : ContextUtils { private fun IrType.llvmType(): LLVMTypeRef = llvmTypes.getOrElse(this@llvmType) { when (computePrimitiveBinaryTypeOrNull()) { - PrimitiveBinaryType.BOOLEAN -> llvm.llvmInt1 - PrimitiveBinaryType.BYTE -> llvm.llvmInt8 - PrimitiveBinaryType.SHORT -> llvm.llvmInt16 - PrimitiveBinaryType.INT -> llvm.llvmInt32 - PrimitiveBinaryType.LONG -> llvm.llvmInt64 - PrimitiveBinaryType.FLOAT -> llvm.llvmFloat - PrimitiveBinaryType.DOUBLE -> llvm.llvmDouble - PrimitiveBinaryType.VECTOR128 -> llvm.llvmVector128 + PrimitiveBinaryType.BOOLEAN -> llvm.int1Type + PrimitiveBinaryType.BYTE -> llvm.int8Type + PrimitiveBinaryType.SHORT -> llvm.int16Type + PrimitiveBinaryType.INT -> llvm.int32Type + PrimitiveBinaryType.LONG -> llvm.int64Type + PrimitiveBinaryType.FLOAT -> llvm.floatType + PrimitiveBinaryType.DOUBLE -> llvm.doubleType + PrimitiveBinaryType.VECTOR128 -> llvm.vector128Type else -> otherLlvmType } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt index 1d745eb99e4..a499d6445df 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt @@ -10,6 +10,4 @@ import org.jetbrains.kotlin.backend.common.serialization.cityHash64 @OptIn(ExperimentalUnsignedTypes::class) internal fun localHash(data: ByteArray): Long { return cityHash64(data).toLong() -} - -internal class LocalHash(val value: Long) : ConstValue by Int64(value) +} \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt index 0fb580bd177..e83e6acbbdc 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt @@ -268,7 +268,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val typeArgument = constant.typeArguments[0] val typeArgumentClass = typeArgument.getClass()!! val typeInfo = codegen.typeInfoValue(typeArgumentClass) - listOf(constPointer(typeInfo).bitcast(int8TypePtr)) + listOf(constPointer(typeInfo).bitcast(codegen.llvm.int8PtrType)) } ConstantConstructorIntrinsicType.KTYPE_IMPL -> reportNonLoweredIntrinsic(intrinsicType) @@ -289,10 +289,10 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv args.single() private fun FunctionGenerationContext.emitIsExperimentalMM(): LLVMValueRef = - Int1(context.memoryModel == MemoryModel.EXPERIMENTAL).llvm + llvm.int1(context.memoryModel == MemoryModel.EXPERIMENTAL) private fun FunctionGenerationContext.emitGetNativeNullPtr(): LLVMValueRef = - kNullInt8Ptr + llvm.kNullInt8Ptr private fun FunctionGenerationContext.emitNativePtrPlusLong(args: List): LLVMValueRef = gep(args[0], args[1]) @@ -315,7 +315,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv } private fun FunctionGenerationContext.emitGetPointerSize(): LLVMValueRef = - Int32(LLVMPointerSize(codegen.llvmTargetData)).llvm + llvm.int32(LLVMPointerSize(codegen.llvmTargetData)) private fun FunctionGenerationContext.emitReadPrimitive(callSite: IrCall, args: List): LLVMValueRef { val pointerType = pointerType(callSite.llvmReturnType) @@ -326,7 +326,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv private fun FunctionGenerationContext.emitWritePrimitive(callSite: IrCall, args: List): LLVMValueRef { val function = callSite.symbol.owner - val pointerType = pointerType(codegen.getLLVMType(function.valueParameters.last().type)) + val pointerType = pointerType(function.valueParameters.last().type.toLLVMType(llvm)) val rawPointer = args[1] val pointer = bitcast(pointerType, rawPointer) store(args[2], pointer) @@ -335,7 +335,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv private fun FunctionGenerationContext.emitReadBits(args: List): LLVMValueRef { val ptr = args[0] - assert(ptr.type == int8TypePtr) + assert(ptr.type == llvm.int8PtrType) val offset = extractConstUnsignedInt(args[1]) val size = extractConstUnsignedInt(args[2]).toInt() @@ -347,9 +347,9 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv // Note: LLVM allows to read without padding tail up to byte boundary, but the result seems to be incorrect. val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum - val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!! + val bitsWithPaddingType = LLVMIntTypeInContext(llvm.llvmContext, bitsWithPaddingNum)!! - val bitsWithPaddingPtr = bitcast(org.jetbrains.kotlin.backend.konan.llvm.pointerType(bitsWithPaddingType), gep(ptr, org.jetbrains.kotlin.backend.konan.llvm.Int64(offset / 8).llvm)) + val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(ptr, llvm.int64(offset / 8))) val bitsWithPadding = load(bitsWithPaddingPtr).setUnaligned() val bits = shr( @@ -358,28 +358,28 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv ) return when { bitsWithPaddingNum == 64 -> bits - bitsWithPaddingNum > 64 -> trunc(bits, org.jetbrains.kotlin.backend.konan.llvm.int64Type) - else -> ext(bits, org.jetbrains.kotlin.backend.konan.llvm.int64Type, signed) + bitsWithPaddingNum > 64 -> trunc(bits, llvm.int64Type) + else -> ext(bits, llvm.int64Type, signed) } } private fun FunctionGenerationContext.emitWriteBits(args: List): LLVMValueRef { val ptr = args[0] - assert(ptr.type == int8TypePtr) + assert(ptr.type == llvm.int8PtrType) val offset = extractConstUnsignedInt(args[1]) val size = extractConstUnsignedInt(args[2]).toInt() val value = args[3] - assert(value.type == int64Type) + assert(value.type == llvm.int64Type) - val bitsType = LLVMIntTypeInContext(llvmContext, size)!! + val bitsType = LLVMIntTypeInContext(llvm.llvmContext, size)!! val prefixBitsNum = (offset % 8).toInt() val suffixBitsNum = (8 - ((size + offset) % 8).toInt()) % 8 val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum - val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!! + val bitsWithPaddingType = LLVMIntTypeInContext(llvm.llvmContext, bitsWithPaddingNum)!! // 0011111000: val discardBitsMask = LLVMConstShl( @@ -392,7 +392,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val preservedBitsMask = LLVMConstNot(discardBitsMask)!! - val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(ptr, Int64(offset / 8).llvm)) + val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(ptr, llvm.int64(offset / 8))) val bits = trunc(value, bitsType) @@ -420,17 +420,13 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val receiver = args[0] val superClass = args[1] - val structType = structType(kInt8Ptr, kInt8Ptr) + val structType = llvm.structType(llvm.int8PtrType, llvm.int8PtrType) val ptr = alloca(structType) - store(receiver, LLVMBuildGEP(builder, ptr, cValuesOf(kImmZero, kImmZero), 2, "")!!) - store(superClass, LLVMBuildGEP(builder, ptr, cValuesOf(kImmZero, kImmOne), 2, "")!!) - return bitcast(int8TypePtr, ptr) + store(receiver, LLVMBuildGEP(builder, ptr, cValuesOf(llvm.kImmInt32Zero, llvm.kImmInt32Zero), 2, "")!!) + store(superClass, LLVMBuildGEP(builder, ptr, cValuesOf(llvm.kImmInt32Zero, llvm.kImmInt32One), 2, "")!!) + return bitcast(llvm.int8PtrType, ptr) } - // TODO: Find better place for these guys. - private val kImmZero = LLVMConstInt(int32Type, 0, 1)!! - private val kImmOne = LLVMConstInt(int32Type, 1, 1)!! - private fun FunctionGenerationContext.emitGetObjCClass(callSite: IrCall): LLVMValueRef { val typeArgument = callSite.getTypeArgument(0) return getObjCClass(typeArgument!!.getClass()!!, environment.exceptionHandler) @@ -439,8 +435,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv private fun FunctionGenerationContext.emitObjCGetMessenger(args: List, isStret: Boolean): LLVMValueRef { val messengerNameSuffix = if (isStret) "_stret" else "" - val functionReturnType = LlvmRetType(int8TypePtr) - val functionParameterTypes = listOf(LlvmParamType(int8TypePtr), LlvmParamType(int8TypePtr)) + val functionReturnType = LlvmRetType(llvm.int8PtrType) + val functionParameterTypes = listOf(LlvmParamType(llvm.int8PtrType), LlvmParamType(llvm.int8PtrType)) val libobjc = context.standardLlvmSymbolsOrigin val normalMessenger = codegen.llvm.externalFunction(LlvmFunctionProto( @@ -460,13 +456,13 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val superClass = args.single() val messenger = LLVMBuildSelect(builder, - If = icmpEq(superClass, kNullInt8Ptr), + If = icmpEq(superClass, llvm.kNullInt8Ptr), Then = normalMessenger.llvmValue, Else = superMessenger.llvmValue, Name = "" )!! - return bitcast(int8TypePtr, messenger) + return bitcast(llvm.int8PtrType, messenger) } private fun FunctionGenerationContext.emitAreEqualByValue(args: List): LLVMValueRef { @@ -477,7 +473,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv LLVMTypeKind.LLVMFloatTypeKind, LLVMTypeKind.LLVMDoubleTypeKind, LLVMTypeKind.LLVMVectorTypeKind -> { // TODO LLVM API does not provide guarantee for LLVMIntTypeInContext availability for longer types; consider meaningful diag message instead of NPE - val integerType = LLVMIntTypeInContext(llvmContext, first.type.sizeInBits())!! + val integerType = LLVMIntTypeInContext(llvm.llvmContext, first.type.sizeInBits())!! icmpEq(bitcast(integerType, first), bitcast(integerType, second)) } LLVMTypeKind.LLVMIntegerTypeKind, LLVMTypeKind.LLVMPointerTypeKind -> icmpEq(first, second) @@ -508,7 +504,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv ) { "Invalid vector element type ${LLVMGetTypeKind(callSite.llvmReturnType)}"} val elementCount = vectorSize / elementSize - emitThrowIfOOB(index, Int32((elementCount)).llvm) + emitThrowIfOOB(index, llvm.int32((elementCount))) val targetType = LLVMVectorType(callSite.llvmReturnType, elementCount)!! return extractElement( @@ -554,11 +550,11 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv private fun FunctionGenerationContext.emitShift(op: LLVMOpcode, args: List): LLVMValueRef { val (first, second) = args - val shift = if (first.type == int64Type) { - val tmp = and(second, Int32(63).llvm) - zext(tmp, int64Type) + val shift = if (first.type == llvm.int64Type) { + val tmp = and(second, llvm.int32(63)) + zext(tmp, llvm.int64Type) } else { - and(second, Int32(31).llvm) + and(second, llvm.int32(31)) } return LLVMBuildBinOp(builder, op, first, shift, "")!! } @@ -722,8 +718,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val (first, second) = args val equal = icmpEq(first, second) val less = if (signed) icmpLt(first, second) else icmpULt(first, second) - val tmp = select(less, Int32(-1).llvm, Int32(1).llvm) - return select(equal, Int32(0).llvm, tmp) + val tmp = select(less, llvm.int32(-1), llvm.int32(1)) + return select(equal, llvm.int32(0), tmp) } private fun FunctionGenerationContext.emitSignedCompareTo(args: List) = @@ -732,13 +728,13 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv private fun FunctionGenerationContext.emitUnsignedCompareTo(args: List) = emitCompareTo(args, signed = false) - private fun makeConstOfType(type: LLVMTypeRef, value: Int): LLVMValueRef = when (type) { - int8Type -> Int8(value.toByte()).llvm - int16Type -> Char16(value.toChar()).llvm - int32Type -> Int32(value).llvm - int64Type -> Int64(value.toLong()).llvm - floatType -> Float32(value.toFloat()).llvm - doubleType -> Float64(value.toDouble()).llvm + private fun FunctionGenerationContext.makeConstOfType(type: LLVMTypeRef, value: Int): LLVMValueRef = when (type) { + llvm.int8Type -> llvm.int8(value.toByte()) + llvm.int16Type -> llvm.char16(value.toChar()) + llvm.int32Type -> llvm.int32(value) + llvm.int64Type -> llvm.int64(value.toLong()) + llvm.floatType -> llvm.float32(value.toFloat()) + llvm.doubleType -> llvm.float64(value.toDouble()) else -> context.reportCompilationError("Unexpected primitive type: $type") } } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index f19f283f4aa..9771cdf4cde 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -454,10 +454,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map 0) { val memory = LLVMGetParam(initFunction, 1)!! - call(llvm.addTLSRecord, listOf(memory, llvm.tlsKey, Int32(llvm.tlsCount).llvm)) + call(llvm.addTLSRecord, listOf(memory, llvm.tlsKey, llvm.int32(llvm.tlsCount))) } ret(null) } @@ -546,7 +546,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map val parameter = codegen.param(function, i) - assert(codegen.getLLVMType(irParameter.type) == parameter.type) + assert(irParameter.type.toLLVMType(llvm) == parameter.type) irParameter to parameter }.toMap() } private fun getGlobalInitStateFor(file: IrFile): LLVMValueRef = llvm.initializersGenerationState.fileGlobalInitStates.getOrPut(file) { - codegen.addGlobal("state_global$${file.fileEntry.name}", int32Type, false).also { - LLVMSetInitializer(it, Int32(FILE_NOT_INITIALIZED).llvm) + codegen.addGlobal("state_global$${file.fileEntry.name}", llvm.int32Type, false).also { + LLVMSetInitializer(it, llvm.int32(FILE_NOT_INITIALIZED)) } } private fun getThreadLocalInitStateFor(file: IrFile): AddressAccess = llvm.initializersGenerationState.fileThreadLocalInitStates.getOrPut(file) { - codegen.addKotlinThreadLocal("state_thread_local$${file.fileEntry.name}", int32Type) + codegen.addKotlinThreadLocal("state_thread_local$${file.fileEntry.name}", llvm.int32Type) } override fun visitFunction(declaration: IrFunction) { @@ -952,7 +952,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map */ @Suppress("UNCHECKED_CAST") - when (value.kind) { - IrConstKind.Null -> return constPointer(codegen.kNullObjHeaderPtr) - IrConstKind.Boolean -> when (value.value) { - true -> return Int1(true) - false -> return Int1(false) - } - IrConstKind.Char -> return Char16(value.value as Char) - IrConstKind.Byte -> return Int8(value.value as Byte) - IrConstKind.Short -> return Int16(value.value as Short) - IrConstKind.Int -> return Int32(value.value as Int) - IrConstKind.Long -> return Int64(value.value as Long) - IrConstKind.String -> return evaluateStringConst(value as IrConst) - IrConstKind.Float -> return Float32(value.value as Float) - IrConstKind.Double -> return Float64(value.value as Double) + return when (value.kind) { + IrConstKind.Null -> constPointer(codegen.kNullObjHeaderPtr) + IrConstKind.Boolean -> llvm.constInt1(value.value as Boolean) + IrConstKind.Char -> llvm.constChar16(value.value as Char) + IrConstKind.Byte -> llvm.constInt8(value.value as Byte) + IrConstKind.Short -> llvm.constInt16(value.value as Short) + IrConstKind.Int -> llvm.constInt32(value.value as Int) + IrConstKind.Long -> llvm.constInt64(value.value as Long) + IrConstKind.String -> evaluateStringConst(value as IrConst) + IrConstKind.Float -> llvm.constFloat32(value.value as Float) + IrConstKind.Double -> llvm.constFloat64(value.value as Double) } - TODO(ir2string(value)) } //-------------------------------------------------------------------------// @@ -1893,9 +1889,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map() using (SuspendableExpressionScope(resumePoints)) { - functionGenerationContext.condBr(functionGenerationContext.icmpEq(suspensionPointId, kNullInt8Ptr), bbStart, bbDispatch) + functionGenerationContext.condBr(functionGenerationContext.icmpEq(suspensionPointId, llvm.kNullInt8Ptr), bbStart, bbDispatch) functionGenerationContext.positionAtEnd(bbStart) val result = evaluateExpression(expression.result, resultSlot) @@ -2362,8 +2358,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map { - assert(args.isNotEmpty() && args[0].type == int32Type) + assert(args.isNotEmpty() && args[0].type == llvm.int32Type) functionGenerationContext.allocArray(constructedClass, args[0], resultLifetime(callee), currentCodeContext.exceptionHandler, resultSlot = resultSlot) } constructedClass == context.ir.symbols.string.owner -> { // TODO: consider returning the empty string literal instead. assert(args.isEmpty()) - functionGenerationContext.allocArray(constructedClass, count = kImmZero, + functionGenerationContext.allocArray(constructedClass, count = llvm.kImmInt32Zero, lifetime = resultLifetime(callee), exceptionHandler = currentCodeContext.exceptionHandler, resultSlot = resultSlot) } @@ -2550,7 +2546,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map): LLVMValueRef { @@ -2678,7 +2672,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map functionGenerationContext.switchThreadState(ThreadState.Runnable) } - if (llvmCallable.returnType == voidType) { + if (llvmCallable.returnType == llvm.voidType) { return codegen.theUnitInstanceRef.llvm } @@ -2706,7 +2700,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { if (args.isEmpty()) return - val argsCasted = args.map { constPointer(it).bitcast(int8TypePtr) } - val llvmUsedGlobal = llvm.staticData.placeGlobalArray(name, int8TypePtr, argsCasted) + val argsCasted = args.map { constPointer(it).bitcast(llvm.int8PtrType) } + val llvmUsedGlobal = llvm.staticData.placeGlobalArray(name, llvm.int8PtrType, argsCasted) LLVMSetLinkage(llvmUsedGlobal.llvmGlobal, LLVMLinkage.LLVMAppendingLinkage) LLVMSetSection(llvmUsedGlobal.llvmGlobal, "llvm.metadata") @@ -2737,7 +2731,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map null SourceInfoType.LIBBACKTRACE -> "Kotlin_getSourceInfo_libbacktrace" @@ -2773,23 +2767,23 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { generateFunctionNoRuntime(codegen, ctorFunction) { val initGuardName = ctorFunction.name.orEmpty() + "_guard" - val initGuard = LLVMAddGlobal(llvm.module, int32Type, initGuardName) - LLVMSetInitializer(initGuard, kImmZero) + val initGuard = LLVMAddGlobal(llvm.module, llvm.int32Type, initGuardName) + LLVMSetInitializer(initGuard, llvm.kImmInt32Zero) LLVMSetLinkage(initGuard, LLVMLinkage.LLVMPrivateLinkage) val bbInited = basicBlock("inited", null) val bbNeedInit = basicBlock("need_init", null) val value = LLVMBuildLoad(builder, initGuard, "")!! - condBr(icmpEq(value, kImmZero), bbNeedInit, bbInited) + condBr(icmpEq(value, llvm.kImmInt32Zero), bbNeedInit, bbInited) appendingTo(bbInited) { ret(null) } appendingTo(bbNeedInit) { - LLVMBuildStore(builder, kImmOne, initGuard) + LLVMBuildStore(builder, llvm.kImmInt32One, initGuard) // TODO: shall we put that into the try block? initializers.forEach { @@ -2970,9 +2964,10 @@ internal class LocationInfo(val scope: DIScopeOpaqueRef, val inlinedAt: LocationInfo? = null) internal fun Context.generateRuntimeConstantsModule() : LLVMModuleRef { - val llvmModule = LLVMModuleCreateWithNameInContext("constants", llvmContext)!! + val llvm = generationState.llvm + val llvmModule = LLVMModuleCreateWithNameInContext("constants", generationState.llvmContext)!! LLVMSetDataLayout(llvmModule, generationState.runtime.dataLayout) - val static = StaticData(llvmModule) + val static = StaticData(llvmModule, llvm) fun setRuntimeConstGlobal(name: String, value: ConstValue) { val global = static.placeGlobal(name, value) @@ -2980,15 +2975,15 @@ internal fun Context.generateRuntimeConstantsModule() : LLVMModuleRef { global.setLinkage(LLVMLinkage.LLVMExternalLinkage) } - setRuntimeConstGlobal("Kotlin_needDebugInfo", Int32(if (shouldContainDebugInfo()) 1 else 0)) - setRuntimeConstGlobal("Kotlin_runtimeAssertsMode", Int32(config.runtimeAssertsMode.value)) + setRuntimeConstGlobal("Kotlin_needDebugInfo", llvm.constInt32(if (shouldContainDebugInfo()) 1 else 0)) + setRuntimeConstGlobal("Kotlin_runtimeAssertsMode", llvm.constInt32(config.runtimeAssertsMode.value)) val runtimeLogs = config.runtimeLogs?.let { static.cStringLiteral(it) - } ?: NullPointer(int8Type) + } ?: NullPointer(llvm.int8Type) setRuntimeConstGlobal("Kotlin_runtimeLogs", runtimeLogs) - setRuntimeConstGlobal("Kotlin_freezingEnabled", Int32(if (config.freezing.enableFreezeAtRuntime) 1 else 0)) - setRuntimeConstGlobal("Kotlin_freezingChecksEnabled", Int32(if (config.freezing.enableFreezeChecks) 1 else 0)) - setRuntimeConstGlobal("Kotlin_gcSchedulerType", Int32(config.gcSchedulerType.value)) + setRuntimeConstGlobal("Kotlin_freezingEnabled", llvm.constInt32(if (config.freezing.enableFreezeAtRuntime) 1 else 0)) + setRuntimeConstGlobal("Kotlin_freezingChecksEnabled", llvm.constInt32(if (config.freezing.enableFreezeChecks) 1 else 0)) + setRuntimeConstGlobal("Kotlin_gcSchedulerType", llvm.constInt32(config.gcSchedulerType.value)) return llvmModule } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt index 5319d92e1be..85f5208f315 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt @@ -39,37 +39,37 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con val exportedClassName = selectExportedClassName(irClass) val className = exportedClassName ?: selectInternalClassName(irClass) - val classNameLiteral = className?.let { staticData.cStringLiteral(it) } ?: NullPointer(int8Type) + val classNameLiteral = className?.let { staticData.cStringLiteral(it) } ?: NullPointer(llvm.int8Type) val info = Struct(runtime.kotlinObjCClassInfo, - classNameLiteral, - Int32(if (exportedClassName != null) 1 else 0), + classNameLiteral, + llvm.constInt32(if (exportedClassName != null) 1 else 0), - staticData.cStringLiteral(superclassName), - staticData.placeGlobalConstArray("", int8TypePtr, - protocolNames.map { staticData.cStringLiteral(it) } + NullPointer(int8Type)), + staticData.cStringLiteral(superclassName), + staticData.placeGlobalConstArray("", llvm.int8PtrType, + protocolNames.map { staticData.cStringLiteral(it) } + NullPointer(llvm.int8Type)), - staticData.placeGlobalConstArray("", runtime.objCMethodDescription, instanceMethods), - Int32(instanceMethods.size), + staticData.placeGlobalConstArray("", runtime.objCMethodDescription, instanceMethods), + llvm.constInt32(instanceMethods.size), - staticData.placeGlobalConstArray("", runtime.objCMethodDescription, classMethods), - Int32(classMethods.size), + staticData.placeGlobalConstArray("", runtime.objCMethodDescription, classMethods), + llvm.constInt32(classMethods.size), - objCLLvmDeclarations.bodyOffsetGlobal.pointer, + objCLLvmDeclarations.bodyOffsetGlobal.pointer, - irClass.typeInfoPtr, - companionObject?.typeInfoPtr ?: NullPointer(runtime.typeInfoType), + irClass.typeInfoPtr, + companionObject?.typeInfoPtr ?: NullPointer(runtime.typeInfoType), - staticData.placeGlobal( + staticData.placeGlobal( "kobjcclassptr:${irClass.fqNameForIrSerialization}#internal", - NullPointer(int8Type) + NullPointer(llvm.int8Type) ).pointer, - generateClassDataImp(irClass) + generateClassDataImp(irClass) ) objCLLvmDeclarations.classInfoGlobal.setInitializer(info) - objCLLvmDeclarations.bodyOffsetGlobal.setInitializer(Int32(0)) + objCLLvmDeclarations.bodyOffsetGlobal.setInitializer(llvm.constInt32(0)) } private fun IrClass.generateMethodDescs(): List = this.generateImpMethodDescs() @@ -105,7 +105,7 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con null // Generate as anonymous. } - private val impType = pointerType(functionType(int8TypePtr, true, int8TypePtr, int8TypePtr)) + private val impType = pointerType(functionType(llvm.int8PtrType, true, llvm.int8PtrType, llvm.int8PtrType)) private inner class ObjCMethodDesc( val selector: String, val encoding: String, val impFunction: LLVMValueRef @@ -136,7 +136,7 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con Zero(runtime.kotlinObjCClassData) ).pointer - val functionType = functionType(classDataPointer.llvmType, false, int8TypePtr, int8TypePtr) + val functionType = functionType(classDataPointer.llvmType, false, llvm.int8PtrType, llvm.int8PtrType) val functionName = "kobjcclassdataimp:${irClass.fqNameForIrSerialization}#internal" val function = generateFunctionNoRuntime(codegen, functionType, functionName) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt index cc5253efd0b..82610d25951 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt @@ -12,17 +12,17 @@ import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.expressions.IrConst -private fun ConstPointer.add(index: Int): ConstPointer { - return constPointer(LLVMConstGEP(llvm, cValuesOf(Int32(index).llvm), 1)!!) +private fun ConstPointer.add(index: LLVMValueRef): ConstPointer { + return constPointer(LLVMConstGEP(llvm, cValuesOf(index), 1)!!) } -internal class KotlinStaticData(override val context: Context, module: LLVMModuleRef) : ContextUtils, StaticData(module) { +internal class KotlinStaticData(override val context: Context, override val llvm: Llvm, module: LLVMModuleRef) : ContextUtils, StaticData(module, llvm) { private val stringLiterals = mutableMapOf() // Must match OBJECT_TAG_PERMANENT_CONTAINER in C++. private fun permanentTag(typeInfo: ConstPointer): ConstPointer { // Only pointer arithmetic via GEP works on constant pointers in LLVM. - return typeInfo.bitcast(int8TypePtr).add(1).bitcast(kTypeInfoPtr) + return typeInfo.bitcast(llvm.int8PtrType).add(llvm.int32(1)).bitcast(kTypeInfoPtr) } @@ -32,13 +32,13 @@ internal class KotlinStaticData(override val context: Context, module: LLVMModul private fun arrayHeader(typeInfo: ConstPointer, length: Int): Struct { assert(length >= 0) - return Struct(runtime.arrayHeaderType, permanentTag(typeInfo), Int32(length)) + return Struct(runtime.arrayHeaderType, permanentTag(typeInfo), llvm.constInt32(length)) } private fun createRef(objHeaderPtr: ConstPointer) = objHeaderPtr.bitcast(kObjHeaderPtr) private fun createKotlinStringLiteral(value: String): ConstPointer { - val elements = value.toCharArray().map(::Char16) + val elements = value.toCharArray().map(llvm::constChar16) val objRef = createConstKotlinArray(context.ir.symbols.string.owner, elements) return objRef } @@ -51,15 +51,15 @@ internal class KotlinStaticData(override val context: Context, module: LLVMModul fun createConstKotlinArray(arrayClass: IrClass, elements: List): ConstPointer { val typeInfo = arrayClass.typeInfoPtr - val bodyElementType: LLVMTypeRef = elements.firstOrNull()?.llvmType ?: int8Type + val bodyElementType: LLVMTypeRef = elements.firstOrNull()?.llvmType ?: llvm.int8Type // (use [0 x i8] as body if there are no elements) val arrayBody = ConstArray(bodyElementType, elements) - val compositeType = structType(runtime.arrayHeaderType, arrayBody.llvmType) + val compositeType = llvm.structType(runtime.arrayHeaderType, arrayBody.llvmType) val global = this.createGlobal(compositeType, "") - val objHeaderPtr = global.pointer.getElementPtr(0) + val objHeaderPtr = global.pointer.getElementPtr(llvm, 0) val arrayHeader = arrayHeader(typeInfo, elements.size) global.setInitializer(Struct(compositeType, arrayHeader, arrayBody)) @@ -73,17 +73,17 @@ internal class KotlinStaticData(override val context: Context, module: LLVMModul val typeInfo = type.typeInfoPtr val objHeader = objHeader(typeInfo) - val global = this.placeGlobal("", Struct(objHeader, *fields)) + val global = this.placeGlobal("", llvm.struct(objHeader, *fields)) global.setUnnamedAddr(true) global.setConstant(true) - val objHeaderPtr = global.pointer.getElementPtr(0) + val objHeaderPtr = global.pointer.getElementPtr(llvm, 0) return createRef(objHeaderPtr) } fun createInitializer(type: IrClass, vararg fields: ConstValue): ConstValue = - Struct(objHeader(type.typeInfoPtr), *fields) + llvm.struct(objHeader(type.typeInfoPtr), *fields) fun createUniqueInstance( kind: UniqueKind, bodyType: LLVMTypeRef, typeInfo: ConstPointer): ConstPointer { @@ -117,7 +117,7 @@ internal class KotlinStaticData(override val context: Context, module: LLVMModul * @param args data for constant creation. */ fun createImmutableBlob(value: IrConst): LLVMValueRef { - val args = value.value.map { Int8(it.code.toByte()).llvm } + val args = value.value.map { llvm.int8(it.code.toByte()) } return createConstKotlinArray(context.ir.symbols.immutableBlob.owner, args) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt index a524fd66df5..3b595c3a764 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt @@ -81,14 +81,14 @@ internal class StaticFieldLlvmDeclarations(val storageAddressAccess: AddressAcce internal class UniqueLlvmDeclarations(val pointer: ConstPointer) private fun ContextUtils.createClassBodyType(name: String, fields: List): LLVMTypeRef { - val fieldTypes = listOf(runtime.objHeaderType) + fields.map { getLLVMType(it.type) } + val fieldTypes = listOf(runtime.objHeaderType) + fields.map { it.type.toLLVMType(llvm) } // TODO: consider adding synthetic ObjHeader field to Any. val classType = LLVMStructCreateNamed(LLVMGetModuleContext(llvm.module), name)!! // LLVMStructSetBody expects the struct to be properly aligned and will insert padding accordingly. In our case // `allocInstance` returns 16x + 8 address, i.e. always misaligned for vector types. Workaround is to use packed struct. - val hasBigAlignment = fields.any { LLVMABIAlignmentOfType(runtime.targetData, getLLVMType(it.type)) > 8 } + val hasBigAlignment = fields.any { LLVMABIAlignmentOfType(runtime.targetData, it.type.toLLVMType(llvm)) > 8 } val packed = if (hasBigAlignment) 1 else 0 LLVMStructSetBody(classType, fieldTypes.toCValues(), fieldTypes.size, packed) @@ -184,16 +184,16 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : val typeInfoGlobalName = "ktypeglobal:$internalName" - val typeInfoWithVtableType = structType( + val typeInfoWithVtableType = llvm.structType( runtime.typeInfoType, - LLVMArrayType(int8TypePtr, context.getLayoutBuilder(declaration).vtableEntries.size)!! + LLVMArrayType(llvm.int8PtrType, context.getLayoutBuilder(declaration).vtableEntries.size)!! ) typeInfoGlobal = staticData.createGlobal(typeInfoWithVtableType, typeInfoGlobalName, isExported = false) val llvmTypeInfoPtr = LLVMAddAlias(llvm.module, kTypeInfoPtr, - typeInfoGlobal.pointer.getElementPtr(0).llvm, + typeInfoGlobal.pointer.getElementPtr(llvm, 0).llvm, typeInfoSymbolName)!! if (declaration.isExported()) { @@ -278,9 +278,9 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : "kobjref:" + qualifyInternalName(irClass) } val instanceAddress = if (threadLocal) { - addKotlinThreadLocal(symbolName, getLLVMType(irClass.defaultType)) + addKotlinThreadLocal(symbolName, irClass.defaultType.toLLVMType(llvm)) } else { - addKotlinGlobal(symbolName, getLLVMType(irClass.defaultType), isExported) + addKotlinGlobal(symbolName, irClass.defaultType.toLLVMType(llvm), isExported) } return SingletonLlvmDeclarations(instanceAddress) @@ -303,7 +303,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : setConstant(true) } - val bodyOffsetGlobal = staticData.createGlobal(int32Type, "kobjcbodyoffs:$internalName") + val bodyOffsetGlobal = staticData.createGlobal(llvm.int32Type, "kobjcbodyoffs:$internalName") return KotlinObjCClassLlvmDeclarations(classInfoGlobal, bodyOffsetGlobal) } @@ -330,9 +330,9 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : // Fields are module-private, so we use internal name: val name = "kvar:" + qualifyInternalName(declaration) val storage = if (declaration.storageKind(context) == FieldStorageKind.THREAD_LOCAL) { - addKotlinThreadLocal(name, getLLVMType(declaration.type)) + addKotlinThreadLocal(name, declaration.type.toLLVMType(llvm)) } else { - addKotlinGlobal(name, getLLVMType(declaration.type), isExported = false) + addKotlinGlobal(name, declaration.type.toLLVMType(llvm), isExported = false) } declaration.metadata = CodegenStaticFieldMetadata( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmLinkOptions.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmLinkOptions.kt index d3e78578e91..4c0c97b1067 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmLinkOptions.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmLinkOptions.kt @@ -6,11 +6,12 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.LLVMAddNamedMetadataOperand +import llvm.LLVMContextRef import llvm.LLVMModuleRef -fun embedLlvmLinkOptions(module: LLVMModuleRef, options: List>) { +fun embedLlvmLinkOptions(llvmContext: LLVMContextRef, module: LLVMModuleRef, options: List>) { options.forEach { - val node = node(*it.map { it.mdString() }.toTypedArray()) + val node = node(llvmContext, *it.map { it.mdString(llvmContext) }.toTypedArray()) LLVMAddNamedMetadataOperand(module, "llvm.linker.options", node) } } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmParamType.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmParamType.kt index ea4fd37b3bd..4908715cd3f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmParamType.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmParamType.kt @@ -25,7 +25,7 @@ typealias LlvmRetType = LlvmParamType internal fun ContextUtils.getLlvmFunctionParameterTypes(function: IrFunction): List { val returnType = getLlvmFunctionReturnType(function).llvmType val paramTypes = ArrayList(function.allParameters.map { - LlvmParamType(getLLVMType(it.type), argumentAbiInfo.defaultParameterAttributesForIrType(it.type)) + LlvmParamType(it.type.toLLVMType(llvm), argumentAbiInfo.defaultParameterAttributesForIrType(it.type)) }) require(!function.isSuspend) { "Suspend functions should be lowered out at this point"} if (isObjectType(returnType)) @@ -36,10 +36,10 @@ internal fun ContextUtils.getLlvmFunctionParameterTypes(function: IrFunction): L internal fun ContextUtils.getLlvmFunctionReturnType(function: IrFunction): LlvmRetType { val returnType = when { - function is IrConstructor -> LlvmParamType(voidType) - function.isSuspend -> error("Suspend functions should be lowered out at this point, but ${function.render()} is still here") + function is IrConstructor -> LlvmParamType(llvm.voidType) + function.isSuspend -> error("Suspend functions should be lowered out at this point, but ${function.render()} is still here") else -> LlvmParamType( - getLLVMReturnType(function.returnType), + function.returnType.getLLVMReturnType(llvm), argumentAbiInfo.defaultParameterAttributesForIrType(function.returnType) ) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 8612f04ddf5..b526e4fbf30 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -10,31 +10,6 @@ import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin -private val llvmContextHolder = ThreadLocal() -internal var llvmContext: LLVMContextRef - get() = llvmContextHolder.get() - set(value) { llvmContextHolder.set(value) } - -internal fun tryDisposeLLVMContext() { - val llvmContext = llvmContextHolder.get() - if (llvmContext != null) - LLVMContextDispose(llvmContext) - llvmContextHolder.remove() -} - -internal val LLVMTypeRef.context: LLVMContextRef - get() = LLVMGetTypeContext(this)!! - -internal val List.context: LLVMContextRef - get() { - val context = this[0].context - for (i in 1 until this.size) - assert(this[i].context == context) { - "Expected the same context for all types in a list" - } - return context - } - internal val LLVMValueRef.type: LLVMTypeRef get() = LLVMTypeOf(this)!! @@ -49,7 +24,7 @@ internal val ConstValue.llvmType: LLVMTypeRef get() = this.llvm.type internal interface ConstPointer : ConstValue { - fun getElementPtr(index: Int): ConstPointer = ConstGetElementPtr(this, index) + fun getElementPtr(llvm: Llvm, index: Int): ConstPointer = ConstGetElementPtr(llvm, this, index) } internal fun constPointer(value: LLVMValueRef) = object : ConstPointer { @@ -60,8 +35,8 @@ internal fun constPointer(value: LLVMValueRef) = object : ConstPointer { override val llvm = value } -private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : ConstPointer { - override val llvm = LLVMConstInBoundsGEP(pointer.llvm, cValuesOf(Int32(0).llvm, Int32(index).llvm), 2)!! +private class ConstGetElementPtr(llvm: Llvm, pointer: ConstPointer, index: Int) : ConstPointer { + override val llvm = LLVMConstInBoundsGEP(pointer.llvm, cValuesOf(llvm.int32(0), llvm.int32(index)), 2)!! // TODO: squash multiple GEPs } @@ -82,8 +57,6 @@ internal open class Struct(val type: LLVMTypeRef?, val elements: List val expectedType = LLVMStructGetTypeAtIndex(type, index) if (element == null) { @@ -103,50 +76,6 @@ internal open class Struct(val type: LLVMTypeRef?, val elements: List): LLVMTypeRef = - LLVMStructTypeInContext(llvmContext, types.toCValues(), types.size, 0)!! - internal fun ContextUtils.numParameters(functionType: LLVMTypeRef) : Int { // Note that type is usually function pointer, so we have to dereference it. return LLVMCountParamTypes(LLVMGetElementType(functionType)) @@ -277,19 +192,17 @@ internal class GlobalAddressAccess(private val address: LLVMValueRef): AddressAc override fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef = address } -internal class TLSAddressAccess( - private val context: Context, private val index: Int): AddressAccess() { - +internal class TLSAddressAccess(private val index: Int) : AddressAccess() { override fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef { - return generationContext!!.call(context.generationState.llvm.lookupTLS, - listOf(context.generationState.llvm.tlsKey, Int32(index).llvm)) + val llvm = generationContext!!.llvm + return generationContext.call(llvm.lookupTLS, listOf(llvm.tlsKey, llvm.int32(index))) } } internal fun ContextUtils.addKotlinThreadLocal(name: String, type: LLVMTypeRef): AddressAccess { return if (isObjectType(type)) { val index = llvm.tlsCount++ - TLSAddressAccess(context, index) + TLSAddressAccess(index) } else { // TODO: This will break if Workers get decoupled from host threads. GlobalAddressAccess(LLVMAddGlobal(llvm.module, type, name)!!.also { @@ -334,7 +247,7 @@ fun getStructElements(type: LLVMTypeRef): List { } } -fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped { +fun parseBitcodeFile(llvmContext: LLVMContextRef, path: String): LLVMModuleRef = memScoped { val bufRef = alloc() val errorRef = allocPointerTo() @@ -400,15 +313,8 @@ internal fun addLlvmFunctionAttribute(function: LLVMValueRef, attribute: LLVMAtt LLVMAddAttributeAtIndex(function, LLVMAttributeFunctionIndex, attribute) } -fun addFunctionSignext(function: LLVMValueRef, index: Int, type: LLVMTypeRef?) { - if (type == int1Type || type == int8Type || type == int16Type) { - val attribute = createLlvmEnumAttribute(LLVMGetTypeContext(function.type)!!, LlvmParameterAttribute.SignExt.asAttributeKindId()) - LLVMAddAttributeAtIndex(function, index, attribute) - } -} - -internal fun String.mdString() = LLVMMDStringInContext(llvmContext, this, this.length)!! -internal fun node(vararg it:LLVMValueRef) = LLVMMDNodeInContext(llvmContext, it.toList().toCValues(), it.size) +internal fun String.mdString(llvmContext: LLVMContextRef) = LLVMMDStringInContext(llvmContext, this, this.length)!! +internal fun node(llvmContext: LLVMContextRef, vararg it: LLVMValueRef) = LLVMMDNodeInContext(llvmContext, it.toList().toCValues(), it.size) internal fun LLVMValueRef.setUnaligned() = apply { LLVMSetAlignment(this, 1) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt index c534524aea5..ab3d65fe248 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt @@ -79,7 +79,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { return result } - inner class InterfaceTableRecord(id: Int32, vtableSize: Int32, vtable: ConstPointer?) : + inner class InterfaceTableRecord(id: ConstInt32, vtableSize: ConstInt32, vtable: ConstPointer?) : Struct(runtime.interfaceTableRecordType, id, vtableSize, vtable) private inner class TypeInfo( @@ -111,27 +111,27 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { // TODO: it used to be a single int32 ABI version, // but klib abi version is not an int anymore. // So now this field is just reserved to preserve the layout. - Int32(0), + llvm.constInt32(0), - Int32(size), + llvm.constInt32(size), superType, objOffsets, - Int32(objOffsetsCount), + llvm.constInt32(objOffsetsCount), interfaces, - Int32(interfacesCount), + llvm.constInt32(interfacesCount), - Int32(interfaceTableSize), + llvm.constInt32(interfaceTableSize), interfaceTable, kotlinStringLiteral(packageName), kotlinStringLiteral(relativeName), - Int32(flags), + llvm.constInt32(flags), - Int32(classId), + llvm.constInt32(classId), *listOfNotNull(writableTypeInfo).toTypedArray(), @@ -159,32 +159,32 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { } private val arrayClasses = mapOf( - IdSignatureValues.array to kObjHeaderPtr, - primitiveArrayTypesSignatures[PrimitiveType.BYTE] to int8Type, - primitiveArrayTypesSignatures[PrimitiveType.CHAR] to int16Type, - primitiveArrayTypesSignatures[PrimitiveType.SHORT] to int16Type, - primitiveArrayTypesSignatures[PrimitiveType.INT] to int32Type, - primitiveArrayTypesSignatures[PrimitiveType.LONG] to int64Type, - primitiveArrayTypesSignatures[PrimitiveType.FLOAT] to floatType, - primitiveArrayTypesSignatures[PrimitiveType.DOUBLE] to doubleType, - primitiveArrayTypesSignatures[PrimitiveType.BOOLEAN] to int8Type, - IdSignatureValues.string to int16Type, - getPublicSignature(KonanFqNames.packageName, "ImmutableBlob") to int8Type, - getPublicSignature(KonanFqNames.internalPackageName, "NativePtrArray") to kInt8Ptr + IdSignatureValues.array to llvm.kObjHeaderPtr, + primitiveArrayTypesSignatures[PrimitiveType.BYTE] to llvm.int8Type, + primitiveArrayTypesSignatures[PrimitiveType.CHAR] to llvm.int16Type, + primitiveArrayTypesSignatures[PrimitiveType.SHORT] to llvm.int16Type, + primitiveArrayTypesSignatures[PrimitiveType.INT] to llvm.int32Type, + primitiveArrayTypesSignatures[PrimitiveType.LONG] to llvm.int64Type, + primitiveArrayTypesSignatures[PrimitiveType.FLOAT] to llvm.floatType, + primitiveArrayTypesSignatures[PrimitiveType.DOUBLE] to llvm.doubleType, + primitiveArrayTypesSignatures[PrimitiveType.BOOLEAN] to llvm.int8Type, + IdSignatureValues.string to llvm.int16Type, + getPublicSignature(KonanFqNames.packageName, "ImmutableBlob") to llvm.int8Type, + getPublicSignature(KonanFqNames.internalPackageName, "NativePtrArray") to llvm.int8PtrType ) // Keep in sync with Konan_RuntimeType. private val runtimeTypeMap = mapOf( - kObjHeaderPtr to 1, - int8Type to 2, - int16Type to 3, - int32Type to 4, - int64Type to 5, - floatType to 6, - doubleType to 7, - kInt8Ptr to 8, - int1Type to 9, - vector128Type to 10 + llvm.kObjHeaderPtr to 1, + llvm.int8Type to 2, + llvm.int16Type to 3, + llvm.int32Type to 4, + llvm.int64Type to 5, + llvm.floatType to 6, + llvm.doubleType to 7, + llvm.int8PtrType to 8, + llvm.int1Type to 9, + llvm.vector128Type to 10 ) private fun getElementType(irClass: IrClass): LLVMTypeRef? { @@ -226,7 +226,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val objOffsets = getObjOffsets(bodyType) - val objOffsetsPtr = staticData.placeGlobalConstArray("krefs:$className", int32Type, objOffsets) + val objOffsetsPtr = staticData.placeGlobalConstArray("krefs:$className", llvm.int32Type, objOffsets) val objOffsetsCount = if (irClass.descriptor == context.builtIns.array) { 1 // To mark it as non-leaf. @@ -269,7 +269,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { typeInfo } else { val vtable = vtable(irClass) - Struct(typeInfo, vtable) + llvm.struct(typeInfo, vtable) } typeInfoGlobal.setInitializer(typeInfoGlobalValue) @@ -285,9 +285,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { } } - private fun getObjOffsets(bodyType: LLVMTypeRef): List = + private fun getObjOffsets(bodyType: LLVMTypeRef): List = getIndicesOfObjectFields(bodyType).map { index -> - Int32(LLVMOffsetOfElement(llvmTargetData, bodyType, index).toInt()) + llvm.constInt32(LLVMOffsetOfElement(llvmTargetData, bodyType, index).toInt()) } fun vtable(irClass: IrClass): ConstArray { @@ -295,12 +295,12 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val vtableEntries = context.getLayoutBuilder(irClass).vtableEntries.map { val implementation = it.implementation if (implementation == null || implementation.isExternalObjCClassMethod() || context.referencedFunctions?.contains(implementation) == false) { - NullPointer(int8Type) + NullPointer(llvm.int8Type) } else { implementation.entryPointAddress } } - return ConstArray(int8TypePtr, vtableEntries) + return ConstArray(llvm.int8PtrType, vtableEntries) } fun interfaceTableRecords(irClass: IrClass): Pair, Int> { @@ -368,20 +368,20 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { return interfaceTableSkeleton.map { iface -> val interfaceId = iface?.classId ?: 0 InterfaceTableRecord( - Int32(interfaceId), - Int32(iface?.interfaceVTableEntries?.size ?: 0), + llvm.constInt32(interfaceId), + llvm.constInt32(iface?.interfaceVTableEntries?.size ?: 0), if (iface == null) - NullPointer(kInt8Ptr) + NullPointer(llvm.int8PtrType) else { val vtableEntries = iface.interfaceVTableEntries.map { ifaceFunction -> val impl = layoutBuilder.overridingOf(ifaceFunction) if (impl == null || context.referencedFunctions?.contains(impl) == false) - NullPointer(int8Type) + NullPointer(llvm.int8Type) else impl.entryPointAddress } staticData.placeGlobalConstArray("kifacevtable:${className}_$interfaceId", - kInt8Ptr, vtableEntries + llvm.int8PtrType, vtableEntries ) } ) @@ -393,7 +393,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { private val debugRuntimeOrNull: LLVMModuleRef? by lazy { context.config.runtimeNativeLibraries.singleOrNull { it.endsWith("debug.bc")}?.let { - parseBitcodeFile(it) + parseBitcodeFile(llvm.llvmContext, it) } } @@ -401,18 +401,18 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { if (debugRuntimeOrNull != null) { val external = LLVMGetNamedGlobal(debugRuntimeOrNull, "Konan_debugOperationsList")!! val local = LLVMAddGlobal(llvm.module, LLVMGetElementType(LLVMTypeOf(external)),"Konan_debugOperationsList")!! - constPointer(LLVMConstBitCast(local, kInt8PtrPtr)!!) + constPointer(LLVMConstBitCast(local, llvm.int8PtrPtrType)!!) } else { - Zero(kInt8PtrPtr) + Zero(llvm.int8PtrPtrType) } } val debugOperationsSize: ConstValue by lazy { if (debugRuntimeOrNull != null) { val external = LLVMGetNamedGlobal(debugRuntimeOrNull, "Konan_debugOperationsList")!! - Int32(LLVMGetArrayLength(LLVMGetElementType(LLVMTypeOf(external)))) + llvm.constInt32(LLVMGetArrayLength(LLVMGetElementType(LLVMTypeOf(external)))) } else - Int32(0) + llvm.constInt32(0) } private fun makeExtendedInfo(irClass: IrClass): ConstPointer { @@ -429,8 +429,8 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { // An array type. val runtimeElementType = mapRuntimeType(elementType) Struct(runtime.extendedTypeInfoType, - Int32(-runtimeElementType), - NullPointer(int32Type), NullPointer(int8Type), NullPointer(kInt8Ptr), + llvm.constInt32(-runtimeElementType), + NullPointer(llvm.int32Type), NullPointer(llvm.int8Type), NullPointer(llvm.int8PtrType), debugOperationsSize, debugOperations) } else { class FieldRecord(val offset: Int, val type: Int, val name: String) @@ -440,14 +440,14 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { mapRuntimeType(LLVMStructGetTypeAtIndex(bodyType, it.index)!!), it.name) } - val offsetsPtr = staticData.placeGlobalConstArray("kextoff:$className", int32Type, - fields.map { Int32(it.offset) }) - val typesPtr = staticData.placeGlobalConstArray("kexttype:$className", int8Type, - fields.map { Int8(it.type.toByte()) }) - val namesPtr = staticData.placeGlobalConstArray("kextname:$className", kInt8Ptr, + val offsetsPtr = staticData.placeGlobalConstArray("kextoff:$className", llvm.int32Type, + fields.map { llvm.constInt32(it.offset) }) + val typesPtr = staticData.placeGlobalConstArray("kexttype:$className", llvm.int8Type, + fields.map { llvm.constInt8(it.type.toByte()) }) + val namesPtr = staticData.placeGlobalConstArray("kextname:$className", llvm.int8PtrType, fields.map { staticData.placeCStringLiteral(it.name) }) - Struct(runtime.extendedTypeInfoType, Int32(fields.size), offsetsPtr, typesPtr, namesPtr, + Struct(runtime.extendedTypeInfoType, llvm.constInt32(fields.size), offsetsPtr, typesPtr, namesPtr, debugOperationsSize, debugOperations) } @@ -518,7 +518,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { assert(superClass.declarations.all { it !is IrProperty && it !is IrField }) val objOffsets = getObjOffsets(bodyType) - val objOffsetsPtr = staticData.placeGlobalConstArray("", int32Type, objOffsets) + val objOffsetsPtr = staticData.placeGlobalConstArray("", llvm.int32Type, objOffsets) val objOffsetsCount = objOffsets.size val writableTypeInfoType = runtime.writableTypeInfoType @@ -530,9 +530,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { .pointer } val vtable = vtable(superClass) - val typeInfoWithVtableType = structType(runtime.typeInfoType, vtable.llvmType) + val typeInfoWithVtableType = llvm.structType(runtime.typeInfoType, vtable.llvmType) val typeInfoWithVtableGlobal = staticData.createGlobal(typeInfoWithVtableType, "", isExported = false) - val result = typeInfoWithVtableGlobal.pointer.getElementPtr(0) + val result = typeInfoWithVtableGlobal.pointer.getElementPtr(llvm, 0) val typeHierarchyInfo = if (!context.ghaEnabled()) ClassGlobalHierarchyInfo.DUMMY else @@ -543,20 +543,20 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val interfaceTable = interfaceTableSkeleton.map { layoutBuilder -> if (layoutBuilder == null) { - InterfaceTableRecord(Int32(0), Int32(0), null) + InterfaceTableRecord(llvm.constInt32(0), llvm.constInt32(0), null) } else { - val vtableEntries = layoutBuilder.interfaceVTableEntries.map { methodImpls[it]!!.bitcast(int8TypePtr) } - val interfaceVTable = staticData.placeGlobalArray("", kInt8Ptr, vtableEntries) + val vtableEntries = layoutBuilder.interfaceVTableEntries.map { methodImpls[it]!!.bitcast(llvm.int8PtrType) } + val interfaceVTable = staticData.placeGlobalArray("", llvm.int8PtrType, vtableEntries) InterfaceTableRecord( - Int32(layoutBuilder.classId), - Int32(layoutBuilder.interfaceVTableEntries.size), - interfaceVTable.pointer.getElementPtr(0) + llvm.constInt32(layoutBuilder.classId), + llvm.constInt32(layoutBuilder.interfaceVTableEntries.size), + interfaceVTable.pointer.getElementPtr(llvm, 0) ) } } val interfaceTablePtr = staticData.placeGlobalConstArray("", runtime.interfaceTableRecordType, interfaceTable) - val typeInfoWithVtable = Struct(TypeInfo( + val typeInfoWithVtable = llvm.struct(TypeInfo( selfPtr = result, extendedInfo = NullPointer(runtime.extendedTypeInfoType), size = size, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt index 9f2aa80f874..e506ff0944b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt @@ -14,8 +14,8 @@ interface RuntimeAware { val runtime: Runtime } -class Runtime(bitcodeFile: String) { - val llvmModule: LLVMModuleRef = parseBitcodeFile(bitcodeFile) +class Runtime(llvmContext: LLVMContextRef, bitcodeFile: String) { + val llvmModule: LLVMModuleRef = parseBitcodeFile(llvmContext, bitcodeFile) val calculatedLLVMTypes: MutableMap = HashMap() val addedLLVMExternalFunctions: MutableMap = HashMap() diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt index 27695625678..6a867095011 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt @@ -6,12 +6,11 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* -import org.jetbrains.kotlin.backend.konan.Context /** * Provides utilities to create static data. */ -internal open class StaticData(val module: LLVMModuleRef) { +internal open class StaticData(val module: LLVMModuleRef, private val llvm: Llvm) { /** * Represents the LLVM global variable. @@ -138,16 +137,16 @@ internal open class StaticData(val module: LLVMModuleRef) { if (elements.isNotEmpty() || isExported) { val global = placeGlobalArray(name, elemType, elements, isExported) global.setConstant(true) - return global.pointer.getElementPtr(0) + return global.pointer.getElementPtr(llvm, 0) } else { return NullPointer(elemType) } } internal fun placeCStringLiteral(value: String) : ConstPointer { - val chars = value.toByteArray(Charsets.UTF_8).map { Int8(it) } + Int8(0) + val chars = value.toByteArray(Charsets.UTF_8).map { llvm.constInt8(it) } + llvm.constInt8(0) - return placeGlobalConstArray("", int8Type, chars) + return placeGlobalConstArray("", llvm.int8Type, chars) } internal fun cStringLiteral(value: String) = cStringLiterals.getOrPut(value) { placeCStringLiteral(value) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt index aa3c35146dd..6c91e7d3a9d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt @@ -75,7 +75,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration "Could not find ${valueDeclaration.render()} in contextVariablesToIndex" } val index = variables.size - val type = functionGenerationContext.getLLVMType(valueDeclaration.type) + val type = valueDeclaration.type.toLLVMType(functionGenerationContext.llvm) val slot = functionGenerationContext.alloca(type, valueDeclaration.name.asString(), variableLocation) if (value != null) functionGenerationContext.storeAny(value, slot, true) @@ -88,7 +88,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration internal fun createParameterOnStack(valueDeclaration: IrValueDeclaration, variableLocation: VariableDebugLocation?): Int { assert(!contextVariablesToIndex.contains(valueDeclaration)) val index = variables.size - val type = functionGenerationContext.getLLVMType(valueDeclaration.type) + val type = valueDeclaration.type.toLLVMType(functionGenerationContext.llvm) val slot = functionGenerationContext.alloca( type, "p-${valueDeclaration.name.asString()}", variableLocation) val isObject = functionGenerationContext.isObjectType(type) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt index cfb7615f0aa..10300f7f681 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt @@ -25,7 +25,7 @@ internal class LLVMCoverageInstrumentation( private val functionNameGlobal = createFunctionNameGlobal(functionRegions.function) - private val functionHash = Int64(functionRegions.structuralHash).llvm + private val functionHash = llvm.int64(functionRegions.structuralHash) // TODO: It's a great place for some debug output. fun instrumentIrElement(element: IrElement) { @@ -38,16 +38,16 @@ internal class LLVMCoverageInstrumentation( * See https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic */ private fun placeRegionIncrement(region: Region) { - val numberOfRegions = Int32(functionRegions.regions.size).llvm - val regionNumber = Int32(functionRegions.regionEnumeration.getValue(region)).llvm + val numberOfRegions = llvm.int32(functionRegions.regions.size) + val regionNumber = llvm.int32(functionRegions.regionEnumeration.getValue(region)) val args = listOf(functionNameGlobal, functionHash, numberOfRegions, regionNumber) - callSitePlacer(LLVMInstrProfIncrement(context.generationState.llvm.module)!!, args) + callSitePlacer(LLVMInstrProfIncrement(llvm.module)!!, args) } // Each profiled function should have a global with its name in a specific format. private fun createFunctionNameGlobal(function: IrFunction): LLVMValueRef { val name = function.llvmFunction.llvmValue.name val pgoFunctionName = LLVMCreatePGOFunctionNameVar(function.llvmFunction.llvmValue, name)!! - return LLVMConstBitCast(pgoFunctionName, int8TypePtr)!! + return LLVMConstBitCast(pgoFunctionName, llvm.int8PtrType)!! } } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/diagnostics.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/diagnostics.kt index cb693552538..29df630aba0 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/diagnostics.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/diagnostics.kt @@ -42,33 +42,33 @@ internal interface LlvmDiagnosticHandler { fun handle(diagnostics: List) } -internal inline fun withLlvmDiagnosticHandler(handler: LlvmDiagnosticHandler, block: () -> R): R { +internal inline fun withLlvmDiagnosticHandler(llvmContext: LLVMContextRef, handler: LlvmDiagnosticHandler, block: () -> R): R { val collector = LlvmDiagnosticCollector() return try { - withLlvmDiagnosticCollector(collector, block) + withLlvmDiagnosticCollector(llvmContext, collector, block) } finally { collector.flush(handler) } } -internal inline fun withLlvmDiagnosticCollector(collector: LlvmDiagnosticCollector, block: () -> R): R { +internal inline fun withLlvmDiagnosticCollector(llvmContext: LLVMContextRef, collector: LlvmDiagnosticCollector, block: () -> R): R { val handler: LLVMDiagnosticHandler = staticCFunction { diagnostic, context -> context!!.asStableRef().get().add(createLlvmDiagnostic(diagnostic)) } val context = StableRef.create(collector) return try { - withLlvmDiagnosticHandler(handler, context.asCPointer(), block) + withLlvmDiagnosticHandler(llvmContext, handler, context.asCPointer(), block) } finally { context.dispose() } } internal inline fun withLlvmDiagnosticHandler( + llvmContext: LLVMContextRef, handler: LLVMDiagnosticHandler, context: COpaquePointer, block: () -> R ): R { - val llvmContext = llvmContext val currentHandler = LLVMContextGetDiagnosticHandler(llvmContext) val currentContext = LLVMContextGetDiagnosticContext(llvmContext) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/linkModules.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/linkModules.kt index 5cedce0d961..6f60c113558 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/linkModules.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/linkModules.kt @@ -24,7 +24,7 @@ internal fun llvmLinkModules2(context: Context, dest: LLVMModuleRef, src: LLVMMo } }) - return withLlvmDiagnosticHandler(diagnosticHandler) { + return withLlvmDiagnosticHandler(context.generationState.llvmContext, diagnosticHandler) { LLVMLinkModules2(dest, src) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt index 652ec625226..8349a660131 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt @@ -29,8 +29,8 @@ internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { private val objcMsgSend = constPointer( llvm.externalFunction(LlvmFunctionProto( "objc_msgSend", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr), LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType), LlvmParamType(llvm.int8PtrType)), isVararg = true, origin = context.stdlibModule.llvmSymbolOrigin )).llvmValue @@ -39,8 +39,8 @@ internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { val objcRelease = run { val proto = LlvmFunctionProto( "llvm.objc.release", - LlvmRetType(voidType), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.voidType), + listOf(LlvmParamType(llvm.int8PtrType)), listOf(LlvmFunctionAttribute.NoUnwind), origin = context.stdlibModule.llvmSymbolOrigin ) @@ -49,23 +49,23 @@ internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { val objcAlloc = llvm.externalFunction(LlvmFunctionProto( "objc_alloc", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), origin = context.stdlibModule.llvmSymbolOrigin )) val objcAutoreleaseReturnValue = llvm.externalFunction(LlvmFunctionProto( "llvm.objc.autoreleaseReturnValue", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), listOf(LlvmFunctionAttribute.NoUnwind), origin = context.stdlibModule.llvmSymbolOrigin )) val objcRetainAutoreleasedReturnValue = llvm.externalFunction(LlvmFunctionProto( "llvm.objc.retainAutoreleasedReturnValue", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), listOf(LlvmFunctionAttribute.NoUnwind), origin = context.stdlibModule.llvmSymbolOrigin )) @@ -75,7 +75,7 @@ internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { val asmString = codegen.context.config.target.getARCRetainAutoreleasedReturnValueMarker() ?: return@lazy null val asmStringBytes = asmString.toByteArray() LLVMGetInlineAsm( - Ty = functionType(voidType, false), + Ty = functionType(llvm.voidType, false), AsmString = asmStringBytes.toCValues(), AsmStringSize = asmStringBytes.size.signExtend(), Constraints = null, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt index b2617b70dd9..63b39f82f1d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt @@ -55,7 +55,7 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { llvm.compilerUsedGlobals += global.pointer.llvm - global.pointer.bitcast(pointerType(int8TypePtr)) + global.pointer.bitcast(pointerType(llvm.int8PtrType)) } private val classObjectType = codegen.runtime.objCClassObjectType @@ -111,12 +111,12 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { if (instanceMethods.isEmpty()) return NullPointer(methodListType) val methodStructs = instanceMethods.map { - Struct(methodType, selectors.get(it.selector), encodings.get(it.encoding), it.imp.bitcast(int8TypePtr)) + Struct(methodType, selectors.get(it.selector), encodings.get(it.encoding), it.imp.bitcast(llvm.int8PtrType)) } - val methodList = Struct( - Int32(LLVMABISizeOfType(codegen.llvmTargetData, methodType).toInt()), - Int32(instanceMethods.size), + val methodList = llvm.struct( + llvm.constInt32(LLVMABISizeOfType(codegen.llvmTargetData, methodType).toInt()), + llvm.constInt32(instanceMethods.size), ConstArray(methodType, methodStructs) ) @@ -151,15 +151,15 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { val fields = mutableListOf() - fields += Int32(flags) - fields += Int32(start) - fields += Int32(size) - fields += NullPointer(int8Type) // ivar layout name + fields += llvm.constInt32(flags) + fields += llvm.constInt32(start) + fields += llvm.constInt32(size) + fields += NullPointer(llvm.int8Type) // ivar layout name fields += classNameLiteral fields += if (isMetaclass) NullPointer(methodListType) else emitInstanceMethodList() fields += NullPointer(protocolListType) fields += NullPointer(ivarListType) - fields += NullPointer(int8Type) // ivar layout + fields += NullPointer(llvm.int8Type) // ivar layout fields += NullPointer(propListType) val roValue = Struct(classRoType, fields) @@ -190,7 +190,7 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { fields += isa fields += superClass fields += emptyCache - val vtableEntryType = pointerType(functionType(int8TypePtr, false, int8TypePtr, int8TypePtr)) + val vtableEntryType = pointerType(functionType(llvm.int8PtrType, false, llvm.int8PtrType, llvm.int8PtrType)) fields += NullPointer(vtableEntryType) // empty vtable fields += classRo @@ -230,8 +230,8 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { val global = llvm.staticData.placeGlobalArray( name, - int8TypePtr, - elements.map { it.bitcast(int8TypePtr) } + llvm.int8PtrType, + elements.map { it.bitcast(llvm.int8PtrType) } ) global.setAlignment( @@ -257,9 +257,9 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { private val literals = mutableMapOf() fun get(value: String) = literals.getOrPut(value) { - val globalPointer = generator.generate(llvm.module, value) + val globalPointer = generator.generate(llvm.module, llvm, value) llvm.compilerUsedGlobals += globalPointer.llvm - globalPointer.getElementPtr(0) + globalPointer.getElementPtr(llvm, 0) } } @@ -275,9 +275,9 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { } class CStringLiteralsGenerator(val label: String, val section: String) { - fun generate(module: LLVMModuleRef, value: String): ConstPointer { - val bytes = value.toByteArray(Charsets.UTF_8).map { Int8(it) } + Int8(0) - val initializer = ConstArray(int8Type, bytes) + fun generate(module: LLVMModuleRef, llvm: Llvm, value: String): ConstPointer { + val bytes = value.toByteArray(Charsets.UTF_8).map { llvm.constInt8(it) } + llvm.constInt8(0) + val initializer = ConstArray(llvm.int8Type, bytes) val llvmGlobal = LLVMAddGlobal(module, initializer.llvmType, label)!! LLVMSetInitializer(llvmGlobal, initializer.llvm) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt index 20d9f9d5c39..1da6415b801 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt @@ -21,9 +21,9 @@ internal fun patchObjCRuntimeModule(context: Context): LLVMModuleRef? { patchBuilder.addObjCPatches() val bitcodeFile = config.objCNativeLibrary - val parsedModule = parseBitcodeFile(bitcodeFile) + val parsedModule = parseBitcodeFile(context.generationState.llvmContext, bitcodeFile) - patchBuilder.buildAndApply(parsedModule) + patchBuilder.buildAndApply(parsedModule, context.generationState.llvm) return parsedModule } @@ -128,7 +128,7 @@ private fun PatchBuilder.addObjCPatches() { } } -private fun PatchBuilder.buildAndApply(llvmModule: LLVMModuleRef) { +private fun PatchBuilder.buildAndApply(llvmModule: LLVMModuleRef, llvm: Llvm) { val nameToGlobalPatch = globalPatches.associateNonRepeatingBy { it.globalName } val sectionToValueToLiteralPatch = literalPatches.groupBy { it.generator.section } @@ -156,7 +156,7 @@ private fun PatchBuilder.buildAndApply(llvmModule: LLVMModuleRef) { val value = getStringValue(initializer) val patch = valueToLiteralPatch[value] if (patch != null) { - if (patch.newValue != value) patchLiteral(global, patch.generator, patch.newValue) + if (patch.newValue != value) patchLiteral(global, llvm, patch.generator, patch.newValue) unusedPatches -= patch } else if (section == ObjCDataGenerator.classNameGenerator.section) { error("Objective-C class name literal is not patched: $value") @@ -199,16 +199,17 @@ private fun List.associateNonRepeatingBy(keySelector: (T) -> K): Map val firstCharPtr = LLVMGetUser(use)!!.also { - require(it.isFirstCharPtr(global)) { + require(it.isFirstCharPtr(llvm, global)) { "Unexpected literal usage: ${llvm2string(it)}" } } @@ -216,8 +217,8 @@ private fun patchLiteral( } } -private fun LLVMValueRef.isFirstCharPtr(global: LLVMValueRef): Boolean = - this.type == int8TypePtr && +private fun LLVMValueRef.isFirstCharPtr(llvm: Llvm, global: LLVMValueRef): Boolean = + this.type == llvm.int8PtrType && LLVMIsConstant(this) != 0 && LLVMGetConstOpcode(this) == LLVMOpcode.LLVMGetElementPtr && LLVMGetNumOperands(this) == 3 && LLVMGetOperand(this, 0) == global diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt index c79e5c34270..4009faab632 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt @@ -25,9 +25,9 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter( val useSeparateHolder = bridge.returnsVoid val bodyType = if (useSeparateHolder) { - structType(codegen.kObjHeader, codegen.kObjHeaderPtr) + llvm.structType(codegen.kObjHeader, codegen.kObjHeaderPtr) } else { - structType(codegen.kObjHeader) + llvm.structType(codegen.kObjHeader) } val invokeImpl = functionGenerator( @@ -57,7 +57,7 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter( // and switching the thread state back to `Runnable` on exceptional path is not required. val result = callAndMaybeRetainAutoreleased( invoke, - bridge.blockType.blockInvokeLlvmType, + bridge.blockType.toBlockInvokeLlvmType(llvm), listOf(blockPtr) + args, exceptionHandler = terminatingExceptionHandler, doRetain = !bridge.returnsVoid @@ -89,11 +89,11 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter( immutable = true ) return functionGenerator( - LlvmFunctionSignature(LlvmRetType(codegen.kObjHeaderPtr), listOf(LlvmParamType(int8TypePtr), LlvmParamType(codegen.kObjHeaderPtrPtr))), + LlvmFunctionSignature(LlvmRetType(codegen.kObjHeaderPtr), listOf(LlvmParamType(llvm.int8PtrType), LlvmParamType(codegen.kObjHeaderPtrPtr))), "convertBlock${bridge.nameSuffix}" ).generate { val blockPtr = param(0) - ifThen(icmpEq(blockPtr, kNullInt8Ptr)) { + ifThen(icmpEq(blockPtr, llvm.kNullInt8Ptr)) { ret(kNullObjHeaderPtr) } @@ -125,7 +125,7 @@ private fun FunctionGenerationContext.loadBlockInvoke( ): LLVMValueRef { val invokePtr = structGep(bitcast(pointerType(codegen.runtime.blockLiteralType), blockPtr), 3) - return bitcast(pointerType(bridge.blockType.blockInvokeLlvmType.llvmFunctionType), load(invokePtr)) + return bitcast(pointerType(bridge.blockType.toBlockInvokeLlvmType(llvm).llvmFunctionType), load(invokePtr)) } private fun FunctionGenerationContext.allocInstanceWithAssociatedObject( @@ -146,25 +146,26 @@ private val BlockPointerBridge.blockType: BlockType */ internal data class BlockType(val numberOfParameters: Int, val returnsVoid: Boolean) -private val BlockType.blockInvokeLlvmType: LlvmFunctionSignature - get() = LlvmFunctionSignature( - LlvmRetType(if (returnsVoid) voidType else int8TypePtr), - (0..numberOfParameters).map { LlvmParamType(int8TypePtr) } - ) +private fun BlockType.toBlockInvokeLlvmType(llvm: Llvm): LlvmFunctionSignature = + LlvmFunctionSignature( + LlvmRetType(if (returnsVoid) llvm.voidType else llvm.int8PtrType), + (0..numberOfParameters).map { LlvmParamType(llvm.int8PtrType) } + ) private val BlockPointerBridge.nameSuffix: String get() = numberOfParameters.toString() + if (returnsVoid) "V" else "" internal class BlockGenerator(private val codegen: CodeGenerator) { + private val llvm = codegen.llvm - private val blockLiteralType = structType( + private val blockLiteralType = llvm.structType( codegen.runtime.blockLiteralType, codegen.runtime.kRefSharedHolderType ) val disposeHelper = generateFunction( codegen, - functionType(voidType, false, int8TypePtr), + functionType(llvm.voidType, false, llvm.int8PtrType), "blockDisposeHelper", switchToRunnable = true ) { @@ -179,7 +180,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { val copyHelper = generateFunction( codegen, - functionType(voidType, false, int8TypePtr, int8TypePtr), + functionType(llvm.voidType, false, llvm.int8PtrType, llvm.int8PtrType), "blockCopyHelper" ) { val dstBlockPtr = bitcast(pointerType(blockLiteralType), param(0)) @@ -207,8 +208,8 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { fun CodeGenerator.LongInt(value: Long) = when (val longWidth = llvm.longTypeWidth) { - 32L -> Int32(value.toInt()) - 64L -> Int64(value) + 32L -> llvm.constInt32(value.toInt()) + 64L -> llvm.constInt64(value) else -> error("Unexpected width of long type: $longWidth") } @@ -236,7 +237,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { constPointer(copyHelper), constPointer(disposeHelper), codegen.staticData.cStringLiteral(signature), - NullPointer(int8Type) + NullPointer(llvm.int8Type) ) } @@ -246,7 +247,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { invokeName: String, genBody: ObjCExportFunctionGenerationContext.(LLVMValueRef, List) -> Unit ): ConstPointer { - val result = functionGenerator(blockType.blockInvokeLlvmType, invokeName) { + val result = functionGenerator(blockType.toBlockInvokeLlvmType(llvm), invokeName) { switchToRunnable = true }.generate { val blockPtr = bitcast(pointerType(blockLiteralType), param(0)) @@ -303,24 +304,24 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { ) return functionGenerator( - LlvmFunctionSignature(LlvmRetType(int8TypePtr), listOf(LlvmParamType(codegen.kObjHeaderPtr))), + LlvmFunctionSignature(LlvmRetType(llvm.int8PtrType), listOf(LlvmParamType(codegen.kObjHeaderPtr))), convertName ).generate { val kotlinRef = param(0) ifThen(icmpEq(kotlinRef, kNullObjHeaderPtr)) { - ret(kNullInt8Ptr) + ret(llvm.kNullInt8Ptr) } val isa = codegen.importGlobal( "_NSConcreteStackBlock", - int8TypePtr, + llvm.int8PtrType, CurrentKlibModuleOrigin ) - val flags = Int32((1 shl 25) or (1 shl 30) or (1 shl 31)).llvm - val reserved = Int32(0).llvm + val flags = llvm.int32((1 shl 25) or (1 shl 30) or (1 shl 31)) + val reserved = llvm.int32(0) - val invokeType = pointerType(functionType(voidType, true, int8TypePtr)) + val invokeType = pointerType(functionType(llvm.voidType, true, llvm.int8PtrType)) val invoke = generateInvoke(blockType, invokeName, genBlockBody).bitcast(invokeType).llvm val descriptor = blockDescriptor.llvmGlobal @@ -328,7 +329,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { val blockOnStackBase = structGep(blockOnStack, 0) val refHolder = structGep(blockOnStack, 1) - listOf(bitcast(int8TypePtr, isa), flags, reserved, invoke, descriptor).forEachIndexed { index, value -> + listOf(bitcast(llvm.int8PtrType, isa), flags, reserved, invoke, descriptor).forEachIndexed { index, value -> // Although value is actually on the stack, it's not in normal slot area, so we cannot handle it // as if it was on the stack. store(value, structGep(blockOnStackBase, index)) @@ -336,7 +337,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { call(llvm.kRefSharedHolderInitLocal, listOf(refHolder, kotlinRef)) - val copiedBlock = callFromBridge(retainBlock, listOf(bitcast(int8TypePtr, blockOnStack))) + val copiedBlock = callFromBridge(retainBlock, listOf(bitcast(llvm.int8PtrType, blockOnStack))) ret(copiedBlock) }.also { @@ -349,8 +350,8 @@ private val ObjCExportCodeGeneratorBase.retainBlock: LlvmCallable get() { val functionProto = LlvmFunctionProto( "objc_retainBlock", - LlvmRetType(int8TypePtr), - listOf(LlvmParamType(int8TypePtr)), + LlvmRetType(llvm.int8PtrType), + listOf(LlvmParamType(llvm.int8PtrType)), origin = CurrentKlibModuleOrigin ) return llvm.externalFunction(functionProto) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index ea9bbc9b9e5..777083f147d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -39,9 +39,9 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.utils.DFS -internal fun TypeBridge.makeNothing() = when (this) { - is ReferenceBridge, is BlockPointerBridge -> kNullInt8Ptr - is ValueTypeBridge -> LLVMConstNull(this.objCValueType.llvmType)!! +internal fun TypeBridge.makeNothing(llvm: Llvm) = when (this) { + is ReferenceBridge, is BlockPointerBridge -> llvm.kNullInt8Ptr + is ValueTypeBridge -> LLVMConstNull(this.objCValueType.toLlvmType(llvm))!! } internal class ObjCExportFunctionGenerationContext( @@ -219,7 +219,7 @@ internal open class ObjCExportCodeGeneratorBase(codegen: CodeGenerator) : ObjCCo private val objcTerminate: LlvmCallable by lazy { llvm.externalFunction(LlvmFunctionProto( "objc_terminate", - LlvmRetType(voidType), + LlvmRetType(llvm.voidType), functionAttributes = listOf(LlvmFunctionAttribute.NoUnwind), origin = CurrentKlibModuleOrigin )) @@ -337,7 +337,7 @@ internal class ObjCExportCodeGenerator( val objcMsgSendType = LlvmFunctionSignature( returnType, - listOf(LlvmParamType(int8TypePtr), LlvmParamType(int8TypePtr)) + parameterTypes + listOf(LlvmParamType(llvm.int8PtrType), LlvmParamType(llvm.int8PtrType)) + parameterTypes ) return callFromBridge(msgSender(objcMsgSendType), listOf(receiver, genSelector(selector)) + args) } @@ -346,7 +346,7 @@ internal class ObjCExportCodeGenerator( value: LLVMValueRef, valueType: ObjCValueType ): LLVMValueRef = when (valueType) { - ObjCValueType.BOOL -> zext(value, int8Type) // TODO: zext behaviour may be strange on bit types. + ObjCValueType.BOOL -> zext(value, llvm.int8Type) // TODO: zext behaviour may be strange on bit types. ObjCValueType.UNICHAR, ObjCValueType.CHAR, ObjCValueType.SHORT, ObjCValueType.INT, ObjCValueType.LONG_LONG, @@ -359,7 +359,7 @@ internal class ObjCExportCodeGenerator( value: LLVMValueRef, valueType: ObjCValueType ): LLVMValueRef = when (valueType) { - ObjCValueType.BOOL -> icmpNe(value, Int8(0).llvm) + ObjCValueType.BOOL -> icmpNe(value, llvm.int8(0)) ObjCValueType.UNICHAR, ObjCValueType.CHAR, ObjCValueType.SHORT, ObjCValueType.INT, ObjCValueType.LONG_LONG, @@ -519,7 +519,7 @@ internal class ObjCExportCodeGenerator( // Note: this globals replace runtime globals with weak linkage: val origin = context.standardLlvmSymbolsOrigin replaceExternalWeakOrCommonGlobal(prefix, sortedAdaptersPointer, origin) - replaceExternalWeakOrCommonGlobal("${prefix}Num", Int32(sortedAdapters.size), origin) + replaceExternalWeakOrCommonGlobal("${prefix}Num", llvm.constInt32(sortedAdapters.size), origin) } } @@ -528,9 +528,9 @@ internal class ObjCExportCodeGenerator( if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { replaceExternalWeakOrCommonGlobal( - "Kotlin_ObjCExport_initTypeAdapters", - Int1(true), - context.standardLlvmSymbolsOrigin + "Kotlin_ObjCExport_initTypeAdapters", + llvm.constInt1(true), + context.standardLlvmSymbolsOrigin ) } } @@ -538,7 +538,7 @@ internal class ObjCExportCodeGenerator( private fun emitStaticInitializers() { if (externalGlobalInitializers.isEmpty()) return - val initializer = generateFunctionNoRuntime(codegen, functionType(voidType, false), "initObjCExportGlobals") { + val initializer = generateFunctionNoRuntime(codegen, functionType(llvm.voidType, false), "initObjCExportGlobals") { externalGlobalInitializers.forEach { (global, value) -> store(value.llvm, global) } @@ -560,7 +560,7 @@ internal class ObjCExportCodeGenerator( // Adding a similar symbol that would explicitly hint to take a look at the YouTrack issue if reported. // Note: for some reason this symbol is reported as the last one, which is good for its purpose. val name = "See https://youtrack.jetbrains.com/issue/KT-42254" - val global = staticData.placeGlobal(name, Int8(0), isExported = true) + val global = staticData.placeGlobal(name, llvm.constInt8(0), isExported = true) llvm.usedGlobals += global.llvmGlobal LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) @@ -588,7 +588,7 @@ internal class ObjCExportCodeGenerator( ) private fun emitSelectorsHolder() { - val impType = functionType(voidType, false, int8TypePtr, int8TypePtr) + val impType = functionType(llvm.voidType, false, llvm.int8PtrType, llvm.int8PtrType) val imp = generateFunctionNoRuntime(codegen, impType, "") { unreachable() } @@ -606,7 +606,7 @@ internal class ObjCExportCodeGenerator( ) } - private val impType = pointerType(functionType(voidType, false)) + private val impType = pointerType(functionType(llvm.voidType, false)) internal val directMethodAdapters = mutableMapOf() @@ -632,10 +632,10 @@ internal class ObjCExportCodeGenerator( ) : Struct( runtime.kotlinToObjCMethodAdapter, staticData.cStringLiteral(selector), - Int32(itablePlace.interfaceId), - Int32(itablePlace.itableSize), - Int32(itablePlace.methodIndex), - Int32(vtableIndex), + llvm.constInt32(itablePlace.interfaceId), + llvm.constInt32(itablePlace.itableSize), + llvm.constInt32(itablePlace.methodIndex), + llvm.constInt32(vtableIndex), kotlinImpl ) @@ -656,10 +656,10 @@ internal class ObjCExportCodeGenerator( typeInfo, vtable, - Int32(vtableSize), + llvm.constInt32(vtableSize), staticData.placeGlobalConstArray("", runtime.interfaceTableRecordType, itable), - Int32(itableSize), + llvm.constInt32(itableSize), staticData.cStringLiteral(objCName), @@ -668,28 +668,28 @@ internal class ObjCExportCodeGenerator( runtime.objCToKotlinMethodAdapter, directAdapters ), - Int32(directAdapters.size), + llvm.constInt32(directAdapters.size), staticData.placeGlobalConstArray( "", runtime.objCToKotlinMethodAdapter, classAdapters ), - Int32(classAdapters.size), + llvm.constInt32(classAdapters.size), staticData.placeGlobalConstArray( "", runtime.objCToKotlinMethodAdapter, virtualAdapters ), - Int32(virtualAdapters.size), + llvm.constInt32(virtualAdapters.size), staticData.placeGlobalConstArray( "", runtime.kotlinToObjCMethodAdapter, reverseAdapters ), - Int32(reverseAdapters.size) + llvm.constInt32(reverseAdapters.size) ) } @@ -755,7 +755,7 @@ private fun ObjCExportCodeGeneratorBase.buildWritableTypeInfoValue( typeAdapter: ConstPointer? = null ): Struct { if (convertToRetained != null) { - val expectedType = pointerType(functionType(int8TypePtr, false, codegen.kObjHeaderPtr)) + val expectedType = pointerType(functionType(llvm.int8PtrType, false, codegen.kObjHeaderPtr)) assert(convertToRetained.llvmType == expectedType) { "Expected: ${LLVMPrintTypeToString(expectedType)!!.toKString()} " + "found: ${LLVMPrintTypeToString(convertToRetained.llvmType)!!.toKString()}" @@ -763,7 +763,7 @@ private fun ObjCExportCodeGeneratorBase.buildWritableTypeInfoValue( } val objCExportAddition = Struct(runtime.typeInfoObjCExportAddition, - convertToRetained?.bitcast(int8TypePtr), + convertToRetained?.bitcast(llvm.int8PtrType), objCClass, typeAdapter ) @@ -773,10 +773,10 @@ private fun ObjCExportCodeGeneratorBase.buildWritableTypeInfoValue( } private val ObjCExportCodeGenerator.kotlinToObjCFunctionType: LlvmFunctionSignature - get() = LlvmFunctionSignature(LlvmRetType(int8TypePtr), listOf(LlvmParamType(codegen.kObjHeaderPtr)), isVararg = false) + get() = LlvmFunctionSignature(LlvmRetType(llvm.int8PtrType), listOf(LlvmParamType(codegen.kObjHeaderPtr)), isVararg = false) private val ObjCExportCodeGeneratorBase.objCToKotlinFunctionType: LLVMTypeRef - get() = functionType(codegen.kObjHeaderPtr, false, int8TypePtr, codegen.kObjHeaderPtrPtr) + get() = functionType(codegen.kObjHeaderPtr, false, llvm.int8PtrType, codegen.kObjHeaderPtrPtr) private fun ObjCExportCodeGenerator.emitBoxConverters() { val irBuiltIns = context.irBuiltIns @@ -817,7 +817,7 @@ private fun ObjCExportCodeGenerator.emitBoxConverter( val nsNumberSubclass = genGetLinkedClass(namer.numberBoxName(boxClass.classId!!).binaryName) // We consider this function fast enough, so don't switch thread state to Native. val instance = callFromBridge(objcAlloc, listOf(nsNumberSubclass)) - val returnType = LlvmRetType(int8TypePtr) + val returnType = LlvmRetType(llvm.int8PtrType) // We consider these methods fast enough, so don't switch thread state to Native. ret(genSendMessage(returnType, valueParameterTypes, instance, nsNumberInitSelector, value)) } @@ -855,7 +855,7 @@ private fun ObjCExportCodeGenerator.generateUnitContinuationToRetainedCompletion check(arguments.size == 1) val errorArgument = arguments[0] - val resultArgument = ifThenElse(icmpNe(errorArgument, kNullInt8Ptr), kNullObjHeaderPtr) { + val resultArgument = ifThenElse(icmpNe(errorArgument, llvm.kNullInt8Ptr), kNullObjHeaderPtr) { codegen.theUnitInstanceRef.llvm } @@ -897,11 +897,11 @@ private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() { "", pointerType(objCToKotlinFunctionType), converters - ).pointer.getElementPtr(0) + ).pointer.getElementPtr(llvm, 0) // Note: defining globals declared in runtime. staticData.placeGlobal("Kotlin_ObjCExport_blockToFunctionConverters", ptr, isExported = true) - staticData.placeGlobal("Kotlin_ObjCExport_blockToFunctionConverters_size", Int32(arityLimit), isExported = true) + staticData.placeGlobal("Kotlin_ObjCExport_blockToFunctionConverters_size", llvm.constInt32(arityLimit), isExported = true) } private fun ObjCExportCodeGenerator.emitSpecialClassesConvertions() { @@ -1098,7 +1098,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp( !is MethodBridge.ReturnValue.WithError -> error("bridge with error parameter has unexpected return type: $returnType") - MethodBridge.ReturnValue.WithError.Success -> Int8(0).llvm // false + MethodBridge.ReturnValue.WithError.Success -> llvm.int8(0) // false is MethodBridge.ReturnValue.WithError.ZeroForError -> { if (returnType.successBridge == MethodBridge.ReturnValue.Instance.InitResult) { @@ -1136,10 +1136,10 @@ private fun ObjCExportCodeGenerator.generateObjCImp( MethodBridge.ReturnValue.Void -> null MethodBridge.ReturnValue.HashCode -> { val kotlinHashCode = targetResult!! - if (codegen.context.is64BitNSInteger()) zext(kotlinHashCode, int64Type) else kotlinHashCode + if (codegen.context.is64BitNSInteger()) zext(kotlinHashCode, llvm.int64Type) else kotlinHashCode } - is MethodBridge.ReturnValue.Mapped -> if (LLVMTypeOf(targetResult!!) == voidType) { - returnBridge.bridge.makeNothing() + is MethodBridge.ReturnValue.Mapped -> if (LLVMTypeOf(targetResult!!) == llvm.voidType) { + returnBridge.bridge.makeNothing(llvm) } else { when (returnBridge.bridge) { is ReferenceBridge -> return autoreleaseAndRet(kotlinReferenceToRetainedObjC(targetResult)) @@ -1147,7 +1147,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp( is ValueTypeBridge -> kotlinToObjC(targetResult, returnBridge.bridge.objCValueType) } } - MethodBridge.ReturnValue.WithError.Success -> Int8(1).llvm // true + MethodBridge.ReturnValue.WithError.Success -> llvm.int8(1) // true is MethodBridge.ReturnValue.WithError.ZeroForError -> return genReturnOnSuccess(returnBridge.successBridge) MethodBridge.ReturnValue.Instance.InitResult -> param(0) MethodBridge.ReturnValue.Instance.FactoryResult -> return autoreleaseAndRet(kotlinReferenceToRetainedObjC(targetResult!!)) // provided by [callKotlin] @@ -1261,8 +1261,8 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( expectedType = parameterToBase[parameter]!!.type, resultLifetime = Lifetime.ARGUMENT ) - if (LLVMTypeOf(kotlinValue) == voidType) { - bridge.bridge.makeNothing() + if (LLVMTypeOf(kotlinValue) == llvm.voidType) { + bridge.bridge.makeNothing(llvm) } else { when (bridge.bridge) { is ReferenceBridge -> kotlinReferenceToRetainedObjC(kotlinValue).also { objCReferenceArgsToRelease += it } @@ -1293,8 +1293,8 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( error("Method is not instance and thus can't have bridge for overriding: $baseMethod") MethodBridgeValueParameter.ErrorOutParameter -> - alloca(int8TypePtr).also { - store(kNullInt8Ptr, it) + alloca(llvm.int8PtrType).also { + store(llvm.kNullInt8Ptr, it) errorOutPtr = it } @@ -1369,8 +1369,8 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( MethodBridge.ReturnValue.HashCode -> { if (codegen.context.is64BitNSInteger()) { - val low = trunc(targetResult, int32Type) - val high = trunc(shr(targetResult, 32, signed = false), int32Type) + val low = trunc(targetResult, llvm.int32Type) + val high = trunc(shr(targetResult, 32, signed = false), llvm.int32Type) xor(low, high) } else { targetResult @@ -1382,7 +1382,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( } MethodBridge.ReturnValue.WithError.Success -> { - ifThen(icmpEq(targetResult, Int8(0).llvm)) { + ifThen(icmpEq(targetResult, llvm.int8(0))) { check(!retainAutoreleasedTargetResult) rethrow() } @@ -1392,12 +1392,12 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( is MethodBridge.ReturnValue.WithError.ZeroForError -> { if (returnBridge.successMayBeZero) { val error = load(errorOutPtr!!) - ifThen(icmpNe(error, kNullInt8Ptr)) { + ifThen(icmpNe(error, llvm.kNullInt8Ptr)) { // error is not null, so targetResult should be null => no need for objc_release on it. rethrow() } } else { - ifThen(icmpEq(targetResult, kNullInt8Ptr)) { + ifThen(icmpEq(targetResult, llvm.kNullInt8Ptr)) { // targetResult is null => no need for objc_release on it. rethrow() } @@ -1506,7 +1506,7 @@ private fun ObjCExportCodeGenerator.createReverseAdapter( val kotlinToObjC = generateKotlinToObjCBridge( irFunction, baseMethod - ).bitcast(int8TypePtr) + ).bitcast(llvm.int8PtrType) return KotlinToObjCMethodAdapter(selector, itablePlace ?: ClassLayoutBuilder.InterfaceTablePlace.INVALID, @@ -1698,7 +1698,7 @@ private fun ObjCExportCodeGenerator.createTypeAdapter( val vtable = if (!irClass.isInterface && !irClass.typeInfoHasVtableAttached) { staticData.placeGlobal("", rttiGenerator.vtable(irClass)).also { it.setConstant(true) - }.pointer.getElementPtr(0) + }.pointer.getElementPtr(llvm, 0) } else { null } @@ -1830,7 +1830,7 @@ private fun ObjCExportCodeGenerator.nonOverridableAdapter( ): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter = KotlinToObjCMethodAdapter( selector, vtableIndex = if (hasSelectorAmbiguity) -2 else -1, // Describes the reason. - kotlinImpl = NullPointer(int8Type), + kotlinImpl = NullPointer(llvm.int8Type), itablePlace = ClassLayoutBuilder.InterfaceTablePlace.INVALID ) @@ -1966,52 +1966,57 @@ private fun ObjCExportCodeGenerator.createThrowableAsErrorAdapter(): ObjCExportC } private fun objCFunctionType(context: Context, methodBridge: MethodBridge): LlvmFunctionSignature { - val paramTypes = methodBridge.paramBridges.map { it.toLlvmParamType() } + val paramTypes = methodBridge.paramBridges.map { it.toLlvmParamType(context.generationState.llvm) } val returnType = methodBridge.returnBridge.toLlvmRetType(context) return LlvmFunctionSignature(returnType, paramTypes, isVararg = false) } -private val ObjCValueType.llvmType: LLVMTypeRef get() = when (this) { - ObjCValueType.BOOL -> int8Type - ObjCValueType.UNICHAR -> int16Type - ObjCValueType.CHAR -> int8Type - ObjCValueType.SHORT -> int16Type - ObjCValueType.INT -> int32Type - ObjCValueType.LONG_LONG -> int64Type - ObjCValueType.UNSIGNED_CHAR -> int8Type - ObjCValueType.UNSIGNED_SHORT -> int16Type - ObjCValueType.UNSIGNED_INT -> int32Type - ObjCValueType.UNSIGNED_LONG_LONG -> int64Type - ObjCValueType.FLOAT -> floatType - ObjCValueType.DOUBLE -> doubleType - ObjCValueType.POINTER -> kInt8Ptr +private fun ObjCValueType.toLlvmType(llvm: Llvm): LLVMTypeRef = when (this) { + ObjCValueType.BOOL -> llvm.int8Type + ObjCValueType.UNICHAR -> llvm.int16Type + ObjCValueType.CHAR -> llvm.int8Type + ObjCValueType.SHORT -> llvm.int16Type + ObjCValueType.INT -> llvm.int32Type + ObjCValueType.LONG_LONG -> llvm.int64Type + ObjCValueType.UNSIGNED_CHAR -> llvm.int8Type + ObjCValueType.UNSIGNED_SHORT -> llvm.int16Type + ObjCValueType.UNSIGNED_INT -> llvm.int32Type + ObjCValueType.UNSIGNED_LONG_LONG -> llvm.int64Type + ObjCValueType.FLOAT -> llvm.floatType + ObjCValueType.DOUBLE -> llvm.doubleType + ObjCValueType.POINTER -> llvm.int8PtrType } -private fun MethodBridgeParameter.toLlvmParamType(): LlvmParamType = when (this) { - is MethodBridgeValueParameter.Mapped -> this.bridge.toLlvmParamType() - is MethodBridgeReceiver -> ReferenceBridge.toLlvmParamType() - MethodBridgeSelector -> LlvmParamType(int8TypePtr) - MethodBridgeValueParameter.ErrorOutParameter -> LlvmParamType(pointerType(ReferenceBridge.toLlvmParamType().llvmType)) - is MethodBridgeValueParameter.SuspendCompletion -> LlvmParamType(int8TypePtr) +private fun MethodBridgeParameter.toLlvmParamType(llvm: Llvm): LlvmParamType = when (this) { + is MethodBridgeValueParameter.Mapped -> this.bridge.toLlvmParamType(llvm) + is MethodBridgeReceiver -> ReferenceBridge.toLlvmParamType(llvm) + MethodBridgeSelector -> LlvmParamType(llvm.int8PtrType) + MethodBridgeValueParameter.ErrorOutParameter -> LlvmParamType(pointerType(ReferenceBridge.toLlvmParamType(llvm).llvmType)) + is MethodBridgeValueParameter.SuspendCompletion -> LlvmParamType(llvm.int8PtrType) } private fun MethodBridge.ReturnValue.toLlvmRetType( context: Context -): LlvmRetType = when (this) { - MethodBridge.ReturnValue.Suspend, - MethodBridge.ReturnValue.Void -> LlvmRetType(voidType) - MethodBridge.ReturnValue.HashCode -> LlvmRetType(if (context.is64BitNSInteger()) int64Type else int32Type) - is MethodBridge.ReturnValue.Mapped -> this.bridge.toLlvmParamType() - MethodBridge.ReturnValue.WithError.Success -> ValueTypeBridge(ObjCValueType.BOOL).toLlvmParamType() +): LlvmRetType { + val llvm = context.generationState.llvm + return when (this) { + MethodBridge.ReturnValue.Suspend, + MethodBridge.ReturnValue.Void -> LlvmRetType(llvm.voidType) - MethodBridge.ReturnValue.Instance.InitResult, - MethodBridge.ReturnValue.Instance.FactoryResult -> ReferenceBridge.toLlvmParamType() - is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.toLlvmRetType(context) + MethodBridge.ReturnValue.HashCode -> LlvmRetType(if (context.is64BitNSInteger()) llvm.int64Type else llvm.int32Type) + is MethodBridge.ReturnValue.Mapped -> this.bridge.toLlvmParamType(llvm) + MethodBridge.ReturnValue.WithError.Success -> ValueTypeBridge(ObjCValueType.BOOL).toLlvmParamType(llvm) + + MethodBridge.ReturnValue.Instance.InitResult, + MethodBridge.ReturnValue.Instance.FactoryResult -> ReferenceBridge.toLlvmParamType(llvm) + + is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.toLlvmRetType(context) + } } -private fun TypeBridge.toLlvmParamType(): LlvmParamType = when (this) { - is ReferenceBridge, is BlockPointerBridge -> LlvmParamType(int8TypePtr) - is ValueTypeBridge -> LlvmParamType(this.objCValueType.llvmType, this.objCValueType.defaultParameterAttributes) +private fun TypeBridge.toLlvmParamType(llvm: Llvm): LlvmParamType = when (this) { + is ReferenceBridge, is BlockPointerBridge -> LlvmParamType(llvm.int8PtrType) + is ValueTypeBridge -> LlvmParamType(this.objCValueType.toLlvmType(llvm), this.objCValueType.defaultParameterAttributes) } internal fun ObjCExportCodeGenerator.getEncoding(methodBridge: MethodBridge): String { @@ -2021,7 +2026,7 @@ internal fun ObjCExportCodeGenerator.getEncoding(methodBridge: MethodBridge): St methodBridge.paramBridges.forEach { append(it.objCEncoding) append(paramOffset) - paramOffset += LLVMStoreSizeOfType(runtime.targetData, it.toLlvmParamType().llvmType).toInt() + paramOffset += LLVMStoreSizeOfType(runtime.targetData, it.toLlvmParamType(llvm).llvmType).toInt() } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index 4ba7e1a9f87..010d4ef6f62 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -496,7 +496,7 @@ internal object DataFlowIR { val placeToClassTable = true val symbolTableIndex = if (placeToClassTable) module.numberOfClasses++ else -1 val type = if (irClass.isExported()) - Type.Public(name.localHash.value, privateTypeIndex++, isFinal, isAbstract, null, + Type.Public(localHash(name.toByteArray()), privateTypeIndex++, isFinal, isAbstract, null, module, symbolTableIndex, irClass, takeName { name }) else Type.Private(privateTypeIndex++, isFinal, isAbstract, null, @@ -618,7 +618,7 @@ internal object DataFlowIR { val escapesBitMask = (escapesAnnotation?.getValueArgument(0) as? IrConst)?.value @Suppress("UNCHECKED_CAST") val pointsToBitMask = (pointsToAnnotation?.getValueArgument(0) as? IrVararg)?.elements?.map { (it as IrConst).value } - FunctionSymbol.External(name.localHash.value, attributes, it, takeName { name }, it.isExported()).apply { + FunctionSymbol.External(localHash(name.toByteArray()), attributes, it, takeName { name }, it.isExported()).apply { escapes = escapesBitMask pointsTo = pointsToBitMask?.toIntArray() } @@ -637,7 +637,7 @@ internal object DataFlowIR { val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1 val frozen = it is IrConstructor && irClass!!.isFrozen(context) val functionSymbol = if (it.isExported()) - FunctionSymbol.Public(name.localHash.value, module, symbolTableIndex, attributes, it, bridgeTargetSymbol, takeName { name }) + FunctionSymbol.Public(localHash(name.toByteArray()), module, symbolTableIndex, attributes, it, bridgeTargetSymbol, takeName { name }) else FunctionSymbol.Private(privateFunIndex++, module, symbolTableIndex, attributes, it, bridgeTargetSymbol, takeName { name }) if (frozen) {