[K/N] Merged two ways of overriding llvm globals

This commit is contained in:
Igor Chevdar
2022-12-12 21:18:09 +02:00
committed by Space Team
parent 9732100764
commit c1bc6682fa
3 changed files with 45 additions and 81 deletions
@@ -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)
@@ -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
}
@@ -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