Append all variable allocations to prologue. (#97)
This commit is contained in:
+22
-12
@@ -14,12 +14,19 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
internal class CodeGenerator(override val context: Context) : ContextUtils {
|
internal class CodeGenerator(override val context: Context) : ContextUtils {
|
||||||
var currentFunction:FunctionDescriptor? = null
|
var currentFunction:FunctionDescriptor? = null
|
||||||
|
|
||||||
fun function(declaration: IrFunction) {
|
fun prologue(declaration: IrFunction) {
|
||||||
assert(declaration.body != null)
|
assert(declaration.body != null)
|
||||||
|
|
||||||
val descriptor = declaration.descriptor
|
val descriptor = declaration.descriptor
|
||||||
if (currentFunction == descriptor) return
|
if (currentFunction == descriptor) return
|
||||||
val fn = prolog(declaration)
|
variableIndex = 0
|
||||||
|
currentFunction = declaration.descriptor
|
||||||
|
val fn = declaration.descriptor.llvmFunction.getLlvmValue()
|
||||||
|
prologueBb = LLVMAppendBasicBlock(fn, "prologue")
|
||||||
|
entryBb = LLVMAppendBasicBlock(fn, "entry")
|
||||||
|
positionAtEnd(entryBb!!)
|
||||||
|
|
||||||
|
function2variables.put(declaration.descriptor, mutableMapOf())
|
||||||
|
|
||||||
var indexOffset = 0
|
var indexOffset = 0
|
||||||
if (descriptor is ClassConstructorDescriptor
|
if (descriptor is ClassConstructorDescriptor
|
||||||
@@ -43,18 +50,15 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fields(descriptor: ClassDescriptor):List<PropertyDescriptor> = descriptor.fields
|
|
||||||
|
|
||||||
private fun prolog(declaration: IrFunction): LLVMValueRef? {
|
fun epilogue(declaration: IrFunction) {
|
||||||
variableIndex = 0
|
appendingTo(prologueBb!!) {
|
||||||
currentFunction = declaration.descriptor
|
br(entryBb!!)
|
||||||
val fn = declaration.descriptor.llvmFunction.getLlvmValue()
|
}
|
||||||
val block = LLVMAppendBasicBlock(fn, "entry")!!
|
|
||||||
positionAtEnd(block)
|
|
||||||
function2variables.put(declaration.descriptor, mutableMapOf())
|
|
||||||
return fn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fields(descriptor: ClassDescriptor):List<PropertyDescriptor> = descriptor.fields
|
||||||
|
|
||||||
fun newVar():String = currentFunction!!.tmpVariable()
|
fun newVar():String = currentFunction!!.tmpVariable()
|
||||||
|
|
||||||
val variablesGlobal = mapOf<String, LLVMValueRef?>()
|
val variablesGlobal = mapOf<String, LLVMValueRef?>()
|
||||||
@@ -71,6 +75,8 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
|
|
||||||
val function2variables = mutableMapOf<FunctionDescriptor, MutableMap<String, LLVMValueRef?>>()
|
val function2variables = mutableMapOf<FunctionDescriptor, MutableMap<String, LLVMValueRef?>>()
|
||||||
|
|
||||||
|
private var prologueBb: LLVMBasicBlockRef? = null
|
||||||
|
private var entryBb: LLVMBasicBlockRef? = null
|
||||||
|
|
||||||
val FunctionDescriptor.variables: MutableMap<String, LLVMValueRef?>
|
val FunctionDescriptor.variables: MutableMap<String, LLVMValueRef?>
|
||||||
get() = this@CodeGenerator.function2variables[this]!!
|
get() = this@CodeGenerator.function2variables[this]!!
|
||||||
@@ -102,7 +108,11 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
fun bitcast(type: LLVMTypeRef?, value: LLVMValueRef, result: String) = LLVMBuildBitCast(builder, value, type, result)!!
|
fun bitcast(type: LLVMTypeRef?, value: LLVMValueRef, result: String) = LLVMBuildBitCast(builder, value, type, result)!!
|
||||||
|
|
||||||
fun alloca(type: KotlinType, varName: String): LLVMValueRef = alloca( getLLVMType(type), varName)
|
fun alloca(type: KotlinType, varName: String): LLVMValueRef = alloca( getLLVMType(type), varName)
|
||||||
fun alloca(type: LLVMTypeRef?, varName: String): LLVMValueRef = LLVMBuildAlloca(builder, type, varName)!!
|
fun alloca(type: LLVMTypeRef?, varName: String): LLVMValueRef {
|
||||||
|
appendingTo(prologueBb!!) {
|
||||||
|
return LLVMBuildAlloca(builder, type, varName)!!
|
||||||
|
}
|
||||||
|
}
|
||||||
fun load(value: LLVMValueRef, varName: String): LLVMValueRef = LLVMBuildLoad(builder, value, varName)!!
|
fun load(value: LLVMValueRef, varName: String): LLVMValueRef = LLVMBuildLoad(builder, value, varName)!!
|
||||||
fun store(value: LLVMValueRef, ptr: LLVMValueRef): LLVMValueRef = LLVMBuildStore(builder, value, ptr)!!
|
fun store(value: LLVMValueRef, ptr: LLVMValueRef): LLVMValueRef = LLVMBuildStore(builder, value, ptr)!!
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -224,7 +224,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitConstructor(constructorDeclaration: IrConstructor) {
|
override fun visitConstructor(constructorDeclaration: IrConstructor) {
|
||||||
codegen.function(constructorDeclaration)
|
codegen.prologue(constructorDeclaration)
|
||||||
val constructorDescriptor = constructorDeclaration.descriptor
|
val constructorDescriptor = constructorDeclaration.descriptor
|
||||||
val classDescriptor = DescriptorUtils.getContainingClass(constructorDescriptor)
|
val classDescriptor = DescriptorUtils.getContainingClass(constructorDescriptor)
|
||||||
val thisPtr = codegen.load(codegen.thisVariable(), codegen.newVar())
|
val thisPtr = codegen.load(codegen.thisVariable(), codegen.newVar())
|
||||||
@@ -281,6 +281,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
|
|
||||||
codegen.ret(thisPtr)
|
codegen.ret(thisPtr)
|
||||||
|
codegen.epilogue(constructorDeclaration)
|
||||||
logger.log("visitConstructor : ${ir2string(constructorDeclaration)}")
|
logger.log("visitConstructor : ${ir2string(constructorDeclaration)}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,12 +365,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
if (declaration.descriptor.modality == Modality.ABSTRACT || declaration.body == null)
|
if (declaration.descriptor.modality == Modality.ABSTRACT || declaration.body == null)
|
||||||
return
|
return
|
||||||
|
|
||||||
codegen.function(declaration)
|
codegen.prologue(declaration)
|
||||||
metadator.function(declaration)
|
metadator.function(declaration)
|
||||||
|
|
||||||
using(FunctionScope(declaration)) {
|
using(FunctionScope(declaration)) {
|
||||||
declaration.acceptChildrenVoid(this)
|
declaration.acceptChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
codegen.epilogue(declaration)
|
||||||
|
|
||||||
verifyModule(context.llvmModule)
|
verifyModule(context.llvmModule)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -425,12 +425,11 @@ task array_list1(type: RunKonanTest) {
|
|||||||
goldValue = "OK\n"
|
goldValue = "OK\n"
|
||||||
source = "runtime/collections/array_list1.kt"
|
source = "runtime/collections/array_list1.kt"
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
task moderately_large_array(type: RunKonanTest) {
|
task moderately_large_array(type: RunKonanTest) {
|
||||||
goldValue = "OK\n"
|
goldValue = "0\n"
|
||||||
source = "runtime/collections/moderately_large_array.kt"
|
source = "runtime/collections/moderately_large_array.kt"
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
task catch1(type: RunKonanTest) {
|
task catch1(type: RunKonanTest) {
|
||||||
goldValue = "Before\nCaught Throwable\nDone\n"
|
goldValue = "Before\nCaught Throwable\nDone\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user