[K/N] Merged two ways of overriding llvm globals
This commit is contained in:
+2
-25
@@ -2671,31 +2671,8 @@ internal class CodeGeneratorVisitor(val generationState: NativeGenerationState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Globals set this way cannot be const, but are overridable when producing final executable.
|
// Globals set this way cannot be const, but are overridable when producing final executable.
|
||||||
private fun overrideRuntimeGlobal(name: String, value: ConstValue) {
|
private fun overrideRuntimeGlobal(name: String, value: ConstValue) =
|
||||||
// TODO: A similar mechanism is used in `ObjCExportCodeGenerator`. Consider merging them.
|
codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime(name, value)
|
||||||
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 overrideRuntimeGlobals() {
|
private fun overrideRuntimeGlobals() {
|
||||||
if (!context.config.isFinalBinary)
|
if (!context.config.isFinalBinary)
|
||||||
|
|||||||
+38
-1
@@ -170,7 +170,7 @@ internal fun ContextUtils.addGlobal(name: String, type: LLVMTypeRef, isExported:
|
|||||||
return LLVMAddGlobal(llvm.module, type, name)!!
|
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)
|
val found = LLVMGetNamedGlobal(llvm.module, name)
|
||||||
return if (found == null)
|
return if (found == null)
|
||||||
addGlobal(name, type, isExported = false)
|
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) =
|
internal fun ContextUtils.importNativeRuntimeGlobal(name: String, type: LLVMTypeRef) =
|
||||||
importGlobal(name, type).also { llvm.dependenciesTracker.addNativeRuntime() }
|
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 {
|
internal abstract class AddressAccess {
|
||||||
abstract fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef
|
abstract fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-55
@@ -463,15 +463,13 @@ internal class ObjCExportCodeGenerator(
|
|||||||
emitSpecialClassesConvertions()
|
emitSpecialClassesConvertions()
|
||||||
|
|
||||||
// Replace runtime global with weak linkage:
|
// Replace runtime global with weak linkage:
|
||||||
replaceExternalWeakOrCommonGlobalFromNativeRuntime(
|
codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime(
|
||||||
"Kotlin_ObjCInterop_uniquePrefix",
|
"Kotlin_ObjCInterop_uniquePrefix",
|
||||||
codegen.staticData.cStringLiteral(namer.topLevelNamePrefix)
|
codegen.staticData.cStringLiteral(namer.topLevelNamePrefix)
|
||||||
)
|
)
|
||||||
|
|
||||||
emitSelectorsHolder()
|
emitSelectorsHolder()
|
||||||
|
|
||||||
emitStaticInitializers()
|
|
||||||
|
|
||||||
emitKt42254Hint()
|
emitKt42254Hint()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,8 +509,8 @@ internal class ObjCExportCodeGenerator(
|
|||||||
val sortedAdaptersPointer = staticData.placeGlobalConstArray("", type, sortedAdapters)
|
val sortedAdaptersPointer = staticData.placeGlobalConstArray("", type, sortedAdapters)
|
||||||
|
|
||||||
// Note: this globals replace runtime globals with weak linkage:
|
// Note: this globals replace runtime globals with weak linkage:
|
||||||
replaceExternalWeakOrCommonGlobalFromNativeRuntime(prefix, sortedAdaptersPointer)
|
codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime(prefix, sortedAdaptersPointer)
|
||||||
replaceExternalWeakOrCommonGlobalFromNativeRuntime("${prefix}Num", llvm.constInt32(sortedAdapters.size))
|
codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime("${prefix}Num", llvm.constInt32(sortedAdapters.size))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,28 +518,13 @@ internal class ObjCExportCodeGenerator(
|
|||||||
emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters")
|
emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters")
|
||||||
|
|
||||||
if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
if (generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||||
replaceExternalWeakOrCommonGlobalFromNativeRuntime(
|
codegen.replaceExternalWeakOrCommonGlobalFromNativeRuntime(
|
||||||
"Kotlin_ObjCExport_initTypeAdapters",
|
"Kotlin_ObjCExport_initTypeAdapters",
|
||||||
llvm.constInt1(true)
|
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() {
|
private fun emitKt42254Hint() {
|
||||||
if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) {
|
if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) {
|
||||||
// Might be affected by https://youtrack.jetbrains.com/issue/KT-42254.
|
// 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(
|
private fun ObjCExportCodeGenerator.setObjCExportTypeInfo(
|
||||||
irClass: IrClass,
|
irClass: IrClass,
|
||||||
convertToRetained: ConstPointer? = null,
|
convertToRetained: ConstPointer? = null,
|
||||||
@@ -733,7 +683,7 @@ private fun ObjCExportCodeGenerator.setObjCExportTypeInfo(
|
|||||||
|
|
||||||
if (codegen.isExternal(irClass)) {
|
if (codegen.isExternal(irClass)) {
|
||||||
// Note: this global replaces the external one with common linkage.
|
// Note: this global replaces the external one with common linkage.
|
||||||
replaceExternalWeakOrCommonGlobal(
|
codegen.replaceExternalWeakOrCommonGlobal(
|
||||||
irClass.writableTypeInfoSymbolName,
|
irClass.writableTypeInfoSymbolName,
|
||||||
writableTypeInfoValue,
|
writableTypeInfoValue,
|
||||||
irClass
|
irClass
|
||||||
|
|||||||
Reference in New Issue
Block a user