Append all variable allocations to prologue. (#97)

This commit is contained in:
Nikolay Igotti
2016-11-29 16:14:29 +03:00
committed by GitHub
parent 075562f46b
commit 51d6dfe713
3 changed files with 28 additions and 17 deletions
@@ -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)!!
@@ -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)
} }
+2 -3
View File
@@ -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"