Group static initializers by modules in codegen (#3325)
This commit is contained in:
committed by
GitHub
parent
ccc5cbe378
commit
cb2da32521
+3
-1
@@ -524,7 +524,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
|||||||
val usedFunctions = mutableListOf<LLVMValueRef>()
|
val usedFunctions = mutableListOf<LLVMValueRef>()
|
||||||
val usedGlobals = mutableListOf<LLVMValueRef>()
|
val usedGlobals = mutableListOf<LLVMValueRef>()
|
||||||
val compilerUsedGlobals = mutableListOf<LLVMValueRef>()
|
val compilerUsedGlobals = mutableListOf<LLVMValueRef>()
|
||||||
val staticInitializers = mutableListOf<LLVMValueRef>()
|
val staticInitializers = mutableListOf<StaticInitializer>()
|
||||||
val fileInitializers = mutableListOf<IrField>()
|
val fileInitializers = mutableListOf<IrField>()
|
||||||
val objects = mutableSetOf<LLVMValueRef>()
|
val objects = mutableSetOf<LLVMValueRef>()
|
||||||
val sharedObjects = mutableSetOf<LLVMValueRef>()
|
val sharedObjects = mutableSetOf<LLVMValueRef>()
|
||||||
@@ -546,3 +546,5 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
|||||||
val llvmFloat = LLVMFloatType()!!
|
val llvmFloat = LLVMFloatType()!!
|
||||||
val llvmDouble = LLVMDoubleType()!!
|
val llvmDouble = LLVMDoubleType()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StaticInitializer(val file: IrFile, val initializer: LLVMValueRef)
|
||||||
|
|||||||
+54
-14
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
|
||||||
internal enum class FieldStorage {
|
internal enum class FieldStorage {
|
||||||
MAIN_THREAD,
|
MAIN_THREAD,
|
||||||
@@ -441,7 +442,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
// Create global initialization records.
|
// Create global initialization records.
|
||||||
val initNode = createInitNode(createInitBody())
|
val initNode = createInitNode(createInitBody())
|
||||||
context.llvm.staticInitializers.add(createInitCtor(initNode))
|
context.llvm.staticInitializers.add(StaticInitializer(declaration, createInitCtor(initNode)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2275,11 +2276,44 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
fun appendStaticInitializers() {
|
fun appendStaticInitializers() {
|
||||||
val ctorName = context.config.moduleId.moduleConstructorName
|
// Null for "current" non-library module:
|
||||||
val ctorFunction = LLVMAddFunction(context.llvmModule, ctorName, kVoidFuncType)!!
|
val libraries = (context.librariesWithDependencies + listOf(null))
|
||||||
LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMExternalLinkage)
|
|
||||||
|
val libraryToInitializers = libraries.associateWith {
|
||||||
|
mutableListOf<LLVMValueRef>()
|
||||||
|
}
|
||||||
|
|
||||||
|
context.llvm.staticInitializers.forEach {
|
||||||
|
val library = it.file.packageFragmentDescriptor.module.konanLibrary
|
||||||
|
val initializers = libraryToInitializers[library]
|
||||||
|
?: error("initializer for not included library ${library?.libraryFile}")
|
||||||
|
|
||||||
|
initializers.add(it.initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
val ctorFunctions = libraries.map { library ->
|
||||||
|
val ctorName = if (library != null) {
|
||||||
|
library.moduleConstructorName
|
||||||
|
} else {
|
||||||
|
context.config.moduleId.moduleConstructorName
|
||||||
|
}
|
||||||
|
|
||||||
|
val ctorFunction = LLVMAddFunction(context.llvmModule, ctorName, kVoidFuncType)!!
|
||||||
|
LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMExternalLinkage)
|
||||||
|
|
||||||
|
val initializers = libraryToInitializers.getValue(library)
|
||||||
|
appendStaticInitializers(ctorFunction, initializers)
|
||||||
|
|
||||||
|
ctorFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
appendGlobalCtors(ctorFunctions)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun appendStaticInitializers(ctorFunction: LLVMValueRef, initializers: List<LLVMValueRef>) {
|
||||||
generateFunction(codegen, ctorFunction) {
|
generateFunction(codegen, ctorFunction) {
|
||||||
val initGuard = LLVMAddGlobal(context.llvmModule, int32Type, "Konan_init_guard")
|
val initGuardName = ctorFunction.name.orEmpty() + "_guard"
|
||||||
|
val initGuard = LLVMAddGlobal(context.llvmModule, int32Type, initGuardName)
|
||||||
LLVMSetInitializer(initGuard, kImmZero)
|
LLVMSetInitializer(initGuard, kImmZero)
|
||||||
LLVMSetLinkage(initGuard, LLVMLinkage.LLVMPrivateLinkage)
|
LLVMSetLinkage(initGuard, LLVMLinkage.LLVMPrivateLinkage)
|
||||||
val bbInited = basicBlock("inited", null)
|
val bbInited = basicBlock("inited", null)
|
||||||
@@ -2296,30 +2330,36 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
LLVMBuildStore(builder, kImmOne, initGuard)
|
LLVMBuildStore(builder, kImmOne, initGuard)
|
||||||
|
|
||||||
// TODO: shall we put that into the try block?
|
// TODO: shall we put that into the try block?
|
||||||
context.llvm.staticInitializers.forEach {
|
initializers.forEach {
|
||||||
call(it, emptyList(), Lifetime.IRRELEVANT,
|
call(it, emptyList(), Lifetime.IRRELEVANT,
|
||||||
exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
||||||
}
|
}
|
||||||
ret(null)
|
ret(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun appendGlobalCtors(ctorFunctions: List<LLVMValueRef>) {
|
||||||
if (context.config.produce.isNativeBinary) {
|
if (context.config.produce.isNativeBinary) {
|
||||||
|
// Generate function calling all [ctorFunctions].
|
||||||
|
val globalCtorFunction = LLVMAddFunction(context.llvmModule, "_Konan_constructors", kVoidFuncType)!!
|
||||||
|
LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||||
|
generateFunction(codegen, globalCtorFunction) {
|
||||||
|
ctorFunctions.forEach {
|
||||||
|
call(it, emptyList(), Lifetime.IRRELEVANT,
|
||||||
|
exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
||||||
|
}
|
||||||
|
ret(null)
|
||||||
|
}
|
||||||
|
|
||||||
// Append initializers of global variables in "llvm.global_ctors" array.
|
// Append initializers of global variables in "llvm.global_ctors" array.
|
||||||
val globalCtors = context.llvm.staticData.placeGlobalArray("llvm.global_ctors", kCtorType,
|
val globalCtors = context.llvm.staticData.placeGlobalArray("llvm.global_ctors", kCtorType,
|
||||||
listOf(createGlobalCtor(ctorFunction)))
|
listOf(createGlobalCtor(globalCtorFunction)))
|
||||||
LLVMSetLinkage(globalCtors.llvmGlobal, LLVMLinkage.LLVMAppendingLinkage)
|
LLVMSetLinkage(globalCtors.llvmGlobal, LLVMLinkage.LLVMAppendingLinkage)
|
||||||
if (context.config.produce == CompilerOutputKind.PROGRAM) {
|
if (context.config.produce == CompilerOutputKind.PROGRAM) {
|
||||||
// Provide an optional handle for calling .ctors, if standard constructors mechanism
|
// Provide an optional handle for calling .ctors, if standard constructors mechanism
|
||||||
// is not available on the platform (i.e. WASM, embedded).
|
// is not available on the platform (i.e. WASM, embedded).
|
||||||
val globalCtorFunction = LLVMAddFunction(context.llvmModule, "_Konan_constructors", kVoidFuncType)!!
|
|
||||||
LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMExternalLinkage)
|
LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMExternalLinkage)
|
||||||
generateFunction(codegen, globalCtorFunction) {
|
|
||||||
// Unfortunately, LLVMAddAlias() doesn't seem to work on WASM yet.
|
|
||||||
call(ctorFunction, emptyList(), Lifetime.IRRELEVANT,
|
|
||||||
exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
|
||||||
ret(null)
|
|
||||||
}
|
|
||||||
appendLlvmUsed("llvm.used", listOf(globalCtorFunction))
|
appendLlvmUsed("llvm.used", listOf(globalCtorFunction))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user