Refactoring:
1. generator -> codegen 2. tmpVariable -> newVar 3. All calls for LLVM* functions migrated to CodeGenerator 4. mutable list -> list for arguments.
This commit is contained in:
committed by
vvlevchenko
parent
c47a58d34f
commit
d1a303bb25
+15
-6
@@ -54,7 +54,7 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
/* constructor */
|
||||
fun initFunction(declaration: IrConstructor) {
|
||||
function(declaration)
|
||||
val thisPtr = bitcast(pointerType(classType(declaration.descriptor.containingDeclaration)), load(thisVariable(), tmpVariable()), tmpVariable())
|
||||
val thisPtr = bitcast(pointerType(classType(declaration.descriptor.containingDeclaration)), load(thisVariable(), newVar()), newVar())
|
||||
|
||||
/**
|
||||
* TODO: check shadowing.
|
||||
@@ -65,10 +65,10 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
if (!declaration.descriptor.valueParameters.any { it -> it.name.asString() == name })
|
||||
return@forEachIndexed
|
||||
|
||||
val ptr = LLVMBuildStructGEP(context.llvmBuilder, thisPtr, i, tmpVariable())
|
||||
val value = load(variable(name)!!, tmpVariable())
|
||||
val ptr = LLVMBuildStructGEP(context.llvmBuilder, thisPtr, i, newVar())
|
||||
val value = load(variable(name)!!, newVar())
|
||||
|
||||
val typePtr = bitcast(pointerType(LLVMTypeOf(value)), ptr!!, tmpVariable())
|
||||
val typePtr = bitcast(pointerType(LLVMTypeOf(value)), ptr!!, newVar())
|
||||
store(value, typePtr!!)
|
||||
}
|
||||
currentClass = declaration.descriptor.constructedClass
|
||||
@@ -86,7 +86,7 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
return fn
|
||||
}
|
||||
|
||||
fun tmpVariable():String = currentFunction!!.tmpVariable()
|
||||
fun newVar():String = currentFunction!!.tmpVariable()
|
||||
|
||||
val variablesGlobal = mapOf<String, LLVMOpaqueValue?>()
|
||||
fun variable(varName:String):LLVMOpaqueValue? = currentFunction!!.variable(varName)
|
||||
@@ -140,7 +140,7 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun call(llvmFunction: LLVMOpaqueValue?, args: MutableList<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||
fun call(llvmFunction: LLVMOpaqueValue?, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||
if (args.size == 0) return LLVMBuildCall(context.llvmBuilder, llvmFunction, null, 0, result)
|
||||
memScoped {
|
||||
val rargs = alloc(array[args.size](Ref to LLVMOpaqueValue))
|
||||
@@ -174,12 +174,21 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
|
||||
fun indexInClass(p:PropertyDescriptor):Int = currentClass!!.fields.indexOf(p)
|
||||
|
||||
|
||||
fun basicBlock(): LLVMOpaqueBasicBlock? = LLVMAppendBasicBlock(currentFunction!!.llvmFunction.getLlvmValue(), currentFunction!!.bbLabel())
|
||||
fun lastBasicBlock(): LLVMOpaqueBasicBlock? = LLVMGetLastBasicBlock(currentFunction!!.llvmFunction.getLlvmValue())
|
||||
|
||||
fun functionLlvmValue(descriptor: FunctionDescriptor) = descriptor.llvmFunction.getLlvmValue()
|
||||
fun functionHash(descriptor: FunctionDescriptor): LLVMOpaqueValue? = descriptor.functionName.localHash.getLlvmValue()
|
||||
|
||||
fun br(bbLabel: LLVMOpaqueBasicBlock) = LLVMBuildBr(context.llvmBuilder, bbLabel)
|
||||
fun condBr(condition: LLVMOpaqueValue?, bbTrue: LLVMOpaqueBasicBlock?, bbFalse: LLVMOpaqueBasicBlock?)
|
||||
= LLVMBuildCondBr(context.llvmBuilder, condition, bbTrue, bbFalse)
|
||||
|
||||
fun positionAtEnd(bbLabel: LLVMOpaqueBasicBlock)
|
||||
= LLVMPositionBuilderAtEnd(context.llvmBuilder, bbLabel)
|
||||
|
||||
fun ret(value: LLVMOpaqueValue?) = LLVMBuildRet(context.llvmBuilder, value)
|
||||
}
|
||||
|
||||
|
||||
|
||||
+105
-111
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
@@ -70,8 +69,8 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
||||
|
||||
internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid {
|
||||
|
||||
val generator = CodeGenerator(context)
|
||||
val logger = Logger(generator, context)
|
||||
val codegen = CodeGenerator(context)
|
||||
val logger = Logger(codegen, context)
|
||||
val metadator = MetadataGenerator(context)
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -86,12 +85,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
logger.log("visitWhen : ${ir2string(expression)}")
|
||||
var bbExit:LLVMOpaqueBasicBlock? = null // By default "when" does not have "exit"
|
||||
if (!KotlinBuiltIns.isNothing(expression.type)) // If "when" has "exit".
|
||||
bbExit = generator.basicBlock() // Create basic block to process "exit".
|
||||
bbExit = codegen.basicBlock() // Create basic block to process "exit".
|
||||
|
||||
expression.branches.forEach { // Iterate through "when" branches (clauses).
|
||||
var bbNext = bbExit // For last clause bbNext coincides with bbExit.
|
||||
if (it != expression.branches.last()) // If it is not last clause.
|
||||
bbNext = generator.basicBlock() // Create new basic block for next clause.
|
||||
bbNext = codegen.basicBlock() // Create new basic block for next clause.
|
||||
generateWhenCase(it, bbNext, bbExit) // Generate code for current clause.
|
||||
}
|
||||
}
|
||||
@@ -105,48 +104,48 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitWhileLoop(loop: IrWhileLoop) {
|
||||
val loopEnter = generator.basicBlock()
|
||||
val loopBody = generator.basicBlock()
|
||||
val loopExit = generator.basicBlock()
|
||||
val loopEnter = codegen.basicBlock()
|
||||
val loopBody = codegen.basicBlock()
|
||||
val loopExit = codegen.basicBlock()
|
||||
|
||||
LLVMBuildBr(context.llvmBuilder, loopEnter)
|
||||
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, loopEnter)
|
||||
val condition = evaluateExpression(generator.tmpVariable(), loop.condition)
|
||||
codegen.positionAtEnd(loopEnter!!)
|
||||
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
||||
LLVMBuildCondBr(context.llvmBuilder, condition, loopBody, loopExit)
|
||||
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, loopBody)
|
||||
evaluateExpression(generator.tmpVariable(), loop.body)
|
||||
codegen.positionAtEnd(loopBody!!)
|
||||
evaluateExpression(codegen.newVar(), loop.body)
|
||||
|
||||
LLVMBuildBr(context.llvmBuilder, loopEnter)
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, loopExit)
|
||||
codegen.positionAtEnd(loopExit!!)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitDoWhileLoop(loop: IrDoWhileLoop) {
|
||||
val loopBody = generator.basicBlock()
|
||||
val loopCheck = generator.basicBlock()
|
||||
val loopExit = generator.basicBlock()
|
||||
val loopBody = codegen.basicBlock()
|
||||
val loopCheck = codegen.basicBlock()
|
||||
val loopExit = codegen.basicBlock()
|
||||
|
||||
LLVMBuildBr(context.llvmBuilder, loopBody)
|
||||
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, loopBody)
|
||||
evaluateExpression(generator.tmpVariable(), loop.body)
|
||||
codegen.positionAtEnd(loopBody!!)
|
||||
evaluateExpression(codegen.newVar(), loop.body)
|
||||
LLVMBuildBr(context.llvmBuilder, loopCheck)
|
||||
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, loopCheck)
|
||||
val condition = evaluateExpression(generator.tmpVariable(), loop.condition)
|
||||
codegen.positionAtEnd(loopCheck!!)
|
||||
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
||||
LLVMBuildCondBr(context.llvmBuilder, condition, loopBody, loopExit)
|
||||
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, loopExit)
|
||||
codegen.positionAtEnd(loopExit!!)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor) {
|
||||
generator.initFunction(declaration)
|
||||
val thisValue = generator.variable("this")
|
||||
codegen.initFunction(declaration)
|
||||
val thisValue = codegen.variable("this")
|
||||
//super.visitConstructor(declaration)
|
||||
/**
|
||||
* %this = alloca i8*
|
||||
@@ -155,7 +154,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
* %tmp0 = load i8*, i8** %this <- epilog
|
||||
* ret i8* %tmp0
|
||||
*/
|
||||
LLVMBuildRet(context.llvmBuilder, generator.load(thisValue!!, generator.tmpVariable()))
|
||||
codegen.ret(codegen.load(thisValue!!, codegen.newVar()))
|
||||
logger.log("visitConstructor : ${ir2string(declaration)}")
|
||||
}
|
||||
|
||||
@@ -163,8 +162,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody) {
|
||||
super.visitBlockBody(body)
|
||||
if (KotlinBuiltIns.isUnit(generator.currentFunction!!.returnType!!)) {
|
||||
LLVMBuildRet(context.llvmBuilder, null)
|
||||
if (KotlinBuiltIns.isUnit(codegen.currentFunction!!.returnType!!)) {
|
||||
codegen.ret(null)
|
||||
}
|
||||
logger.log("visitBlockBody : ${ir2string(body)}")
|
||||
}
|
||||
@@ -172,7 +171,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
|
||||
evaluateCall(generator.tmpVariable(), expression)
|
||||
evaluateCall(codegen.newVar(), expression)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -180,14 +179,14 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
override fun visitCall(expression: IrCall) {
|
||||
logger.log("visitCall ${ir2string(expression)}")
|
||||
val isUnit = KotlinBuiltIns.isUnit(expression.descriptor.returnType!!)
|
||||
val tmpVariable = if (isUnit) "" else generator.tmpVariable()
|
||||
val tmpVariable = if (isUnit) "" else codegen.newVar()
|
||||
evaluateExpression(tmpVariable, expression)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
generator.function(declaration)
|
||||
codegen.function(declaration)
|
||||
metadator.function(declaration)
|
||||
declaration.acceptChildrenVoid(this)
|
||||
}
|
||||
@@ -220,27 +219,27 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
logger.log("visitVariable : ${ir2string(declaration)}")
|
||||
val variableName = declaration.descriptor.name.asString()
|
||||
val variableType = declaration.descriptor.type
|
||||
val newVariable = generator.alloca(variableType, variableName) // Create LLVM variable.
|
||||
generator.registerVariable(variableName, newVariable) // Map variableName -> LLVM variable.
|
||||
val newVariable = codegen.alloca(variableType, variableName) // Create LLVM variable.
|
||||
codegen.registerVariable(variableName, newVariable) // Map variableName -> LLVM variable.
|
||||
val value = evaluateExpression(variableName, declaration.initializer) // Generate initialization code.
|
||||
generator.store(value!!, generator.variable(variableName)!!) // Store init result in the variable
|
||||
codegen.store(value!!, codegen.variable(variableName)!!) // Store init result in the variable
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitReturn(expression: IrReturn) {
|
||||
logger.log("visitReturn : ${ir2string(expression)}")
|
||||
val tmpVarName = generator.tmpVariable() // Generate new tmp name.
|
||||
val tmpVarName = codegen.newVar() // Generate new tmp name.
|
||||
val value = evaluateExpression(tmpVarName, expression.value) //
|
||||
LLVMBuildRet(context.llvmBuilder, value)
|
||||
codegen.ret(value)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable) {
|
||||
logger.log("visitSetVariable : ${ir2string(expression)}")
|
||||
val value = evaluateExpression(generator.tmpVariable(), expression.value)
|
||||
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
||||
val value = evaluateExpression(codegen.newVar(), expression.value)
|
||||
codegen.store(value!!, codegen.variable(expression.descriptor.name.asString())!!)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -269,7 +268,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
val args = mutableListOf<LLVMOpaqueValue?>() // Create list of function args.
|
||||
value!!.acceptChildrenVoid(object: IrElementVisitorVoid { // Iterate args of the function.
|
||||
override fun visitElement(element: IrElement) { // Visit arg.
|
||||
val tmp = generator.tmpVariable() // Create variable representing the arg in generator
|
||||
val tmp = codegen.newVar() // Create variable representing the arg in codegen
|
||||
args.add(evaluateExpression(tmp, element as IrExpression)) // Evaluate expression and get LLVM arg
|
||||
}
|
||||
})
|
||||
@@ -291,12 +290,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
is LocalVariableDescriptor,
|
||||
is ValueParameterDescriptor,
|
||||
is IrTemporaryVariableDescriptor -> {
|
||||
val variable = generator.variable(value.descriptor.name.asString())
|
||||
return generator.load(variable!!, tmpVariableName)
|
||||
val variable = codegen.variable(value.descriptor.name.asString())
|
||||
return codegen.load(variable!!, tmpVariableName)
|
||||
}
|
||||
is LazyClassReceiverParameterDescriptor -> {
|
||||
if (value.descriptor.name.asString() == "<this>") {
|
||||
return generator.load(generator.thisVariable(), tmpVariableName)
|
||||
return codegen.load(codegen.thisVariable(), tmpVariableName)
|
||||
}
|
||||
TODO()
|
||||
}
|
||||
@@ -310,19 +309,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
private fun evaluateSetVariable(value: IrSetVariable): LLVMOpaqueValue {
|
||||
logger.log("evaluateSetVariable : ${ir2string(value)}")
|
||||
val ret = evaluateExpression(generator.tmpVariable(), value.value)
|
||||
return generator.store(ret!!, generator.variable(value.descriptor.name.asString())!!)
|
||||
val ret = evaluateExpression(codegen.newVar(), value.value)
|
||||
return codegen.store(ret!!, codegen.variable(value.descriptor.name.asString())!!)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateVariable(value: IrVariable): LLVMOpaqueValue {
|
||||
logger.log("evaluateVariable : ${ir2string(value)}")
|
||||
val ret = evaluateExpression(generator.tmpVariable(), value.initializer)
|
||||
val ret = evaluateExpression(codegen.newVar(), value.initializer)
|
||||
val variableName = value.descriptor.name.asString()
|
||||
val variable = generator.alloca(LLVMTypeOf(ret), variableName)
|
||||
generator.registerVariable(variableName, variable)
|
||||
return generator.store(ret!!, variable)
|
||||
val variable = codegen.alloca(LLVMTypeOf(ret), variableName)
|
||||
codegen.registerVariable(variableName, variable)
|
||||
return codegen.store(ret!!, variable)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -331,13 +330,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
logger.log("evaluateGetField : ${ir2string(value)}")
|
||||
if (value.descriptor.dispatchReceiverParameter != null) {
|
||||
if (value.descriptor.getter != null) {
|
||||
val tmpThis = generator.load(generator.thisVariable(), generator.tmpVariable())
|
||||
return evaluateSimpleFunctionCall(generator.tmpVariable(), value.descriptor.getter!!.original, mutableListOf(tmpThis))!!
|
||||
val tmpThis = codegen.load(codegen.thisVariable(), codegen.newVar())
|
||||
return evaluateSimpleFunctionCall(codegen.newVar(), value.descriptor.getter!!.original, mutableListOf(tmpThis))!!
|
||||
} else {
|
||||
val thisPtr = generator.load(generator.thisVariable(), generator.tmpVariable())
|
||||
val typedPtr = generator.bitcast(pointerType(generator.classType(generator.currentClass!!)), thisPtr, generator.tmpVariable())
|
||||
val fieldPtr = LLVMBuildStructGEP(generator.context.llvmBuilder, typedPtr, generator.indexInClass(value.descriptor), generator.tmpVariable())
|
||||
return generator.load(fieldPtr!!, generator.tmpVariable())
|
||||
val thisPtr = codegen.load(codegen.thisVariable(), codegen.newVar())
|
||||
val typedPtr = codegen.bitcast(pointerType(codegen.classType(codegen.currentClass!!)), thisPtr, codegen.newVar())
|
||||
val fieldPtr = LLVMBuildStructGEP(codegen.context.llvmBuilder, typedPtr, codegen.indexInClass(value.descriptor), codegen.newVar())
|
||||
return codegen.load(fieldPtr!!, codegen.newVar())
|
||||
}
|
||||
}
|
||||
TODO()
|
||||
@@ -356,8 +355,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
IrConstKind.Char -> return LLVMConstInt(LLVMInt16Type(), (value.value as Char).toLong(), 0)
|
||||
IrConstKind.Byte -> return LLVMConstInt(LLVMInt32Type(), (value.value as Byte).toLong(), 1)
|
||||
IrConstKind.Short -> return LLVMConstInt(LLVMInt32Type(), (value.value as Short).toLong(), 1)
|
||||
IrConstKind.Int -> return LLVMConstInt(LLVMInt32Type(), (value.value as Int).toLong(), 1)
|
||||
IrConstKind.Long -> return LLVMConstInt(LLVMInt64Type(), value.value as Long, 1)
|
||||
IrConstKind.Int -> return LLVMConstInt(LLVMInt32Type(), (value.value as Int).toLong(), 1)
|
||||
IrConstKind.Long -> return LLVMConstInt(LLVMInt64Type(), value.value as Long, 1)
|
||||
IrConstKind.String ->
|
||||
return context.staticData.createStringLiteral(value as IrConst<String>).getLlvmValue()
|
||||
IrConstKind.Float -> return LLVMConstRealOfString(LLVMFloatType(), (value.value as Float).toString())
|
||||
@@ -370,8 +369,8 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
private fun evaluateReturn(value: IrReturn): LLVMOpaqueValue? {
|
||||
logger.log("evaluateReturn : ${ir2string(value)}")
|
||||
val ret = evaluateExpression(generator.tmpVariable(), value.value)
|
||||
return LLVMBuildRet(context.llvmBuilder, ret)
|
||||
val ret = evaluateExpression(codegen.newVar(), value.value)
|
||||
return codegen.ret(ret)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -379,9 +378,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
private fun evaluateBlock(value: IrBlock): LLVMOpaqueValue? {
|
||||
logger.log("evaluateBlock : ${ir2string(value)}")
|
||||
value.statements.dropLast(1).forEach {
|
||||
evaluateExpression(generator.tmpVariable(), it)
|
||||
evaluateExpression(codegen.newVar(), it)
|
||||
}
|
||||
return evaluateExpression(generator.tmpVariable(), value.statements.lastOrNull())
|
||||
return evaluateExpression(codegen.newVar(), value.statements.lastOrNull())
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -411,18 +410,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
logger.log("evaluateConstructorCall : $variableName = ${ir2string(callee)}")
|
||||
memScoped {
|
||||
val containingClass = (callee.descriptor as ClassConstructorDescriptor).containingDeclaration
|
||||
val typeInfo = generator.typeInfoValue(containingClass)
|
||||
val typeInfo = codegen.typeInfoValue(containingClass)
|
||||
val allocHint = Int32(1).getLlvmValue()
|
||||
val thisValue = if (containingClass.isArray) {
|
||||
assert(args.size == 1 && LLVMTypeOf(args[0]) == LLVMInt32Type())
|
||||
val size = args[0]
|
||||
val params = allocNativeArrayOf(LLVMOpaqueValue, typeInfo, allocHint, size)
|
||||
LLVMBuildCall(
|
||||
context.llvmBuilder, context.allocArrayFunction, params[0], 3, variableName)
|
||||
codegen.call(context.allocArrayFunction, mutableListOf(typeInfo, allocHint, args[0]), variableName)
|
||||
} else {
|
||||
val params = allocNativeArrayOf(LLVMOpaqueValue, typeInfo, allocHint)
|
||||
LLVMBuildCall(
|
||||
context.llvmBuilder, context.allocInstanceFunction, params[0], 2, variableName)
|
||||
codegen.call(context.allocInstanceFunction, mutableListOf(typeInfo, allocHint), variableName)
|
||||
}
|
||||
val constructorParams: MutableList<LLVMOpaqueValue?> = mutableListOf()
|
||||
constructorParams += thisValue
|
||||
@@ -449,12 +443,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
val operandType = callee.argument0.type
|
||||
assert(operandType == callee.argument1.type)
|
||||
when {
|
||||
KotlinBuiltIns.isByte (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isShort (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isInt (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isLong (operandType) -> return generator.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isFloat (operandType) -> return generator.fcmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isDouble(operandType) -> return generator.fcmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isByte (operandType) -> return codegen.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isShort (operandType) -> return codegen.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isInt (operandType) -> return codegen.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isLong (operandType) -> return codegen.icmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isFloat (operandType) -> return codegen.fcmpEq(arg0, arg1, tmpVariableName)
|
||||
KotlinBuiltIns.isDouble(operandType) -> return codegen.fcmpEq(arg0, arg1, tmpVariableName)
|
||||
else -> TODO("ComplexType")
|
||||
}
|
||||
}
|
||||
@@ -462,20 +456,20 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun generateWhenCase(branch: IrBranch, bbNext: LLVMOpaqueBasicBlock?, bbExit: LLVMOpaqueBasicBlock?) {
|
||||
if (isUnconditional(branch)) { // It is the "else" clause.
|
||||
evaluateExpression(generator.tmpVariable(), branch.result) // Generate clause body.
|
||||
if (bbExit == null) return // If "when" does not have exit - return.
|
||||
LLVMBuildBr(context.llvmBuilder, bbExit) // Generate branch to bbExit.
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, bbExit) // Switch generation to bbExit.
|
||||
} else { // It is conditional clause.
|
||||
val bbCurr = generator.basicBlock() // Create block for clause body.
|
||||
val condition = evaluateExpression(generator.tmpVariable(), branch.condition) // Generate cmp instruction.
|
||||
LLVMBuildCondBr(context.llvmBuilder, condition, bbCurr, bbNext) // Conditional branch depending on cmp result.
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, bbCurr) // Switch generation to block for clause body.
|
||||
evaluateExpression(generator.tmpVariable(), branch.result) // Generate clause body.
|
||||
if (!KotlinBuiltIns.isNothing(branch.result.type)) // If clause code does not contain "return".
|
||||
LLVMBuildBr(context.llvmBuilder, bbExit) // Generate branch to bbExit.
|
||||
LLVMPositionBuilderAtEnd(context.llvmBuilder, bbNext) // Switch generation to bbNextClause.
|
||||
if (isUnconditional(branch)) { // It is the "else" clause.
|
||||
evaluateExpression(codegen.newVar(), branch.result) // Generate clause body.
|
||||
if (bbExit == null) return // If "when" does not have exit - return.
|
||||
codegen.br(bbExit) // Generate branch to bbExit.
|
||||
codegen.positionAtEnd(bbExit) // Switch generation to bbExit.
|
||||
} else { // It is conditional clause.
|
||||
val bbCurr = codegen.basicBlock() // Create block for clause body.
|
||||
val condition = evaluateExpression(codegen.newVar(), branch.condition) // Generate cmp instruction.
|
||||
codegen.condBr(condition, bbCurr, bbNext) // Conditional branch depending on cmp result.
|
||||
codegen.positionAtEnd(bbCurr!!) // Switch generation to block for clause body.
|
||||
evaluateExpression(codegen.newVar(), branch.result) // Generate clause body.
|
||||
if (!KotlinBuiltIns.isNothing(branch.result.type)) // If clause code does not contain "return".
|
||||
codegen.br(bbExit!!) // Generate branch to bbExit.
|
||||
codegen.positionAtEnd(bbNext!!) // Switch generation to bbNextClause.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,47 +482,47 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun callDirect(descriptor: FunctionDescriptor, args: MutableList<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||
val llvmFunction = generator.functionLlvmValue(descriptor)
|
||||
return generator.call(llvmFunction, args, result)
|
||||
fun callDirect(descriptor: FunctionDescriptor, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||
val llvmFunction = codegen.functionLlvmValue(descriptor)
|
||||
return codegen.call(llvmFunction, args, result)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
/* Runtime constant */
|
||||
private val kTypeInfo = LLVMGetTypeByName(context.llvmModule, "struct.TypeInfo")!!
|
||||
private val kTypeInfo = LLVMGetTypeByName(context.llvmModule, "struct.TypeInfo")!!
|
||||
private val kTypeInfoPtr = pointerType(kTypeInfo)
|
||||
private val kInt8Ptr = pointerType(LLVMInt8Type())
|
||||
private val kInt8PtrPtr = pointerType(kInt8Ptr)
|
||||
private val kInt8Ptr = pointerType(LLVMInt8Type())
|
||||
private val kInt8PtrPtr = pointerType(kInt8Ptr)
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun callVirtual(descriptor: FunctionDescriptor, args: MutableList<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||
val thisI8PtrPtr = generator.bitcast(kInt8PtrPtr, args[0]!!, generator.tmpVariable()) // Cast "this (i8*)" to i8**.
|
||||
val typeInfoI8Ptr = generator.load(thisI8PtrPtr!!, generator.tmpVariable()) // Load TypeInfo address.
|
||||
val typeInfoPtr = generator.bitcast(kTypeInfoPtr, typeInfoI8Ptr, generator.tmpVariable()) // Cast TypeInfo (i8*) to TypeInfo*.
|
||||
val methodHash = generator.functionHash(descriptor) // Calculate hash of the method to be invoked
|
||||
val lookupArgs = mutableListOf(typeInfoPtr, methodHash) // Prepare args for lookup
|
||||
val llvmMethod = generator.call(
|
||||
fun callVirtual(descriptor: FunctionDescriptor, args: List<LLVMOpaqueValue?>, result: String?): LLVMOpaqueValue? {
|
||||
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*.
|
||||
val methodHash = codegen.functionHash(descriptor) // Calculate hash of the method to be invoked
|
||||
val lookupArgs = listOf(typeInfoPtr, methodHash) // Prepare args for lookup
|
||||
val llvmMethod = codegen.call(
|
||||
context.lookupOpenMethodFunction,
|
||||
lookupArgs,
|
||||
generator.tmpVariable()) // Get method ptr to be invoked
|
||||
codegen.newVar()) // Get method ptr to be invoked
|
||||
|
||||
val functionPtrType = pointerType(getLlvmFunctionType(descriptor)) // Construct type of the method to be invoked
|
||||
val function = generator.bitcast(functionPtrType, llvmMethod!!, generator.tmpVariable()) // Cast method address to the type
|
||||
return generator.call(function, args, result) // Invoke the method
|
||||
val functionPtrType = pointerType(getLlvmFunctionType(descriptor)) // Construct type of the method to be invoked
|
||||
val function = codegen.bitcast(functionPtrType, llvmMethod!!, codegen.newVar()) // Cast method address to the type
|
||||
return codegen.call(function, args, result) // Invoke the method
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun superCall(result:String, descriptor:ClassConstructorDescriptor, args:MutableList<LLVMOpaqueValue?> ):LLVMOpaqueValue? {
|
||||
val tmp = generator.load(generator.thisVariable(), generator.tmpVariable())
|
||||
var rargs:MutableList<LLVMOpaqueValue?>? = null
|
||||
if (args.size != 0)
|
||||
rargs = mutableListOf<LLVMOpaqueValue?>(tmp, *args.toTypedArray())
|
||||
else
|
||||
rargs = mutableListOf<LLVMOpaqueValue?>(tmp)
|
||||
return callDirect(descriptor, rargs, result)
|
||||
fun superCall(result:String, descriptor:ClassConstructorDescriptor, args:List<LLVMOpaqueValue?> ):LLVMOpaqueValue? {
|
||||
val tmp = codegen.load(codegen.thisVariable(), codegen.newVar())
|
||||
val rargs =
|
||||
if (args.isNotEmpty())
|
||||
listOf<LLVMOpaqueValue?>(tmp, *args.toTypedArray())
|
||||
else
|
||||
listOf<LLVMOpaqueValue?>(tmp)
|
||||
return callDirect(descriptor, rargs!!, result)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-2
@@ -16,10 +16,12 @@ internal class Logger(val generator: CodeGenerator, override val context: Contex
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
fun log(msg: String) {
|
||||
logIr()
|
||||
// logIr()
|
||||
println(msg)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
fun logIr() {
|
||||
val function = generator.currentFunction ?: return
|
||||
|
||||
@@ -29,7 +31,7 @@ internal class Logger(val generator: CodeGenerator, override val context: Contex
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
//-----------------------------------------------------------------------------//
|
||||
|
||||
fun ir2string(ir: IrElement?): String {
|
||||
val strWriter = StringWriter()
|
||||
@@ -38,6 +40,8 @@ fun ir2string(ir: IrElement?): String {
|
||||
return strWriter.toString().takeWhile { it != '\n' }
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------//
|
||||
|
||||
fun llvm2string(value: LLVMOpaqueValue?): String {
|
||||
if (value == null) return "<null>"
|
||||
return LLVMPrintValueToString(value)!!.asCString().toString()
|
||||
|
||||
Reference in New Issue
Block a user