backend: refactor ConstValue

also improve other code
This commit is contained in:
Svyatoslav Scherbina
2016-12-02 17:21:59 +07:00
committed by SvyatoslavScherbina
parent e0dfd312e4
commit e28a9c71a8
10 changed files with 107 additions and 107 deletions
@@ -21,7 +21,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
if (currentFunction == descriptor) return if (currentFunction == descriptor) return
variableIndex = 0 variableIndex = 0
currentFunction = declaration.descriptor currentFunction = declaration.descriptor
val fn = declaration.descriptor.llvmFunction.getLlvmValue() val fn = declaration.descriptor.llvmFunction
prologueBb = LLVMAppendBasicBlock(fn, "prologue") prologueBb = LLVMAppendBasicBlock(fn, "prologue")
entryBb = LLVMAppendBasicBlock(fn, "entry") entryBb = LLVMAppendBasicBlock(fn, "entry")
positionAtEnd(entryBb!!) positionAtEnd(entryBb!!)
@@ -122,20 +122,19 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
/* to class descriptor */ /* to class descriptor */
fun classType(descriptor: ClassDescriptor): LLVMTypeRef = LLVMGetTypeByName(context.llvmModule, descriptor.symbolName)!! fun classType(descriptor: ClassDescriptor): LLVMTypeRef = LLVMGetTypeByName(context.llvmModule, descriptor.symbolName)!!
fun typeInfoType(descriptor: ClassDescriptor): LLVMTypeRef = descriptor.llvmTypeInfoPtr.getLlvmType() fun typeInfoValue(descriptor: ClassDescriptor): LLVMValueRef = descriptor.llvmTypeInfoPtr
fun typeInfoValue(descriptor: ClassDescriptor): LLVMValueRef = descriptor.llvmTypeInfoPtr.getLlvmValue()!!
fun param(fn: FunctionDescriptor, i: Int): LLVMValueRef { fun param(fn: FunctionDescriptor, i: Int): LLVMValueRef {
assert (i >= 0 && i < countParams(fn)) assert (i >= 0 && i < countParams(fn))
return LLVMGetParam(fn.llvmFunction.getLlvmValue(), i)!! return LLVMGetParam(fn.llvmFunction, i)!!
} }
fun countParams(fn: FunctionDescriptor) = LLVMCountParams(fn.llvmFunction.getLlvmValue()) fun countParams(fn: FunctionDescriptor) = LLVMCountParams(fn.llvmFunction)
fun indexInClass(p:PropertyDescriptor):Int = (p.containingDeclaration as ClassDescriptor).fields.indexOf(p) fun indexInClass(p:PropertyDescriptor):Int = (p.containingDeclaration as ClassDescriptor).fields.indexOf(p)
fun basicBlock(name: String = "label_"): LLVMBasicBlockRef = fun basicBlock(name: String = "label_"): LLVMBasicBlockRef =
LLVMAppendBasicBlock(currentFunction!!.llvmFunction.getLlvmValue(), name)!! LLVMAppendBasicBlock(currentFunction!!.llvmFunction, name)!!
fun basicBlock(name: String, code: () -> Unit) = basicBlock(name).apply { fun basicBlock(name: String, code: () -> Unit) = basicBlock(name).apply {
appendingTo(this) { appendingTo(this) {
@@ -143,10 +142,10 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
} }
} }
fun lastBasicBlock(): LLVMBasicBlockRef? = LLVMGetLastBasicBlock(currentFunction!!.llvmFunction.getLlvmValue()) fun lastBasicBlock(): LLVMBasicBlockRef? = LLVMGetLastBasicBlock(currentFunction!!.llvmFunction)
fun functionLlvmValue(descriptor: FunctionDescriptor) = descriptor.llvmFunction.getLlvmValue()!! fun functionLlvmValue(descriptor: FunctionDescriptor) = descriptor.llvmFunction
fun functionHash(descriptor: FunctionDescriptor): LLVMValueRef = descriptor.functionName.localHash.getLlvmValue()!! fun functionHash(descriptor: FunctionDescriptor): LLVMValueRef = descriptor.functionName.localHash.llvm
fun br(bbLabel: LLVMBasicBlockRef): LLVMValueRef { fun br(bbLabel: LLVMBasicBlockRef): LLVMValueRef {
val res = LLVMBuildBr(builder, bbLabel)!! val res = LLVMBuildBr(builder, bbLabel)!!
@@ -56,15 +56,16 @@ internal interface ContextUtils {
* LLVM function generated from the Kotlin function. * LLVM function generated from the Kotlin function.
* It may be declared as external function prototype. * It may be declared as external function prototype.
*/ */
val FunctionDescriptor.llvmFunction: ConstValue val FunctionDescriptor.llvmFunction: LLVMValueRef
get() { get() {
assert (this.kind.isReal) assert (this.kind.isReal)
val globalName = this.symbolName val globalName = this.symbolName
val module = context.llvmModule val module = context.llvmModule
val functionType = getLlvmFunctionType(this) val functionType = getLlvmFunctionType(this)
val function = LLVMGetNamedFunction(module, globalName) ?: LLVMAddFunction(module, globalName, functionType)
return constValue(function) return LLVMGetNamedFunction(module, globalName) ?:
LLVMAddFunction(module, globalName, functionType)!!
} }
/** /**
@@ -72,7 +73,7 @@ internal interface ContextUtils {
*/ */
val FunctionDescriptor.entryPointAddress: ConstValue val FunctionDescriptor.entryPointAddress: ConstValue
get() { get() {
val result = LLVMConstBitCast(this.llvmFunction.getLlvmValue(), pointerType(LLVMInt8Type())) val result = LLVMConstBitCast(this.llvmFunction, int8TypePtr)!!
return constValue(result) return constValue(result)
} }
@@ -80,16 +81,19 @@ internal interface ContextUtils {
* Pointer to type info for given class. * Pointer to type info for given class.
* It may be declared as pointer to external variable. * It may be declared as pointer to external variable.
*/ */
val ClassDescriptor.llvmTypeInfoPtr: ConstPointer val ClassDescriptor.llvmTypeInfoPtr: LLVMValueRef
get() { get() {
val module = context.llvmModule val module = context.llvmModule
val globalName = this.typeInfoSymbolName val globalName = this.typeInfoSymbolName
val globalPtr = LLVMGetNamedGlobal(module, globalName) ?: val globalPtr = LLVMGetNamedGlobal(module, globalName) ?:
LLVMAddGlobal(module, runtime.typeInfoType, globalName) LLVMAddGlobal(module, runtime.typeInfoType, globalName)!!
return constPointer(globalPtr) return globalPtr
} }
val ClassDescriptor.typeInfoPtr: ConstPointer
get() = constPointer(this.llvmTypeInfoPtr)
/** /**
* Returns contents of this [GlobalHash]. * Returns contents of this [GlobalHash].
* *
@@ -470,7 +470,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
return paramDescriptors.mapIndexed { i, paramDescriptor -> return paramDescriptors.mapIndexed { i, paramDescriptor ->
val param = codegen.param(descriptor, i) val param = codegen.param(descriptor, i)
assert(codegen.getLLVMType(paramDescriptor.type) == LLVMTypeOf(param)) assert(codegen.getLLVMType(paramDescriptor.type) == param.type)
paramDescriptor to param paramDescriptor to param
}.toMap() }.toMap()
} }
@@ -694,11 +694,11 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun evaluateVararg(tmpVariableName: String, value: IrVararg): LLVMValueRef? { private fun evaluateVararg(tmpVariableName: String, value: IrVararg): LLVMValueRef? {
val arrayCreationArgs = listOf(codegen.kTheArrayTypeInfo!!, kImmInt32One!!, Int32(value.elements.size).getLlvmValue()!!) val arrayCreationArgs = listOf(codegen.kTheArrayTypeInfo, kImmInt32One, Int32(value.elements.size).llvm)
val array = currentCodeContext.genCall(context.allocArrayFunction, arrayCreationArgs, tmpVariableName) val array = currentCodeContext.genCall(context.allocArrayFunction, arrayCreationArgs, tmpVariableName)
value.elements.forEachIndexed { i, it -> value.elements.forEachIndexed { i, it ->
val elementValueRaw = evaluateExpression(codegen.newVar(), it) val elementValueRaw = evaluateExpression(codegen.newVar(), it)
currentCodeContext.genCall(context.setArrayFunction, listOf(array!!, Int32(i).getLlvmValue()!!, elementValueRaw!!), "") currentCodeContext.genCall(context.setArrayFunction, listOf(array, Int32(i).llvm, elementValueRaw!!), "")
return@forEachIndexed return@forEachIndexed
} }
return array return array
@@ -1316,7 +1316,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
IrConstKind.Int -> return LLVMConstInt(LLVMInt32Type(), (value.value as Int).toLong(), 1) IrConstKind.Int -> return LLVMConstInt(LLVMInt32Type(), (value.value as Int).toLong(), 1)
IrConstKind.Long -> return LLVMConstInt(LLVMInt64Type(), value.value as Long, 1) IrConstKind.Long -> return LLVMConstInt(LLVMInt64Type(), value.value as Long, 1)
IrConstKind.String -> IrConstKind.String ->
return context.staticData.kotlinStringLiteral(value as IrConst<String>).getLlvmValue() return context.staticData.kotlinStringLiteral(value as IrConst<String>).llvm
IrConstKind.Float -> return LLVMConstRealOfString(LLVMFloatType(), (value.value as Float).toString()) IrConstKind.Float -> return LLVMConstRealOfString(LLVMFloatType(), (value.value as Float).toString())
IrConstKind.Double -> return LLVMConstRealOfString(LLVMDoubleType(), (value.value as Double).toString()) IrConstKind.Double -> return LLVMConstRealOfString(LLVMDoubleType(), (value.value as Double).toString())
} }
@@ -1464,9 +1464,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
memScoped { memScoped {
val containingClass = (callee.descriptor as ClassConstructorDescriptor).containingDeclaration val containingClass = (callee.descriptor as ClassConstructorDescriptor).containingDeclaration
val typeInfo = codegen.typeInfoValue(containingClass) val typeInfo = codegen.typeInfoValue(containingClass)
val allocHint = Int32(1).getLlvmValue()!! val allocHint = Int32(1).llvm
val thisValue = if (containingClass.isArray) { val thisValue = if (containingClass.isArray) {
assert(args.size == 1 && LLVMTypeOf(args[0]) == LLVMInt32Type()) assert(args.size == 1 && args[0].type == int32Type)
val allocArrayInstanceArgs = listOf(typeInfo, allocHint, args[0]) val allocArrayInstanceArgs = listOf(typeInfo, allocHint, args[0])
currentCodeContext.genCall(context.allocArrayFunction, allocArrayInstanceArgs, variableName) currentCodeContext.genCall(context.allocArrayFunction, allocArrayInstanceArgs, variableName)
} else { } else {
@@ -1670,7 +1670,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
val thisPtr = currentCodeContext.genGetValue(constructedClass.thisAsReceiverParameter) val thisPtr = currentCodeContext.genGetValue(constructedClass.thisAsReceiverParameter)
val thisPtrArgType = codegen.getLLVMType(descriptor.allValueParameters[0].type) val thisPtrArgType = codegen.getLLVMType(descriptor.allValueParameters[0].type)
val thisPtrArg = if (LLVMTypeOf(thisPtr) == thisPtrArgType) { val thisPtrArg = if (thisPtr.type == thisPtrArgType) {
thisPtr thisPtr
} else { } else {
// e.g. when array constructor calls super (i.e. Any) constructor. // e.g. when array constructor calls super (i.e. Any) constructor.
@@ -1703,7 +1703,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
memScoped { memScoped {
val arrayLength = args.size val arrayLength = args.size
val argsCasted = args.map{it -> constPointer(LLVMConstBitCast(it, int8TypePtr)) } val argsCasted = args.map { it -> constPointer(it).bitcast(int8TypePtr) }
val llvmUsedGlobal = val llvmUsedGlobal =
context.staticData.placeGlobalArray("llvm.used", int8TypePtr, argsCasted) context.staticData.placeGlobalArray("llvm.used", int8TypePtr, argsCasted)
@@ -5,51 +5,51 @@ import llvm.*
import org.jetbrains.kotlin.backend.konan.allValueParameters import org.jetbrains.kotlin.backend.konan.allValueParameters
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
internal val LLVMValueRef.type: LLVMTypeRef
get() = LLVMTypeOf(this)!!
/** /**
* Represents the value which can be emitted as bitcode const value * Represents the value which can be emitted as bitcode const value
*/ */
internal interface ConstValue { internal interface ConstValue {
fun getLlvmValue(): LLVMValueRef? val llvm: LLVMValueRef
fun getLlvmType(): LLVMTypeRef {
return LLVMTypeOf(getLlvmValue())!!
}
} }
internal val ConstValue.llvmType: LLVMTypeRef
get() = this.llvm.type
internal interface ConstPointer : ConstValue { internal interface ConstPointer : ConstValue {
fun getElementPtr(index: Int): ConstPointer = ConstGetElementPtr(this, index) fun getElementPtr(index: Int): ConstPointer = ConstGetElementPtr(this, index)
} }
internal fun constPointer(value: LLVMValueRef?) = object : ConstPointer { internal fun constPointer(value: LLVMValueRef) = object : ConstPointer {
override fun getLlvmValue() = value
init {
assert (LLVMIsConstant(value) == 1)
}
override val llvm = value
} }
private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : ConstPointer { private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : ConstPointer {
override fun getLlvmValue(): LLVMValueRef? { override val llvm = memScoped {
// TODO: probably it should be computed once when initialized?
// TODO: squash multiple GEPs // TODO: squash multiple GEPs
val indices = intArrayOf(0, index).map { Int32(it).getLlvmValue() } val indices = intArrayOf(0, index).map { Int32(it).llvm }
memScoped { val indicesArray = allocArrayOf(indices)
val indicesArray = allocArrayOf(indices) LLVMConstInBoundsGEP(pointer.llvm, indicesArray[0].ptr, indices.size)!!
return LLVMConstInBoundsGEP(pointer.getLlvmValue(), indicesArray[0].ptr, indices.size)
}
} }
} }
internal fun ConstPointer.bitcast(toType: LLVMTypeRef) = constPointer(LLVMConstBitCast(this.getLlvmValue(), toType)) internal fun ConstPointer.bitcast(toType: LLVMTypeRef) = constPointer(LLVMConstBitCast(this.llvm, toType)!!)
internal class ConstArray(val elemType: LLVMTypeRef?, val elements: List<ConstValue>) : ConstValue { internal class ConstArray(val elemType: LLVMTypeRef?, val elements: List<ConstValue>) : ConstValue {
override fun getLlvmValue(): LLVMValueRef? { override val llvm = memScoped {
val values = elements.map { it.getLlvmValue() }.toTypedArray() val values = elements.map { it.llvm }.toTypedArray()
memScoped { val valuesNativeArrayPtr = allocArrayOf(*values)[0].ptr
val valuesNativeArrayPtr = allocArrayOf(*values)[0].ptr LLVMConstArray(elemType, valuesNativeArrayPtr, values.size)!!
return LLVMConstArray(elemType, valuesNativeArrayPtr, values.size)
}
} }
} }
@@ -57,49 +57,51 @@ internal open class Struct(val type: LLVMTypeRef?, val elements: List<ConstValue
constructor(type: LLVMTypeRef?, vararg elements: ConstValue) : this(type, elements.toList()) constructor(type: LLVMTypeRef?, vararg elements: ConstValue) : this(type, elements.toList())
override fun getLlvmValue(): LLVMValueRef? { override val llvm = memScoped {
val values = elements.map { it.getLlvmValue() }.toTypedArray() val values = elements.map { it.llvm }.toTypedArray()
memScoped { val valuesNativeArrayPtr = allocArrayOf(*values)[0].ptr
val valuesNativeArrayPtr = allocArrayOf(*values)[0].ptr LLVMConstNamedStruct(type, valuesNativeArrayPtr, values.size)!!
return LLVMConstNamedStruct(type, valuesNativeArrayPtr, values.size)
}
} }
} }
internal class Int8(val value: Byte) : ConstValue { internal class Int8(val value: Byte) : ConstValue {
override fun getLlvmValue() = LLVMConstInt(LLVMInt8Type(), value.toLong(), 1) override val llvm = LLVMConstInt(LLVMInt8Type(), value.toLong(), 1)!!
} }
internal class Int32(val value: Int) : ConstValue { internal class Int32(val value: Int) : ConstValue {
override fun getLlvmValue() = LLVMConstInt(LLVMInt32Type(), value.toLong(), 1) override val llvm = LLVMConstInt(LLVMInt32Type(), value.toLong(), 1)!!
} }
internal class Int64(val value: Long) : ConstValue { internal class Int64(val value: Long) : ConstValue {
override fun getLlvmValue() = LLVMConstInt(LLVMInt64Type(), value, 1) override val llvm = LLVMConstInt(LLVMInt64Type(), value, 1)!!
} }
internal class Zero(val type: LLVMTypeRef?) : ConstValue { internal class Zero(val type: LLVMTypeRef) : ConstValue {
override fun getLlvmValue() = LLVMConstNull(type) override val llvm = LLVMConstNull(type)!!
} }
internal class NullPointer(val pointeeType: LLVMTypeRef?): ConstPointer { internal class NullPointer(val pointeeType: LLVMTypeRef): ConstPointer {
override fun getLlvmValue() = LLVMConstNull(pointerType(pointeeType)) override val llvm = LLVMConstNull(pointerType(pointeeType))!!
} }
internal fun constValue(value: LLVMValueRef?) = object : ConstValue { internal fun constValue(value: LLVMValueRef) = object : ConstValue {
override fun getLlvmValue() = value init {
assert (LLVMIsConstant(value) == 1)
}
override val llvm = value
} }
internal val int8Type = LLVMInt8Type()!! internal val int8Type = LLVMInt8Type()!!
internal val int32Type = LLVMInt32Type()!! internal val int32Type = LLVMInt32Type()!!
internal val int8TypePtr = pointerType(int8Type) internal val int8TypePtr = pointerType(int8Type)
internal val voidType = LLVMVoidType() internal val voidType = LLVMVoidType()!!
internal val ContextUtils.kTheAnyTypeInfo: LLVMValueRef? internal val ContextUtils.kTheAnyTypeInfo: LLVMValueRef
get() = KonanPlatform.builtIns.any.llvmTypeInfoPtr.getLlvmValue() get() = KonanPlatform.builtIns.any.llvmTypeInfoPtr
internal val ContextUtils.kTheArrayTypeInfo: LLVMValueRef? internal val ContextUtils.kTheArrayTypeInfo: LLVMValueRef
get() = KonanPlatform.builtIns.array.llvmTypeInfoPtr.getLlvmValue() get() = KonanPlatform.builtIns.array.llvmTypeInfoPtr
internal val ContextUtils.kTypeInfo: LLVMTypeRef internal val ContextUtils.kTypeInfo: LLVMTypeRef
get() = LLVMGetTypeByName(context.llvmModule, "struct.TypeInfo")!! get() = LLVMGetTypeByName(context.llvmModule, "struct.TypeInfo")!!
internal val ContextUtils.kObjHeader: LLVMTypeRef internal val ContextUtils.kObjHeader: LLVMTypeRef
@@ -114,30 +116,30 @@ internal val ContextUtils.kArrayHeaderPtr: LLVMTypeRef
get() = pointerType(kArrayHeader) get() = pointerType(kArrayHeader)
internal val ContextUtils.kTypeInfoPtr: LLVMTypeRef internal val ContextUtils.kTypeInfoPtr: LLVMTypeRef
get() = pointerType(kTypeInfo) get() = pointerType(kTypeInfo)
internal val kInt1 = LLVMInt1Type() internal val kInt1 = LLVMInt1Type()!!
internal val kInt8Ptr = pointerType(LLVMInt8Type()) internal val kInt8Ptr = pointerType(int8Type)
internal val kInt8PtrPtr = pointerType(kInt8Ptr) internal val kInt8PtrPtr = pointerType(kInt8Ptr)
internal val kImmInt32One = Int32(1).getLlvmValue() internal val kImmInt32One = Int32(1).llvm
internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef
get() = LLVMConstNull(this.kObjHeaderPtr)!! get() = LLVMConstNull(this.kObjHeaderPtr)!!
internal val ContextUtils.kNullArrayHeaderPtr: LLVMValueRef internal val ContextUtils.kNullArrayHeaderPtr: LLVMValueRef
get() = LLVMConstNull(this.kArrayHeaderPtr)!! get() = LLVMConstNull(this.kArrayHeaderPtr)!!
internal fun pointerType(pointeeType: LLVMTypeRef?) = LLVMPointerType(pointeeType, 0)!! internal fun pointerType(pointeeType: LLVMTypeRef) = LLVMPointerType(pointeeType, 0)!!
internal fun structType(vararg types: LLVMTypeRef?): LLVMTypeRef = memScoped { internal fun structType(vararg types: LLVMTypeRef): LLVMTypeRef = memScoped {
LLVMStructType(allocArrayOf(*types)[0].ptr, types.size, 0)!! LLVMStructType(allocArrayOf(*types)[0].ptr, types.size, 0)!!
} }
internal fun ContextUtils.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef? { internal fun ContextUtils.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef {
val returnType = getLLVMType(function.returnType!!) val returnType = getLLVMType(function.returnType!!)
val params = function.allValueParameters val params = function.allValueParameters
val paramTypes = params.map { getLLVMType(it.type) } val paramTypes = params.map { getLLVMType(it.type) }
memScoped { memScoped {
val paramTypesPtr = allocArrayOf(paramTypes)[0].ptr val paramTypesPtr = allocArrayOf(paramTypes)[0].ptr
return LLVMFunctionType(returnType, paramTypesPtr, paramTypes.size, 0) return LLVMFunctionType(returnType, paramTypesPtr, paramTypes.size, 0)!!
} }
} }
@@ -147,12 +149,12 @@ internal fun ContextUtils.getLlvmFunctionType(function: FunctionDescriptor): LLV
internal fun CArray<CInt8Var>.getBytes(size: Long) = internal fun CArray<CInt8Var>.getBytes(size: Long) =
(0 .. size-1).map { this[it].value }.toByteArray() (0 .. size-1).map { this[it].value }.toByteArray()
internal fun getFunctionType(ptrToFunction: LLVMValueRef?): LLVMTypeRef { internal fun getFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef {
return getGlobalType(ptrToFunction) return getGlobalType(ptrToFunction)
} }
internal fun getGlobalType(ptrToGlobal: LLVMValueRef?): LLVMTypeRef { internal fun getGlobalType(ptrToGlobal: LLVMValueRef): LLVMTypeRef {
return LLVMGetElementType(LLVMTypeOf(ptrToGlobal))!! return LLVMGetElementType(ptrToGlobal.type)!!
} }
internal fun ContextUtils.externalFunction(name: String, type: LLVMTypeRef): LLVMValueRef { internal fun ContextUtils.externalFunction(name: String, type: LLVMTypeRef): LLVMValueRef {
@@ -175,7 +177,7 @@ internal fun ContextUtils.externalGlobal(name: String, type: LLVMTypeRef): LLVMV
} }
} }
internal fun functionType(returnType: LLVMTypeRef?, isVarArg: Boolean = false, vararg paramTypes: LLVMTypeRef?) = internal fun functionType(returnType: LLVMTypeRef, isVarArg: Boolean = false, vararg paramTypes: LLVMTypeRef) =
memScoped { memScoped {
val paramTypesPtr = allocArrayOf(*paramTypes)[0].ptr val paramTypesPtr = allocArrayOf(*paramTypes)[0].ptr
LLVMFunctionType(returnType, paramTypesPtr, paramTypes.size, if (isVarArg) 1 else 0)!! LLVMFunctionType(returnType, paramTypesPtr, paramTypes.size, if (isVarArg) 1 else 0)!!
@@ -21,7 +21,7 @@ internal class Logger(val generator: CodeGenerator, override val context: Contex
fun logIr() { fun logIr() {
val function = generator.currentFunction ?: return val function = generator.currentFunction ?: return
val irFunctionDeclaration = LLVMPrintValueToString(function.llvmFunction.getLlvmValue())!!.asCString().toString() val irFunctionDeclaration = LLVMPrintValueToString(function.llvmFunction)!!.asCString().toString()
irFunctionDeclaration.lines().forEach { println(" $it") } irFunctionDeclaration.lines().forEach { println(" $it") }
} }
@@ -18,20 +18,15 @@ import java.io.*
fun readModuleMetadata(file: File): String { fun readModuleMetadata(file: File): String {
val reader = MetadataReader(file) val reader = MetadataReader(file)
var metadataString: String? = null
try { reader.use {
val metadataNode = reader.namedMetadataNode("kmetadata", 0); val metadataNode = reader.namedMetadataNode("kmetadata", 0);
val stringNode = reader.metadataOperand(metadataNode, 0)!! val stringNode = reader.metadataOperand(metadataNode, 0)
metadataString = reader.string(stringNode) return reader.string(stringNode)
} finally {
reader.close()
} }
return metadataString!!
} }
class MetadataReader(file: File) { class MetadataReader(file: File) : Closeable {
lateinit var llvmModule: LLVMModuleRef lateinit var llvmModule: LLVMModuleRef
lateinit var llvmContext: LLVMContextRef lateinit var llvmContext: LLVMContextRef
@@ -69,10 +64,10 @@ class MetadataReader(file: File) {
fun namedMetadataNode(name: String, index: Int): LLVMValueRef { fun namedMetadataNode(name: String, index: Int): LLVMValueRef {
memScoped { memScoped {
val nodeCount = LLVMGetNamedMetadataNumOperands(llvmModule, "kmetadata")!! val nodeCount = LLVMGetNamedMetadataNumOperands(llvmModule, "kmetadata")
val nodeArray = allocArray<LLVMValueRefVar>(nodeCount) val nodeArray = allocArray<LLVMValueRefVar>(nodeCount)
LLVMGetNamedMetadataOperands(llvmModule, "kmetadata", nodeArray[0].ptr)!! LLVMGetNamedMetadataOperands(llvmModule, "kmetadata", nodeArray[0].ptr)
return nodeArray[0].value!! return nodeArray[0].value!!
} }
@@ -80,16 +75,16 @@ class MetadataReader(file: File) {
fun metadataOperand(metadataNode: LLVMValueRef, index: Int): LLVMValueRef { fun metadataOperand(metadataNode: LLVMValueRef, index: Int): LLVMValueRef {
memScoped { memScoped {
val operandCount = LLVMGetMDNodeNumOperands(metadataNode)!! val operandCount = LLVMGetMDNodeNumOperands(metadataNode)
val operandArray = allocArray<LLVMValueRefVar>(operandCount) val operandArray = allocArray<LLVMValueRefVar>(operandCount)
LLVMGetMDNodeOperands(metadataNode, operandArray[0].ptr)!! LLVMGetMDNodeOperands(metadataNode, operandArray[0].ptr)
return operandArray[0].value!! return operandArray[0].value!!
} }
} }
fun close() { override fun close() {
LLVMDisposeModule(llvmModule) LLVMDisposeModule(llvmModule)
LLVMContextDispose(llvmContext) LLVMContextDispose(llvmContext)
} }
@@ -155,7 +150,7 @@ internal class MetadataGenerator(override val context: Context): ContextUtils {
} }
internal fun function(declaration: IrFunction) { internal fun function(declaration: IrFunction) {
val fn = declaration.descriptor.llvmFunction.getLlvmValue() val fn = declaration.descriptor.llvmFunction
val proto = serializeFunSignature(declaration) val proto = serializeFunSignature(declaration)
@@ -165,7 +160,7 @@ internal class MetadataGenerator(override val context: Context): ContextUtils {
// Quick check consistency // Quick check consistency
private fun debug_blob(blob: String) { private fun debug_blob(blob: String) {
var metadataList = mutableListOf<KotlinKonanMetadata>() val metadataList = mutableListOf<KotlinKonanMetadata>()
KotlinKonanMetadataUtils.parseMetadata(blob, metadataList) KotlinKonanMetadataUtils.parseMetadata(blob, metadataList)
val body = metadataList.first().body val body = metadataList.first().body
@@ -151,9 +151,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
val superTypeOrAny = classDesc.getSuperClassOrAny() val superTypeOrAny = classDesc.getSuperClassOrAny()
val superType = if (KotlinBuiltIns.isAny(classDesc)) NullPointer(runtime.typeInfoType) val superType = if (KotlinBuiltIns.isAny(classDesc)) NullPointer(runtime.typeInfoType)
else superTypeOrAny.llvmTypeInfoPtr else superTypeOrAny.typeInfoPtr
val interfaces = classDesc.implementedInterfaces.map { it.llvmTypeInfoPtr } val interfaces = classDesc.implementedInterfaces.map { it.typeInfoPtr }
val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className", val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className",
pointerType(runtime.typeInfoType), interfaces) pointerType(runtime.typeInfoType), interfaces)
@@ -212,8 +212,8 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
methodsPtr, methods.size, methodsPtr, methods.size,
fieldsPtr, if (classDesc.isInterface) -1 else fields.size) fieldsPtr, if (classDesc.isInterface) -1 else fields.size)
val typeInfoGlobal = classDesc.llvmTypeInfoPtr.getLlvmValue() // TODO: it is a hack val typeInfoGlobal = classDesc.llvmTypeInfoPtr // TODO: it is a hack
LLVMSetInitializer(typeInfoGlobal, typeInfo.getLlvmValue()) LLVMSetInitializer(typeInfoGlobal, typeInfo.llvm)
LLVMSetGlobalConstant(typeInfoGlobal, 1) LLVMSetGlobalConstant(typeInfoGlobal, 1)
exportTypeInfoIfRequired(classDesc, typeInfoGlobal) exportTypeInfoIfRequired(classDesc, typeInfoGlobal)
@@ -25,7 +25,7 @@ internal class StaticData(override val context: Context): ContextUtils {
} }
fun setInitializer(value: ConstValue) { fun setInitializer(value: ConstValue) {
LLVMSetInitializer(llvmGlobal, value.getLlvmValue()) LLVMSetInitializer(llvmGlobal, value.llvm)
} }
fun setConstant(value: Boolean) { fun setConstant(value: Boolean) {
@@ -51,7 +51,7 @@ internal class StaticData(override val context: Context): ContextUtils {
private fun getElementOffset(index: Int): Long { private fun getElementOffset(index: Int): Long {
val llvmTargetData = global.staticData.llvmTargetData val llvmTargetData = global.staticData.llvmTargetData
val type = LLVMGetElementType(delegate.getLlvmType()) val type = LLVMGetElementType(delegate.llvmType)
return when (LLVMGetTypeKind(type)) { return when (LLVMGetTypeKind(type)) {
LLVMTypeKind.LLVMStructTypeKind -> LLVMOffsetOfElement(llvmTargetData, type, index) LLVMTypeKind.LLVMStructTypeKind -> LLVMOffsetOfElement(llvmTargetData, type, index)
LLVMTypeKind.LLVMArrayTypeKind -> LLVMABISizeOfType(llvmTargetData, LLVMGetElementType(type)) * index LLVMTypeKind.LLVMArrayTypeKind -> LLVMABISizeOfType(llvmTargetData, LLVMGetElementType(type)) * index
@@ -95,7 +95,7 @@ internal class StaticData(override val context: Context): ContextUtils {
* Creates [Global] with given name and value. * Creates [Global] with given name and value.
*/ */
fun placeGlobal(name: String, initializer: ConstValue): Global { fun placeGlobal(name: String, initializer: ConstValue): Global {
val global = createGlobal(initializer.getLlvmType(), name) val global = createGlobal(initializer.llvmType, name)
global.setInitializer(initializer) global.setInitializer(initializer)
return global return global
} }
@@ -10,9 +10,9 @@ import llvm.*
* If [elements] is empty, then null pointer is returned. * If [elements] is empty, then null pointer is returned.
*/ */
internal fun StaticData.placeGlobalConstArray(name: String, internal fun StaticData.placeGlobalConstArray(name: String,
elemType: LLVMTypeRef?, elemType: LLVMTypeRef,
elements: List<ConstValue>): ConstPointer { elements: List<ConstValue>): ConstPointer {
if (elements.size > 0) { if (elements.isNotEmpty()) {
val global = this.placeGlobalArray(name, elemType, elements) val global = this.placeGlobalArray(name, elemType, elements)
global.setConstant(true) global.setConstant(true)
return global.pointer.getElementPtr(0) return global.pointer.getElementPtr(0)
@@ -22,6 +22,6 @@ internal fun StaticData.placeGlobalConstArray(name: String,
} }
internal fun StaticData.createAlias(name: String, aliasee: ConstPointer): ConstPointer { internal fun StaticData.createAlias(name: String, aliasee: ConstPointer): ConstPointer {
val alias = LLVMAddAlias(context.llvmModule, aliasee.getLlvmType(), aliasee.getLlvmValue(), name)!! val alias = LLVMAddAlias(context.llvmModule, aliasee.llvmType, aliasee.llvm, name)!!
return constPointer(alias) return constPointer(alias)
} }
@@ -42,7 +42,7 @@ internal fun StaticData.createKotlinStringLiteral(value: IrConst<String>): Const
val stringClass = value.type.constructor.declarationDescriptor as ClassDescriptor val stringClass = value.type.constructor.declarationDescriptor as ClassDescriptor
assert (stringClass.fqNameSafe.asString() == "kotlin.String") assert (stringClass.fqNameSafe.asString() == "kotlin.String")
val arrayHeader = arrayHeader(containerOffsetNegative, stringClass.llvmTypeInfoPtr, arrayCount) val arrayHeader = arrayHeader(containerOffsetNegative, stringClass.typeInfoPtr, arrayCount)
val array = ConstArray(int8Type, valueBytes.map { Int8(it) } ) val array = ConstArray(int8Type, valueBytes.map { Int8(it) } )
@@ -50,7 +50,7 @@ internal fun StaticData.createKotlinStringLiteral(value: IrConst<String>): Const
val stringRef = objHeaderPtr.bitcast(getLLVMType(value.type)) val stringRef = objHeaderPtr.bitcast(getLLVMType(value.type))
val res = createAlias("kstr:$base64Str", stringRef) val res = createAlias("kstr:$base64Str", stringRef)
LLVMSetLinkage(res.getLlvmValue(), LLVMLinkage.LLVMWeakAnyLinkage) LLVMSetLinkage(res.llvm, LLVMLinkage.LLVMWeakAnyLinkage)
return res return res
} }