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 71544d426af..5d277f897fb 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 @@ -2671,31 +2671,8 @@ internal class CodeGeneratorVisitor(val generationState: NativeGenerationState, } // Globals set this way cannot be const, but are overridable when producing final executable. - private fun overrideRuntimeGlobal(name: String, value: ConstValue) { - // TODO: A similar mechanism is used in `ObjCExportCodeGenerator`. Consider merging them. - if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { - // When some dynamic caches are used, we consider that stdlib is in the dynamic cache as well. - // Runtime is linked into stdlib module only, so import runtime global from it. - val global = codegen.importNativeRuntimeGlobal(name, value.llvmType) - val initializer = generateFunctionNoRuntime(codegen, functionType(llvm.voidType, false), "") { - store(value.llvm, global) - ret(null) - } - - LLVMSetLinkage(initializer, LLVMLinkage.LLVMPrivateLinkage) - - llvm.otherStaticInitializers += initializer - } else { - generationState.dependenciesTracker.addNativeRuntime() - // Define a strong runtime global. It'll overrule a weak global defined in a statically linked runtime. - val global = llvm.staticData.placeGlobal(name, value, true) - - if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { - llvm.usedGlobals += global.llvmGlobal - LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) - } - } - } + private fun overrideRuntimeGlobal(name: String, value: ConstValue) = + codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime(name, value) private fun overrideRuntimeGlobals() { if (!context.config.isFinalBinary) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 7b76b2ce503..3459484fd7d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -170,7 +170,7 @@ internal fun ContextUtils.addGlobal(name: String, type: LLVMTypeRef, isExported: return LLVMAddGlobal(llvm.module, type, name)!! } -internal fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef): LLVMValueRef { +private fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef): LLVMValueRef { val found = LLVMGetNamedGlobal(llvm.module, name) return if (found == null) addGlobal(name, type, isExported = false) @@ -189,6 +189,43 @@ internal fun ContextUtils.importObjCGlobal(name: String, type: LLVMTypeRef) = im internal fun ContextUtils.importNativeRuntimeGlobal(name: String, type: LLVMTypeRef) = importGlobal(name, type).also { llvm.dependenciesTracker.addNativeRuntime() } +private fun CodeGenerator.replaceExternalWeakOrCommonGlobal(name: String, value: ConstValue) { + if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + // When some dynamic caches are used, we consider that stdlib is in the dynamic cache as well. + // Runtime is linked into stdlib module only, so import runtime global from it. + val global = importGlobal(name, value.llvmType) + val initializer = generateFunctionNoRuntime(this, functionType(llvm.voidType, false), "") { + store(value.llvm, global) + ret(null) + } + LLVMSetLinkage(initializer, LLVMLinkage.LLVMPrivateLinkage) + + llvm.otherStaticInitializers += initializer + } else { + val global = staticData.placeGlobal(name, value, isExported = true) + + 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 + LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) + + // See also [emitKt42254Hint]. + } + } +} + +internal fun CodeGenerator.replaceExternalWeakOrCommonGlobal( + name: String, + value: ConstValue, + declaration: IrDeclaration +) = replaceExternalWeakOrCommonGlobal(name, value).also { generationState.dependenciesTracker.add(declaration) } + +internal fun CodeGenerator.replaceExternalWeakOrCommonGlobalFromNativeRuntime( + name: String, + value: ConstValue +) = replaceExternalWeakOrCommonGlobal(name, value).also { generationState.dependenciesTracker.addNativeRuntime() } + internal abstract class AddressAccess { abstract fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef } 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 79bb1f6e03f..c2181ae7c1f 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 @@ -463,15 +463,13 @@ internal class ObjCExportCodeGenerator( emitSpecialClassesConvertions() // Replace runtime global with weak linkage: - replaceExternalWeakOrCommonGlobalFromNativeRuntime( + codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime( "Kotlin_ObjCInterop_uniquePrefix", codegen.staticData.cStringLiteral(namer.topLevelNamePrefix) ) emitSelectorsHolder() - emitStaticInitializers() - emitKt42254Hint() } @@ -511,8 +509,8 @@ internal class ObjCExportCodeGenerator( val sortedAdaptersPointer = staticData.placeGlobalConstArray("", type, sortedAdapters) // Note: this globals replace runtime globals with weak linkage: - replaceExternalWeakOrCommonGlobalFromNativeRuntime(prefix, sortedAdaptersPointer) - replaceExternalWeakOrCommonGlobalFromNativeRuntime("${prefix}Num", llvm.constInt32(sortedAdapters.size)) + codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime(prefix, sortedAdaptersPointer) + codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime("${prefix}Num", llvm.constInt32(sortedAdapters.size)) } } @@ -520,28 +518,13 @@ internal class ObjCExportCodeGenerator( emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters") if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { - replaceExternalWeakOrCommonGlobalFromNativeRuntime( + codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime( "Kotlin_ObjCExport_initTypeAdapters", llvm.constInt1(true) ) } } - private fun emitStaticInitializers() { - if (externalGlobalInitializers.isEmpty()) return - - val initializer = generateFunctionNoRuntime(codegen, functionType(llvm.voidType, false), "initObjCExportGlobals") { - externalGlobalInitializers.forEach { (global, value) -> - store(value.llvm, global) - } - ret(null) - } - - LLVMSetLinkage(initializer, LLVMLinkage.LLVMInternalLinkage) - - llvm.otherStaticInitializers += initializer - } - private fun emitKt42254Hint() { if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) { // Might be affected by https://youtrack.jetbrains.com/issue/KT-42254. @@ -686,39 +669,6 @@ internal class ObjCExportCodeGenerator( } -private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobal( - name: String, - value: ConstValue -) { - // TODO: A similar mechanism is used in `IrToBitcode.overrideRuntimeGlobal`. Consider merging them. - if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { - val global = codegen.importGlobal(name, value.llvmType) - externalGlobalInitializers[global] = value - } else { - val global = staticData.placeGlobal(name, value, isExported = true) - - 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 - LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) - - // See also [emitKt42254Hint]. - } - } -} - -private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobal( - name: String, - value: ConstValue, - declaration: IrDeclaration -) = replaceExternalWeakOrCommonGlobal(name, value).also { generationState.dependenciesTracker.add(declaration) } - -private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobalFromNativeRuntime( - name: String, - value: ConstValue -) = replaceExternalWeakOrCommonGlobal(name, value).also { generationState.dependenciesTracker.addNativeRuntime() } - private fun ObjCExportCodeGenerator.setObjCExportTypeInfo( irClass: IrClass, convertToRetained: ConstPointer? = null, @@ -733,7 +683,7 @@ private fun ObjCExportCodeGenerator.setObjCExportTypeInfo( if (codegen.isExternal(irClass)) { // Note: this global replaces the external one with common linkage. - replaceExternalWeakOrCommonGlobal( + codegen.replaceExternalWeakOrCommonGlobal( irClass.writableTypeInfoSymbolName, writableTypeInfoValue, irClass