backend: refactor ConstValue
also improve other code
This commit is contained in:
committed by
SvyatoslavScherbina
parent
e0dfd312e4
commit
e28a9c71a8
+8
-9
@@ -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)!!
|
||||||
|
|||||||
+11
-7
@@ -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].
|
||||||
*
|
*
|
||||||
|
|||||||
+8
-8
@@ -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)
|
||||||
|
|
||||||
|
|||||||
+56
-54
@@ -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)!!
|
||||||
|
|||||||
+1
-1
@@ -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") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-16
@@ -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
|
||||||
|
|||||||
+4
-4
@@ -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)
|
||||||
|
|||||||
+3
-3
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user