Split generateFunction into different categories (#4712)
This commit is contained in:
committed by
Vasily Levchenko
parent
f766a3eae4
commit
276b4f19fa
+35
@@ -150,6 +150,41 @@ internal inline fun generateFunction(
|
||||
return function
|
||||
}
|
||||
|
||||
// TODO: Consider using different abstraction than `FunctionGenerationContext` for `generateFunctionNoRuntime`.
|
||||
internal inline fun <R> generateFunctionNoRuntime(
|
||||
codegen: CodeGenerator,
|
||||
function: LLVMValueRef,
|
||||
code: FunctionGenerationContext.(FunctionGenerationContext) -> R,
|
||||
) {
|
||||
val functionGenerationContext = FunctionGenerationContext(function, codegen, null, null)
|
||||
try {
|
||||
functionGenerationContext.forbidRuntime = true
|
||||
require(!functionGenerationContext.isObjectType(functionGenerationContext.returnType!!)) {
|
||||
"Cannot return object from function without Kotlin runtime"
|
||||
}
|
||||
|
||||
generateFunctionBody(functionGenerationContext, code)
|
||||
} finally {
|
||||
functionGenerationContext.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun generateFunctionNoRuntime(
|
||||
codegen: CodeGenerator,
|
||||
functionType: LLVMTypeRef,
|
||||
name: String,
|
||||
code: FunctionGenerationContext.(FunctionGenerationContext) -> Unit,
|
||||
): LLVMValueRef {
|
||||
val function = addLlvmFunctionWithDefaultAttributes(
|
||||
codegen.context,
|
||||
codegen.context.llvmModule!!,
|
||||
name,
|
||||
functionType
|
||||
)
|
||||
generateFunctionNoRuntime(codegen, function, code)
|
||||
return function
|
||||
}
|
||||
|
||||
private inline fun <R> generateFunctionBody(
|
||||
functionGenerationContext: FunctionGenerationContext,
|
||||
code: FunctionGenerationContext.(FunctionGenerationContext) -> R) {
|
||||
|
||||
+6
-22
@@ -505,18 +505,11 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun createInitCtor(initNodePtr: LLVMValueRef): LLVMValueRef {
|
||||
val ctorFunction = addLlvmFunctionWithDefaultAttributes(
|
||||
context,
|
||||
context.llvmModule!!,
|
||||
"",
|
||||
kVoidFuncType
|
||||
)
|
||||
LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
generateFunction(codegen, ctorFunction) {
|
||||
forbidRuntime = true
|
||||
val ctorFunction = generateFunctionNoRuntime(codegen, kVoidFuncType, "") {
|
||||
call(context.llvm.appendToInitalizersTail, listOf(initNodePtr))
|
||||
ret(null)
|
||||
}
|
||||
LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
return ctorFunction
|
||||
}
|
||||
|
||||
@@ -2413,8 +2406,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
// 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.importGlobal(name, value.llvmType, context.standardLlvmSymbolsOrigin)
|
||||
val initializer = generateFunction(codegen, functionType(voidType, false), "") {
|
||||
forbidRuntime = true
|
||||
val initializer = generateFunctionNoRuntime(codegen, functionType(voidType, false), "") {
|
||||
store(value.llvm, global)
|
||||
ret(null)
|
||||
}
|
||||
@@ -2520,8 +2512,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
}
|
||||
|
||||
private fun appendStaticInitializers(ctorFunction: LLVMValueRef, initializers: List<LLVMValueRef>) {
|
||||
generateFunction(codegen, ctorFunction) {
|
||||
forbidRuntime = true
|
||||
generateFunctionNoRuntime(codegen, ctorFunction) {
|
||||
val initGuardName = ctorFunction.name.orEmpty() + "_guard"
|
||||
val initGuard = LLVMAddGlobal(context.llvmModule, int32Type, initGuardName)
|
||||
LLVMSetInitializer(initGuard, kImmZero)
|
||||
@@ -2553,21 +2544,14 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
private fun appendGlobalCtors(ctorFunctions: List<LLVMValueRef>) {
|
||||
if (context.config.produce.isFinalBinary) {
|
||||
// Generate function calling all [ctorFunctions].
|
||||
val globalCtorFunction = addLlvmFunctionWithDefaultAttributes(
|
||||
context,
|
||||
context.llvmModule!!,
|
||||
"_Konan_constructors",
|
||||
kVoidFuncType
|
||||
)
|
||||
LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
generateFunction(codegen, globalCtorFunction) {
|
||||
forbidRuntime = true
|
||||
val globalCtorFunction = generateFunctionNoRuntime(codegen, kVoidFuncType, "_Konan_constructors") {
|
||||
ctorFunctions.forEach {
|
||||
call(it, emptyList(), Lifetime.IRRELEVANT,
|
||||
exceptionHandler = ExceptionHandler.Caller, verbatim = true)
|
||||
}
|
||||
ret(null)
|
||||
}
|
||||
LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
|
||||
// Append initializers of global variables in "llvm.global_ctors" array.
|
||||
val globalCtors = context.llvm.staticData.placeGlobalArray("llvm.global_ctors", kCtorType,
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con
|
||||
val functionType = functionType(classDataPointer.llvmType, false, int8TypePtr, int8TypePtr)
|
||||
val functionName = "kobjcclassdataimp:${irClass.fqNameForIrSerialization}#internal"
|
||||
|
||||
val function = generateFunction(codegen, functionType, functionName) {
|
||||
val function = generateFunctionNoRuntime(codegen, functionType, functionName) {
|
||||
ret(classDataPointer.llvm)
|
||||
}.also {
|
||||
LLVMSetLinkage(it, LLVMLinkage.LLVMPrivateLinkage)
|
||||
|
||||
+2
-4
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -353,8 +352,7 @@ internal class ObjCExportCodeGenerator(
|
||||
private fun emitStaticInitializers() {
|
||||
if (externalGlobalInitializers.isEmpty()) return
|
||||
|
||||
val initializer = generateFunction(codegen, functionType(voidType, false), "initObjCExportGlobals") {
|
||||
forbidRuntime = true
|
||||
val initializer = generateFunctionNoRuntime(codegen, functionType(voidType, false), "initObjCExportGlobals") {
|
||||
externalGlobalInitializers.forEach { (global, value) ->
|
||||
store(value.llvm, global)
|
||||
}
|
||||
@@ -405,7 +403,7 @@ internal class ObjCExportCodeGenerator(
|
||||
|
||||
private fun emitSelectorsHolder() {
|
||||
val impType = functionType(voidType, false, int8TypePtr, int8TypePtr)
|
||||
val imp = generateFunction(codegen, impType, "") {
|
||||
val imp = generateFunctionNoRuntime(codegen, impType, "") {
|
||||
unreachable()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user