From 51d6dfe713d0f9750ce126e8536204f8283f88a9 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Tue, 29 Nov 2016 16:14:29 +0300 Subject: [PATCH] Append all variable allocations to prologue. (#97) --- .../backend/konan/llvm/CodeGenerator.kt | 34 ++++++++++++------- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 6 ++-- backend.native/tests/build.gradle | 5 ++- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index de3679fad8e..8444440d2a1 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -14,12 +14,19 @@ import org.jetbrains.kotlin.types.KotlinType internal class CodeGenerator(override val context: Context) : ContextUtils { var currentFunction:FunctionDescriptor? = null - fun function(declaration: IrFunction) { + fun prologue(declaration: IrFunction) { assert(declaration.body != null) val descriptor = declaration.descriptor 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 if (descriptor is ClassConstructorDescriptor @@ -43,18 +50,15 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { } } - fun fields(descriptor: ClassDescriptor):List = descriptor.fields - private fun prolog(declaration: IrFunction): LLVMValueRef? { - variableIndex = 0 - currentFunction = declaration.descriptor - val fn = declaration.descriptor.llvmFunction.getLlvmValue() - val block = LLVMAppendBasicBlock(fn, "entry")!! - positionAtEnd(block) - function2variables.put(declaration.descriptor, mutableMapOf()) - return fn + fun epilogue(declaration: IrFunction) { + appendingTo(prologueBb!!) { + br(entryBb!!) + } } + fun fields(descriptor: ClassDescriptor):List = descriptor.fields + fun newVar():String = currentFunction!!.tmpVariable() val variablesGlobal = mapOf() @@ -71,6 +75,8 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { val function2variables = mutableMapOf>() + private var prologueBb: LLVMBasicBlockRef? = null + private var entryBb: LLVMBasicBlockRef? = null val FunctionDescriptor.variables: MutableMap 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 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 store(value: LLVMValueRef, ptr: LLVMValueRef): LLVMValueRef = LLVMBuildStore(builder, value, ptr)!! diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 60ef734b4ca..feee8bd1fff 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -224,7 +224,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// override fun visitConstructor(constructorDeclaration: IrConstructor) { - codegen.function(constructorDeclaration) + codegen.prologue(constructorDeclaration) val constructorDescriptor = constructorDeclaration.descriptor val classDescriptor = DescriptorUtils.getContainingClass(constructorDescriptor) val thisPtr = codegen.load(codegen.thisVariable(), codegen.newVar()) @@ -281,6 +281,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid } codegen.ret(thisPtr) + codegen.epilogue(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) return - codegen.function(declaration) + codegen.prologue(declaration) metadator.function(declaration) using(FunctionScope(declaration)) { declaration.acceptChildrenVoid(this) } + codegen.epilogue(declaration) verifyModule(context.llvmModule) } diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index d72339e9ca9..38dc08410d7 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -425,12 +425,11 @@ task array_list1(type: RunKonanTest) { goldValue = "OK\n" source = "runtime/collections/array_list1.kt" } -/* + task moderately_large_array(type: RunKonanTest) { - goldValue = "OK\n" + goldValue = "0\n" source = "runtime/collections/moderately_large_array.kt" } -*/ task catch1(type: RunKonanTest) { goldValue = "Before\nCaught Throwable\nDone\n"