diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt index 98a55efed06..5becbc2f988 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt @@ -233,7 +233,12 @@ private class ExportedElement(val kind: ElementKind, val irClass = irSymbol.owner as IrClass cname = "_konan_function_${owner.nextFunctionIndex()}" // Produce type getter. - val getTypeFunction = LLVMAddFunction(context.llvmModule, "${cname}_type", owner.kGetTypeFuncType)!! + val getTypeFunction = addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + "${cname}_type", + owner.kGetTypeFuncType + ) val builder = LLVMCreateBuilderInContext(llvmContext)!! val bb = LLVMAppendBasicBlockInContext(llvmContext, getTypeFunction, "")!! LLVMPositionBuilderAtEnd(builder, bb) 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 3f610a1ea0f..3fa91b65d85 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 @@ -140,7 +140,12 @@ internal inline fun generateFunction( name: String, block: FunctionGenerationContext.(FunctionGenerationContext) -> Unit ): LLVMValueRef { - val function = LLVMAddFunction(codegen.context.llvmModule, name, functionType)!! + val function = addLlvmFunctionWithDefaultAttributes( + codegen.context, + codegen.context.llvmModule!!, + name, + functionType + ) generateFunction(codegen, function, startLocation = null, endLocation = null, code = block) return function } @@ -1041,9 +1046,13 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, ObjectStorageKind.THREAD_LOCAL -> { val valueGetterName = irClass.threadLocalObjectStorageGetterSymbolName val valueGetterFunction = LLVMGetNamedFunction(context.llvmModule, valueGetterName) - ?: LLVMAddFunction(context.llvmModule, valueGetterName, - functionType(kObjHeaderPtrPtr, false)) - call(valueGetterFunction!!, + ?: addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + valueGetterName, + functionType(kObjHeaderPtrPtr, false) + ) + call(valueGetterFunction, listOf(), resultLifetime = Lifetime.GLOBAL, exceptionHandler = exceptionHandler) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 680ba5e927b..b6c840a2133 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -314,12 +314,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { private fun importMemset(): LLVMValueRef { val functionType = functionType(voidType, false, int8TypePtr, int8Type, int32Type, int1Type) - return LLVMAddFunction(llvmModule, "llvm.memset.p0i8.i32", functionType)!! - } - - private fun importMemcpy(): LLVMValueRef { - val functionType = functionType(voidType, false, int8TypePtr, int8TypePtr, int32Type, int1Type) - return LLVMAddFunction(llvmModule, "llvm.memcpy.p0i8.p0i8.i32", functionType)!! + return llvmIntrinsic("llvm.memset.p0i8.i32", functionType) } private fun llvmIntrinsic(name: String, type: LLVMTypeRef, vararg attributes: String): LLVMValueRef { @@ -350,7 +345,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { } else { // As exported functions are written in C++ they assume sign extension for promoted types - // mention that in attributes. - val function = LLVMAddFunction(llvmModule, name, type)!! + val function = addLlvmFunctionWithDefaultAttributes(context, llvmModule, name, type) return memScoped { val paramCount = LLVMCountParamTypes(type) val paramTypes = allocArray(paramCount) 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 5c032c67613..49a6facbce4 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 @@ -389,7 +389,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { if (context.config.produce.isFinalBinary) { // Generate function calling all [ctorFunctions]. - val globalCtorFunction = LLVMAddFunction(context.llvmModule, "_Konan_constructors", kVoidFuncType)!! + val globalCtorFunction = addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + "_Konan_constructors", + kVoidFuncType + ) LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage) generateFunction(codegen, globalCtorFunction) { ctorFunctions.forEach { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt index e1d35a12afd..ab8b1b50a2f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt @@ -5,8 +5,7 @@ package org.jetbrains.kotlin.backend.konan.llvm -import llvm.LLVMAddTargetDependentFunctionAttr -import llvm.LLVMValueRef +import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFunction @@ -14,15 +13,30 @@ import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.util.isThrowable import org.jetbrains.kotlin.konan.target.Family -internal fun addLlvmAttributes(context: Context, irFunction: IrFunction, llvmFunction: LLVMValueRef) { - if (irFunction.returnType.isNothing()) { - setFunctionNoReturn(llvmFunction) - } +internal fun addLlvmFunctionWithDefaultAttributes( + context: Context, + module: LLVMModuleRef, + name: String, + type: LLVMTypeRef +): LLVMValueRef = LLVMAddFunction(module, name, type)!!.also { + addDefaultLlvmFunctionAttributes(context, it) +} +/** + * Mimics parts of clang's `CodeGenModule::getDefaultFunctionAttributes` + * that are required for Kotlin/Native compiler. + */ +private fun addDefaultLlvmFunctionAttributes(context: Context, llvmFunction: LLVMValueRef) { if (shouldEnforceFramePointer(context)) { // Note: this is default for clang on at least on iOS and macOS. enforceFramePointer(llvmFunction) } +} + +internal fun addLlvmAttributesForKotlinFunction(context: Context, irFunction: IrFunction, llvmFunction: LLVMValueRef) { + if (irFunction.returnType.isNothing()) { + setFunctionNoReturn(llvmFunction) + } if (mustNotInline(context, irFunction)) { setFunctionNoInline(llvmFunction) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt index 59fe67afec9..d0307816f08 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt @@ -366,11 +366,15 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } else { "kfun:" + qualifyInternalName(declaration) } - val function = LLVMAddFunction(context.llvmModule, symbolName, llvmFunctionType)!! - addLlvmAttributes(context, declaration, function) - - function + addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + symbolName, + llvmFunctionType + ).also { + addLlvmAttributesForKotlinFunction(context, declaration, it) + } } declaration.metadata = CodegenFunctionMetadata( 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 092f87dbbc1..80d316cf7c3 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 @@ -742,7 +742,12 @@ private inline fun ObjCExportCodeGenerator.generateObjCImpBy( debugInfo: Boolean = false, genBody: FunctionGenerationContext.() -> Unit ): LLVMValueRef { - val result = LLVMAddFunction(context.llvmModule, "objc2kotlin", objCFunctionType(context, methodBridge))!! + val result = addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + "objc2kotlin", + objCFunctionType(context, methodBridge) + ) val location = if (debugInfo) { setupBridgeDebugInfo(context, result)