From 276b4f19fa19d6d4c75e210b7943e7027dbb1d7e Mon Sep 17 00:00:00 2001 From: Alexander Shabalin Date: Fri, 19 Feb 2021 17:34:06 +0300 Subject: [PATCH] Split generateFunction into different categories (#4712) --- .../backend/konan/llvm/CodeGenerator.kt | 35 +++++++++++++++++++ .../kotlin/backend/konan/llvm/IrToBitcode.kt | 28 ++++----------- .../llvm/KotlinObjCClassInfoGenerator.kt | 2 +- .../objcexport/ObjCExportCodeGenerator.kt | 6 ++-- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 48ca2a89b60..097d7731e33 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -150,6 +150,41 @@ internal inline fun generateFunction( return function } +// TODO: Consider using different abstraction than `FunctionGenerationContext` for `generateFunctionNoRuntime`. +internal inline fun 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 generateFunctionBody( functionGenerationContext: FunctionGenerationContext, code: FunctionGenerationContext.(FunctionGenerationContext) -> R) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index d2796f57542..d69ad7e3310 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -505,18 +505,11 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { - 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) { 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, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt index 12d417dfb94..51c3662eae4 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt @@ -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) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index 88434f9e2c4..2d8a8caba37 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -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() }