Ensure generated LLVM functions get attributes
In particular, fix missing frame pointers for ObjCExport bridges. #KT-44549 Fixed.
This commit is contained in:
committed by
Vasily Levchenko
parent
ae32e18634
commit
59c6940caf
+6
-1
@@ -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)
|
||||
|
||||
+13
-4
@@ -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)
|
||||
|
||||
+2
-7
@@ -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<LLVMTypeRefVar>(paramCount)
|
||||
|
||||
+24
-4
@@ -389,7 +389,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
val DEINIT_GLOBALS = 3
|
||||
|
||||
private fun createInitBody(): LLVMValueRef {
|
||||
val initFunction = LLVMAddFunction(context.llvmModule, "", kInitFuncType)!!
|
||||
val initFunction = addLlvmFunctionWithDefaultAttributes(
|
||||
context,
|
||||
context.llvmModule!!,
|
||||
"",
|
||||
kInitFuncType
|
||||
)
|
||||
LLVMSetLinkage(initFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
generateFunction(codegen, initFunction) {
|
||||
using(FunctionScope(initFunction, "init_body", it)) {
|
||||
@@ -500,7 +505,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun createInitCtor(initNodePtr: LLVMValueRef): LLVMValueRef {
|
||||
val ctorFunction = LLVMAddFunction(context.llvmModule, "", kVoidFuncType)!!
|
||||
val ctorFunction = addLlvmFunctionWithDefaultAttributes(
|
||||
context,
|
||||
context.llvmModule!!,
|
||||
"",
|
||||
kVoidFuncType
|
||||
)
|
||||
LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
generateFunction(codegen, ctorFunction) {
|
||||
call(context.llvm.appendToInitalizersTail, listOf(initNodePtr))
|
||||
@@ -2480,7 +2490,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
context.config.moduleId.moduleConstructorName
|
||||
}
|
||||
|
||||
val ctorFunction = LLVMAddFunction(context.llvmModule, ctorName, kVoidFuncType)!!
|
||||
val ctorFunction = addLlvmFunctionWithDefaultAttributes(
|
||||
context,
|
||||
context.llvmModule!!,
|
||||
ctorName,
|
||||
kVoidFuncType
|
||||
)
|
||||
LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMExternalLinkage)
|
||||
|
||||
val initializers = libraryToInitializers.getValue(library)
|
||||
@@ -2535,7 +2550,12 @@ 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 = LLVMAddFunction(context.llvmModule, "_Konan_constructors", kVoidFuncType)!!
|
||||
val globalCtorFunction = addLlvmFunctionWithDefaultAttributes(
|
||||
context,
|
||||
context.llvmModule!!,
|
||||
"_Konan_constructors",
|
||||
kVoidFuncType
|
||||
)
|
||||
LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage)
|
||||
generateFunction(codegen, globalCtorFunction) {
|
||||
ctorFunctions.forEach {
|
||||
|
||||
+20
-6
@@ -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)
|
||||
|
||||
+8
-4
@@ -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(
|
||||
|
||||
+6
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user