Merge pull request #32 from JetBrains/ir-processing-enchancements
ir-enchancement:support operations with variables and block processing
This commit is contained in:
+72
-1
@@ -9,7 +9,10 @@ import org.jetbrains.kotlin.descriptors.impl.LazyClassReceiverParameterDescripto
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
@@ -126,7 +129,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateExpression(tmpVariableName: String, value: IrExpression?): LLVMOpaqueValue? {
|
private fun evaluateExpression(tmpVariableName: String, value: IrElement?): LLVMOpaqueValue? {
|
||||||
when (value) {
|
when (value) {
|
||||||
is IrCall -> return evaluateCall(tmpVariableName, value)
|
is IrCall -> return evaluateCall(tmpVariableName, value)
|
||||||
is IrGetValue -> {
|
is IrGetValue -> {
|
||||||
@@ -147,6 +150,17 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
is IrSetVariable -> {
|
||||||
|
val ret = evaluateExpression(generator.tmpVariable(), value.value)
|
||||||
|
return generator.store(ret!!, generator.variable(value.descriptor.name.asString())!!)
|
||||||
|
}
|
||||||
|
is IrVariable -> {
|
||||||
|
val ret = evaluateExpression(generator.tmpVariable(), value.initializer)
|
||||||
|
val variableName = value.descriptor.name.asString()
|
||||||
|
val variable = generator.alloca(LLVMTypeOf(ret), variableName)
|
||||||
|
generator.registerVariable(variableName, ret!!)
|
||||||
|
return generator.store(ret, variable)
|
||||||
|
}
|
||||||
is IrGetField -> {
|
is IrGetField -> {
|
||||||
if (value.descriptor.dispatchReceiverParameter != null) {
|
if (value.descriptor.dispatchReceiverParameter != null) {
|
||||||
val thisPtr = generator.load(generator.thisVariable(), generator.tmpVariable())
|
val thisPtr = generator.load(generator.thisVariable(), generator.tmpVariable())
|
||||||
@@ -170,6 +184,14 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
IrConstKind.Double -> TODO()
|
IrConstKind.Double -> TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is IrBlock -> {
|
||||||
|
|
||||||
|
value.statements.dropLast(1).forEach {
|
||||||
|
evaluateExpression(generator.tmpVariable(), it)
|
||||||
|
}
|
||||||
|
return evaluateExpression(generator.tmpVariable(), value.statements.lastOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
null -> return null
|
null -> return null
|
||||||
else -> {
|
else -> {
|
||||||
TODO()
|
TODO()
|
||||||
@@ -193,7 +215,56 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun evaluateGetValue(tmpVariableName: String, value: IrGetValue): LLVMOpaqueValue {
|
||||||
|
when (value.descriptor) {
|
||||||
|
is LocalVariableDescriptor,
|
||||||
|
is ValueParameterDescriptor,
|
||||||
|
is IrTemporaryVariableDescriptor -> {
|
||||||
|
val variable = generator.variable(value.descriptor.name.asString())
|
||||||
|
return generator.load(variable!!, tmpVariableName)
|
||||||
|
}
|
||||||
|
is LazyClassReceiverParameterDescriptor -> {
|
||||||
|
if (value.descriptor.name.asString() == "<this>") {
|
||||||
|
return generator.load(generator.thisVariable(), tmpVariableName)
|
||||||
|
}
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun evaluateSetVariable(value: IrSetVariable): LLVMOpaqueValue {
|
||||||
|
val ret = evaluateExpression(generator.tmpVariable(), value.value)
|
||||||
|
return generator.store(ret!!, generator.variable(value.descriptor.name.asString())!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun evaluateVariable(value: IrVariable): LLVMOpaqueValue {
|
||||||
|
val ret = evaluateExpression(generator.tmpVariable(), value.initializer)
|
||||||
|
val variableName = value.descriptor.name.asString()
|
||||||
|
val variable = generator.alloca(LLVMTypeOf(ret), variableName)
|
||||||
|
generator.registerVariable(variableName, variable)
|
||||||
|
return generator.store(ret!!, variable)
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun evaluateGetField(value: IrGetField): LLVMOpaqueValue {
|
||||||
|
if (value.descriptor.dispatchReceiverParameter != null) {
|
||||||
|
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())
|
||||||
|
}
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ task sum_3const(type: UnitKonanTest) {
|
|||||||
source = "codegen/function/sum_3const.kt"
|
source = "codegen/function/sum_3const.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task local_variable(type: UnitKonanTest) {
|
||||||
|
source = "codegen/basics/local_variable.kt"
|
||||||
|
}
|
||||||
|
|
||||||
//task hello0(type: RunKonanTest) {
|
//task hello0(type: RunKonanTest) {
|
||||||
// source = "runtime/basic/hello0.kt"
|
// source = "runtime/basic/hello0.kt"
|
||||||
//}
|
//}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
extern void *resolve_symbol(const char*);
|
||||||
|
|
||||||
|
int
|
||||||
|
run_test() {
|
||||||
|
int (*local_variable)(int) = resolve_symbol("kfun:local_variable");
|
||||||
|
|
||||||
|
if (local_variable(3) != 14) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun local_variable(a: Int) : Int {
|
||||||
|
var b = 0
|
||||||
|
b = a + 11
|
||||||
|
return b
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user