diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BitcodeCompiler.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BitcodeCompiler.kt index 090fa55917c..74433e56b19 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BitcodeCompiler.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BitcodeCompiler.kt @@ -12,8 +12,9 @@ typealias BitcodeFile = String typealias ObjectFile = String typealias ExecutableFile = String -internal class BitcodeCompiler(val context: Context) { +internal class BitcodeCompiler(val generationState: NativeGenerationState) { + private val context = generationState.context private val platform = context.config.platform private val optimize = context.shouldOptimize() private val debug = context.config.debug @@ -31,7 +32,7 @@ internal class BitcodeCompiler(val context: Context) { .execute() private fun temporary(name: String, suffix: String): String = - context.generationState.tempFiles.create(name, suffix).absolutePath + generationState.tempFiles.create(name, suffix).absolutePath private fun targetTool(tool: String, vararg arg: String) { val absoluteToolName = if (platform.configurables is AppleConfigurables) { 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 4d152599cb3..ad29831f93a 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 @@ -167,26 +167,27 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context. * Initialize static boxing. * If output target is native binary then the cache is created. */ -internal fun initializeCachedBoxes(context: Context) { +internal fun initializeCachedBoxes(generationState: NativeGenerationState) { BoxCache.values().forEach { cache -> val cacheName = "${cache.name}_CACHE" val rangeStart = "${cache.name}_RANGE_FROM" val rangeEnd = "${cache.name}_RANGE_TO" - initCache(cache, context, cacheName, rangeStart, rangeEnd, - declareOnly = !context.generationState.shouldDefineCachedBoxes - ).also { context.generationState.llvm.boxCacheGlobals[cache] = it } + initCache(cache, generationState, cacheName, rangeStart, rangeEnd, + declareOnly = !generationState.shouldDefineCachedBoxes + ).also { generationState.llvm.boxCacheGlobals[cache] = it } } } /** * Adds global that refers to the cache. */ -private fun initCache(cache: BoxCache, context: Context, cacheName: String, +private fun initCache(cache: BoxCache, generationState: NativeGenerationState, cacheName: String, rangeStartName: String, rangeEndName: String, declareOnly: Boolean) : StaticData.Global { + val context = generationState.context val kotlinType = context.irBuiltIns.getKotlinClass(cache) - val staticData = context.generationState.llvm.staticData - val llvm = context.generationState.llvm + val staticData = generationState.llvm.staticData + val llvm = generationState.llvm val llvmType = kotlinType.defaultType.toLLVMType(llvm) val llvmBoxType = llvm.structType(llvm.runtime.objHeaderType, llvmType) val (start, end) = context.config.target.getBoxCacheRange(cache) @@ -207,14 +208,15 @@ private fun initCache(cache: BoxCache, context: Context, cacheName: String, } } -internal fun IrConstantPrimitive.toBoxCacheValue(context: Context): ConstValue? { +internal fun IrConstantPrimitive.toBoxCacheValue(generationState: NativeGenerationState): ConstValue? { + val irBuiltIns = generationState.context.irBuiltIns val cacheType = when (value.type) { - context.irBuiltIns.booleanType -> BoxCache.BOOLEAN - context.irBuiltIns.byteType -> BoxCache.BYTE - context.irBuiltIns.shortType -> BoxCache.SHORT - context.irBuiltIns.charType -> BoxCache.CHAR - context.irBuiltIns.intType -> BoxCache.INT - context.irBuiltIns.longType -> BoxCache.LONG + irBuiltIns.booleanType -> BoxCache.BOOLEAN + irBuiltIns.byteType -> BoxCache.BYTE + irBuiltIns.shortType -> BoxCache.SHORT + irBuiltIns.charType -> BoxCache.CHAR + irBuiltIns.intType -> BoxCache.INT + irBuiltIns.longType -> BoxCache.LONG else -> return null } val value = when (value.kind) { @@ -226,9 +228,9 @@ internal fun IrConstantPrimitive.toBoxCacheValue(context: Context): ConstValue? IrConstKind.Long -> value.value as Long else -> throw IllegalArgumentException("IrConst of kind ${value.kind} can't be converted to box cache") } - val (start, end) = context.config.target.getBoxCacheRange(cacheType) + val (start, end) = generationState.context.config.target.getBoxCacheRange(cacheType) return if (value in start..end) { - context.generationState.llvm.let { llvm -> + generationState.llvm.let { llvm -> llvm.boxCacheGlobals[cacheType]?.pointer?.getElementPtr(llvm, value.toInt() - start)?.getElementPtr(llvm, 0) } } else { 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 438d28daa84..f159085310f 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 @@ -719,7 +719,7 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi fun generateBindings(codegen: CodeGenerator) = BindingsBuilder(codegen).build() inner class BindingsBuilder(val codegen: CodeGenerator) : ContextUtils { - override val context = this@CAdapterGenerator.context + override val generationState = codegen.generationState internal val prefix = context.config.fullExportedNamePrefix.replace("-|\\.".toRegex(), "_") private lateinit var outputStreamWriter: PrintWriter @@ -929,7 +929,7 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi val exportedSymbols = mutableListOf() private fun makeGlobalStruct(top: ExportedElementScope) { - val headerFile = context.generationState.outputFiles.cAdapterHeader + val headerFile = generationState.outputFiles.cAdapterHeader outputStreamWriter = headerFile.printWriter() val exportedSymbol = "${prefix}_symbols" @@ -1014,7 +1014,7 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi outputStreamWriter.close() println("Produced library API in ${prefix}_api.h") - outputStreamWriter = context.generationState.tempFiles + outputStreamWriter = generationState.tempFiles .cAdapterCpp .printWriter() @@ -1154,7 +1154,7 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi outputStreamWriter.close() if (context.config.target.family == Family.MINGW) { - outputStreamWriter = context.generationState.outputFiles + outputStreamWriter = generationState.outputFiles .cAdapterDef .printWriter() output("EXPORTS") 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 0fb244300c1..fe14dd1d99c 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,8 +20,9 @@ private fun LLVMValueRef.isLLVMBuiltin(): Boolean { } -private class CallsChecker(context: Context, goodFunctions: List) { - private val llvm = context.generationState.llvm +private class CallsChecker(generationState: NativeGenerationState, goodFunctions: List) { + private val llvm = generationState.llvm + private val context = generationState.context private val goodFunctionsExact = goodFunctions.filterNot { it.endsWith("*") }.toSet() private val goodFunctionsByPrefix = goodFunctions.filter { it.endsWith("*") }.map { it.substring(0, it.length - 1) }.sorted() @@ -164,8 +165,8 @@ private class CallsChecker(context: Context, goodFunctions: List) { private const val functionListGlobal = "Kotlin_callsCheckerKnownFunctions" private const val functionListSizeGlobal = "Kotlin_callsCheckerKnownFunctionsCount" -internal fun checkLlvmModuleExternalCalls(context: Context) { - val llvm = context.generationState.llvm +internal fun checkLlvmModuleExternalCalls(generationState: NativeGenerationState) { + val llvm = generationState.llvm val staticData = llvm.staticData @@ -177,19 +178,19 @@ internal fun checkLlvmModuleExternalCalls(context: Context) { }.toList() } ?: emptyList() - val checker = CallsChecker(context, goodFunctions) + val checker = CallsChecker(generationState, goodFunctions) getFunctions(llvm.module) .filter { !it.isExternalFunction() && it !in ignoredFunctions } .forEach(checker::processFunction) // otherwise optimiser can inline it staticData.getGlobal(functionListGlobal)?.setExternallyInitialized(true); staticData.getGlobal(functionListSizeGlobal)?.setExternallyInitialized(true); - context.verifyBitCode() + generationState.verifyBitCode() } // this should be a separate pass, to handle DCE correctly -internal fun addFunctionsListSymbolForChecker(context: Context) { - val llvm = context.generationState.llvm +internal fun addFunctionsListSymbolForChecker(generationState: NativeGenerationState) { + val llvm = generationState.llvm val staticData = llvm.staticData val functions = getFunctions(llvm.module) @@ -203,5 +204,5 @@ internal fun addFunctionsListSymbolForChecker(context: Context) { staticData.getGlobal(functionListSizeGlobal) ?.setInitializer(llvm.constInt32(functions.size)) ?: throw IllegalStateException("$functionListSizeGlobal global not found") - context.verifyBitCode() + generationState.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 4815eda6181..96a311006dc 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 @@ -87,13 +87,14 @@ internal fun llvmIrDumpCallback(state: ActionState, module: IrModuleFragment, co } } -internal fun produceCStubs(context: Context) { - context.generationState.cStubsManager.compile( +internal fun produceCStubs(generationState: NativeGenerationState) { + val context = generationState.context + generationState.cStubsManager.compile( context.config.clang, context.messageCollector, context.inVerbosePhase ).forEach { - parseAndLinkBitcodeFile(context, context.generationState.llvm.module, it.absolutePath) + parseAndLinkBitcodeFile(generationState, generationState.llvm.module, it.absolutePath) } } @@ -111,11 +112,11 @@ private data class LlvmModules( * - Runtime modules. These may be used as an input for a separate LTO (e.g. for debug builds). * - Everything else. */ -private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List): LlvmModules { - val config = context.config +private fun collectLlvmModules(generationState: NativeGenerationState, generatedBitcodeFiles: List): LlvmModules { + val config = generationState.context.config - val (bitcodePartOfStdlib, bitcodeLibraries) = context.generationState.llvm.bitcodeToLink - .partition { it.isStdlib && context.generationState.producedLlvmModuleContainsStdlib } + val (bitcodePartOfStdlib, bitcodeLibraries) = generationState.llvm.bitcodeToLink + .partition { it.isStdlib && generationState.producedLlvmModuleContainsStdlib } .toList() .map { libraries -> libraries.flatMap { it.bitcodePaths }.filter { it.isBitcode } @@ -123,7 +124,7 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List): List = files.map { bitcodeFile -> - val parsedModule = parseBitcodeFile(context.generationState.llvmContext, bitcodeFile) - if (!context.shouldUseDebugInfoFromNativeLibs()) { + val parsedModule = parseBitcodeFile(generationState.llvmContext, bitcodeFile) + if (!generationState.context.shouldUseDebugInfoFromNativeLibs()) { LLVMStripModuleDebugInfo(parsedModule) } parsedModule @@ -145,67 +146,68 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List) { - val (runtimeModules, additionalModules) = collectLlvmModules(context, generatedBitcodeFiles) +private fun linkAllDependencies(generationState: NativeGenerationState, generatedBitcodeFiles: List) { + val (runtimeModules, additionalModules) = collectLlvmModules(generationState, generatedBitcodeFiles) // TODO: Possibly slow, maybe to a separate phase? - val optimizedRuntimeModules = RuntimeLinkageStrategy.pick(context, runtimeModules).run() + val optimizedRuntimeModules = RuntimeLinkageStrategy.pick(generationState, runtimeModules).run() (optimizedRuntimeModules + additionalModules).forEach { - val failed = llvmLinkModules2(context, context.generationState.llvm.module, it) + val failed = llvmLinkModules2(generationState, generationState.llvm.module, it) if (failed != 0) { error("Failed to link ${it.getName()}") } } } -private fun insertAliasToEntryPoint(context: Context) { - val nomain = context.config.configuration.get(KonanConfigKeys.NOMAIN) ?: false - if (context.config.produce != CompilerOutputKind.PROGRAM || nomain) +private fun insertAliasToEntryPoint(generationState: NativeGenerationState) { + val config = generationState.context.config + val nomain = config.configuration.get(KonanConfigKeys.NOMAIN) ?: false + if (config.produce != CompilerOutputKind.PROGRAM || nomain) return - val module = context.generationState.llvm.module - val entryPointName = context.config.entryPointName + val module = generationState.llvm.module + val entryPointName = config.entryPointName val entryPoint = LLVMGetNamedFunction(module, entryPointName) ?: error("Module doesn't contain `$entryPointName`") LLVMAddAlias(module, LLVMTypeOf(entryPoint)!!, entryPoint, "main") } -internal fun linkBitcodeDependencies(context: Context) { - val config = context.config.configuration - val tempFiles = context.generationState.tempFiles - val produce = config.get(KonanConfigKeys.PRODUCE) +internal fun linkBitcodeDependencies(generationState: NativeGenerationState) { + val config = generationState.context.config + val tempFiles = generationState.tempFiles + val produce = config.produce val generatedBitcodeFiles = if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) { produceCAdapterBitcode( - context.config.clang, + config.clang, tempFiles.cAdapterCppName, tempFiles.cAdapterBitcodeName) listOf(tempFiles.cAdapterBitcodeName) } else emptyList() - if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) { - embedAppleLinkerOptionsToBitcode(context.generationState.llvm, context.config) + if (produce == CompilerOutputKind.FRAMEWORK && config.produceStaticFramework) { + embedAppleLinkerOptionsToBitcode(generationState.llvm, config) } - linkAllDependencies(context, generatedBitcodeFiles) + linkAllDependencies(generationState, generatedBitcodeFiles) } -internal fun produceOutput(context: Context) { - - val config = context.config.configuration - val tempFiles = context.generationState.tempFiles - val produce = context.config.produce +internal fun produceOutput(generationState: NativeGenerationState) { + val context = generationState.context + val config = context.config + val tempFiles = generationState.tempFiles + val produce = config.produce if (produce == CompilerOutputKind.FRAMEWORK) { - context.objCExport.produceFrameworkInterface() - if (context.config.omitFrameworkBinary) { + generationState.objCExport.produceFrameworkInterface() + if (config.omitFrameworkBinary) { // Compiler does not compile anything in this mode, so return early. return } @@ -218,21 +220,21 @@ internal fun produceOutput(context: Context) { CompilerOutputKind.STATIC_CACHE, CompilerOutputKind.PROGRAM -> { val output = tempFiles.nativeBinaryFileName - context.bitcodeFileName = output + generationState.bitcodeFileName = output // Insert `_main` after pipeline so we won't worry about optimizations // corrupting entry point. - insertAliasToEntryPoint(context) - LLVMWriteBitcodeToFile(context.generationState.llvm.module, output) + insertAliasToEntryPoint(generationState) + LLVMWriteBitcodeToFile(generationState.llvm.module, output) } CompilerOutputKind.LIBRARY -> { - val nopack = config.getBoolean(KonanConfigKeys.NOPACK) - val output = context.generationState.outputFiles.klibOutputFileName(!nopack) - val libraryName = context.config.moduleId - val shortLibraryName = context.config.shortModuleName + val nopack = config.configuration.getBoolean(KonanConfigKeys.NOPACK) + val output = generationState.outputFiles.klibOutputFileName(!nopack) + val libraryName = config.moduleId + val shortLibraryName = config.shortModuleName val neededLibraries = context.librariesWithDependencies val abiVersion = KotlinAbiVersion.CURRENT val compilerVersion = CompilerVersion.CURRENT.toString() - val libraryVersion = config.get(KonanConfigKeys.LIBRARY_VERSION) + val libraryVersion = config.configuration.get(KonanConfigKeys.LIBRARY_VERSION) val metadataVersion = KlibMetadataVersion.INSTANCE.toString() val irVersion = KlibIrVersion.INSTANCE.toString() val versions = KotlinLibraryVersioning( @@ -242,19 +244,19 @@ internal fun produceOutput(context: Context) { metadataVersion = metadataVersion, irVersion = irVersion ) - val target = context.config.target - val manifestProperties = context.config.manifestProperties + val target = config.target + val manifestProperties = config.manifestProperties if (!nopack) { - val suffix = context.config.produce.suffix(target) + val suffix = config.produce.suffix(target) if (!output.endsWith(suffix)) { error("please specify correct output: packed: ${!nopack}, $output$suffix") } } val library = buildLibrary( - context.config.nativeLibraries, - context.config.includeBinaries, + config.nativeLibraries, + config.includeBinaries, neededLibraries, context.serializedMetadata!!, context.serializedIr, @@ -267,23 +269,23 @@ internal fun produceOutput(context: Context) { manifestProperties, context.dataFlowGraph) - context.bitcodeFileName = library.mainBitcodeFileName + generationState.bitcodeFileName = library.mainBitcodeFileName } CompilerOutputKind.BITCODE -> { - val output = context.generationState.outputFile - context.bitcodeFileName = output - LLVMWriteBitcodeToFile(context.generationState.llvm.module, output) + val output = generationState.outputFile + generationState.bitcodeFileName = output + LLVMWriteBitcodeToFile(generationState.llvm.module, output) } else -> error("not supported: $produce") } } -internal fun parseAndLinkBitcodeFile(context: Context, llvmModule: LLVMModuleRef, path: String) { - val parsedModule = parseBitcodeFile(context.generationState.llvmContext, path) - if (!context.shouldUseDebugInfoFromNativeLibs()) { +private fun parseAndLinkBitcodeFile(generationState: NativeGenerationState, llvmModule: LLVMModuleRef, path: String) { + val parsedModule = parseBitcodeFile(generationState.llvmContext, path) + if (!generationState.context.shouldUseDebugInfoFromNativeLibs()) { LLVMStripModuleDebugInfo(parsedModule) } - val failed = llvmLinkModules2(context, llvmModule, parsedModule) + val failed = llvmLinkModules2(generationState, llvmModule, parsedModule) if (failed != 0) { throw Error("failed to link $path") } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt index d2e12053294..d2949d87e54 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt @@ -15,9 +15,10 @@ import org.jetbrains.kotlin.backend.konan.descriptors.GlobalHierarchyAnalysisRes import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.backend.konan.llvm.CodegenClassMetadata import org.jetbrains.kotlin.backend.konan.llvm.Lifetime -import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager import org.jetbrains.kotlin.backend.konan.lower.* import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport +import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportCodeSpec +import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportedInterface import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis import org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFG import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker @@ -65,8 +66,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config), Confi lateinit var moduleDescriptor: ModuleDescriptor - lateinit var objCExport: ObjCExport - lateinit var cAdapterGenerator: CAdapterGenerator lateinit var expectDescriptorToSymbol: MutableMap @@ -190,10 +189,10 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config), Confi InteropBuiltIns(this.builtIns) } - lateinit var bitcodeFileName: String - lateinit var library: KonanLibraryLayout + var objCExportedInterface: ObjCExportedInterface? = null + var objCExportCodeSpec: ObjCExportCodeSpec? = null - val coverage by lazy { CoverageManager(this) } + lateinit var library: KonanLibraryLayout fun separator(title: String) { println("\n\n--- ${title} ----------------------\n") @@ -229,8 +228,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config), Confi internal val stdlibModule get() = this.builtIns.any.module - lateinit var compilerOutput: List - val declaredLocalArrays: MutableMap = HashMap() lateinit var irLinker: KonanIrLinker diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt index b60ed35d862..e41031da104 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt @@ -22,14 +22,15 @@ import org.jetbrains.kotlin.name.Name internal object DECLARATION_ORIGIN_ENTRY_POINT : IrDeclarationOriginImpl("ENTRY_POINT") -internal fun makeEntryPoint(context: Context): IrFunction { +internal fun makeEntryPoint(generationState: NativeGenerationState): IrFunction { + val context = generationState.context val actualMain = context.ir.symbols.entryPoint!!.owner // TODO: Do we need to do something with the offsets if
is in a cached library? - val startOffset = if (context.generationState.llvmModuleSpecification.containsDeclaration(actualMain)) + val startOffset = if (generationState.llvmModuleSpecification.containsDeclaration(actualMain)) actualMain.startOffset else SYNTHETIC_OFFSET - val endOffset = if (context.generationState.llvmModuleSpecification.containsDeclaration(actualMain)) + val endOffset = if (generationState.llvmModuleSpecification.containsDeclaration(actualMain)) actualMain.endOffset else SYNTHETIC_OFFSET diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt index b95ab5b9bc3..eddb4d54107 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt @@ -150,7 +150,7 @@ internal val sharedVariablesPhase = makeKonanFileLoweringPhase( ) internal val inventNamesForLocalClasses = makeKonanFileLoweringPhase( - { NativeInventNamesForLocalClasses(it) }, + { NativeInventNamesForLocalClasses(it.generationState) }, name = "InventNamesForLocalClasses", description = "Invent names for local classes and anonymous objects" ) @@ -186,7 +186,7 @@ internal val wrapInlineDeclarationsWithReifiedTypeParametersLowering = makeKonan internal val inlinePhase = makeKonanFileOpPhase( { context, irFile -> - FunctionInlining(context, NativeInlineFunctionResolver(context)).lower(irFile) + FunctionInlining(context, NativeInlineFunctionResolver(context, context.generationState)).lower(irFile) }, name = "Inline", description = "Functions inlining", @@ -250,10 +250,10 @@ internal val initializersPhase = makeKonanFileLoweringPhase( prerequisite = setOf(enumConstructorsPhase) ) -internal val objectClassesPhase = makeKonanFileLoweringPhase( - ::ObjectClassLowering, +internal val objectClassesPhase = makeKonanFileOpPhase( + op = { context, irFile -> ObjectClassLowering(context.generationState).lower(irFile) }, name = "ObjectClasses", - description = "Enum constructors lowering" + description = "Object classes lowering" ) internal val localFunctionsPhase = makeKonanFileOpPhase( @@ -333,13 +333,13 @@ internal val testProcessorPhase = makeKonanFileOpPhase( ) internal val delegationPhase = makeKonanFileLoweringPhase( - ::PropertyDelegationLowering, + { PropertyDelegationLowering(it.generationState) }, name = "Delegation", description = "Delegation lowering" ) internal val functionReferencePhase = makeKonanFileLoweringPhase( - ::FunctionReferenceLowering, + { FunctionReferenceLowering(it.generationState) }, name = "FunctionReference", description = "Function references lowering", prerequisite = setOf(delegationPhase, localFunctionsPhase) // TODO: make weak dependency on `testProcessorPhase` @@ -382,7 +382,7 @@ internal val builtinOperatorPhase = makeKonanFileLoweringPhase( ) internal val interopPhase = makeKonanFileLoweringPhase( - ::InteropLowering, + { InteropLowering(it.generationState) }, name = "Interop", description = "Interop lowering", prerequisite = setOf(inlinePhase, localFunctionsPhase, functionReferencePhase) @@ -397,7 +397,7 @@ internal val varargPhase = makeKonanFileLoweringPhase( internal val coroutinesPhase = makeKonanFileOpPhase( { context, irFile -> - NativeSuspendFunctionsLowering(context).lower(irFile) + NativeSuspendFunctionsLowering(context.generationState).lower(irFile) AddContinuationToNonLocalSuspendFunctionsLowering(context).lower(irFile) NativeAddContinuationToFunctionCallsLowering(context).lower(irFile) AddFunctionSupertypeToSuspendFunctionLowering(context).lower(irFile) @@ -483,7 +483,7 @@ internal val exportInternalAbiPhase = makeKonanFileLoweringPhase( ) internal val useInternalAbiPhase = makeKonanFileLoweringPhase( - ::ImportCachesAbiTransformer, + { ImportCachesAbiTransformer(it.generationState) }, name = "UseInternalAbi", description = "Use internal ABI functions to access private entities" ) \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt index fa110f7de84..b4c1a7eea5a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt @@ -33,8 +33,9 @@ internal fun determineLinkerOutput(context: Context): LinkerOutputKind = else -> TODO("${context.config.produce} should not reach native linker stage") } -internal class CacheStorage(val context: Context) { - private val outputFiles = context.generationState.outputFiles +internal class CacheStorage(val generationState: NativeGenerationState) { + private val config = generationState.context.config + private val outputFiles = generationState.outputFiles fun renameOutput() { // For caches the output file is a directory. It might be created by someone else, @@ -53,30 +54,30 @@ internal class CacheStorage(val context: Context) { } private fun saveCacheBitcodeDependencies() { - val bitcodeDependencies = context.config.resolvedLibraries + val bitcodeDependencies = config.resolvedLibraries .getFullList(TopologicalLibraryOrder) .map { it as KonanLibrary } .filter { - context.generationState.llvmImports.bitcodeIsUsed(it) - && it != context.config.cacheSupport.libraryToCache?.klib // Skip loops. + generationState.llvmImports.bitcodeIsUsed(it) + && it != config.cacheSupport.libraryToCache?.klib // Skip loops. } outputFiles.bitcodeDependenciesFile!!.writeLines(bitcodeDependencies.map { it.uniqueName }) } private fun saveInlineFunctionBodies() { outputFiles.inlineFunctionBodiesFile!!.writeBytes( - InlineFunctionBodyReferenceSerializer.serialize(context.generationState.inlineFunctionBodies)) + InlineFunctionBodyReferenceSerializer.serialize(generationState.inlineFunctionBodies)) } private fun saveClassFields() { outputFiles.classFieldsFile!!.writeBytes( - ClassFieldsSerializer.serialize(context.generationState.classFields)) + ClassFieldsSerializer.serialize(generationState.classFields)) } } // TODO: We have a Linker.kt file in the shared module. -internal class Linker(val context: Context) { - +internal class Linker(val generationState: NativeGenerationState) { + private val context = generationState.context private val platform = context.config.platform private val config = context.config.configuration private val linkerOutput = determineLinkerOutput(context) @@ -86,13 +87,13 @@ internal class Linker(val context: Context) { private val debug = context.config.debug || context.config.lightDebug fun link(objectFiles: List) { - val nativeDependencies = context.generationState.llvm.nativeDependenciesToLink + val nativeDependencies = generationState.llvm.nativeDependenciesToLink val includedBinariesLibraries = context.config.libraryToCache?.let { listOf(it.klib) } ?: nativeDependencies.filterNot { context.config.cachedLibraries.isLibraryCached(it) } val includedBinaries = includedBinariesLibraries.map { (it as? KonanLibrary)?.includedPaths.orEmpty() }.flatten() - val libraryProvidedLinkerFlags = context.generationState.llvm.allNativeDependencies.map { it.linkerOpts }.flatten() + val libraryProvidedLinkerFlags = generationState.llvm.allNativeDependencies.map { it.linkerOpts }.flatten() runLinker(objectFiles, includedBinaries, libraryProvidedLinkerFlags) } @@ -117,7 +118,7 @@ internal class Linker(val context: Context) { private fun runLinker(objectFiles: List, includedBinaries: List, libraryProvidedLinkerFlags: List): ExecutableFile? { - val outputFiles = context.generationState.outputFiles + val outputFiles = generationState.outputFiles val additionalLinkerArgs: List val executable: String @@ -134,7 +135,7 @@ internal class Linker(val context: Context) { } executable = outputFiles.nativeBinaryFile } else { - val framework = File(context.generationState.outputFile) + val framework = File(generationState.outputFile) val dylibName = framework.name.removeSuffix(".framework") val dylibRelativePath = when (target.family) { Family.IOS, @@ -149,7 +150,7 @@ internal class Linker(val context: Context) { executable = dylibPath.absolutePath } - val needsProfileLibrary = context.coverage.enabled + val needsProfileLibrary = generationState.coverage.enabled val mimallocEnabled = context.config.allocationMode == AllocationMode.MIMALLOC val linkerInput = determineLinkerInput(objectFiles, linkerOutput) @@ -203,7 +204,7 @@ internal class Linker(val context: Context) { } private fun determineLinkerInput(objectFiles: List, linkerOutputKind: LinkerOutputKind): LinkerInput { - val caches = determineCachesToLink(context) + val caches = determineCachesToLink(generationState) // Since we have several linker stages that involve caching, // we should detect cache usage early to report errors correctly. val cachingInvolved = caches.static.isNotEmpty() || caches.dynamic.isNotEmpty() @@ -213,7 +214,7 @@ internal class Linker(val context: Context) { LinkerInput(objectFiles, CachesToLink(emptyList(), caches.dynamic), emptyList(), cachingInvolved) } shouldPerformPreLink(caches, linkerOutputKind) -> { - val preLinkResult = context.generationState.tempFiles.create("withStaticCaches", ".o").absolutePath + val preLinkResult = generationState.tempFiles.create("withStaticCaches", ".o").absolutePath val preLinkCommands = linker.preLinkCommands(objectFiles + caches.static, preLinkResult) LinkerInput(listOf(preLinkResult), CachesToLink(emptyList(), caches.dynamic), preLinkCommands, cachingInvolved) } @@ -231,13 +232,13 @@ private class LinkerInput( private class CachesToLink(val static: List, val dynamic: List) -private fun determineCachesToLink(context: Context): CachesToLink { +private fun determineCachesToLink(generationState: NativeGenerationState): CachesToLink { val staticCaches = mutableListOf() val dynamicCaches = mutableListOf() - context.generationState.llvm.allCachedBitcodeDependencies.forEach { library -> - val currentBinaryContainsLibrary = context.generationState.llvmModuleSpecification.containsLibrary(library) - val cache = context.config.cachedLibraries.getLibraryCache(library) + generationState.llvm.allCachedBitcodeDependencies.forEach { library -> + val currentBinaryContainsLibrary = generationState.llvmModuleSpecification.containsLibrary(library) + val cache = generationState.context.config.cachedLibraries.getLibraryCache(library) ?: error("Library $library is expected to be cached") // Consistency check. Generally guaranteed by implementation. diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt index bf4292b16d2..319e6f0df99 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt @@ -43,7 +43,7 @@ internal class DefaultLlvmModuleSpecification(cachedLibraries: CachedLibraries) } internal class CacheLlvmModuleSpecification( - private val context: Context, + private val generationState: NativeGenerationState, cachedLibraries: CachedLibraries, private val libraryToCache: PartialCacheInfo ) : LlvmModuleSpecificationBase(cachedLibraries) { @@ -52,10 +52,10 @@ internal class CacheLlvmModuleSpecification( override fun containsLibrary(library: KotlinLibrary): Boolean = library == libraryToCache.klib override fun containsDeclaration(declaration: IrDeclaration): Boolean { - if (context.generationState.shouldDefineFunctionClasses && declaration.getPackageFragment().isFunctionInterfaceFile) + if (generationState.shouldDefineFunctionClasses && declaration.getPackageFragment().isFunctionInterfaceFile) return true if (!super.containsDeclaration(declaration)) return false - return (context.generationState.cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile) + return (generationState.cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile) ?.filePath.let { it == null || it == declaration.fileOrNull?.path } } } 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 41a267df362..9af65bea952 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,7 +10,9 @@ 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.coverage.CoverageManager import org.jetbrains.kotlin.backend.konan.llvm.verifyModule +import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.serialization.SerializedClassFields import org.jetbrains.kotlin.backend.konan.serialization.SerializedInlineFunctionReference import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer @@ -40,7 +42,7 @@ internal class FileLowerState { "$prefix${cStubCount++}" } -internal class NativeGenerationState(private val context: Context, val cacheDeserializationStrategy: CacheDeserializationStrategy?) { +internal class NativeGenerationState(val context: Context, val cacheDeserializationStrategy: CacheDeserializationStrategy?) { private val config = context.config private val outputPath = config.cacheSupport.tryGetImplicitOutput(cacheDeserializationStrategy) ?: config.outputPath @@ -75,7 +77,7 @@ internal class NativeGenerationState(private val context: Context, val cacheDese val llvmModuleSpecification by lazy { if (config.produce.isCache) - CacheLlvmModuleSpecification(context, config.cachedLibraries, + CacheLlvmModuleSpecification(this, config.cachedLibraries, PartialCacheInfo(config.libraryToCache!!.klib, cacheDeserializationStrategy!!)) else DefaultLlvmModuleSpecification(config.cachedLibraries) } @@ -83,8 +85,8 @@ internal class NativeGenerationState(private val context: Context, val cacheDese val producedLlvmModuleContainsStdlib get() = llvmModuleSpecification.containsModule(context.stdlibModule) 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) } + private val llvmDelegate = lazy { Llvm(this, LLVMModuleCreateWithNameInContext("out", llvmContext)!!) } + private val debugInfoDelegate = lazy { DebugInfo(this) } val llvmContext = LLVMContextCreate()!! val llvmImports = Llvm.ImportsImpl(context) @@ -94,6 +96,14 @@ internal class NativeGenerationState(private val context: Context, val cacheDese val cStubsManager = CStubsManager(config.target, this) lateinit var llvmDeclarations: LlvmDeclarations + lateinit var bitcodeFileName: String + + lateinit var compilerOutput: List + + val coverage by lazy { CoverageManager(this) } + + lateinit var objCExport: ObjCExport + fun hasDebugInfo() = debugInfoDelegate.isInitialized() fun verifyBitCode() { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt index aa0bae65792..7d4379f4239 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt @@ -86,10 +86,11 @@ private fun tryGetInlineThreshold(context: Context): Int? { * Still, runtime is not intended to be debugged by user, and we can optimize it pretty aggressively * even in debug compilation. */ -internal fun createLTOPipelineConfigForRuntime(context: Context): LlvmPipelineConfig { +internal fun createLTOPipelineConfigForRuntime(generationState: NativeGenerationState): LlvmPipelineConfig { + val context = generationState.context val configurables: Configurables = context.config.platform.configurables return LlvmPipelineConfig( - context.generationState.llvm.targetTriple, + generationState.llvm.targetTriple, getCpuModel(context), getCpuFeatures(context), LlvmOptimizationLevel.AGGRESSIVE, @@ -114,7 +115,8 @@ internal fun createLTOPipelineConfigForRuntime(context: Context): LlvmPipelineCo * In case of debug we do almost nothing (that's why we need [createLTOPipelineConfigForRuntime]), * but for release binaries we rely on "closed" world and enable a lot of optimizations. */ -internal fun createLTOFinalPipelineConfig(context: Context): LlvmPipelineConfig { +internal fun createLTOFinalPipelineConfig(generationState: NativeGenerationState): LlvmPipelineConfig { + val context = generationState.context val target = context.config.target val configurables: Configurables = context.config.platform.configurables val cpuModel = getCpuModel(context) @@ -142,7 +144,7 @@ internal fun createLTOFinalPipelineConfig(context: Context): LlvmPipelineConfig val globalDce = true // Since we are in a "closed world" internalization can be safely used // to reduce size of a bitcode with global dce. - val internalize = context.generationState.llvmModuleSpecification.isFinal + val internalize = generationState.llvmModuleSpecification.isFinal // Hidden visibility makes symbols internal when linking the binary. // When producing dynamic library, this enables stripping unused symbols from binary with -dead_strip flag, // similar to DCE enabled by internalize but later: @@ -160,7 +162,7 @@ internal fun createLTOFinalPipelineConfig(context: Context): LlvmPipelineConfig } return LlvmPipelineConfig( - context.generationState.llvm.targetTriple, + generationState.llvm.targetTriple, cpuModel, cpuFeatures, optimizationLevel, 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 d7651ca5d9d..83bad1b42c7 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 @@ -36,7 +36,7 @@ internal sealed class RuntimeLinkageStrategy { * Links all runtime modules into a single one and optimizes it. */ class LinkAndOptimize( - private val context: Context, + private val generationState: NativeGenerationState, private val runtimeNativeLibraries: List ) : RuntimeLinkageStrategy() { @@ -44,15 +44,15 @@ internal sealed class RuntimeLinkageStrategy { if (runtimeNativeLibraries.isEmpty()) { return emptyList() } - val runtimeModule = LLVMModuleCreateWithNameInContext("runtime", context.generationState.llvmContext)!! + val runtimeModule = LLVMModuleCreateWithNameInContext("runtime", generationState.llvmContext)!! runtimeNativeLibraries.forEach { - val failed = llvmLinkModules2(context, runtimeModule, it) + val failed = llvmLinkModules2(generationState, runtimeModule, it) if (failed != 0) { throw Error("Failed to link ${it.getName()}") } } - val config = createLTOPipelineConfigForRuntime(context) - LlvmOptimizationPipeline(config, runtimeModule, context).use { + val config = createLTOPipelineConfigForRuntime(generationState) + LlvmOptimizationPipeline(config, runtimeModule, generationState.context).use { it.run() } return listOf(runtimeModule) @@ -63,12 +63,13 @@ internal sealed class RuntimeLinkageStrategy { /** * Choose runtime linkage strategy based on current compiler configuration and [BinaryOptions.linkRuntime]. */ - internal fun pick(context: Context, runtimeLlvmModules: List): RuntimeLinkageStrategy { - val binaryOption = context.config.configuration.get(BinaryOptions.linkRuntime) + internal fun pick(generationState: NativeGenerationState, runtimeLlvmModules: List): RuntimeLinkageStrategy { + val config = generationState.context.config + val binaryOption = config.configuration.get(BinaryOptions.linkRuntime) return when { binaryOption == RuntimeLinkageStrategyBinaryOption.Raw -> Raw(runtimeLlvmModules) - binaryOption == RuntimeLinkageStrategyBinaryOption.Optimize -> LinkAndOptimize(context, runtimeLlvmModules) - context.config.debug -> LinkAndOptimize(context, runtimeLlvmModules) + binaryOption == RuntimeLinkageStrategyBinaryOption.Optimize -> LinkAndOptimize(generationState, runtimeLlvmModules) + config.debug -> LinkAndOptimize(generationState, runtimeLlvmModules) else -> Raw(runtimeLlvmModules) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index 4d08bcfe03a..4913362582d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.lower.CacheInfoBuilder import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker -import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.objcexport.createCodeSpec import org.jetbrains.kotlin.backend.konan.objcexport.produceObjCExportInterface import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer @@ -92,13 +91,12 @@ internal val createSymbolTablePhase = konanUnitPhase( internal val objCExportPhase = konanUnitPhase( op = { - val objcInterface = when { + objCExportedInterface = when { !config.target.family.isAppleFamily -> null config.produce != CompilerOutputKind.FRAMEWORK -> null else -> produceObjCExportInterface(this) } - val codeSpec = objcInterface?.createCodeSpec(symbolTable!!) - objCExport = ObjCExport(this, objcInterface, codeSpec) + objCExportCodeSpec = objCExportedInterface?.createCodeSpec(symbolTable!!) }, name = "ObjCExport", description = "Objective-C header generation", @@ -135,7 +133,7 @@ internal val buildAdditionalCacheInfoPhase = konanUnitPhase( if (moduleDeserializer == null) { require(module.descriptor.isFromInteropLibrary()) { "No module deserializer for ${module.descriptor}" } } else { - CacheInfoBuilder(this, moduleDeserializer).build() + CacheInfoBuilder(this.generationState, moduleDeserializer, module).build() } }, name = "BuildAdditionalCacheInfo", @@ -216,25 +214,25 @@ internal val serializerPhase = konanUnitPhase( ) internal val saveAdditionalCacheInfoPhase = konanUnitPhase( - op = { CacheStorage(this).saveAdditionalCacheInfo() }, + op = { CacheStorage(generationState).saveAdditionalCacheInfo() }, name = "SaveAdditionalCacheInfo", description = "Save additional cache info (inline functions bodies and fields of classes)" ) internal val objectFilesPhase = konanUnitPhase( - op = { compilerOutput = BitcodeCompiler(this).makeObjectFiles(bitcodeFileName) }, + op = { this.generationState.compilerOutput = BitcodeCompiler(this.generationState).makeObjectFiles(this.generationState.bitcodeFileName) }, name = "ObjectFiles", description = "Bitcode to object file" ) internal val linkerPhase = konanUnitPhase( - op = { Linker(this).link(compilerOutput) }, + op = { Linker(this.generationState).link(this.generationState.compilerOutput) }, name = "Linker", description = "Linker" ) internal val finalizeCachePhase = konanUnitPhase( - op = { CacheStorage(this).renameOutput() }, + op = { CacheStorage(this.generationState).renameOutput() }, name = "FinalizeCache", description = "Finalize cache (rename temp to the final dist)" ) @@ -393,7 +391,7 @@ internal val entryPointPhase = makeCustomPhase( context.irModule!!.addFile(NaiveSourceBasedFileEntryImpl("entryPointOwner"), FqName("kotlin.native.internal.abi")) } - file.addChild(makeEntryPoint(context)) + file.addChild(makeEntryPoint(context.generationState)) } ) 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 273b64d1d0a..d791732f133 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 @@ -9,6 +9,7 @@ import llvm.LLVMStoreSizeOfType import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.* +import org.jetbrains.kotlin.backend.konan.llvm.Llvm import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName import org.jetbrains.kotlin.backend.konan.llvm.toLLVMType import org.jetbrains.kotlin.backend.konan.llvm.localHash @@ -407,31 +408,34 @@ internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context) { * All fields of the class instance. * The order respects the class hierarchy, i.e. a class [fields] contains superclass [fields] as a prefix. */ - val fields: List - get() = fieldsInternal.map { fieldInfo -> - val mappedField = fieldInfo.irField?.let { context.mapping.lateInitFieldToNullableField[it] ?: it } - if (mappedField == fieldInfo.irField) - fieldInfo - else - mappedField!!.toFieldInfo().also { it.index = fieldInfo.index } - } + fun getFields(llvm: Llvm): List = getFieldsInternal(llvm).map { fieldInfo -> + val mappedField = fieldInfo.irField?.let { context.mapping.lateInitFieldToNullableField[it] ?: it } + if (mappedField == fieldInfo.irField) + fieldInfo + else + mappedField!!.toFieldInfo().also { it.index = fieldInfo.index } + } + + private var fields: List? = null + + private fun getFieldsInternal(llvm: Llvm): List { + fields?.let { return it } - private val fieldsInternal: List by lazy { val superClass = irClass.getSuperClassNotAny() - val superFields = if (superClass != null) context.getLayoutBuilder(superClass).fieldsInternal else emptyList() + val superFields = if (superClass != null) context.getLayoutBuilder(superClass).getFieldsInternal(llvm) else emptyList() val declaredFields = getDeclaredFields() val sortedDeclaredFields = if (irClass.hasAnnotation(KonanFqNames.noReorderFields)) declaredFields else declaredFields.sortedByDescending { - with(context.generationState.llvm) { LLVMStoreSizeOfType(runtime.targetData, it.type.toLLVMType(this)) } + with(llvm) { LLVMStoreSizeOfType(runtime.targetData, it.type.toLLVMType(this)) } } val superFieldsCount = 1 /* First field is ObjHeader */ + superFields.size sortedDeclaredFields.forEachIndexed { index, field -> field.index = superFieldsCount + index } - superFields + sortedDeclaredFields + return (superFields + sortedDeclaredFields).also { fields = it } } val associatedObjects by lazy { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt index 932962d5f26..0a5dfc3a49e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.konan.llvm.coverage.runCoveragePass import org.jetbrains.kotlin.backend.konan.lower.InlineClassPropertyAccessorsLowering import org.jetbrains.kotlin.backend.konan.lower.RedundantCoercionsCleaner import org.jetbrains.kotlin.backend.konan.lower.ReturnsInsertionLowering +import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.optimizations.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement @@ -24,14 +25,14 @@ import org.jetbrains.kotlin.util.OperatorNameConventions internal val createLLVMDeclarationsPhase = makeKonanModuleOpPhase( name = "CreateLLVMDeclarations", description = "Map IR declarations to LLVM", - op = { context, _ -> context.generationState.llvmDeclarations = createLlvmDeclarations(context) } + op = { context, _ -> context.generationState.llvmDeclarations = createLlvmDeclarations(context.generationState, context.ir.irModule) } ) internal val RTTIPhase = makeKonanModuleOpPhase( name = "RTTI", description = "RTTI generation", op = { context, irModule -> - val visitor = RTTIGeneratorVisitor(context) + val visitor = RTTIGeneratorVisitor(context.generationState) irModule.acceptVoid(visitor) visitor.dispose() } @@ -245,7 +246,9 @@ internal val codegenPhase = makeKonanModuleOpPhase( name = "Codegen", description = "Code generation", op = { context, irModule -> - irModule.acceptVoid(CodeGeneratorVisitor(context, context.lifetimes)) + context.generationState.objCExport = ObjCExport(context.generationState, context.objCExportedInterface, context.objCExportCodeSpec) + + irModule.acceptVoid(CodeGeneratorVisitor(context.generationState, context.lifetimes)) if (context.generationState.hasDebugInfo()) DIFinalize(context.generationState.debugInfo.builder) @@ -255,25 +258,25 @@ internal val codegenPhase = makeKonanModuleOpPhase( internal val cStubsPhase = makeKonanModuleOpPhase( name = "CStubs", description = "C stubs compilation", - op = { context, _ -> produceCStubs(context) } + op = { context, _ -> produceCStubs(context.generationState) } ) internal val linkBitcodeDependenciesPhase = makeKonanModuleOpPhase( name = "LinkBitcodeDependencies", description = "Link bitcode dependencies", - op = { context, _ -> linkBitcodeDependencies(context) } + op = { context, _ -> linkBitcodeDependencies(context.generationState) } ) internal val checkExternalCallsPhase = makeKonanModuleOpPhase( name = "CheckExternalCalls", description = "Check external calls", - op = { context, _ -> checkLlvmModuleExternalCalls(context) } + op = { context, _ -> checkLlvmModuleExternalCalls(context.generationState) } ) internal val rewriteExternalCallsCheckerGlobals = makeKonanModuleOpPhase( name = "RewriteExternalCallsCheckerGlobals", description = "Rewrite globals for external calls checker after optimizer run", - op = { context, _ -> addFunctionsListSymbolForChecker(context) } + op = { context, _ -> addFunctionsListSymbolForChecker(context.generationState) } ) @@ -282,7 +285,7 @@ internal val bitcodeOptimizationPhase = makeKonanModuleOpPhase( name = "BitcodeOptimization", description = "Optimize bitcode", op = { context, _ -> - val config = createLTOFinalPipelineConfig(context) + val config = createLTOFinalPipelineConfig(context.generationState) LlvmOptimizationPipeline(config, context.generationState.llvm.module, context).use { it.run() } @@ -292,13 +295,13 @@ internal val bitcodeOptimizationPhase = makeKonanModuleOpPhase( internal val coveragePhase = makeKonanModuleOpPhase( name = "Coverage", description = "Produce coverage information", - op = { context, _ -> runCoveragePass(context) } + op = { context, _ -> runCoveragePass(context.generationState) } ) internal val optimizeTLSDataLoadsPhase = makeKonanModuleOpPhase( name = "OptimizeTLSDataLoads", description = "Optimize multiple loads of thread data", - op = { context, _ -> removeMultipleThreadDataLoads(context) } + op = { context, _ -> removeMultipleThreadDataLoads(context.generationState) } ) internal val produceOutputPhase = namedUnitPhase( @@ -306,7 +309,7 @@ internal val produceOutputPhase = namedUnitPhase( description = "Produce output", lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState, context: Context, input: Unit) { - produceOutput(context) + produceOutput(context.generationState) } } ) 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 be09544fa72..d8d8a60302c 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 @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.konan.ForeignExceptionMode -internal class CodeGenerator(override val context: Context) : ContextUtils { +internal class CodeGenerator(override val generationState: NativeGenerationState) : ContextUtils { fun llvmFunction(function: IrFunction): LlvmCallable = llvmFunctionOrNull(function) ?: error("no function ${function.name} in ${function.file.fqName}") @@ -32,7 +32,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { fun llvmFunctionOrNull(function: IrFunction): LlvmCallable? = function.llvmFunctionOrNull - val llvmDeclarations = context.generationState.llvmDeclarations + val llvmDeclarations = generationState.llvmDeclarations val intPtrType = LLVMIntPtrTypeInContext(llvm.llvmContext, llvmTargetData)!! internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!! internal val immThreeIntPtrType = LLVMConstInt(intPtrType, 3, 1)!! @@ -350,7 +350,7 @@ internal class StackLocalsManagerImpl( call(llvm.zeroArrayRefsFunction, listOf(stackLocal.objHeaderPtr)) } else { val type = llvmDeclarations.forClass(stackLocal.irClass).bodyType - for (field in context.getLayoutBuilder(stackLocal.irClass).fields) { + for (field in context.getLayoutBuilder(stackLocal.irClass).getFields(llvm)) { val fieldIndex = field.index val fieldType = LLVMStructGetTypeAtIndex(type, fieldIndex)!! @@ -427,8 +427,8 @@ internal abstract class FunctionGenerationContext( irFunction = builder.irFunction ) - override val context = codegen.context - val llvmDeclarations = codegen.llvmDeclarations + override val generationState = codegen.generationState + val llvmDeclarations = generationState.llvmDeclarations val vars = VariableManager(this) private val basicBlockToLastLocation = mutableMapOf() @@ -496,7 +496,7 @@ internal abstract class FunctionGenerationContext( init { irFunction?.let { if (!irFunction.isExported()) { - if (!context.config.producePerFileCache || irFunction !in context.generationState.calledFromExportedInlineFunctions) + if (!context.config.producePerFileCache || irFunction !in generationState.calledFromExportedInlineFunctions) LLVMSetLinkage(function, LLVMLinkage.LLVMInternalLinkage) // (Cannot do this before the function body is created) } } @@ -544,7 +544,7 @@ internal abstract class FunctionGenerationContext( val slotAddress = LLVMBuildAlloca(builder, type, name)!! variableLocation?.let { DIInsertDeclaration( - builder = codegen.context.generationState.debugInfo.builder, + builder = generationState.debugInfo.builder, value = slotAddress, localVariable = it.localVariable, location = it.location, @@ -1354,7 +1354,7 @@ internal abstract class FunctionGenerationContext( val expr = longArrayOf(DwarfOp.DW_OP_plus_uconst.value, runtime.pointerSize * slot.toLong()).toCValues() DIInsertDeclaration( - builder = codegen.context.generationState.debugInfo.builder, + builder = generationState.debugInfo.builder, value = slots, localVariable = variable.localVariable, location = variable.location, 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 b5ff583179a..cf2b0eb868d 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 @@ -136,10 +136,13 @@ internal sealed class Lifetime(val slotType: SlotType) { * Provides utility methods to the implementer. */ internal interface ContextUtils : RuntimeAware { + val generationState: NativeGenerationState + val context: Context + get() = generationState.context override val runtime: Runtime - get() = context.generationState.llvm.runtime + get() = generationState.llvm.runtime val argumentAbiInfo: TargetAbiInfo get() = context.targetAbiInfo @@ -153,17 +156,17 @@ internal interface ContextUtils : RuntimeAware { get() = runtime.targetData val llvm: Llvm - get() = context.generationState.llvm + get() = generationState.llvm val staticData: KotlinStaticData - get() = context.generationState.llvm.staticData + get() = generationState.llvm.staticData /** * TODO: maybe it'd be better to replace with [IrDeclaration::isEffectivelyExternal()], * or just drop all [else] branches of corresponding conditionals. */ fun isExternal(declaration: IrDeclaration): Boolean { - return !context.generationState.llvmModuleSpecification.containsDeclaration(declaration) + return !generationState.llvmModuleSpecification.containsDeclaration(declaration) } /** @@ -192,7 +195,7 @@ internal interface ContextUtils : RuntimeAware { llvm.externalFunction(proto) } } else { - context.generationState.llvmDeclarations.forFunctionOrNull(this) + generationState.llvmDeclarations.forFunctionOrNull(this) } } @@ -217,7 +220,7 @@ internal interface ContextUtils : RuntimeAware { constPointer(importGlobal(typeInfoSymbolName, runtime.typeInfoType, origin = this.llvmSymbolOrigin)) } else { - context.generationState.llvmDeclarations.forClass(this).typeInfo + generationState.llvmDeclarations.forClass(this).typeInfo } } @@ -294,8 +297,9 @@ internal class ConstFloat64(llvm: Llvm, val value: Double) : ConstValue { } @Suppress("FunctionName", "PropertyName", "PrivatePropertyName") -internal class Llvm(private val context: Context, val module: LLVMModuleRef) : RuntimeAware { - val llvmContext = context.generationState.llvmContext +internal class Llvm(private val generationState: NativeGenerationState, val module: LLVMModuleRef) : RuntimeAware { + private val context = generationState.context + val llvmContext = generationState.llvmContext private fun importFunction(name: String, otherModule: LLVMModuleRef): LlvmCallable { if (LLVMGetNamedFunction(module, name) != null) { @@ -357,7 +361,7 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R } } - val imports get() = context.generationState.llvmImports + val imports get() = generationState.llvmImports class ImportsImpl(private val context: Context) : LlvmImports { @@ -450,11 +454,11 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R } private fun shouldContainBitcode(library: KonanLibrary): Boolean { - if (!context.generationState.llvmModuleSpecification.containsLibrary(library)) { + if (!generationState.llvmModuleSpecification.containsLibrary(library)) { return false } - if (!context.generationState.llvmModuleSpecification.isFinal) { + if (!generationState.llvmModuleSpecification.isFinal) { return true } @@ -464,11 +468,11 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R val additionalProducedBitcodeFiles = mutableListOf() - val staticData = KotlinStaticData(context, this, module) + val staticData = KotlinStaticData(generationState, this, module) private val target = context.config.target - override val runtime get() = context.generationState.runtime + override val runtime get() = generationState.runtime val targetTriple = runtime.target 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 db6fadae790..453048737ff 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 @@ -57,7 +57,7 @@ internal object DWARF { fun KonanConfig.debugInfoVersion(): Int = configuration[KonanConfigKeys.DEBUG_INFO_VERSION] ?: 1 -internal class DebugInfo(override val context: Context) : ContextUtils { +internal class DebugInfo(override val generationState: NativeGenerationState) : ContextUtils { private val config = context.config val builder: DIBuilderRef = LLVMCreateDIBuilder(llvm.module)!! @@ -66,7 +66,7 @@ internal class DebugInfo(override val context: Context) : ContextUtils { val objHeaderPointerType: DITypeOpaqueRef init { - val path = context.generationState.outputFile.toFileAndFolder(config) + val path = generationState.outputFile.toFileAndFolder(config) compilationUnit = DICreateCompilationUnit( builder = builder, lang = DWARF.language(config), @@ -266,12 +266,12 @@ internal fun String?.toFileAndFolder(config: KonanConfig): FileAndFolder { internal fun alignTo(value: Long, align: Long): Long = (value + align - 1) / align * align -internal fun setupBridgeDebugInfo(context: Context, function: LLVMValueRef): LocationInfo? { - if (!context.shouldContainLocationDebugInfo()) { +internal fun setupBridgeDebugInfo(generationState: NativeGenerationState, function: LLVMValueRef): LocationInfo? { + if (!generationState.context.shouldContainLocationDebugInfo()) { return null } - val debugInfo = context.generationState.debugInfo + val debugInfo = generationState.debugInfo val file = debugInfo.compilerGeneratedFile // TODO: can we share the scope among all bridges? @@ -282,7 +282,7 @@ internal fun setupBridgeDebugInfo(context: Context, function: LLVMValueRef): Loc linkageName = function.name, file = file, lineNo = 0, - type = debugInfo.subroutineType(context.generationState.runtime.targetData, emptyList()), // TODO: use proper type. + type = debugInfo.subroutineType(generationState.runtime.targetData, emptyList()), // TODO: use proper type. isLocal = 0, isDefinition = 1, scopeLine = 0 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 6cbbc2e0690..44145be23de 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 @@ -81,10 +81,10 @@ internal fun IrField.isGlobalNonPrimitive(context: Context) = when { internal fun IrField.shouldBeFrozen(context: Context): Boolean = this.storageKind(context) == FieldStorageKind.SHARED_FROZEN -internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid { - val generator = RTTIGenerator(context) +internal class RTTIGeneratorVisitor(generationState: NativeGenerationState) : IrElementVisitorVoid { + val generator = RTTIGenerator(generationState) - val kotlinObjCClassInfoGenerator = KotlinObjCClassInfoGenerator(context) + val kotlinObjCClassInfoGenerator = KotlinObjCClassInfoGenerator(generationState) override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) @@ -191,12 +191,13 @@ private interface CodeContext { //-------------------------------------------------------------------------// -internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) : IrElementVisitorVoid { - private val llvm = context.generationState.llvm +internal class CodeGeneratorVisitor(val generationState: NativeGenerationState, val lifetimes: Map) : IrElementVisitorVoid { + private val context = generationState.context + private val llvm = generationState.llvm private val debugInfo: DebugInfo - get() = context.generationState.debugInfo + get() = generationState.debugInfo - val codegen = CodeGenerator(context) + val codegen = CodeGenerator(generationState) // TODO: consider eliminating mutable state private var currentCodeContext: CodeContext = TopLevelCodeContext @@ -330,12 +331,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map if (irField.type.binaryTypeIsReference() && irField.storageKind(context) != FieldStorageKind.THREAD_LOCAL) { - val address = context.generationState.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( + val address = generationState.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( functionGenerationContext ) storeHeapRef(codegen.kNullObjHeaderPtr, address) @@ -695,7 +696,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map functionGenerationContext.call(function, args) } + generationState.coverage.tryGetInstrumentation(declaration) { function, args -> functionGenerationContext.call(function, args) } override fun genReturn(target: IrSymbolOwner, value: LLVMValueRef?) { if (declaration == null || target == declaration) { @@ -886,7 +887,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map if (field.isConst) { @@ -1905,7 +1906,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map (if (context.config.produce.isCache) context.generationState.outputFiles.cacheFileName else context.config.moduleId).moduleConstructorName + library == null -> (if (context.config.produce.isCache) generationState.outputFiles.cacheFileName else context.config.moduleId).moduleConstructorName library == context.config.libraryToCache?.klib && context.config.producePerFileCache -> - fileCtorName(library.uniqueName, context.generationState.outputFiles.perFileCacheFileName) + fileCtorName(library.uniqueName, generationState.outputFiles.perFileCacheFileName) else -> library.moduleConstructorName } - if (library == null || context.generationState.llvmModuleSpecification.containsLibrary(library)) { + if (library == null || generationState.llvmModuleSpecification.containsLibrary(library)) { val otherInitializers = llvm.otherStaticInitializers.takeIf { library == null }.orEmpty() val ctorFunction = addCtorFunction(ctorName) @@ -2906,10 +2907,9 @@ internal class LocationInfo(val scope: DIScopeOpaqueRef, val column: Int, val inlinedAt: LocationInfo? = null) -internal fun Context.generateRuntimeConstantsModule() : LLVMModuleRef { - val llvm = generationState.llvm - val llvmModule = LLVMModuleCreateWithNameInContext("constants", generationState.llvmContext)!! - LLVMSetDataLayout(llvmModule, generationState.runtime.dataLayout) +internal fun NativeGenerationState.generateRuntimeConstantsModule() : LLVMModuleRef { + val llvmModule = LLVMModuleCreateWithNameInContext("constants", llvmContext)!! + LLVMSetDataLayout(llvmModule, runtime.dataLayout) val static = StaticData(llvmModule, llvm) fun setRuntimeConstGlobal(name: String, value: ConstValue) { @@ -2918,7 +2918,8 @@ internal fun Context.generateRuntimeConstantsModule() : LLVMModuleRef { global.setLinkage(LLVMLinkage.LLVMExternalLinkage) } - setRuntimeConstGlobal("Kotlin_needDebugInfo", llvm.constInt32(if (shouldContainDebugInfo()) 1 else 0)) + val config = context.config + setRuntimeConstGlobal("Kotlin_needDebugInfo", llvm.constInt32(if (context.shouldContainDebugInfo()) 1 else 0)) setRuntimeConstGlobal("Kotlin_runtimeAssertsMode", llvm.constInt32(config.runtimeAssertsMode.value)) val runtimeLogs = config.runtimeLogs?.let { static.cStringLiteral(it) 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 85f5208f315..716ee1f90c1 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 @@ -16,11 +16,11 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -internal class KotlinObjCClassInfoGenerator(override val context: Context) : ContextUtils { +internal class KotlinObjCClassInfoGenerator(override val generationState: NativeGenerationState) : ContextUtils { fun generate(irClass: IrClass) { assert(irClass.isFinalClass) - val objCLLvmDeclarations = context.generationState.llvmDeclarations.forClass(irClass).objCDeclarations!! + val objCLLvmDeclarations = generationState.llvmDeclarations.forClass(irClass).objCDeclarations!! val instanceMethods = generateInstanceMethodDescs(irClass) @@ -148,7 +148,7 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con return constPointer(function) } - private val codegen = CodeGenerator(context) + private val codegen = CodeGenerator(generationState) companion object { const val createdClassFieldIndex = 11 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 82610d25951..ce5aa761b86 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 @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.cValuesOf import llvm.* import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.expressions.IrConst @@ -16,7 +17,7 @@ private fun ConstPointer.add(index: LLVMValueRef): ConstPointer { return constPointer(LLVMConstGEP(llvm, cValuesOf(index), 1)!!) } -internal class KotlinStaticData(override val context: Context, override val llvm: Llvm, module: LLVMModuleRef) : ContextUtils, StaticData(module, llvm) { +internal class KotlinStaticData(override val generationState: NativeGenerationState, override val llvm: Llvm, module: LLVMModuleRef) : ContextUtils, StaticData(module, llvm) { private val stringLiterals = mutableMapOf() // Must match OBJECT_TAG_PERMANENT_CONTAINER in C++. @@ -107,7 +108,7 @@ internal class KotlinStaticData(override val context: Context, override val llvm kind.llvmName, runtime.objHeaderType, origin = descriptor.llvmSymbolOrigin )) } else { - context.generationState.llvmDeclarations.forUnique(kind).pointer + generationState.llvmDeclarations.forUnique(kind).pointer } } 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 eeeb262aafd..6fa48ab8957 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 @@ -22,9 +22,9 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import kotlin.collections.set -internal fun createLlvmDeclarations(context: Context): LlvmDeclarations { - val generator = DeclarationsGeneratorVisitor(context) - context.ir.irModule.acceptChildrenVoid(generator) +internal fun createLlvmDeclarations(generationState: NativeGenerationState, irModule: IrModuleFragment): LlvmDeclarations { + val generator = DeclarationsGeneratorVisitor(generationState) + irModule.acceptChildrenVoid(generator) return LlvmDeclarations(generator.uniques) } @@ -89,8 +89,8 @@ private fun ContextUtils.createClassBodyType(name: String, fields: List() @@ -156,7 +156,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : private fun createClassDeclarations(declaration: IrClass): ClassLlvmDeclarations { val internalName = qualifyInternalName(declaration) - val fields = context.getLayoutBuilder(declaration).fields + val fields = context.getLayoutBuilder(declaration).getFields(llvm) val bodyType = createClassBodyType("kclassbody:$internalName", fields) val typeInfoPtr: ConstPointer @@ -168,7 +168,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : if (!context.config.producePerFileCache) "${MangleConstant.CLASS_PREFIX}:$internalName" else { - val containerName = (context.generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath + val containerName = (generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath declaration.computePrivateTypeInfoSymbolName(containerName) } } @@ -196,7 +196,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : throw IllegalArgumentException("Global '$typeInfoSymbolName' already exists") } } else { - if (!context.config.producePerFileCache || declaration !in context.generationState.constructedFromExportedInlineFunctions) + if (!context.config.producePerFileCache || declaration !in generationState.constructedFromExportedInlineFunctions) LLVMSetLinkage(llvmTypeInfoPtr, LLVMLinkage.LLVMInternalLinkage) } @@ -281,7 +281,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : if (!containingClass.requiresRtti()) return val classDeclarations = (containingClass.metadata as? CodegenClassMetadata)?.llvm ?: error(containingClass.descriptor.toString()) - val allFields = context.getLayoutBuilder(containingClass).fields + val allFields = context.getLayoutBuilder(containingClass).getFields(llvm) val fieldInfo = allFields.firstOrNull { it.irField == declaration } ?: error("Field ${declaration.render()} is not found") declaration.metadata = CodegenInstanceFieldMetadata( declaration.metadata?.name, @@ -341,7 +341,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : "${MangleConstant.FUN_PREFIX}:${qualifyInternalName(declaration)}" else { val containerName = declaration.parentClassOrNull?.fqNameForIrSerialization?.asString() - ?: (context.generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath + ?: (generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath declaration.computePrivateSymbolName(containerName) } } 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 0365f1a9448..ee7c1da5788 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 @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName -internal class RTTIGenerator(override val context: Context) : ContextUtils { +internal class RTTIGenerator(override val generationState: NativeGenerationState) : ContextUtils { private val acyclicCache = mutableMapOf() private val safeAcyclicFieldTypes = setOf( @@ -26,7 +26,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { context.irBuiltIns.booleanClass, context.irBuiltIns.charClass, context.irBuiltIns.byteClass, context.irBuiltIns.shortClass, context.irBuiltIns.intClass, context.irBuiltIns.longClass, - context.irBuiltIns.floatClass,context.irBuiltIns.doubleClass) + + context.irBuiltIns.floatClass, context.irBuiltIns.doubleClass) + context.ir.symbols.primitiveTypesToPrimitiveArrays.values + context.ir.symbols.unsignedTypesToUnsignedArrays.values @@ -45,7 +45,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { private fun checkAcyclicClass(irClass: IrClass): Boolean = when { irClass.symbol == context.ir.symbols.array -> false irClass.isArray -> true - context.getLayoutBuilder(irClass).fields.all { checkAcyclicFieldType(it.type) } -> true + context.getLayoutBuilder(irClass).getFields(llvm).all { checkAcyclicFieldType(it.type) } -> true else -> false } @@ -204,7 +204,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val className = irClass.fqNameForIrSerialization - val llvmDeclarations = context.generationState.llvmDeclarations.forClass(irClass) + val llvmDeclarations = generationState.llvmDeclarations.forClass(irClass) val bodyType = llvmDeclarations.bodyType @@ -422,7 +422,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { return NullPointer(runtime.extendedTypeInfoType) val className = irClass.fqNameForIrSerialization.toString() - val llvmDeclarations = context.generationState.llvmDeclarations.forClass(irClass) + val llvmDeclarations = generationState.llvmDeclarations.forClass(irClass) val bodyType = llvmDeclarations.bodyType val elementType = getElementType(irClass) @@ -435,7 +435,8 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { debugOperationsSize, debugOperations) } else { class FieldRecord(val offset: Int, val type: Int, val name: String) - val fields = context.getLayoutBuilder(irClass).fields.map { + + val fields = context.getLayoutBuilder(irClass).getFields(llvm).map { FieldRecord( LLVMOffsetOfElement(llvmTargetData, bodyType, it.index).toInt(), mapRuntimeType(LLVMStructGetTypeAtIndex(bodyType, it.index)!!), @@ -450,8 +451,8 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { Struct(runtime.extendedTypeInfoType, llvm.constInt32(fields.size), offsetsPtr, typesPtr, namesPtr, debugOperationsSize, debugOperations) - } + val result = staticData.placeGlobal("", value) result.setConstant(true) return result.pointer @@ -465,7 +466,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val associatedObjectTableRecords = associatedObjects.map { (key, value) -> val function = context.getObjectClassInstanceFunction(value) - val llvmFunction = context.generationState.llvmDeclarations.forFunction(function).llvmValue + val llvmFunction = generationState.llvmDeclarations.forFunction(function).llvmValue Struct(runtime.associatedObjectTableRecordType, key.typeInfoPtr, constPointer(llvmFunction)) } @@ -596,16 +597,16 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { when { irClass.isAnonymousObject -> { - relativeName = context.generationState.getLocalClassName(irClass) + relativeName = generationState.getLocalClassName(irClass) flags = 0 // Forbid to use package and relative names in KClass.[simpleName|qualifiedName]. } irClass.isLocal -> { - relativeName = context.generationState.getLocalClassName(irClass) + relativeName = generationState.getLocalClassName(irClass) flags = TF_REFLECTION_SHOW_REL_NAME // Only allow relative name to be used in KClass.simpleName. } isLoweredFunctionReference(irClass) -> { // TODO: might return null so use fallback here, to be fixed in KT-47194 - relativeName = context.generationState.getLocalClassName(irClass) ?: generateDefaultRelativeName(irClass) + relativeName = generationState.getLocalClassName(irClass) ?: generateDefaultRelativeName(irClass) flags = 0 // Forbid to use package and relative names in KClass.[simpleName|qualifiedName]. } else -> { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt index 99295217648..05cbe04ab2d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt @@ -19,22 +19,24 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module /** * "Umbrella" class of all the of the code coverage related logic. */ -internal class CoverageManager(val context: Context) { +internal class CoverageManager(val generationState: NativeGenerationState) { + private val context = generationState.context + private val config = context.config private val shouldCoverSources: Boolean = - context.config.shouldCoverSources + config.shouldCoverSources private val librariesToCover: Set = - context.config.resolve.coveredLibraries.map { it.libraryName }.toSet() + config.resolve.coveredLibraries.map { it.libraryName }.toSet() private val llvmProfileFilenameGlobal = "__llvm_profile_filename" private val defaultOutputFilePath: String by lazy { - "${context.generationState.outputFile}.profraw" + "${generationState.outputFile}.profraw" } private val outputFileName: String = - context.config.configuration.get(KonanConfigKeys.PROFRAW_PATH) + config.configuration.get(KonanConfigKeys.PROFRAW_PATH) ?.let { File(it).absolutePath } ?: defaultOutputFilePath @@ -43,13 +45,13 @@ internal class CoverageManager(val context: Context) { init { if (enabled && !checkRestrictions()) { - context.reportCompilationError("Coverage is not supported for ${context.config.target}.") + context.reportCompilationError("Coverage is not supported for ${config.target}.") } } private fun checkRestrictions(): Boolean { - val isKindAllowed = context.config.produce.involvesBitcodeGeneration - val target = context.config.target + val isKindAllowed = config.produce.involvesBitcodeGeneration + val target = config.target val isTargetAllowed = target.supportsCodeCoverage() return isKindAllowed && isTargetAllowed } @@ -85,7 +87,7 @@ internal class CoverageManager(val context: Context) { */ fun tryGetInstrumentation(irFunction: IrFunction?, callSitePlacer: (function: LLVMValueRef, args: List) -> Unit) = if (enabled && irFunction != null) { - getFunctionRegions(irFunction)?.let { LLVMCoverageInstrumentation(context, it, callSitePlacer) } + getFunctionRegions(irFunction)?.let { LLVMCoverageInstrumentation(generationState, it, callSitePlacer) } } else { null } @@ -95,7 +97,7 @@ internal class CoverageManager(val context: Context) { */ fun writeRegionInfo() { if (enabled) { - LLVMCoverageWriter(context, filesRegionsInfo).write() + LLVMCoverageWriter(generationState, filesRegionsInfo).write() } } @@ -121,11 +123,11 @@ internal class CoverageManager(val context: Context) { } } -internal fun runCoveragePass(context: Context) { - if (!context.coverage.enabled) return +internal fun runCoveragePass(generationState: NativeGenerationState) { + if (!generationState.coverage.enabled) return val passManager = LLVMCreatePassManager()!! - LLVMKotlinAddTargetLibraryInfoWrapperPass(passManager, context.generationState.llvm.targetTriple) - context.coverage.addLateLlvmPasses(passManager) - LLVMRunPassManager(passManager, context.generationState.llvm.module) + LLVMKotlinAddTargetLibraryInfoWrapperPass(passManager, generationState.llvm.targetTriple) + generationState.coverage.addLateLlvmPasses(passManager) + LLVMRunPassManager(passManager, generationState.llvm.module) LLVMDisposePassManager(passManager) } \ No newline at end of file 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 10300f7f681..1ad7279458c 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 @@ -9,6 +9,7 @@ import llvm.LLVMCreatePGOFunctionNameVar import llvm.LLVMInstrProfIncrement import llvm.LLVMValueRef import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFunction @@ -18,7 +19,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction * region in [functionRegions]. */ internal class LLVMCoverageInstrumentation( - override val context: Context, + override val generationState: NativeGenerationState, private val functionRegions: FunctionRegions, private val callSitePlacer: (function: LLVMValueRef, args: List) -> Unit ) : ContextUtils { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageWriter.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageWriter.kt index a5672643b02..38612d83d9c 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageWriter.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageWriter.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm.coverage import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.llvm.name import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.path @@ -34,13 +35,13 @@ private fun LLVMCoverageRegion.populateFrom(region: Region, regionId: Int, files * See http://llvm.org/docs/CoverageMappingFormat.html for the format description. */ internal class LLVMCoverageWriter( - private val context: Context, + private val generationState: NativeGenerationState, private val filesRegionsInfo: List ) { fun write() { if (filesRegionsInfo.isEmpty()) return - val module = context.generationState.llvm.module + val module = generationState.llvm.module val filesIndex = filesRegionsInfo.mapIndexed { index, fileRegionInfo -> fileRegionInfo.file to index }.toMap() val coverageGlobal = memScoped { @@ -53,8 +54,8 @@ internal class LLVMCoverageWriter( fileIds.toCValues(), fileIds.size.signExtend(), regions.toCValues(), regions.size.signExtend()) - val functionName = context.generationState.llvmDeclarations.forFunction(functionRegions.function).llvmValue.name - val functionMappingRecord = LLVMAddFunctionMappingRecord(LLVMGetModuleContext(context.generationState.llvm.module), + val functionName = generationState.llvmDeclarations.forFunction(functionRegions.function).llvmValue.name + val functionMappingRecord = LLVMAddFunctionMappingRecord(LLVMGetModuleContext(generationState.llvm.module), functionName, functionRegions.structuralHash, functionCoverage)!! Pair(functionMappingRecord, functionCoverage) @@ -69,6 +70,6 @@ internal class LLVMCoverageWriter( retval } - context.generationState.llvm.usedGlobals.add(coverageGlobal) + generationState.llvm.usedGlobals.add(coverageGlobal) } } 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 6f60c113558..973683d4c26 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 @@ -7,9 +7,10 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState -internal fun llvmLinkModules2(context: Context, dest: LLVMModuleRef, src: LLVMModuleRef): LLVMBool { - val diagnosticHandler = DefaultLlvmDiagnosticHandler(context, object : DefaultLlvmDiagnosticHandler.Policy { +internal fun llvmLinkModules2(generationState: NativeGenerationState, dest: LLVMModuleRef, src: LLVMModuleRef): LLVMBool { + val diagnosticHandler = DefaultLlvmDiagnosticHandler(generationState.context, object : DefaultLlvmDiagnosticHandler.Policy { override fun suppressWarning(diagnostic: LlvmDiagnostic): Boolean { if (super.suppressWarning(diagnostic)) return true @@ -24,7 +25,7 @@ internal fun llvmLinkModules2(context: Context, dest: LLVMModuleRef, src: LLVMMo } }) - return withLlvmDiagnosticHandler(context.generationState.llvmContext, diagnosticHandler) { + return withLlvmDiagnosticHandler(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 8349a660131..a6e02403acf 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 @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.konan.getARCRetainAutoreleasedReturnValueMar import org.jetbrains.kotlin.backend.konan.llvm.* internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { + val generationState = codegen.generationState val context = codegen.context val llvm = codegen.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 1da6415b801..8fc4225a2c0 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 @@ -8,26 +8,27 @@ package org.jetbrains.kotlin.backend.konan.llvm.objc import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.isFinalBinary import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.objcexport.NSNumberKind import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer -internal fun patchObjCRuntimeModule(context: Context): LLVMModuleRef? { - val config = context.config +internal fun patchObjCRuntimeModule(generationState: NativeGenerationState): LLVMModuleRef? { + val config = generationState.context.config if (!(config.isFinalBinary && config.target.family.isAppleFamily)) return null - val patchBuilder = PatchBuilder(context) + val patchBuilder = PatchBuilder(generationState.objCExport.namer) patchBuilder.addObjCPatches() val bitcodeFile = config.objCNativeLibrary - val parsedModule = parseBitcodeFile(context.generationState.llvmContext, bitcodeFile) + val parsedModule = parseBitcodeFile(generationState.llvmContext, bitcodeFile) - patchBuilder.buildAndApply(parsedModule, context.generationState.llvm) + patchBuilder.buildAndApply(parsedModule, generationState.llvm) return parsedModule } -private class PatchBuilder(val context: Context) { +private class PatchBuilder(val objCExportNamer: ObjCExportNamer) { enum class GlobalKind(val prefix: String) { OBJC_CLASS("OBJC_CLASS_\$_"), OBJC_METACLASS("OBJC_METACLASS_\$_"), @@ -51,8 +52,6 @@ private class PatchBuilder(val context: Context) { val globalPatches = mutableListOf() val literalPatches = mutableListOf() - val objCExportNamer = context.objCExport.namer - // Note: exported classes anyway use the same prefix, // so using more unique private prefix wouldn't help to prevent any clashes. private val privatePrefix = objCExportNamer.topLevelNamePrefix 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 72eb496652c..93b3c81affd 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 @@ -215,7 +215,7 @@ internal open class ObjCExportCodeGeneratorBase(codegen: CodeGenerator) : ObjCCo val runtime get() = codegen.runtime val staticData get() = codegen.staticData - val rttiGenerator = RTTIGenerator(context) + val rttiGenerator = RTTIGenerator(generationState) private val objcTerminate: LlvmCallable by lazy { llvm.externalFunction(LlvmFunctionProto( @@ -287,7 +287,7 @@ internal class ObjCExportBlockCodeGenerator(codegen: CodeGenerator) : ObjCExport // 1. Enumerates [BuiltInFictitiousFunctionIrClassFactory] built classes, which may be incomplete otherwise. // 2. Modifies stdlib global initializers. // 3. Defines runtime-declared globals. - require(context.generationState.shouldDefineFunctionClasses) + require(generationState.shouldDefineFunctionClasses) } fun generate() { @@ -499,7 +499,7 @@ internal class ObjCExportCodeGenerator( descriptorToAdapter[adapter.objCName] = typeAdapter if (irClass != null) { - if (!context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + if (!generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { setObjCExportTypeInfo(irClass, typeAdapter = typeAdapter) } else { // Optimization: avoid generating huge initializers; @@ -527,7 +527,7 @@ internal class ObjCExportCodeGenerator( emitSortedAdapters(placedClassAdapters, "Kotlin_ObjCExport_sortedClassAdapters") emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters") - if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { replaceExternalWeakOrCommonGlobal( "Kotlin_ObjCExport_initTypeAdapters", llvm.constInt1(true), @@ -555,7 +555,7 @@ internal class ObjCExportCodeGenerator( if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) { // Might be affected by https://youtrack.jetbrains.com/issue/KT-42254. // The code below generally follows [replaceExternalWeakOrCommonGlobal] implementation. - if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { + if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { // So the compiler uses caches. If a user is linking two such static frameworks into a single binary, // the linker might fail with a lot of "duplicate symbol" errors due to KT-42254. // Adding a similar symbol that would explicitly hint to take a look at the YouTrack issue if reported. @@ -701,14 +701,14 @@ private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobal( origin: CompiledKlibModuleOrigin ) { // TODO: A similar mechanism is used in `IrToBitcode.overrideRuntimeGlobal`. Consider merging them. - if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { val global = codegen.importGlobal(name, value.llvmType, origin) externalGlobalInitializers[global] = value } else { - context.generationState.llvmImports.add(origin) + generationState.llvmImports.add(origin) val global = staticData.placeGlobal(name, value, isExported = true) - if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { + if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { // Note: actually this is required only if global's weak/common definition is in another object file, // but it is simpler to do this for all globals, considering that all usages can't be removed by DCE anyway. llvm.usedGlobals += global.llvmGlobal @@ -745,7 +745,7 @@ private fun ObjCExportCodeGenerator.setObjCExportTypeInfo( private fun ObjCExportCodeGeneratorBase.setOwnWritableTypeInfo(irClass: IrClass, writableTypeInfoValue: Struct) { require(!codegen.isExternal(irClass)) - val writeableTypeInfoGlobal = context.generationState.llvmDeclarations.forClass(irClass).writableTypeInfoGlobal!! + val writeableTypeInfoGlobal = generationState.llvmDeclarations.forClass(irClass).writableTypeInfoGlobal!! writeableTypeInfoGlobal.setLinkage(LLVMLinkage.LLVMExternalLinkage) writeableTypeInfoGlobal.setInitializer(writableTypeInfoValue) } @@ -872,7 +872,7 @@ private val ObjCExportBlockCodeGenerator.mappedFunctionNClasses get() = .filter { it.descriptor.isMappedFunctionClass() } private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() { - require(context.generationState.shouldDefineFunctionClasses) + require(generationState.shouldDefineFunctionClasses) mappedFunctionNClasses.forEach { functionClass -> val convertToRetained = kotlinFunctionToRetainedBlockConverter(BlockPointerBridge(functionClass.arity, returnsVoid = false)) @@ -882,7 +882,7 @@ private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() { } private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() { - require(context.generationState.shouldDefineFunctionClasses) + require(generationState.shouldDefineFunctionClasses) val functionClassesByArity = mappedFunctionNClasses.associateBy { it.arity } val arityLimit = (functionClassesByArity.keys.maxOrNull() ?: -1) + 1 @@ -956,7 +956,7 @@ private fun ObjCExportCodeGenerator.emitCollectionConverters() { } private fun ObjCExportFunctionGenerationContextBuilder.setupBridgeDebugInfo() { - val location = setupBridgeDebugInfo(this.objCExportCodegen.context, function) + val location = setupBridgeDebugInfo(this.objCExportCodegen.generationState, function) startLocation = location endLocation = location } @@ -967,7 +967,7 @@ private inline fun ObjCExportCodeGenerator.generateObjCImpBy( suffix: String, genBody: ObjCExportFunctionGenerationContext.() -> Unit ): LLVMValueRef { - val functionType = objCFunctionType(context, methodBridge) + val functionType = objCFunctionType(generationState, methodBridge) val functionName = "objc2kotlin_$suffix" val result = functionGenerator(functionType, functionName) { if (debugInfo) { @@ -1107,7 +1107,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp( // Release init receiver, as required by convention. objcReleaseFromRunnableThreadState(param(0)) } - Zero(returnType.toLlvmRetType(context).llvmType).llvm + Zero(returnType.toLlvmRetType(generationState).llvmType).llvm } } @@ -1138,7 +1138,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp( MethodBridge.ReturnValue.Void -> null MethodBridge.ReturnValue.HashCode -> { val kotlinHashCode = targetResult!! - if (codegen.context.is64BitNSInteger()) zext(kotlinHashCode, llvm.int64Type) else kotlinHashCode + if (generationState.is64BitNSInteger()) zext(kotlinHashCode, llvm.int64Type) else kotlinHashCode } is MethodBridge.ReturnValue.Mapped -> if (LLVMTypeOf(targetResult!!) == llvm.voidType) { returnBridge.bridge.makeNothing(llvm) @@ -1332,7 +1332,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( val retainAutoreleasedTargetResult = methodBridge.returnBridge.isAutoreleasedObjCReference() - val objCFunctionType = objCFunctionType(context, methodBridge) + val objCFunctionType = objCFunctionType(generationState, methodBridge) val objcMsgSend = msgSender(objCFunctionType) // Using terminatingExceptionHandler, so any exception thrown by the method will lead to the termination, @@ -1370,7 +1370,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( MethodBridge.ReturnValue.Void -> null MethodBridge.ReturnValue.HashCode -> { - if (codegen.context.is64BitNSInteger()) { + if (generationState.is64BitNSInteger()) { val low = trunc(targetResult, llvm.int32Type) val high = trunc(shr(targetResult, 32, signed = false), llvm.int32Type) xor(low, high) @@ -1877,7 +1877,7 @@ private inline fun ObjCExportCodeGenerator.generateObjCToKotlinSyntheticGetter( MethodBridgeReceiver.Static, valueParameters = emptyList() ) - val functionType = objCFunctionType(context, methodBridge) + val functionType = objCFunctionType(generationState, methodBridge) val functionName = "objc2kotlin_$suffix" val imp = functionGenerator(functionType, functionName) { switchToRunnable = true @@ -1975,9 +1975,9 @@ private fun ObjCExportCodeGenerator.createThrowableAsErrorAdapter(): ObjCExportC return objCToKotlinMethodAdapter(selector, methodBridge, imp) } -private fun objCFunctionType(context: Context, methodBridge: MethodBridge): LlvmFunctionSignature { - val paramTypes = methodBridge.paramBridges.map { it.toLlvmParamType(context.generationState.llvm) } - val returnType = methodBridge.returnBridge.toLlvmRetType(context) +private fun objCFunctionType(generationState: NativeGenerationState, methodBridge: MethodBridge): LlvmFunctionSignature { + val paramTypes = methodBridge.paramBridges.map { it.toLlvmParamType(generationState.llvm) } + val returnType = methodBridge.returnBridge.toLlvmRetType(generationState) return LlvmFunctionSignature(returnType, paramTypes, isVararg = false) } @@ -2006,21 +2006,21 @@ private fun MethodBridgeParameter.toLlvmParamType(llvm: Llvm): LlvmParamType = w } private fun MethodBridge.ReturnValue.toLlvmRetType( - context: Context + generationState: NativeGenerationState ): LlvmRetType { - val llvm = context.generationState.llvm + val llvm = generationState.llvm return when (this) { MethodBridge.ReturnValue.Suspend, MethodBridge.ReturnValue.Void -> LlvmRetType(llvm.voidType) - MethodBridge.ReturnValue.HashCode -> LlvmRetType(if (context.is64BitNSInteger()) llvm.int64Type else llvm.int32Type) + MethodBridge.ReturnValue.HashCode -> LlvmRetType(if (generationState.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) + is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.toLlvmRetType(generationState) } } @@ -2040,22 +2040,22 @@ internal fun ObjCExportCodeGenerator.getEncoding(methodBridge: MethodBridge): St } } - val returnTypeEncoding = methodBridge.returnBridge.getObjCEncoding(context) + val returnTypeEncoding = methodBridge.returnBridge.getObjCEncoding(generationState) val paramSize = paramOffset return "$returnTypeEncoding$paramSize$params" } -private fun MethodBridge.ReturnValue.getObjCEncoding(context: Context): String = when (this) { +private fun MethodBridge.ReturnValue.getObjCEncoding(generationState: NativeGenerationState): String = when (this) { MethodBridge.ReturnValue.Suspend, MethodBridge.ReturnValue.Void -> "v" - MethodBridge.ReturnValue.HashCode -> if (context.is64BitNSInteger()) "Q" else "I" + MethodBridge.ReturnValue.HashCode -> if (generationState.is64BitNSInteger()) "Q" else "I" is MethodBridge.ReturnValue.Mapped -> this.bridge.objCEncoding MethodBridge.ReturnValue.WithError.Success -> ObjCValueType.BOOL.encoding MethodBridge.ReturnValue.Instance.InitResult, MethodBridge.ReturnValue.Instance.FactoryResult -> ReferenceBridge.objCEncoding - is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.getObjCEncoding(context) + is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.getObjCEncoding(generationState) } private val MethodBridgeParameter.objCEncoding: String get() = when (this) { @@ -2071,10 +2071,10 @@ private val TypeBridge.objCEncoding: String get() = when (this) { is ValueTypeBridge -> this.objCValueType.encoding } -private fun Context.is64BitNSInteger(): Boolean { - val configurables = this.config.platform.configurables +private fun NativeGenerationState.is64BitNSInteger(): Boolean { + val configurables = context.config.platform.configurables require(configurables is AppleConfigurables) { "Target ${configurables.target} has no support for NSInteger type." } - return generationState.llvm.nsIntegerTypeWidth == 64L + return llvm.nsIntegerTypeWidth == 64L } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CacheInfoBuilder.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CacheInfoBuilder.kt index 93920a9ae85..121007a3a54 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CacheInfoBuilder.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CacheInfoBuilder.kt @@ -5,8 +5,8 @@ package org.jetbrains.kotlin.backend.konan.lower -import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_FUNCTION_CLASS +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr import org.jetbrains.kotlin.ir.IrElement @@ -16,34 +16,37 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -internal class CacheInfoBuilder(private val context: Context, private val moduleDeserializer: KonanIrLinker.KonanPartialModuleDeserializer) { - fun build() = with(moduleDeserializer) { - moduleFragment.acceptChildrenVoid(object : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) +internal class CacheInfoBuilder( + private val generationState: NativeGenerationState, + private val moduleDeserializer: KonanIrLinker.KonanPartialModuleDeserializer, + private val irModule: IrModuleFragment +) { + fun build() = irModule.acceptChildrenVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitClass(declaration: IrClass) { + declaration.acceptChildrenVoid(this) + + if (!declaration.isInterface && !declaration.isLocal + && declaration.isExported && declaration.origin != DECLARATION_ORIGIN_FUNCTION_CLASS + ) { + val declaredFields = generationState.context.getLayoutBuilder(declaration).getDeclaredFields() + generationState.classFields.add(moduleDeserializer.buildClassFields(declaration, declaredFields)) } + } - override fun visitClass(declaration: IrClass) { - declaration.acceptChildrenVoid(this) + override fun visitFunction(declaration: IrFunction) { + // Don't need to visit the children here: classes would be all local and wouldn't be handled anyway, + // as for functions - both their callees will be handled and inline bodies will be built for the top function. - if (!declaration.isInterface && !declaration.isLocal - && declaration.isExported && declaration.origin != DECLARATION_ORIGIN_FUNCTION_CLASS - ) { - context.generationState.classFields.add(buildClassFields(declaration, context.getLayoutBuilder(declaration).getDeclaredFields())) - } + if (!declaration.isFakeOverride && declaration.isInline && declaration.isExported) { + generationState.inlineFunctionBodies.add(moduleDeserializer.buildInlineFunctionReference(declaration)) + trackCallees(declaration) } - - override fun visitFunction(declaration: IrFunction) { - // Don't need to visit the children here: classes would be all local and wouldn't be handled anyway, - // as for functions - both their callees will be handled and inline bodies will be built for the top function. - - if (!declaration.isFakeOverride && declaration.isInline && declaration.isExported) { - context.generationState.inlineFunctionBodies.add(buildInlineFunctionReference(declaration)) - trackCallees(declaration) - } - } - }) - } + } + }) private val IrDeclaration.isExported get() = with(KonanManglerIr) { isExported(compatibleMode = moduleDeserializer.compatibilityMode.oldSignatures) } @@ -61,9 +64,9 @@ internal class CacheInfoBuilder(private val context: Context, private val module private fun processFunction(function: IrFunction) { if (function.getPackageFragment() !is IrExternalPackageFragment) { - context.generationState.calledFromExportedInlineFunctions.add(function) + generationState.calledFromExportedInlineFunctions.add(function) (function as? IrConstructor)?.constructedClass?.let { - context.generationState.constructedFromExportedInlineFunctions.add(it) + generationState.constructedFromExportedInlineFunctions.add(it) } if (function.isInline && !function.isExported) { // An exported inline function calls a non-exported inline function: @@ -76,13 +79,13 @@ internal class CacheInfoBuilder(private val context: Context, private val module override fun visitGetObjectValue(expression: IrGetObjectValue) { expression.acceptChildrenVoid(this) - processFunction(context.getObjectClassInstanceFunction(expression.symbol.owner)) + processFunction(generationState.context.getObjectClassInstanceFunction(expression.symbol.owner)) } override fun visitGetEnumValue(expression: IrGetEnumValue) { expression.acceptChildrenVoid(this) - processFunction(context.enumsSupport.getValueGetter(expression.symbol.owner.parentAsClass)) + processFunction(generationState.context.enumsSupport.getValueGetter(expression.symbol.owner.parentAsClass)) } override fun visitCall(expression: IrCall) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt index 60258749ff0..1332f0876c0 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.getOrPut import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.NativeMapping import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin @@ -145,9 +146,10 @@ internal class ExportCachesAbiVisitor(val context: Context) : FileLoweringPass, } } -internal class ImportCachesAbiTransformer(val context: Context) : FileLoweringPass, IrElementTransformerVoid() { - private val cachesAbiSupport = context.cachesAbiSupport - private val llvmImports = context.generationState.llvmImports +internal class ImportCachesAbiTransformer(val generationState: NativeGenerationState) : FileLoweringPass, IrElementTransformerVoid() { + private val cachesAbiSupport = generationState.context.cachesAbiSupport + private val innerClassesSupport = generationState.context.innerClassesSupport + private val llvmImports = generationState.llvmImports override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) @@ -162,9 +164,9 @@ internal class ImportCachesAbiTransformer(val context: Context) : FileLoweringPa val property = field.correspondingPropertySymbol?.owner return when { - context.generationState.llvmModuleSpecification.containsDeclaration(field) -> expression + generationState.llvmModuleSpecification.containsDeclaration(field) -> expression - irClass?.isInner == true && context.innerClassesSupport.getOuterThisField(irClass) == field -> { + irClass?.isInner == true && innerClassesSupport.getOuterThisField(irClass) == field -> { val accessor = cachesAbiSupport.getOuterThisAccessor(irClass) llvmImports.add(irClass.llvmSymbolOrigin) return irCall(expression.startOffset, expression.endOffset, accessor, emptyList()).apply { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt index 0f8a8051f06..d0743ee54a0 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.descriptors.* @@ -24,7 +25,8 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid -internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass { +internal class PropertyDelegationLowering(val generationState: NativeGenerationState) : FileLoweringPass { + private val context = generationState.context private var tempIndex = 0 private fun getKPropertyImpl(receiverTypes: List, @@ -234,7 +236,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa irFile, irFile, this, - this@PropertyDelegationLowering.context, + generationState, irBuilder, ) val (newClass, newExpression) = builder.build() diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt index 976fa132694..080250ddf8c 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.llvm.computeFullName import org.jetbrains.kotlin.descriptors.DescriptorVisibilities @@ -28,7 +29,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -internal class FunctionReferenceLowering(val context: Context) : FileLoweringPass { +internal class FunctionReferenceLowering(val generationState: NativeGenerationState) : FileLoweringPass { private object DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL") companion object { @@ -136,9 +137,9 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression { val parent: IrDeclarationContainer = (currentClass?.irElement as? IrClass) ?: irFile - val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, + val irBuilder = generationState.context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset) - val (clazz, newExpression) = FunctionReferenceBuilder(irFile, parent, expression, context, irBuilder, samSuperType).build() + val (clazz, newExpression) = FunctionReferenceBuilder(irFile, parent, expression, generationState, irBuilder, samSuperType).build() generatedClasses.add(clazz) return newExpression } @@ -153,16 +154,17 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas val irFile: IrFile, val parent: IrDeclarationParent, val functionReference: IrFunctionReference, - val context: Context, + val generationState: NativeGenerationState, val irBuilder: IrBuilderWithScope, val samSuperType: IrType? = null, ) { data class BuiltFunctionReference(val functionReferenceClass: IrClass, val functionReferenceExpression: IrExpression) + private val context = generationState.context private val irBuiltIns = context.irBuiltIns private val symbols = context.ir.symbols private val irFactory = context.irFactory - private val fileLowerState = context.generationState.fileLowerState + private val fileLowerState = generationState.fileLowerState private val startOffset = functionReference.startOffset private val endOffset = functionReference.endOffset @@ -202,7 +204,7 @@ internal class FunctionReferenceLowering(val context: Context) : FileLoweringPas createParameterDeclarations() // copy the generated name for IrClass, partially solves KT-47194 - context.generationState.copyLocalClassName(functionReference, this) + generationState.copyLocalClassName(functionReference, this) } private val functionReferenceThis = functionReferenceClass.thisReceiver!! diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt index 9e4c3a11053..9a200ac15a2 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt @@ -46,10 +46,10 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.konan.ForeignExceptionMode import org.jetbrains.kotlin.konan.library.KonanLibrary -internal class InteropLowering(context: Context) : FileLoweringPass { +internal class InteropLowering(generationState: NativeGenerationState) : FileLoweringPass { // TODO: merge these lowerings. - private val part1 = InteropLoweringPart1(context) - private val part2 = InteropLoweringPart2(context) + private val part1 = InteropLoweringPart1(generationState) + private val part2 = InteropLoweringPart2(generationState) override fun lower(irFile: IrFile) { part1.lower(irFile) @@ -57,7 +57,9 @@ internal class InteropLowering(context: Context) : FileLoweringPass { } } -private abstract class BaseInteropIrTransformer(private val context: Context) : IrBuildingTransformer(context) { +private abstract class BaseInteropIrTransformer( + private val generationState: NativeGenerationState +) : IrBuildingTransformer(generationState.context) { protected inline fun generateWithStubs(element: IrElement? = null, block: KotlinStubs.() -> T): T = createKotlinStubs(element).block() @@ -81,7 +83,8 @@ private abstract class BaseInteropIrTransformer(private val context: Context) : } return object : KotlinStubs { - private val cStubsManager = context.generationState.cStubsManager + private val context = generationState.context + private val cStubsManager = generationState.cStubsManager override val irBuiltIns get() = context.irBuiltIns override val symbols get() = context.ir.symbols @@ -106,7 +109,7 @@ private abstract class BaseInteropIrTransformer(private val context: Context) : "$uniquePrefix${cStubsManager.getUniqueName(prefix)}" override fun getUniqueKotlinFunctionReferenceClassName(prefix: String) = - context.generationState.fileLowerState.getFunctionReferenceImplUniqueName(prefix) + generationState.fileLowerState.getFunctionReferenceImplUniqueName(prefix) override val target get() = context.config.target @@ -126,7 +129,8 @@ private abstract class BaseInteropIrTransformer(private val context: Context) : protected abstract fun addTopLevel(declaration: IrDeclaration) } -private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransformer(context), FileLoweringPass { +private class InteropLoweringPart1(val generationState: NativeGenerationState) : BaseInteropIrTransformer(generationState), FileLoweringPass { + private val context = generationState.context private val symbols get() = context.ir.symbols @@ -539,7 +543,7 @@ private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfor ): IrExpression = generateWithStubs(call) { if (method.parent !is IrClass) { // Category-provided. - this@InteropLoweringPart1.context.generationState.llvmImports.add(method.llvmSymbolOrigin) + generationState.llvmImports.add(method.llvmSymbolOrigin) } this.generateObjCCall( @@ -746,9 +750,9 @@ private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfor /** * Lowers some interop intrinsic calls. */ -private class InteropLoweringPart2(val context: Context) : FileLoweringPass { +private class InteropLoweringPart2(val generationState: NativeGenerationState) : FileLoweringPass { override fun lower(irFile: IrFile) { - val transformer = InteropTransformer(context, irFile) + val transformer = InteropTransformer(generationState, irFile) irFile.transformChildrenVoid(transformer) while (transformer.newTopLevelDeclarations.isNotEmpty()) { @@ -765,7 +769,11 @@ private class InteropLoweringPart2(val context: Context) : FileLoweringPass { } } -private class InteropTransformer(val context: Context, override val irFile: IrFile) : BaseInteropIrTransformer(context) { +private class InteropTransformer( + val generationState: NativeGenerationState, + override val irFile: IrFile +) : BaseInteropIrTransformer(generationState) { + private val context = generationState.context val newTopLevelDeclarations = mutableListOf() @@ -1003,7 +1011,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi private fun generateCCall(expression: IrCall): IrExpression { val function = expression.symbol.owner - context.generationState.llvmImports.add(function.llvmSymbolOrigin) + generationState.llvmImports.add(function.llvmSymbolOrigin) val exceptionMode = ForeignExceptionMode.byValue( function.konanLibrary?.manifestProperties?.getProperty(ForeignExceptionMode.manifestKey) ) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt index 0c0b3c1e7e5..e9afeaca65f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.inline.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.InlineFunctionOriginInfo +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.NativeMapping import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.declarations.IrFile @@ -37,16 +38,16 @@ internal class InlineFunctionsSupport(mapping: NativeMapping) { } // TODO: This is a bit hacky. Think about adopting persistent IR ideas. -internal class NativeInlineFunctionResolver(override val context: Context) : DefaultInlineFunctionResolver(context) { +internal class NativeInlineFunctionResolver(override val context: Context, val generationState: NativeGenerationState) : DefaultInlineFunctionResolver(context) { override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction { val function = super.getFunctionDeclaration(symbol) - context.generationState.loweredInlineFunctions[function]?.let { return it.irFunction } + generationState.loweredInlineFunctions[function]?.let { return it.irFunction } val packageFragment = function.getPackageFragment() val (possiblyLoweredFunction, shouldLower) = if (packageFragment !is IrExternalPackageFragment) { context.inlineFunctionsSupport.getNonLoweredInlineFunction(function, copy = context.config.producePerFileCache).also { - context.generationState.loweredInlineFunctions[function] = + generationState.loweredInlineFunctions[function] = InlineFunctionOriginInfo(it, packageFragment as IrFile, function.startOffset, function.endOffset) } to true } else { @@ -58,7 +59,7 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def "No IR and no cache for ${function.render()}" } val (shouldLower, deserializedInlineFunction) = moduleDeserializer.deserializeInlineFunction(function) - context.generationState.loweredInlineFunctions[function] = deserializedInlineFunction + generationState.loweredInlineFunctions[function] = deserializedInlineFunction function to shouldLower } @@ -66,7 +67,7 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def val body = possiblyLoweredFunction.body ?: return possiblyLoweredFunction - PreInlineLowering(context).lower(body, possiblyLoweredFunction, context.generationState.loweredInlineFunctions[function]!!.irFile) + PreInlineLowering(context).lower(body, possiblyLoweredFunction, generationState.loweredInlineFunctions[function]!!.irFile) ArrayConstructorLowering(context).lower(body, possiblyLoweredFunction) @@ -80,7 +81,7 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def LocalClassesInInlineLambdasLowering(context).lower(body, possiblyLoweredFunction) - if (context.generationState.llvmModuleSpecification.containsDeclaration(function)) { + if (generationState.llvmModuleSpecification.containsDeclaration(function)) { // Do not extract local classes off of inline functions from cached libraries. LocalClassesInInlineFunctionsLowering(context).lower(body, possiblyLoweredFunction) LocalClassesExtractionFromInlineFunctionsLowering(context).lower(body, possiblyLoweredFunction) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInventNamesForLocalClasses.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInventNamesForLocalClasses.kt index 29978539496..b631d0a6421 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInventNamesForLocalClasses.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInventNamesForLocalClasses.kt @@ -7,15 +7,16 @@ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.lower.InventNamesForLocalClasses import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer import org.jetbrains.kotlin.ir.declarations.IrClass // TODO: consider replacing '$' by another delimeter that can't be used in class name specified with backticks (``) -internal class NativeInventNamesForLocalClasses(val context: Context) : InventNamesForLocalClasses(allowTopLevelCallables = true) { +internal class NativeInventNamesForLocalClasses(val generationState: NativeGenerationState) : InventNamesForLocalClasses(allowTopLevelCallables = true) { override fun computeTopLevelClassName(clazz: IrClass): String = clazz.name.asString() override fun sanitizeNameIfNeeded(name: String) = name override fun putLocalClassName(declaration: IrAttributeContainer, localClassName: String) { - context.generationState.putLocalClassName(declaration, localClassName) + generationState.putLocalClassName(declaration, localClassName) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeSuspendFunctionLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeSuspendFunctionLowering.kt index 7f47c72ffa0..287c6567056 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeSuspendFunctionLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeSuspendFunctionLowering.kt @@ -4,6 +4,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrElement @@ -29,9 +30,11 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.Name -internal class NativeSuspendFunctionsLowering(ctx: Context) : AbstractSuspendFunctionsLowering(ctx) { +internal class NativeSuspendFunctionsLowering( + generationState: NativeGenerationState +) : AbstractSuspendFunctionsLowering(generationState.context) { private val symbols = context.ir.symbols - private val fileLowerState = context.generationState.fileLowerState + private val fileLowerState = generationState.fileLowerState override val stateMachineMethodName = Name.identifier("invokeSuspend") diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ObjectClassLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ObjectClassLowering.kt index 1fcfc498627..df6fec00fed 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ObjectClassLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ObjectClassLowering.kt @@ -62,7 +62,8 @@ internal fun Context.getObjectClassInstanceFunction(clazz: IrClass) = mapping.ob } } -internal class ObjectClassLowering(val context: Context) : FileLoweringPass { +internal class ObjectClassLowering(val generationState: NativeGenerationState) : FileLoweringPass { + val context = generationState.context val symbols = context.ir.symbols override fun lower(irFile: IrFile) { @@ -166,7 +167,7 @@ internal class ObjectClassLowering(val context: Context) : FileLoweringPass { private fun IrClass.hasConstStateAndNoSideEffects(): Boolean { if (this.hasAnnotation(KonanFqNames.canBePrecreated)) return true - val fields = context.getLayoutBuilder(this).fields + val fields = context.getLayoutBuilder(this).getFields(generationState.llvm) return fields.all { it.isConst } && this.constructors.all { it.isAutogeneratedSimpleConstructor() } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt index d643f730d6e..e2c96c69fae 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt @@ -56,10 +56,11 @@ internal fun produceObjCExportInterface(context: Context): ObjCExportedInterface } internal class ObjCExport( - val context: Context, + val generationState: NativeGenerationState, private val exportedInterface: ObjCExportedInterface?, private val codeSpec: ObjCExportCodeSpec? ) { + private val context = generationState.context private val target get() = context.config.target private val topLevelNamePrefix get() = context.objCExportTopLevelNamePrefix @@ -68,7 +69,7 @@ internal class ObjCExport( internal fun generate(codegen: CodeGenerator) { if (!target.family.isAppleFamily) return - if (context.generationState.shouldDefineFunctionClasses) { + if (generationState.shouldDefineFunctionClasses) { ObjCExportBlockCodeGenerator(codegen).generate() } @@ -101,7 +102,7 @@ internal class ObjCExport( } private fun produceFrameworkSpecific(headerLines: List) { - val frameworkDirectory = File(context.generationState.outputFile) + val frameworkDirectory = File(generationState.outputFile) val frameworkName = frameworkDirectory.name.removeSuffix(".framework") val frameworkBuilder = FrameworkBuilder( context.config, @@ -154,7 +155,7 @@ internal class ObjCExport( val result = Command(clangCommand).getResult(withErrors = true) if (result.exitCode == 0) { - context.generationState.llvm.additionalProducedBitcodeFiles += bitcode.absolutePath + generationState.llvm.additionalProducedBitcodeFiles += bitcode.absolutePath } else { // Note: ignoring compile errors intentionally. // In this case resulting framework will likely be unusable due to compile errors when importing it. diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/RemoveMultipleThreadDataLoads.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/RemoveMultipleThreadDataLoads.kt index cd08af5dd9f..e19287e6f68 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/RemoveMultipleThreadDataLoads.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/RemoveMultipleThreadDataLoads.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.optimizations import llvm.* import org.jetbrains.kotlin.backend.konan.Context +import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.llvm.getBasicBlocks import org.jetbrains.kotlin.backend.konan.llvm.getFunctions import org.jetbrains.kotlin.backend.konan.llvm.getInstructions @@ -31,10 +32,10 @@ private fun process(function: LLVMValueRef, currentThreadTLV: LLVMValueRef) { } } -internal fun removeMultipleThreadDataLoads(context: Context) { - val currentThreadTLV = context.generationState.llvm.runtimeAnnotationMap["current_thread_tlv"]?.singleOrNull() ?: return +internal fun removeMultipleThreadDataLoads(generationState: NativeGenerationState) { + val currentThreadTLV = generationState.llvm.runtimeAnnotationMap["current_thread_tlv"]?.singleOrNull() ?: return - getFunctions(context.generationState.llvm.module) + getFunctions(generationState.llvm.module) .filter { it.name?.startsWith("kfun:") == true } .filterNot { LLVMIsDeclaration(it) == 1 } .forEach { process(it, currentThreadTLV) }