diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt index aaa19b5e9b0..01b6d9b6a03 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt @@ -5,9 +5,7 @@ package org.jetbrains.kotlin.backend.konan -import llvm.LLVMArrayType -import llvm.LLVMConstInt -import llvm.LLVMTypeRef +import llvm.* import org.jetbrains.kotlin.backend.common.getOrPut import org.jetbrains.kotlin.backend.konan.llvm.ConstValue import org.jetbrains.kotlin.backend.konan.llvm.StaticData @@ -183,7 +181,16 @@ internal fun IrConstantPrimitive.toBoxCacheValue(generationState: NativeGenerati val (start, end) = generationState.config.target.getBoxCacheRange(cacheType) return if (value in start..end) { generationState.llvm.let { llvm -> - llvm.boxCacheGlobals[cacheType]?.pointer?.getElementPtr(llvm, value.toInt() - start)?.getElementPtr(llvm, 0) + val llvmType = llvm.structType(llvm.runtime.objHeaderType, when (cacheType) { + BoxCache.BOOLEAN -> llvm.int1Type + BoxCache.BYTE -> llvm.int8Type + BoxCache.SHORT -> llvm.int16Type + BoxCache.CHAR -> llvm.int16Type + BoxCache.INT -> llvm.int32Type + BoxCache.LONG -> llvm.int64Type + }) + val llvmArrayType = LLVMArrayType(llvmType, end - start + 1)!! + llvm.boxCacheGlobals[cacheType]?.pointer?.getElementPtr(llvm, llvmArrayType, value.toInt() - start)?.getElementPtr(llvm, llvmType, 0) } } else { null diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt index 2de34d243d9..5b6611b4dfe 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CheckExternalCalls.kt @@ -127,7 +127,8 @@ private class CallsChecker(generationState: NativeGenerationState, goodFunctions callSiteDescription = "$functionName (over objc_msgSendSuper2)" calledName = null val superStruct = LLVMGetArgOperand(call, 0) - val superClassPtrPtr = LLVMBuildGEP(builder, superStruct, listOf(llvm.int32(0), llvm.int32(1)).toCValues(), 2, "") + val superStructType = llvm.structType(llvm.int8PtrType, llvm.int8PtrType) + val superClassPtrPtr = LLVMBuildStructGEP2(builder, superStructType, superStruct, 1, "") val superClassPtr = LLVMBuildLoad2(builder, llvm.int8PtrType, superClassPtrPtr, "")!! val classPtr = getSuperClass.buildCall(builder, listOf(superClassPtr)) val calledPtrLlvmFunPtr = getMethodImpl.buildCall(builder, listOf(classPtr, LLVMGetArgOperand(call, 1)!!)) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt index 7b4d02bfb4e..57630dd088b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt @@ -148,7 +148,8 @@ internal fun insertAliasToEntryPoint(context: PhaseContext, module: LLVMModuleRe val entryPointName = config.entryPointName val entryPoint = LLVMGetNamedFunction(module, entryPointName) ?: error("Module doesn't contain `$entryPointName`") - LLVMAddAlias(module, LLVMTypeOf(entryPoint)!!, entryPoint, "main") + val programAddressSpace = LLVMGetProgramAddressSpace(module) + LLVMAddAlias2(module, getGlobalFunctionType(entryPoint), programAddressSpace, entryPoint, "main") } internal fun linkBitcodeDependencies(generationState: NativeGenerationState, 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 983dac30155..acf0b4abc18 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 @@ -209,13 +209,13 @@ private inline fun generateFunctionBody( internal object VirtualTablesLookup { private fun FunctionGenerationContext.getInterfaceTableRecord(typeInfo: LLVMValueRef, interfaceId: Int): LLVMValueRef { val interfaceTableRecordPtrType = pointerType(runtime.interfaceTableRecordType) - val interfaceTableSize = load(llvm.int32Type, structGep(typeInfo, 9 /* interfaceTableSize_ */)) - val interfaceTable = load(interfaceTableRecordPtrType, structGep(typeInfo, 10 /* interfaceTable_ */)) + val interfaceTableSize = load(llvm.int32Type, structGep(runtime.typeInfoType, typeInfo, 9 /* interfaceTableSize_ */)) + val interfaceTable = load(interfaceTableRecordPtrType, structGep(runtime.typeInfoType, typeInfo, 10 /* interfaceTable_ */)) fun fastPath(): LLVMValueRef { // The fastest optimistic version. val interfaceTableIndex = and(interfaceTableSize, llvm.int32(interfaceId)) - return gep(interfaceTable, interfaceTableIndex) + return gep(runtime.interfaceTableRecordType, interfaceTable, interfaceTableIndex) } // See details in ClassLayoutBuilder. @@ -260,7 +260,7 @@ internal object VirtualTablesLookup { // Essentially: typeInfo.itable[place(interfaceId)].id == interfaceId val interfaceId = dstHierarchyInfo.interfaceId val interfaceTableRecord = getInterfaceTableRecord(objTypeInfo, interfaceId) - icmpEq(load(llvm.int32Type, structGep(interfaceTableRecord, 0 /* id */)), llvm.int32(interfaceId)) + icmpEq(load(llvm.int32Type, structGep(runtime.interfaceTableRecordType, interfaceTableRecord, 0 /* id */)), llvm.int32(interfaceId)) } } @@ -278,14 +278,15 @@ internal object VirtualTablesLookup { val canCallViaVtable = !owner.isInterface val layoutBuilder = generationState.context.getLayoutBuilder(owner) - val functionPtrType = pointerType(codegen.getLlvmFunctionType(irFunction)) + val functionType = codegen.getLlvmFunctionType(irFunction) + val functionPtrType = pointerType(functionType) val functionPtrPtrType = pointerType(functionPtrType) val llvmMethod = when { canCallViaVtable -> { val index = layoutBuilder.vtableIndex(irFunction) - val vtablePlace = gep(typeInfoPtr, llvm.int32(1)) // typeInfoPtr + 1 + val vtablePlace = gep(runtime.typeInfoType, typeInfoPtr, llvm.int32(1)) // typeInfoPtr + 1 val vtable = bitcast(llvm.int8PtrPtrType, vtablePlace) - val slot = gep(vtable, llvm.int32(index)) + val slot = gep(llvm.int8PtrType, vtable, llvm.int32(index)) load(functionPtrType, bitcast(functionPtrPtrType, slot)) } @@ -293,12 +294,13 @@ internal object VirtualTablesLookup { // Essentially: typeInfo.itable[place(interfaceId)].vtable[method] val itablePlace = layoutBuilder.itablePlace(irFunction) val interfaceTableRecord = getInterfaceTableRecord(typeInfoPtr, itablePlace.interfaceId) - val vtable = load(llvm.int8PtrPtrType, structGep(interfaceTableRecord, 2 /* vtable */)) - val slot = gep(vtable, llvm.int32(itablePlace.methodIndex)) + val vtable = load(llvm.int8PtrPtrType, structGep(runtime.interfaceTableRecordType, interfaceTableRecord, 2 /* vtable */)) + val slot = gep(llvm.int8PtrType, vtable, llvm.int32(itablePlace.methodIndex)) load(functionPtrType, bitcast(functionPtrPtrType, slot)) } } return LlvmCallable( + functionType, bitcast(functionPtrType, llvmMethod), LlvmFunctionSignature(irFunction, this) ) @@ -418,7 +420,7 @@ internal class StackLocalsManagerImpl( memset(bitcast(llvm.int8PtrType, stackSlot), 0, LLVMSizeOfTypeInBits(codegen.llvmTargetData, type).toInt() / 8) - val objectHeader = structGep(stackSlot, 0, "objHeader") + val objectHeader = structGep(type, stackSlot, 0, "objHeader") val typeInfo = codegen.typeInfoForAllocation(irClass) setTypeInfoForLocalObject(objectHeader, typeInfo) val gcRootSetSlot = createRootSetSlot() @@ -472,12 +474,12 @@ internal class StackLocalsManagerImpl( val typeInfo = codegen.typeInfoValue(irClass) val arraySlot = LLVMBuildAlloca(builder, arrayType, "")!! // Set array size in ArrayHeader. - val arrayHeaderSlot = structGep(arraySlot, 0, "arrayHeader") + val arrayHeaderSlot = structGep(arrayType, arraySlot, 0, "arrayHeader") setTypeInfoForLocalObject(arrayHeaderSlot, typeInfo) - val sizeField = structGep(arrayHeaderSlot, 1, "count_") + val sizeField = structGep(runtime.arrayHeaderType, arrayHeaderSlot, 1, "count_") store(count, sizeField) - memset(bitcast(llvm.int8PtrType, structGep(arraySlot, 1, "arrayBody")), + memset(bitcast(llvm.int8PtrType, structGep(arrayType, arraySlot, 1, "arrayBody")), 0, constCount * LLVMSizeOfTypeInBits(codegen.llvmTargetData, arrayToElementType[irClass.symbol]).toInt() / 8 ) @@ -503,9 +505,10 @@ internal class StackLocalsManagerImpl( if (stackLocal.irClass.symbol == context.ir.symbols.array) { call(llvm.zeroArrayRefsFunction, listOf(stackLocal.objHeaderPtr)) } else if (!refsOnly) { - memset(bitcast(llvm.int8PtrType, structGep(stackLocal.stackAllocationPtr, 1, "arrayBody")), + val arrayType = localArrayType(stackLocal.irClass, stackLocal.arraySize!!) + memset(bitcast(llvm.int8PtrType, structGep(arrayType, stackLocal.stackAllocationPtr, 1, "arrayBody")), 0, - stackLocal.arraySize!! * LLVMSizeOfTypeInBits(codegen.llvmTargetData, arrayToElementType[stackLocal.irClass.symbol]).toInt() / 8 + stackLocal.arraySize * LLVMSizeOfTypeInBits(codegen.llvmTargetData, arrayToElementType[stackLocal.irClass.symbol]).toInt() / 8 ) } } else { @@ -515,7 +518,7 @@ internal class StackLocalsManagerImpl( val fieldType = LLVMStructGetTypeAtIndex(type, fieldIndex)!! if (isObjectType(fieldType)) { - val fieldPtr = LLVMBuildStructGEP(builder, stackLocal.stackAllocationPtr, fieldIndex, "")!! + val fieldPtr = structGep(type, stackLocal.stackAllocationPtr, fieldIndex, "") if (refsOnly) storeHeapRef(kNullObjHeaderPtr, fieldPtr) else @@ -538,7 +541,7 @@ internal class StackLocalsManagerImpl( } private fun setTypeInfoForLocalObject(objectHeader: LLVMValueRef, typeInfoPointer: LLVMValueRef) = with(functionGenerationContext) { - val typeInfo = structGep(objectHeader, 0, "typeInfoOrMeta_") + val typeInfo = structGep(runtime.objHeaderType, objectHeader, 0, "typeInfoOrMeta_") // Set tag OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER. val typeInfoValue = intToPtr(or(ptrToInt(typeInfoPointer, codegen.intPtrType), codegen.immThreeIntPtrType), kTypeInfoPtr) @@ -681,7 +684,7 @@ internal abstract class FunctionGenerationContext( fun alloca(type: LLVMTypeRef?, name: String = "", variableLocation: VariableDebugLocation? = null): LLVMValueRef { if (isObjectType(type!!)) { appendingTo(localsInitBb) { - val slotAddress = gep(slotsPhi!!, llvm.int32(slotCount), name) + val slotAddress = gep(type, slotsPhi!!, llvm.int32(slotCount), name) variableLocation?.let { slotToVariableLocation[slotCount] = it } @@ -1036,11 +1039,12 @@ internal abstract class FunctionGenerationContext( fun intToPtr(value: LLVMValueRef?, DestTy: LLVMTypeRef, Name: String = "") = LLVMBuildIntToPtr(builder, value, DestTy, Name)!! fun ptrToInt(value: LLVMValueRef?, DestTy: LLVMTypeRef, Name: String = "") = LLVMBuildPtrToInt(builder, value, DestTy, Name)!! - fun gep(base: LLVMValueRef, index: LLVMValueRef, name: String = ""): LLVMValueRef { - return LLVMBuildGEP(builder, base, cValuesOf(index), 1, name)!! - } - fun structGep(base: LLVMValueRef, index: Int, name: String = ""): LLVMValueRef = - LLVMBuildStructGEP(builder, base, index, name)!! + + fun gep(type: LLVMTypeRef, base: LLVMValueRef, index: LLVMValueRef, name: String = ""): LLVMValueRef = + LLVMBuildGEP2(builder, type, base, cValuesOf(index), 1, name)!! + + fun structGep(type: LLVMTypeRef, base: LLVMValueRef, index: Int, name: String = ""): LLVMValueRef = + LLVMBuildStructGEP2(builder, type, base, index, name)!! fun extractValue(aggregate: LLVMValueRef, index: Int, name: String = ""): LLVMValueRef = LLVMBuildExtractValue(builder, aggregate, index, name)!! @@ -1276,7 +1280,7 @@ internal abstract class FunctionGenerationContext( } fun loadTypeInfo(objPtr: LLVMValueRef): LLVMValueRef { - val typeInfoOrMetaPtr = structGep(objPtr, 0 /* typeInfoOrMeta_ */) + val typeInfoOrMetaPtr = structGep(runtime.objHeaderType, objPtr, 0 /* typeInfoOrMeta_ */) val memoryOrder = if (context.config.targetHasAddressDependency) { /** @@ -1294,7 +1298,7 @@ internal abstract class FunctionGenerationContext( // Clear two lower bits. val typeInfoOrMetaRaw = and(typeInfoOrMetaWithFlags, codegen.immTypeInfoMask) val typeInfoOrMeta = intToPtr(typeInfoOrMetaRaw, kTypeInfoPtr) - val typeInfoPtrPtr = structGep(typeInfoOrMeta, 0 /* typeInfo */) + val typeInfoPtrPtr = structGep(runtime.typeInfoType, typeInfoOrMeta, 0 /* typeInfo */) return load(codegen.kTypeInfoPtr, typeInfoPtrPtr, memoryOrder = LLVMAtomicOrdering.LLVMAtomicOrderingMonotonic) } @@ -1345,7 +1349,7 @@ internal abstract class FunctionGenerationContext( } val classInfo = codegen.kotlinObjCClassInfo(irClass) - val classPointerGlobal = load(llvm.int8PtrPtrType, structGep(classInfo, KotlinObjCClassInfoGenerator.createdClassFieldIndex)) + val classPointerGlobal = load(llvm.int8PtrPtrType, structGep(runtime.kotlinObjCClassInfo, classInfo, KotlinObjCClassInfoGenerator.createdClassFieldIndex)) val storedClass = this.load(llvm.int8PtrType, classPointerGlobal) 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 caa2830d92a..841d2be1241 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 @@ -327,12 +327,12 @@ internal class CodegenLlvmHelpers(private val generationState: NativeGenerationS val attributesCopier = LlvmFunctionAttributeProvider.copyFromExternal(externalFunction) - val functionType = getFunctionType(externalFunction) + val functionType = getGlobalFunctionType(externalFunction) val function = LLVMAddFunction(module, name, functionType)!! attributesCopier.addFunctionAttributes(function) - return LlvmCallable(function, attributesCopier) + return LlvmCallable(functionType, function, attributesCopier) } private fun importGlobal(name: String, otherModule: LLVMModuleRef): LLVMValueRef { @@ -358,7 +358,7 @@ internal class CodegenLlvmHelpers(private val generationState: NativeGenerationS val kindId = getLlvmAttributeKindId(it) addLlvmFunctionEnumAttribute(result, kindId) } - return LlvmCallable(result, LlvmFunctionAttributeProvider.copyFromExternal(result)) + return LlvmCallable(type, result, LlvmFunctionAttributeProvider.copyFromExternal(result)) } internal fun externalFunction(llvmFunctionProto: LlvmFunctionProto): LlvmCallable { @@ -367,12 +367,13 @@ internal class CodegenLlvmHelpers(private val generationState: NativeGenerationS } val found = LLVMGetNamedFunction(module, llvmFunctionProto.name) if (found != null) { - require(getFunctionType(found) == llvmFunctionProto.signature.llvmFunctionType) { + require(getGlobalFunctionType(found) == llvmFunctionProto.signature.llvmFunctionType) { "Expected: ${LLVMPrintTypeToString(llvmFunctionProto.signature.llvmFunctionType)!!.toKString()} " + - "found: ${LLVMPrintTypeToString(getFunctionType(found))!!.toKString()}" + "found: ${LLVMPrintTypeToString(getGlobalFunctionType(found))!!.toKString()}" } require(LLVMGetLinkage(found) == llvmFunctionProto.linkage) - return LlvmCallable(found, llvmFunctionProto.signature) + val functionType = getGlobalFunctionType(found) + return LlvmCallable(functionType, found, llvmFunctionProto.signature) } else { return llvmFunctionProto.createLlvmFunction(context, module) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt index b10c6d8f09d..d3519abea0f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt @@ -1,6 +1,5 @@ package org.jetbrains.kotlin.backend.konan.llvm -import kotlinx.cinterop.cValuesOf import llvm.* import org.jetbrains.kotlin.backend.konan.KonanFqNames import org.jetbrains.kotlin.backend.konan.MemoryModel @@ -447,7 +446,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv llvm.kNullInt8Ptr private fun FunctionGenerationContext.emitNativePtrPlusLong(args: List): LLVMValueRef = - gep(args[0], args[1]) + gep(llvm.int8Type, args[0], args[1]) private fun FunctionGenerationContext.emitNativePtrToLong(callSite: IrCall, args: List): LLVMValueRef { val intPtrValue = ptrToInt(args.single(), codegen.intPtrType) @@ -508,7 +507,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum val bitsWithPaddingType = LLVMIntTypeInContext(llvm.llvmContext, bitsWithPaddingNum)!! - val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(ptr, llvm.int64(offset / 8))) + val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(llvm.int8Type, ptr, llvm.int64(offset / 8))) val bitsWithPadding = load(bitsWithPaddingType, bitsWithPaddingPtr).setUnaligned() val bits = shr( @@ -551,7 +550,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val preservedBitsMask = LLVMConstNot(discardBitsMask)!! - val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(ptr, llvm.int64(offset / 8))) + val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(llvm.int8Type, ptr, llvm.int64(offset / 8))) val bits = trunc(value, bitsType) @@ -581,8 +580,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv val structType = llvm.structType(llvm.int8PtrType, llvm.int8PtrType) val ptr = alloca(structType) - store(receiver, LLVMBuildGEP(builder, ptr, cValuesOf(llvm.kImmInt32Zero, llvm.kImmInt32Zero), 2, "")!!) - store(superClass, LLVMBuildGEP(builder, ptr, cValuesOf(llvm.kImmInt32Zero, llvm.kImmInt32One), 2, "")!!) + store(receiver, structGep(structType, ptr, 0, "")) + store(superClass, structGep(structType, ptr, 1, "")) return bitcast(llvm.int8PtrType, ptr) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt index f3d0297c8e0..1fc9c273875 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinStaticData.kt @@ -11,8 +11,12 @@ import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.expressions.IrConst -private fun ConstPointer.add(index: LLVMValueRef): ConstPointer { - return constPointer(LLVMConstGEP(llvm, cValuesOf(index), 1)!!) +private fun ConstPointer.addBits(llvm: CodegenLlvmHelpers, type: LLVMTypeRef, bits: Int): ConstPointer { + val rawPtr = LLVMConstBitCast(this.llvm, llvm.int8PtrType) + // Only pointer arithmetic via GEP works on constant pointers in LLVM. + val withBits = LLVMConstGEP2(llvm.int8Type, rawPtr, cValuesOf(llvm.int32(bits)), 1)!! + val withType = LLVMConstBitCast(withBits, type)!! + return constPointer(withType) } internal class KotlinStaticData(override val generationState: NativeGenerationState, override val llvm: CodegenLlvmHelpers, module: LLVMModuleRef) : ContextUtils, StaticData(module, llvm) { @@ -20,8 +24,7 @@ internal class KotlinStaticData(override val generationState: NativeGenerationSt // Must match OBJECT_TAG_PERMANENT_CONTAINER in C++. private fun permanentTag(typeInfo: ConstPointer): ConstPointer { - // Only pointer arithmetic via GEP works on constant pointers in LLVM. - return typeInfo.bitcast(llvm.int8PtrType).add(llvm.int32(1)).bitcast(kTypeInfoPtr) + return typeInfo.addBits(llvm, kTypeInfoPtr, 1) } @@ -58,7 +61,7 @@ internal class KotlinStaticData(override val generationState: NativeGenerationSt val global = this.createGlobal(compositeType, "") - val objHeaderPtr = global.pointer.getElementPtr(llvm, 0) + val objHeaderPtr = global.pointer.getElementPtr(llvm, compositeType, 0) val arrayHeader = arrayHeader(typeInfo, elements.size) global.setInitializer(Struct(compositeType, arrayHeader, arrayBody)) @@ -73,7 +76,7 @@ internal class KotlinStaticData(override val generationState: NativeGenerationSt global.setUnnamedAddr(true) global.setConstant(true) - val objHeaderPtr = global.pointer.getElementPtr(llvm, 0) + val objHeaderPtr = global.pointer.bitcast(llvm.runtime.objHeaderPtrType) return createRef(objHeaderPtr) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmCallable.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmCallable.kt index d85328916ba..7bf020c3875 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmCallable.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmCallable.kt @@ -14,7 +14,7 @@ import llvm.* * @todo This class mixes "something that can be called" and function abstractions. * Some of it's methods make sense only for functions. Probably, LlvmFunction sub-class should be extracted. */ -class LlvmCallable(private val llvmValue: LLVMValueRef, private val attributeProvider: LlvmFunctionAttributeProvider) { +class LlvmCallable(val functionType: LLVMTypeRef, private val llvmValue: LLVMValueRef, private val attributeProvider: LlvmFunctionAttributeProvider) { val returnType: LLVMTypeRef by lazy { LLVMGetReturnType(functionType)!! } @@ -23,12 +23,8 @@ class LlvmCallable(private val llvmValue: LLVMValueRef, private val attributePro llvmValue.name } - val functionType: LLVMTypeRef by lazy { - getFunctionType(llvmValue) - } - val numParams by lazy { - LLVMCountParams(llvmValue) + LLVMCountParamTypes(functionType) } val pgoFunctionNameVar by lazy { @@ -40,12 +36,12 @@ class LlvmCallable(private val llvmValue: LLVMValueRef, private val attributePro } fun buildCall(builder: LLVMBuilderRef, args: List, name: String = "") = - LLVMBuildCall(builder, llvmValue, args.toCValues(), args.size, name)!!.also { - attributeProvider.addCallSiteAttributes(it) - } + LLVMBuildCall2(builder, functionType, llvmValue, args.toCValues(), args.size, name)!!.also { + attributeProvider.addCallSiteAttributes(it) + } fun buildInvoke(builder: LLVMBuilderRef, args: List, success: LLVMBasicBlockRef, catch: LLVMBasicBlockRef, name: String = "") = - LLVMBuildInvoke(builder, llvmValue, args.toCValues(), args.size, success, catch, name)!!.also { + LLVMBuildInvoke2(builder, functionType, llvmValue, args.toCValues(), args.size, success, catch, name)!!.also { attributeProvider.addCallSiteAttributes(it) } 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 e1d2f6caafb..2b7e704df20 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 @@ -305,7 +305,7 @@ private class DeclarationsGeneratorVisitor(override val generationState: NativeG typeInfoGlobal.setLinkage(LLVMLinkage.LLVMExternalLinkage) } - typeInfoPtr = typeInfoGlobal.pointer.getElementPtr(llvm, 0) + typeInfoPtr = typeInfoGlobal.pointer.getElementPtr(llvm, typeInfoWithVtableType, 0) } else { typeInfoGlobal = staticData.createGlobal(runtime.typeInfoType, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmFunctionPrototype.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmFunctionPrototype.kt index 897f6756ee4..40b599ace3a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmFunctionPrototype.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmFunctionPrototype.kt @@ -178,7 +178,7 @@ internal class LlvmFunctionProto( addTargetCpuAndFeaturesAttributes(context, function) signature.addFunctionAttributes(function) LLVMSetLinkage(function, linkage) - return LlvmCallable(function, signature) + return LlvmCallable(signature.llvmFunctionType, function, signature) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 6f9b59c1ab7..4887e208aaa 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -23,7 +23,8 @@ internal val ConstValue.llvmType: LLVMTypeRef get() = this.llvm.type internal interface ConstPointer : ConstValue { - fun getElementPtr(llvm: CodegenLlvmHelpers, index: Int): ConstPointer = ConstGetElementPtr(llvm, this, index) + fun getElementPtr(llvm: CodegenLlvmHelpers, pointeeType: LLVMTypeRef, index: Int): ConstPointer = + ConstGetElementPtr(llvm, pointeeType, this, index) } internal fun constPointer(value: LLVMValueRef) = object : ConstPointer { @@ -34,8 +35,8 @@ internal fun constPointer(value: LLVMValueRef) = object : ConstPointer { override val llvm = value } -private class ConstGetElementPtr(llvm: CodegenLlvmHelpers, pointer: ConstPointer, index: Int) : ConstPointer { - override val llvm = LLVMConstInBoundsGEP(pointer.llvm, cValuesOf(llvm.int32(0), llvm.int32(index)), 2)!! +private class ConstGetElementPtr(llvm: CodegenLlvmHelpers, pointeeType: LLVMTypeRef, pointer: ConstPointer, index: Int) : ConstPointer { + override val llvm = LLVMConstInBoundsGEP2(pointeeType, pointer.llvm, cValuesOf(llvm.int32(0), llvm.int32(index)), 2)!! // TODO: squash multiple GEPs } @@ -116,11 +117,6 @@ internal val RuntimeAware.kNothingFakeValue: LLVMValueRef internal fun pointerType(pointeeType: LLVMTypeRef) = LLVMPointerType(pointeeType, 0)!! -internal fun ContextUtils.numParameters(functionType: LLVMTypeRef) : Int { - // Note that type is usually function pointer, so we have to dereference it. - return LLVMCountParamTypes(LLVMGetElementType(functionType)) -} - fun extractConstUnsignedInt(value: LLVMValueRef): Long { assert(LLVMIsConstant(value) != 0) return LLVMConstIntGetZExtValue(value) @@ -150,12 +146,12 @@ internal fun LLVMValueRef.getAsCString() : String { } -internal fun getFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef { +internal fun getGlobalFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef { return getGlobalType(ptrToFunction) } internal fun getGlobalType(ptrToGlobal: LLVMValueRef): LLVMTypeRef { - return LLVMGetElementType(ptrToGlobal.type)!! + return LLVMGlobalGetValueType(ptrToGlobal)!! } internal fun ContextUtils.addGlobal(name: String, type: LLVMTypeRef, isExported: Boolean): LLVMValueRef { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt index fd643bc6455..0b16288d25c 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt @@ -404,7 +404,7 @@ internal class RTTIGenerator( private val debugOperations: ConstValue by lazy { if (debugRuntimeOrNull != null) { val external = LLVMGetNamedGlobal(debugRuntimeOrNull, "Konan_debugOperationsList")!! - val local = LLVMAddGlobal(llvm.module, LLVMGetElementType(LLVMTypeOf(external)),"Konan_debugOperationsList")!! + val local = LLVMAddGlobal(llvm.module, LLVMGlobalGetValueType(external),"Konan_debugOperationsList")!! constPointer(LLVMConstBitCast(local, llvm.int8PtrPtrType)!!) } else { Zero(llvm.int8PtrPtrType) @@ -414,7 +414,7 @@ internal class RTTIGenerator( val debugOperationsSize: ConstValue by lazy { if (debugRuntimeOrNull != null) { val external = LLVMGetNamedGlobal(debugRuntimeOrNull, "Konan_debugOperationsList")!! - llvm.constInt32(LLVMGetArrayLength(LLVMGetElementType(LLVMTypeOf(external)))) + llvm.constInt32(LLVMGetArrayLength(LLVMGlobalGetValueType(external))) } else llvm.constInt32(0) } @@ -531,7 +531,7 @@ internal class RTTIGenerator( val vtable = vtable(superClass) val typeInfoWithVtableType = llvm.structType(runtime.typeInfoType, vtable.llvmType) val typeInfoWithVtableGlobal = staticData.createGlobal(typeInfoWithVtableType, "", isExported = false) - val result = typeInfoWithVtableGlobal.pointer.getElementPtr(llvm, 0) + val result = typeInfoWithVtableGlobal.pointer.getElementPtr(llvm, typeInfoWithVtableType, 0) val typeHierarchyInfo = if (!context.ghaEnabled()) ClassGlobalHierarchyInfo.DUMMY else @@ -546,10 +546,11 @@ internal class RTTIGenerator( } else { val vtableEntries = layoutBuilder.interfaceVTableEntries.map { methodImpls[it]!!.bitcast(llvm.int8PtrType) } val interfaceVTable = staticData.placeGlobalArray("", llvm.int8PtrType, vtableEntries) + val interfaceVTableType = LLVMArrayType(llvm.int8PtrType, vtableEntries.size)!! InterfaceTableRecord( llvm.constInt32(layoutBuilder.classId), llvm.constInt32(layoutBuilder.interfaceVTableEntries.size), - interfaceVTable.pointer.getElementPtr(llvm, 0) + interfaceVTable.pointer.getElementPtr(llvm, interfaceVTableType, 0) ) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt index 2ce7ace21ed..c3ec1ff5ecb 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt @@ -142,7 +142,7 @@ internal open class StaticData(val module: LLVMModuleRef, private val llvm: Code if (elements.isNotEmpty() || isExported) { val global = placeGlobalArray(name, elemType, elements, isExported) global.setConstant(true) - return global.pointer.getElementPtr(llvm, 0) + return global.pointer.getElementPtr(llvm, LLVMArrayType(elemType, elements.size)!!, 0) } else { return NullPointer(elemType) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt index fa089bce5e7..0f181b51358 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt @@ -4,11 +4,7 @@ */ package org.jetbrains.kotlin.backend.konan.llvm.coverage -import llvm.LLVMConstBitCast -import llvm.LLVMCreatePGOFunctionNameVar -import llvm.LLVMInstrProfIncrement -import llvm.LLVMValueRef -import org.jetbrains.kotlin.backend.konan.Context +import llvm.* import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.ir.IrElement @@ -31,6 +27,7 @@ internal class LLVMCoverageInstrumentation( private val instrProfIncrement by lazy { val incrementFun = LLVMInstrProfIncrement(llvm.module)!! LlvmCallable( + getGlobalFunctionType(incrementFun), incrementFun, LlvmFunctionAttributeProvider.copyFromExternal(incrementFun) ) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt index bd3f3254bec..7de231bc8bd 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt @@ -7,10 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm.objc import kotlinx.cinterop.signExtend import kotlinx.cinterop.toCValues -import llvm.LLVMGetElementType -import llvm.LLVMGetInlineAsm -import llvm.LLVMInlineAsmDialect -import llvm.LLVMValueRef +import llvm.* import org.jetbrains.kotlin.backend.konan.getARCRetainAutoreleasedReturnValueMarker import org.jetbrains.kotlin.backend.konan.llvm.* @@ -79,16 +76,18 @@ internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { } // TODO: this doesn't support stret. - fun msgSender(functionType: LlvmFunctionSignature): LlvmCallable = - LlvmCallable( - objcMsgSend.bitcast(pointerType(functionType.llvmFunctionType)).llvm, - functionType - ) + fun msgSender(functionType: LlvmFunctionSignature): LlvmCallable { + val llvmType = functionType.llvmFunctionType + return LlvmCallable( + llvmType, + objcMsgSend.bitcast(pointerType(llvmType)).llvm, + functionType) + } } internal fun FunctionGenerationContext.genObjCSelector(selector: String): LLVMValueRef { - val selectorRef = codegen.objCDataGenerator!!.genSelectorRef(selector) + val selectorRef = codegen.objCDataGenerator!!.genSelectorRef(selector).llvm // TODO: clang emits it with `invariant.load` metadata. // TODO: Propagate the type here without using the typed pointer. - return load(LLVMGetElementType(selectorRef.llvmType)!!, selectorRef.llvm) + return load(LLVMGlobalGetValueType(selectorRef)!!, selectorRef) } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt index 2f21ae667f0..7ea5aec2610 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt @@ -254,7 +254,7 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) { fun get(value: String) = literals.getOrPut(value) { val globalPointer = generator.generate(llvm.module, llvm, value) llvm.compilerUsedGlobals += globalPointer.llvm - globalPointer.getElementPtr(llvm, 0) + globalPointer.bitcast(llvm.int8PtrType) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt index 3ae0187099c..8c8a1563761 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt @@ -203,7 +203,7 @@ private fun patchLiteral( ) { val module = LLVMGetGlobalParent(global)!! - val newFirstCharPtr = generator.generate(module, llvm, newValue).getElementPtr(llvm, 0).llvm + val newFirstCharPtr = generator.generate(module, llvm, newValue).bitcast(llvm.int8PtrType).llvm generateSequence(LLVMGetFirstUse(global), { LLVMGetNextUse(it) }).forEach { use -> val firstCharPtr = LLVMGetUser(use)!!.also { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt index cee152a52dc..f18f2f2946f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt @@ -41,7 +41,7 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter( val thisRef = param(0) val associatedObjectHolder = if (useSeparateHolder) { val bodyPtr = bitcast(pointerType(bodyType), thisRef) - loadSlot(codegen.kObjHeaderPtr, structGep(bodyPtr, 1), isVar = false) + loadSlot(codegen.kObjHeaderPtr, structGep(bodyType, bodyPtr, 1), isVar = false) } else { thisRef } @@ -109,7 +109,7 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter( retainedBlockPtr, Lifetime.ARGUMENT ) - storeHeapRef(holder, structGep(bodyPtr, 1)) + storeHeapRef(holder, structGep(bodyType, bodyPtr, 1)) result } else { allocInstanceWithAssociatedObject(typeInfo, retainedBlockPtr, Lifetime.RETURN_VALUE) @@ -123,11 +123,12 @@ private fun FunctionGenerationContext.loadBlockInvoke( blockPtr: LLVMValueRef, bridge: BlockPointerBridge ): LlvmCallable { - val invokePtr = structGep(bitcast(pointerType(codegen.runtime.blockLiteralType), blockPtr), 3) + val invokePtr = structGep(codegen.runtime.blockLiteralType, bitcast(pointerType(codegen.runtime.blockLiteralType), blockPtr), 3) val signature = bridge.blockType.toBlockInvokeLlvmType(llvm) - val functionPointerType = pointerType(signature.llvmFunctionType) + val functionType = signature.llvmFunctionType + val functionPointerType = pointerType(functionType) val functionPointer = load(functionPointerType, bitcast(pointerType(functionPointerType), invokePtr)) - return LlvmCallable(functionPointer, signature) + return LlvmCallable(functionType, functionPointer, signature) } private fun FunctionGenerationContext.allocInstanceWithAssociatedObject( @@ -180,7 +181,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { switchToRunnable = true ) { val blockPtr = bitcast(pointerType(blockLiteralType), param(0)) - val refHolder = structGep(blockPtr, 1) + val refHolder = structGep(blockLiteralType, blockPtr, 1) call(llvm.kRefSharedHolderDispose, listOf(refHolder)) ret(null) @@ -200,10 +201,10 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { copyProto, ) { val dstBlockPtr = bitcast(pointerType(blockLiteralType), param(0)) - val dstRefHolder = structGep(dstBlockPtr, 1) + val dstRefHolder = structGep(blockLiteralType, dstBlockPtr, 1) val srcBlockPtr = bitcast(pointerType(blockLiteralType), param(1)) - val srcRefHolder = structGep(srcBlockPtr, 1) + val srcRefHolder = structGep(blockLiteralType, srcBlockPtr, 1) // Note: in current implementation copy helper is invoked only for stack-allocated blocks from the same thread, // so it is technically not necessary to check owner. @@ -267,7 +268,7 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { val blockPtr = bitcast(pointerType(blockLiteralType), param(0)) val kotlinObject = call( llvm.kRefSharedHolderRef, - listOf(structGep(blockPtr, 1)), + listOf(structGep(blockLiteralType, blockPtr, 1)), exceptionHandler = ExceptionHandler.Caller, verbatim = true ) @@ -335,13 +336,13 @@ internal class BlockGenerator(private val codegen: CodeGenerator) { val descriptor = blockDescriptor.llvmGlobal val blockOnStack = alloca(blockLiteralType) - val blockOnStackBase = structGep(blockOnStack, 0) - val refHolder = structGep(blockOnStack, 1) + val blockOnStackBase = structGep(blockLiteralType, blockOnStack, 0) + val refHolder = structGep(blockLiteralType, blockOnStack, 1) listOf(bitcast(llvm.int8PtrType, isa), flags, reserved, invoke, descriptor).forEachIndexed { index, value -> // Although value is actually on the stack, it's not in normal slot area, so we cannot handle it // as if it was on the stack. - store(value, structGep(blockOnStackBase, index)) + store(value, structGep(codegen.runtime.blockLiteralType, blockOnStackBase, index)) } call(llvm.kRefSharedHolderInitLocal, listOf(refHolder, kotlinRef)) 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 7de3405365c..9fc9fc2efb3 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 @@ -177,13 +177,13 @@ internal fun ObjCExportFunctionGenerationContext.callAndMaybeRetainAutoreleased( forbidRuntime = true // Don't emit safe points, frame management etc. val actualArgs = signature.parameterTypes.indices.map { param(it) } - val actualCallable = if (functionIsPassedAsLastParameter) LlvmCallable(param(signature.parameterTypes.size), signature) else function + val actualCallable = if (functionIsPassedAsLastParameter) LlvmCallable(signature.llvmFunctionType, param(signature.parameterTypes.size), signature) else function // Use LLVMBuildCall instead of call, because the latter enforces using exception handler, which is exactly what we have to avoid. val result = actualCallable.buildCall(builder, actualArgs).let { callResult -> // Simplified version of emitAutoreleasedReturnValueMarker in Clang: objCExportCodegen.objcRetainAutoreleasedReturnValueMarker?.let { - LLVMBuildCall(arg0 = builder, Fn = it, Args = null, NumArgs = 0, Name = "") + LLVMBuildCall2(arg0 = builder, functionType(llvm.voidType), Fn = it, Args = null, NumArgs = 0, Name = "") } call(objCExportCodegen.objcRetainAutoreleasedReturnValue, listOf(callResult)).also { @@ -217,8 +217,9 @@ internal open class ObjCExportCodeGeneratorBase(codegen: CodeGenerator) : ObjCCo resultLifetime: Lifetime = Lifetime.IRRELEVANT ): LLVMValueRef { val llvmDeclarations = LlvmCallable( - llvmFunction, + getGlobalFunctionType(llvmFunction), // llvmFunction could be a function pointer here, and we can't infer attributes from it. + llvmFunction, LlvmFunctionAttributeProvider.makeEmpty() ) return callFromBridge(llvmDeclarations, args, resultLifetime) @@ -831,11 +832,12 @@ private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() { } ?: NullPointer(objCToKotlinFunctionType) } + val type = pointerType(objCToKotlinFunctionType) val ptr = staticData.placeGlobalArray( "", - pointerType(objCToKotlinFunctionType), + type, converters - ).pointer.getElementPtr(llvm, 0) + ).pointer.getElementPtr(llvm, LLVMArrayType(type, converters.size)!!, 0) // Note: defining globals declared in runtime. staticData.placeGlobal("Kotlin_ObjCExport_blockToFunctionConverters", ptr, isExported = true) @@ -1628,9 +1630,10 @@ private fun ObjCExportCodeGenerator.createTypeAdapter( } val vtable = if (!irClass.isInterface && !irClass.typeInfoHasVtableAttached) { - staticData.placeGlobal("", rttiGenerator.vtable(irClass)).also { + val table = rttiGenerator.vtable(irClass) + staticData.placeGlobal("", table).also { it.setConstant(true) - }.pointer.getElementPtr(llvm, 0) + }.pointer.getElementPtr(llvm, LLVMArrayType(llvm.int8PtrType, table.elements.size)!!, 0) } else { null } diff --git a/kotlin-native/backend.native/llvm.def b/kotlin-native/backend.native/llvm.def index 41eb9677712..5004cc40a90 100644 --- a/kotlin-native/backend.native/llvm.def +++ b/kotlin-native/backend.native/llvm.def @@ -86,6 +86,7 @@ excludedFunctions = LLVMInitializeAllAsmParsers LLVMInitializeAllAsmPrinters LLV LLVMX86FP80Type LLVMFP128Type LLVMPPCFP128Type LLVMX86MMXType LLVMStructType LLVMVoidType LLVMLabelType \ LLVMMDString LLVMMDNode LLVMConstString LLVMConstStruct LLVMAppendBasicBlock LLVMInsertBasicBlock LLVMCreateBuilder \ LLVMParseBitcode LLVMParseBitcode2 LLVMGetBitcodeModule LLVMGetBitcodeModule2 LLVMGetGlobalContext LLVMModuleCreateWithName \ - LLVMBuildLoad + LLVMBuildLoad LLVMBuildGEP LLVMBuildStructGEP LLVMConstGEP LLVMConstInBoundsGEP LLVMAddAlias LLVMBuildInvoke LLVMBuildCall \ + LLVMGetElementType strictEnums = LLVMIntPredicate LLVMOpcode LLVMDLLStorageClass LLVMCallConv LLVMThreadLocalMode LLVMAtomicOrdering diff --git a/kotlin-native/libllvmext/src/main/cpp/OpaquePointerAPI.cpp b/kotlin-native/libllvmext/src/main/cpp/OpaquePointerAPI.cpp index c58538de828..169f5fed717 100644 --- a/kotlin-native/libllvmext/src/main/cpp/OpaquePointerAPI.cpp +++ b/kotlin-native/libllvmext/src/main/cpp/OpaquePointerAPI.cpp @@ -34,4 +34,9 @@ LLVMValueRef LLVMConstInBoundsGEP2(LLVMTypeRef Ty, LLVMValueRef ConstantVal, NumIndices); Constant *Val = unwrap(ConstantVal); return wrap(ConstantExpr::getInBoundsGetElementPtr(unwrap(Ty), Val, IdxList)); -} \ No newline at end of file +} + +unsigned LLVMGetProgramAddressSpace(LLVMModuleRef moduleRef) { + auto module = unwrap(moduleRef); + return module ? module->getDataLayout().getProgramAddressSpace() : 0; +} diff --git a/kotlin-native/libllvmext/src/main/include/OpaquePointerAPI.h b/kotlin-native/libllvmext/src/main/include/OpaquePointerAPI.h index d62dcccf070..47ca919a792 100644 --- a/kotlin-native/libllvmext/src/main/include/OpaquePointerAPI.h +++ b/kotlin-native/libllvmext/src/main/include/OpaquePointerAPI.h @@ -27,6 +27,8 @@ LLVMValueRef LLVMAddAlias2(LLVMModuleRef M, LLVMTypeRef ValueTy, unsigned AddrSpace, LLVMValueRef Aliasee, const char *Name); +unsigned LLVMGetProgramAddressSpace(LLVMModuleRef moduleRef); + # ifdef __cplusplus } # endif