Split generateFunction into different categories (#4712)

This commit is contained in:
Alexander Shabalin
2021-02-19 17:34:06 +03:00
committed by Vasily Levchenko
parent f766a3eae4
commit 276b4f19fa
4 changed files with 44 additions and 27 deletions
@@ -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) {
@@ -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,
@@ -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)
@@ -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()
}