backend: use fancy type names for LLVM C API

This commit is contained in:
Svyatoslav Scherbina
2016-11-23 15:38:53 +07:00
parent f3dab21718
commit 46ff436fb3
9 changed files with 93 additions and 104 deletions
@@ -45,7 +45,7 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
fun fields(descriptor: ClassDescriptor):List<PropertyDescriptor> = descriptor.fields
private fun prolog(declaration: IrFunction): LLVMOpaqueValue? {
private fun prolog(declaration: IrFunction): LLVMValueRef? {
variableIndex = 0
labelIndex = 0
currentFunction = declaration.descriptor
@@ -58,8 +58,8 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
fun newVar():String = currentFunction!!.tmpVariable()
val variablesGlobal = mapOf<String, LLVMOpaqueValue?>()
fun variable(varName:String):LLVMOpaqueValue? = currentFunction!!.variable(varName)
val variablesGlobal = mapOf<String, LLVMValueRef?>()
fun variable(varName:String): LLVMValueRef? = currentFunction!!.variable(varName)
private var variableIndex:Int = 0
private var FunctionDescriptor.tmpVariableIndex: Int
@@ -74,48 +74,48 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
fun FunctionDescriptor.tmpVariable():String = "tmp_${tmpVariableIndex++}"
fun FunctionDescriptor.bbLabel():String = "label_${bbLabelIndex++}"
fun registerVariable(varName: String, value:LLVMOpaqueValue) = currentFunction!!.registerVariable(varName, value)
fun registerVariable(varName: String, value: LLVMValueRef) = currentFunction!!.registerVariable(varName, value)
val function2variables = mutableMapOf<FunctionDescriptor, MutableMap<String, LLVMOpaqueValue?>>()
val function2variables = mutableMapOf<FunctionDescriptor, MutableMap<String, LLVMValueRef?>>()
val FunctionDescriptor.variables: MutableMap<String, LLVMOpaqueValue?>
val FunctionDescriptor.variables: MutableMap<String, LLVMValueRef?>
get() = this@CodeGenerator.function2variables[this]!!
val ClassConstructorDescriptor.thisValue:LLVMOpaqueValue?
val ClassConstructorDescriptor.thisValue: LLVMValueRef?
get() = thisValue
fun FunctionDescriptor.registerVariable(varName: String, value:LLVMOpaqueValue?) = variables.put(varName, value)
private fun FunctionDescriptor.variable(varName: String): LLVMOpaqueValue? = variables[varName]
fun FunctionDescriptor.registerVariable(varName: String, value: LLVMValueRef?) = variables.put(varName, value)
private fun FunctionDescriptor.variable(varName: String): LLVMValueRef? = variables[varName]
fun plus (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildAdd (context.llvmBuilder, arg0, arg1, result)!!
fun mul (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildMul (context.llvmBuilder, arg0, arg1, result)!!
fun minus (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildSub (context.llvmBuilder, arg0, arg1, result)!!
fun div (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildSDiv(context.llvmBuilder, arg0, arg1, result)!!
fun srem (arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildSRem(context.llvmBuilder, arg0, arg1, result)!!
fun plus (arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildAdd (context.llvmBuilder, arg0, arg1, result)!!
fun mul (arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildMul (context.llvmBuilder, arg0, arg1, result)!!
fun minus (arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildSub (context.llvmBuilder, arg0, arg1, result)!!
fun div (arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildSDiv(context.llvmBuilder, arg0, arg1, result)!!
fun srem (arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildSRem(context.llvmBuilder, arg0, arg1, result)!!
/* integers comparisons */
fun icmpEq(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntEQ, arg0, arg1, result)!!
fun icmpGt(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSGT, arg0, arg1, result)!!
fun icmpGe(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSGE, arg0, arg1, result)!!
fun icmpLt(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSLT, arg0, arg1, result)!!
fun icmpLe(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, result)!!
fun icmpNe(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, result)!!
fun icmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntEQ, arg0, arg1, result)!!
fun icmpGt(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSGT, arg0, arg1, result)!!
fun icmpGe(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSGE, arg0, arg1, result)!!
fun icmpLt(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSLT, arg0, arg1, result)!!
fun icmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, result)!!
fun icmpNe(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildICmp(context.llvmBuilder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, result)!!
/* floating-point comparisons */
fun fcmpEq(arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, result: String): LLVMOpaqueValue = LLVMBuildFCmp(context.llvmBuilder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, result)!!
fun fcmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, result: String): LLVMValueRef = LLVMBuildFCmp(context.llvmBuilder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, result)!!
fun bitcast(type: LLVMOpaqueType?, value: LLVMOpaqueValue, result: String) = LLVMBuildBitCast(context.llvmBuilder, value, type, result)
fun bitcast(type: LLVMTypeRef?, value: LLVMValueRef, result: String) = LLVMBuildBitCast(context.llvmBuilder, value, type, result)
fun alloca(type: KotlinType, varName: String):LLVMOpaqueValue = alloca( getLLVMType(type), varName)
fun alloca(type: LLVMOpaqueType?, varName: String): LLVMOpaqueValue = LLVMBuildAlloca(context.llvmBuilder, type, varName)!!
fun load(value:LLVMOpaqueValue, varName: String):LLVMOpaqueValue = LLVMBuildLoad(context.llvmBuilder, value, varName)!!
fun store(value:LLVMOpaqueValue, ptr:LLVMOpaqueValue):LLVMOpaqueValue = LLVMBuildStore(context.llvmBuilder, value, ptr)!!
fun alloca(type: KotlinType, varName: String): LLVMValueRef = alloca( getLLVMType(type), varName)
fun alloca(type: LLVMTypeRef?, varName: String): LLVMValueRef = LLVMBuildAlloca(context.llvmBuilder, type, varName)!!
fun load(value: LLVMValueRef, varName: String): LLVMValueRef = LLVMBuildLoad(context.llvmBuilder, value, varName)!!
fun store(value: LLVMValueRef, ptr: LLVMValueRef): LLVMValueRef = LLVMBuildStore(context.llvmBuilder, value, ptr)!!
//-------------------------------------------------------------------------//
fun call(llvmFunction: LLVMOpaqueValue?, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
fun call(llvmFunction: LLVMValueRef?, args: List<LLVMValueRef?>, result: String?): LLVMValueRef? {
if (args.size == 0) return LLVMBuildCall(context.llvmBuilder, llvmFunction, null, 0, result)
memScoped {
val rargs = allocArrayOf(args)
@@ -139,31 +139,31 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
}
/* to class descriptor */
fun classType(descriptor: ClassDescriptor):LLVMOpaqueType = LLVMGetTypeByName(context.llvmModule, descriptor.symbolName)!!
fun typeInfoType(descriptor: ClassDescriptor): LLVMOpaqueType? = descriptor.llvmTypeInfoPtr.getLlvmType()
fun typeInfoValue(descriptor: ClassDescriptor): LLVMOpaqueValue? = descriptor.llvmTypeInfoPtr.getLlvmValue()
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.getLlvmValue()
fun thisVariable() = variable("this")!!
fun param(fn: FunctionDescriptor?, i: Int): LLVMOpaqueValue? = LLVMGetParam(fn!!.llvmFunction.getLlvmValue(), i)
fun param(fn: FunctionDescriptor?, i: Int): LLVMValueRef? = LLVMGetParam(fn!!.llvmFunction.getLlvmValue(), i)
fun indexInClass(p:PropertyDescriptor):Int = (p.containingDeclaration as ClassDescriptor).fields.indexOf(p)
fun basicBlock(): LLVMOpaqueBasicBlock? = LLVMAppendBasicBlock(currentFunction!!.llvmFunction.getLlvmValue(), currentFunction!!.bbLabel())
fun lastBasicBlock(): LLVMOpaqueBasicBlock? = LLVMGetLastBasicBlock(currentFunction!!.llvmFunction.getLlvmValue())
fun basicBlock(): LLVMBasicBlockRef? = LLVMAppendBasicBlock(currentFunction!!.llvmFunction.getLlvmValue(), currentFunction!!.bbLabel())
fun lastBasicBlock(): LLVMBasicBlockRef? = LLVMGetLastBasicBlock(currentFunction!!.llvmFunction.getLlvmValue())
fun functionLlvmValue(descriptor: FunctionDescriptor) = descriptor.llvmFunction.getLlvmValue()
fun functionHash(descriptor: FunctionDescriptor): LLVMOpaqueValue? = descriptor.functionName.localHash.getLlvmValue()
fun functionHash(descriptor: FunctionDescriptor): LLVMValueRef? = descriptor.functionName.localHash.getLlvmValue()
fun br(bbLabel: LLVMOpaqueBasicBlock) = LLVMBuildBr(context.llvmBuilder, bbLabel)
fun condBr(condition: LLVMOpaqueValue?, bbTrue: LLVMOpaqueBasicBlock?, bbFalse: LLVMOpaqueBasicBlock?)
fun br(bbLabel: LLVMBasicBlockRef) = LLVMBuildBr(context.llvmBuilder, bbLabel)
fun condBr(condition: LLVMValueRef?, bbTrue: LLVMBasicBlockRef?, bbFalse: LLVMBasicBlockRef?)
= LLVMBuildCondBr(context.llvmBuilder, condition, bbTrue, bbFalse)
fun positionAtEnd(bbLabel: LLVMOpaqueBasicBlock)
fun positionAtEnd(bbLabel: LLVMBasicBlockRef)
= LLVMPositionBuilderAtEnd(context.llvmBuilder, bbLabel)
fun ret(value: LLVMOpaqueValue?) = LLVMBuildRet(context.llvmBuilder, value)
fun unreachable(): LLVMOpaqueValue? = LLVMBuildUnreachable(context.llvmBuilder)
fun ret(value: LLVMValueRef?) = LLVMBuildRet(context.llvmBuilder, value)
fun unreachable(): LLVMValueRef? = LLVMBuildUnreachable(context.llvmBuilder)
}
@@ -334,7 +334,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateExpression(tmpVariableName: String, value: IrElement?): LLVMOpaqueValue? {
private fun evaluateExpression(tmpVariableName: String, value: IrElement?): LLVMValueRef? {
when (value) {
is IrSetterCallImpl -> return evaluateSetterCall (tmpVariableName, value)
is IrTypeOperatorCall-> return evaluateTypeOperator(tmpVariableName, value)
@@ -359,7 +359,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateThrow(tmpVariableName: String, expression: IrThrow): LLVMOpaqueValue? {
private fun evaluateThrow(tmpVariableName: String, expression: IrThrow): LLVMValueRef? {
val objPointer = evaluateExpression(codegen.newVar(), expression.value)
val objHeaderPtr = codegen.bitcast(kObjHeaderPtr, objPointer!!, codegen.newVar())
val args = listOf(objHeaderPtr) // Create arg list.
@@ -368,9 +368,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateWhen(tmpVariableName:String, expression: IrWhen): LLVMOpaqueValue? {
private fun evaluateWhen(tmpVariableName:String, expression: IrWhen): LLVMValueRef? {
logger.log("evaluateWhen : ${ir2string(expression)}")
var bbExit:LLVMOpaqueBasicBlock? = null // By default "when" does not have "exit".
var bbExit: LLVMBasicBlockRef? = null // By default "when" does not have "exit".
if (!KotlinBuiltIns.isNothing(expression.type)) // If "when" has "exit".
bbExit = codegen.basicBlock() // Create basic block to process "exit".
@@ -393,7 +393,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateGetValue(tmpVariableName: String, value: IrGetValue): LLVMOpaqueValue {
private fun evaluateGetValue(tmpVariableName: String, value: IrGetValue): LLVMValueRef {
logger.log("evaluateGetValue : $tmpVariableName = ${ir2string(value)}")
when (value.descriptor) {
is LocalVariableDescriptor,
@@ -416,7 +416,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateSetVariable(value: IrSetVariable): LLVMOpaqueValue {
private fun evaluateSetVariable(value: IrSetVariable): LLVMValueRef {
logger.log("evaluateSetVariable : ${ir2string(value)}")
val ret = evaluateExpression(codegen.newVar(), value.value)
return codegen.store(ret!!, codegen.variable(value.descriptor.name.asString())!!)
@@ -424,7 +424,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateVariable(value: IrVariable): LLVMOpaqueValue {
private fun evaluateVariable(value: IrVariable): LLVMValueRef {
logger.log("evaluateVariable : ${ir2string(value)}")
val ret = evaluateExpression(codegen.newVar(), value.initializer)
val variableName = value.descriptor.name.asString()
@@ -435,7 +435,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateTypeOperator(tmpVariableName: String, value: IrTypeOperatorCall): LLVMOpaqueValue {
private fun evaluateTypeOperator(tmpVariableName: String, value: IrTypeOperatorCall): LLVMValueRef {
when (value.operator) {
IrTypeOperator.CAST -> return evaluateCast(tmpVariableName, value)
IrTypeOperator.IMPLICIT_CAST -> TODO()
@@ -461,7 +461,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
// float | fptosi fptosi fptosi fptosi x fpext
// double | fptosi fptosi fptosi fptosi fptrunc x
private fun evaluateCast(tmpVariableName: String, value: IrTypeOperatorCall): LLVMOpaqueValue {
private fun evaluateCast(tmpVariableName: String, value: IrTypeOperatorCall): LLVMValueRef {
logger.log("evaluateCast : ${ir2string(value)}")
assert(!KotlinBuiltIns.isPrimitiveType(value.type) && !KotlinBuiltIns.isPrimitiveType(value.argument.type))
@@ -476,7 +476,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateInstanceOf(tmpVariableName: String, value: IrTypeOperatorCall): LLVMOpaqueValue {
private fun evaluateInstanceOf(tmpVariableName: String, value: IrTypeOperatorCall): LLVMValueRef {
logger.log("evaluateInstanceOf : ${ir2string(value)}")
val dstDescriptor = TypeUtils.getClassDescriptor(value.typeOperand) // Get class descriptor for dst type.
@@ -491,14 +491,14 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateNotInstanceOf(tmpVariableName: String, value: IrTypeOperatorCall): LLVMOpaqueValue {
private fun evaluateNotInstanceOf(tmpVariableName: String, value: IrTypeOperatorCall): LLVMValueRef {
val instanceOfResult = evaluateInstanceOf(codegen.newVar(), value)
return LLVMBuildNot(context.llvmBuilder, instanceOfResult, tmpVariableName)!!
}
//-------------------------------------------------------------------------//
private fun evaluateGetField(value: IrGetField): LLVMOpaqueValue {
private fun evaluateGetField(value: IrGetField): LLVMValueRef {
logger.log("evaluateGetField : ${ir2string(value)}")
if (value.descriptor.dispatchReceiverParameter != null) {
val thisPtr = codegen.load(codegen.thisVariable(), codegen.newVar())
@@ -512,7 +512,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateSetField(value: IrSetField): LLVMOpaqueValue {
private fun evaluateSetField(value: IrSetField): LLVMValueRef {
logger.log("evaluateSetField : ${ir2string(value)}")
val valueToAssign = evaluateExpression(codegen.newVar(), value.value)!!
if (value.descriptor.dispatchReceiverParameter != null) {
@@ -559,7 +559,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
}
*/
private fun fieldPtrOfClass(thisPtr: LLVMOpaqueValue, value: PropertyDescriptor): LLVMOpaqueValue? {
private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: PropertyDescriptor): LLVMValueRef? {
val objHeaderPtr = codegen.bitcast(kObjHeaderPtr, thisPtr, codegen.newVar())
val typePtr = pointerType(codegen.classType(value.containingDeclaration as ClassDescriptor))
memScoped {
@@ -573,7 +573,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateConst(value: IrConst<*>): LLVMOpaqueValue? {
private fun evaluateConst(value: IrConst<*>): LLVMValueRef? {
logger.log("evaluateConst : ${ir2string(value)}")
when (value.kind) {
IrConstKind.Null -> return kNullPtr
@@ -596,7 +596,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateReturn(value: IrReturn): LLVMOpaqueValue? {
private fun evaluateReturn(value: IrReturn): LLVMValueRef? {
logger.log("evaluateReturn : ${ir2string(value)}")
val ret = evaluateExpression(codegen.newVar(), value.value)
return codegen.ret(ret)
@@ -604,7 +604,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateBlock(value: IrBlock): LLVMOpaqueValue? {
private fun evaluateBlock(value: IrBlock): LLVMValueRef? {
logger.log("evaluateBlock : ${ir2string(value)}")
value.statements.dropLast(1).forEach {
evaluateExpression(codegen.newVar(), it)
@@ -614,9 +614,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateCall(tmpVariableName: String, value: IrMemberAccessExpression?): LLVMOpaqueValue? {
private fun evaluateCall(tmpVariableName: String, value: IrMemberAccessExpression?): LLVMValueRef? {
logger.log("evaluateCall : $tmpVariableName = ${ir2string(value)}")
val args = mutableListOf<LLVMOpaqueValue?>() // Create list of function args.
val args = mutableListOf<LLVMValueRef?>() // Create list of function args.
value!!.acceptChildrenVoid(object: IrElementVisitorVoid { // Iterate args of the function.
override fun visitElement(element: IrElement) { // Visit arg.
val tmp = codegen.newVar() // Create variable representing the arg in codegen
@@ -635,7 +635,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateFunctionCall(tmpVariableName: String, callee: IrCall, args: List<LLVMOpaqueValue?>): LLVMOpaqueValue? {
private fun evaluateFunctionCall(tmpVariableName: String, callee: IrCall, args: List<LLVMValueRef?>): LLVMValueRef? {
val descriptor:FunctionDescriptor = callee.descriptor as FunctionDescriptor
when (descriptor) {
is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall (tmpVariableName, callee, args)
@@ -646,7 +646,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateSimpleFunctionCall(tmpVariableName: String, descriptor: FunctionDescriptor, args: List<LLVMOpaqueValue?>): LLVMOpaqueValue? {
private fun evaluateSimpleFunctionCall(tmpVariableName: String, descriptor: FunctionDescriptor, args: List<LLVMValueRef?>): LLVMValueRef? {
//logger.log("evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}")
if (descriptor.isOverridable)
return callVirtual(descriptor, args, tmpVariableName)
@@ -656,9 +656,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateSetterCall(tmpVariableName: String, value: IrSetterCallImpl): LLVMOpaqueValue? {
private fun evaluateSetterCall(tmpVariableName: String, value: IrSetterCallImpl): LLVMValueRef? {
val descriptor = value.descriptor as FunctionDescriptor
val args = mutableListOf<LLVMOpaqueValue?>()
val args = mutableListOf<LLVMValueRef?>()
if (descriptor.dispatchReceiverParameter != null)
args.add(evaluateExpression(codegen.newVar(), value.dispatchReceiver)) //add this ptr
args.add(evaluateExpression(codegen.newVar(), value.getValueArgument(0)))
@@ -667,7 +667,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateConstructorCall(variableName: String, callee: IrCall, args: List<LLVMOpaqueValue?>): LLVMOpaqueValue? {
private fun evaluateConstructorCall(variableName: String, callee: IrCall, args: List<LLVMValueRef?>): LLVMValueRef? {
logger.log("evaluateConstructorCall : $variableName = ${ir2string(callee)}")
memScoped {
val containingClass = (callee.descriptor as ClassConstructorDescriptor).containingDeclaration
@@ -679,7 +679,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
} else {
codegen.call(context.allocInstanceFunction, listOf(typeInfo, allocHint), variableName)
}
val constructorParams: MutableList<LLVMOpaqueValue?> = mutableListOf()
val constructorParams: MutableList<LLVMValueRef?> = mutableListOf()
constructorParams += thisValue
constructorParams += args
return evaluateSimpleFunctionCall(variableName, callee.descriptor as FunctionDescriptor, constructorParams)
@@ -700,7 +700,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
private val kFalse = LLVMConstInt(LLVMInt1Type(), 0, 1)!!
private fun evaluateOperatorCall(tmpVariableName: String, callee: IrCall, args: List<LLVMOpaqueValue?>): LLVMOpaqueValue {
private fun evaluateOperatorCall(tmpVariableName: String, callee: IrCall, args: List<LLVMValueRef?>): LLVMValueRef {
logger.log("evaluateCall $tmpVariableName origin:$callee")
val descriptor = callee.descriptor
when (descriptor.name) {
@@ -732,7 +732,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateOperatorEqeq(callee: IrBinaryPrimitiveImpl, arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, tmpVariableName: String): LLVMOpaqueValue {
private fun evaluateOperatorEqeq(callee: IrBinaryPrimitiveImpl, arg0: LLVMValueRef, arg1: LLVMValueRef, tmpVariableName: String): LLVMValueRef {
val arg0Type = callee.argument0.type
val isFp = KotlinBuiltIns.isDouble(arg0Type) || KotlinBuiltIns.isFloat(arg0Type)
@@ -746,7 +746,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun generateEqeqForObjects(callee: IrBinaryPrimitiveImpl, arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue, tmpVariableName: String): LLVMOpaqueValue {
private fun generateEqeqForObjects(callee: IrBinaryPrimitiveImpl, arg0: LLVMValueRef, arg1: LLVMValueRef, tmpVariableName: String): LLVMValueRef {
val arg0Type = callee.argument0.type
val descriptor = getEquals(arg0Type, "equals") // Get descriptor for "arg0.equals".
if (arg0Type.isMarkedNullable) { // If arg0 is nullable.
@@ -778,8 +778,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateOperatorEqeqeq(callee: IrBinaryPrimitiveImpl,
arg0: LLVMOpaqueValue, arg1: LLVMOpaqueValue,
tmpVariableName: String):LLVMOpaqueValue {
arg0: LLVMValueRef, arg1: LLVMValueRef,
tmpVariableName: String): LLVMValueRef {
val arg0Type = callee.argument0.type
val arg1Type = callee.argument1.type
@@ -794,7 +794,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun generateWhenCase(isUnit:Boolean, isNothing:Boolean, resultPtr:LLVMOpaqueValue?, branch: IrBranch, bbNext: LLVMOpaqueBasicBlock?, bbExit: LLVMOpaqueBasicBlock?) {
private fun generateWhenCase(isUnit:Boolean, isNothing:Boolean, resultPtr: LLVMValueRef?, branch: IrBranch, bbNext: LLVMBasicBlockRef?, bbExit: LLVMBasicBlockRef?) {
val neitherUnitNorNothing = !isNothing && !isUnit // If branches doesn't end with 'return' either result hasn't got 'unit' type.
if (isUnconditional(branch)) { // It is the "else" clause.
val brResult = evaluateExpression(codegen.newVar(), branch.result) // Generate clause body.
@@ -826,7 +826,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
fun callDirect(descriptor: FunctionDescriptor, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
fun callDirect(descriptor: FunctionDescriptor, args: List<LLVMValueRef?>, result: String?): LLVMValueRef? {
val realDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor)
val llvmFunction = codegen.functionLlvmValue(realDescriptor)
return call(descriptor, llvmFunction, args, result)
@@ -846,7 +846,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
fun callVirtual(descriptor: FunctionDescriptor, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
fun callVirtual(descriptor: FunctionDescriptor, args: List<LLVMValueRef?>, result: String?): LLVMValueRef? {
val thisI8PtrPtr = codegen.bitcast(kInt8PtrPtr, args[0]!!, codegen.newVar()) // Cast "this (i8*)" to i8**.
val typeInfoI8Ptr = codegen.load(thisI8PtrPtr!!, codegen.newVar()) // Load TypeInfo address.
val typeInfoPtr = codegen.bitcast(kTypeInfoPtr, typeInfoI8Ptr, codegen.newVar()) // Cast TypeInfo (i8*) to TypeInfo*.
@@ -864,19 +864,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun call(descriptor: FunctionDescriptor, function: LLVMOpaqueValue?, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
private fun call(descriptor: FunctionDescriptor, function: LLVMValueRef?, args: List<LLVMValueRef?>, result: String?): LLVMValueRef? {
return codegen.call(function, args, if (KotlinBuiltIns.isUnit(descriptor.returnType!!)) "" else result)
}
//-------------------------------------------------------------------------//
fun superCall(result:String, descriptor:ClassConstructorDescriptor, args:List<LLVMOpaqueValue?> ):LLVMOpaqueValue? {
fun superCall(result:String, descriptor:ClassConstructorDescriptor, args:List<LLVMValueRef?> ): LLVMValueRef? {
val tmp = codegen.load(codegen.thisVariable(), codegen.newVar())
val rargs =
if (args.isNotEmpty())
listOf<LLVMOpaqueValue?>(tmp, *args.toTypedArray())
listOf<LLVMValueRef?>(tmp, *args.toTypedArray())
else
listOf<LLVMOpaqueValue?>(tmp)
listOf<LLVMValueRef?>(tmp)
return callDirect(descriptor, rargs!!, result)
}
@@ -38,7 +38,7 @@ fun ir2string(ir: IrElement?): String {
//-----------------------------------------------------------------------------//
fun llvm2string(value: LLVMOpaqueValue?): String {
fun llvm2string(value: LLVMValueRef?): String {
if (value == null) return "<null>"
return LLVMPrintValueToString(value)!!.asCString().toString()
}
@@ -57,7 +57,7 @@ class MetadataReader(file: File) {
}
fun string(node: LLVMOpaqueValue): String {
fun string(node: LLVMValueRef): String {
memScoped {
val len = alloc<CInt32Var>()
val str1 = LLVMGetMDString(node, len.ptr)!!
@@ -67,7 +67,7 @@ class MetadataReader(file: File) {
}
}
fun namedMetadataNode(name: String, index: Int): LLVMOpaqueValue {
fun namedMetadataNode(name: String, index: Int): LLVMValueRef {
memScoped {
val nodeCount = LLVMGetNamedMetadataNumOperands(llvmModule, "kmetadata")!!
val nodeArray = allocArray<LLVMValueRefVar>(nodeCount)
@@ -78,7 +78,7 @@ class MetadataReader(file: File) {
}
}
fun metadataOperand(metadataNode: LLVMOpaqueValue, index: Int): LLVMOpaqueValue {
fun metadataOperand(metadataNode: LLVMValueRef, index: Int): LLVMValueRef {
memScoped {
val operandCount = LLVMGetMDNodeNumOperands(metadataNode)!!
val operandArray = allocArray<LLVMValueRefVar>(operandCount)
@@ -98,24 +98,24 @@ class MetadataReader(file: File) {
internal class MetadataGenerator(override val context: Context): ContextUtils {
private fun metadataString(str: String): LLVMOpaqueValue {
private fun metadataString(str: String): LLVMValueRef {
return LLVMMDString(str, str.length)!!
}
private fun metadataNode(args: List<LLVMOpaqueValue?>): LLVMOpaqueValue {
private fun metadataNode(args: List<LLVMValueRef?>): LLVMValueRef {
memScoped {
val references = allocArrayOf(args)
return LLVMMDNode(references[0].ptr, args.size)!!
}
}
private fun metadataFun(fn: LLVMOpaqueValue?, info: String): LLVMOpaqueValue {
private fun metadataFun(fn: LLVMValueRef?, info: String): LLVMValueRef {
val args = listOf(fn, metadataString(info));
val md = metadataNode(args)
return md
}
private fun emitModuleMetadata(name: String, md: LLVMOpaqueValue?) {
private fun emitModuleMetadata(name: String, md: LLVMValueRef?) {
LLVMAddNamedMetadataOperand(context.llvmModule, name, md)
}
@@ -59,7 +59,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
)
// TODO: probably it should be moved out of this class and shared.
private fun createStructFor(className: FqName, fields: List<PropertyDescriptor>): LLVMOpaqueType? {
private fun createStructFor(className: FqName, fields: List<PropertyDescriptor>): LLVMTypeRef? {
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), "kclass:" + className)
val fieldTypes = fields.map { getLLVMType(it.returnType!!) }.toTypedArray()
@@ -115,7 +115,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
return allMethods
}
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMOpaqueValue?) {
private fun exportTypeInfoIfRequired(classDesc: ClassDescriptor, typeInfoGlobal: LLVMValueRef?) {
val annot = classDesc.annotations.findAnnotation(FqName("kotlin.ExportTypeInfo"))
if (annot != null) {
val nameValue = annot.allValueArguments.values.single() as StringValue
@@ -138,7 +138,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
"kotlin.String" to -1
)
private fun getInstanceSize(classType: LLVMOpaqueType?, className: FqName) : Int {
private fun getInstanceSize(classType: LLVMTypeRef?, className: FqName) : Int {
val arraySize = arrayClasses.get(className.asString());
if (arraySize != null) return arraySize;
return LLVMStoreSizeOfType(runtime.targetData, classType).toInt()
@@ -9,7 +9,7 @@ class Runtime(private val bitcodeFile: String) {
init {
llvmModule = memScoped {
val bufRef = allocPointerTo<LLVMOpaqueMemoryBuffer>()
val bufRef = alloc<LLVMMemoryBufferRefVar>()
val errorRef = allocPointerTo<CInt8Var>()
val res = LLVMCreateMemoryBufferWithContentsOfFile(bitcodeFile, bufRef.ptr, errorRef.ptr)
if (res != 0) {
@@ -11,9 +11,9 @@ internal class StaticData(override val context: Context): ContextUtils {
/**
* Represents the LLVM global variable.
*/
class Global private constructor(val staticData: StaticData, val llvmGlobal: LLVMOpaqueValue) {
class Global private constructor(val staticData: StaticData, val llvmGlobal: LLVMValueRef) {
companion object {
fun create(staticData: StaticData, type: LLVMOpaqueType, name: String): Global {
fun create(staticData: StaticData, type: LLVMTypeRef, name: String): Global {
val module = staticData.context.llvmModule
if (LLVMGetNamedGlobal(module, name) != null) {
throw IllegalArgumentException("Global '$name' already exists")
@@ -87,7 +87,7 @@ internal class StaticData(override val context: Context): ContextUtils {
*
* It is external until explicitly initialized with [Global.setInitializer].
*/
fun createGlobal(type: LLVMOpaqueType, name: String): Global {
fun createGlobal(type: LLVMTypeRef, name: String): Global {
return Global.create(this, type, name)
}
@@ -103,7 +103,7 @@ internal class StaticData(override val context: Context): ContextUtils {
/**
* Creates array-typed global with given name and value.
*/
fun placeGlobalArray(name: String, elemType: LLVMOpaqueType?, elements: List<ConstValue>): Global {
fun placeGlobalArray(name: String, elemType: LLVMTypeRef?, elements: List<ConstValue>): Global {
val initializer = ConstArray(elemType, elements)
val global = placeGlobal(name, initializer)
@@ -10,7 +10,7 @@ import llvm.*
* If [elements] is empty, then null pointer is returned.
*/
internal fun StaticData.placeGlobalConstArray(name: String,
elemType: LLVMOpaqueType?,
elemType: LLVMTypeRef?,
elements: List<ConstValue>): ConstPointer {
if (elements.size > 0) {
val global = this.placeGlobalArray(name, elemType, elements)
@@ -1,11 +0,0 @@
package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.CPointer
import kotlinx.cinterop.CPointerVarWithValueMappedTo
// TODO: the definitions below are required to perform smooth migration to new interop;
// remove after replacing with LLVM*Ref typedefs
typealias LLVMOpaqueValue = CPointer<llvm.LLVMOpaqueValue>
typealias LLVMOpaqueType = CPointer<llvm.LLVMOpaqueType>
typealias LLVMOpaqueBasicBlock = CPointer<llvm.LLVMOpaqueBasicBlock>