From 8369cecda51b37f16c433f52f437dedc50fa720d Mon Sep 17 00:00:00 2001 From: e5l Date: Mon, 18 Jul 2016 16:08:37 +0300 Subject: [PATCH] translator: class allocation --- car_llvmkot/.idea/misc.xml | 6 +- car_llvmkot/kotlib/kotlin_main.ll | 77 +++----------- car_llvmkot/kotlib/memory.ll | 6 -- translator/gradlew | 2 +- .../kotlinnative/translator/ClassCodegen.kt | 62 ++++++----- .../translator/FunctionCodegen.kt | 30 +++--- .../translator/llvm/LLVMBuilder.kt | 100 +++++++++++------- .../translator/llvm/LLVMClassVariable.kt | 2 +- .../translator/llvm/LLVMConstructorCall.kt | 6 -- .../translator/llvm/generators.kt | 2 +- 10 files changed, 128 insertions(+), 165 deletions(-) delete mode 100644 translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstructorCall.kt diff --git a/car_llvmkot/.idea/misc.xml b/car_llvmkot/.idea/misc.xml index 5ed4e021c34..927ee3908fa 100644 --- a/car_llvmkot/.idea/misc.xml +++ b/car_llvmkot/.idea/misc.xml @@ -1,5 +1,10 @@ + + + + + @@ -10,7 +15,6 @@ - diff --git a/car_llvmkot/kotlib/kotlin_main.ll b/car_llvmkot/kotlib/kotlin_main.ll index 666eaf2c981..b562df0a884 100644 --- a/car_llvmkot/kotlib/kotlin_main.ll +++ b/car_llvmkot/kotlib/kotlin_main.ll @@ -1,78 +1,33 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) +declare i8* @malloc_static(i32) attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" } -@CAR_MODE_REMOTE_CONTROL = global i32 1, align 4 -@PROGRAM_DURATIOH_MS = global i32 3000, align 4 -@CAR_MODE_LAST = global i32 2, align 4 -@CAR_MODE_PROGRAMMED = global i32 0, align 4 -%class.MyClass = type { i32, i16, i8 } -define void @MyClass(%class.MyClass* %instance, i32 %i, i16 %j, i8 %k) #0 +%class.Simple = type { i32 } +define void @Simple(%class.Simple* %classvariable.this, i32 %i) #0 { -%instance.addr = alloca %class.MyClass, align 4 +%classvariable.this.addr = alloca %class.Simple, align 4 %i.addr = alloca i32, align 4 store i32 %i, i32* %i.addr, align 4 -%j.addr = alloca i16, align 2 -store i16 %j, i16* %j.addr, align 2 -%k.addr = alloca i8, align 1 -store i8 %k, i8* %k.addr, align 1 %var1 = load i32* %i.addr, align 4 -%var2 = getelementptr inbounds %class.MyClass* %instance.addr, i32 0, i32 0 +%var2 = getelementptr inbounds %class.Simple* %classvariable.this.addr, i32 0, i32 0 store i32 %var1, i32* %var2, align 4 -%var3 = load i16* %j.addr, align 2 -%var4 = getelementptr inbounds %class.MyClass* %instance.addr, i32 0, i32 1 -store i16 %var3, i16* %var4, align 2 -%var5 = load i8* %k.addr, align 1 -%var6 = getelementptr inbounds %class.MyClass* %instance.addr, i32 0, i32 2 -store i8 %var5, i8* %var6, align 1 -%var7 = bitcast %class.MyClass* %instance to i8* -%var8 = bitcast %class.MyClass* %instance.addr to i8* -call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var7, i8* %var8, i64 7, i32 4, i1 false) +%var3 = bitcast %class.Simple* %classvariable.this to i8* +%var4 = bitcast %class.Simple* %classvariable.this.addr to i8* +call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var3, i8* %var4, i64 4, i32 4, i1 false) ret void } -declare void @wait(i32 %i) #0 -define void @engine_program() #0 +define void @a() #0 { -call void @engine_init() -br label %label.while.1 -label.while.1: -%var9 = icmp slt i32 2, 3 -br i1 %var9, label %label.while.2, label %label.while.3 -label.while.2: -call void @engine_forward() -%var10 = load i32* @PROGRAM_DURATIOH_MS, align 4 -call void @wait(i32 %var10) -call void @engine_stop() -call void @engine_backward() -%var11 = load i32* @PROGRAM_DURATIOH_MS, align 4 -call void @wait(i32 %var11) -call void @engine_stop() -call void @engine_turn_right() -%var12 = load i32* @PROGRAM_DURATIOH_MS, align 4 -call void @wait(i32 %var12) -call void @engine_stop() -call void @engine_turn_right() -%var13 = load i32* @PROGRAM_DURATIOH_MS, align 4 -call void @wait(i32 %var13) -call void @engine_stop() -br label %label.while.1 -label.while.3: ret void } -declare void @time_init() #0 -declare void @leds_init() #0 -declare void @engine_init() #0 -declare void @run_rc_car(void ()* %i) #0 -declare void @engine_backward() #0 define void @kotlin_main() #0 { -call void @time_init() -call void @engine_program() +%var6 = call i8* @malloc_static(i32 4) +%var5 = bitcast i8* %var6 to %class.Simple* +call void @Simple(%class.Simple* %var5, i32 5) +%managed.s.1 = alloca %class.Simple, align 4 +%var7 = load %class.Simple* %var5, align 4 +store %class.Simple %var7, %class.Simple* %managed.s.1, align 4 +call void @a() ret void } -declare void @VCP_init() #0 -declare void @engine_stop() #0 -declare void @user_brn_init(void ()* %i) #0 -declare void @engine_forward() #0 -declare void @run_programmed_car(void ()* %i) #0 -declare void @engine_turn_left() #0 -declare void @engine_turn_right() #0 diff --git a/car_llvmkot/kotlib/memory.ll b/car_llvmkot/kotlib/memory.ll index 10b202e0c64..7ec7ad50c57 100644 --- a/car_llvmkot/kotlib/memory.ll +++ b/car_llvmkot/kotlib/memory.ll @@ -81,9 +81,3 @@ define i8* @malloc_dynamic(i32 %size) #0 { attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -!llvm.module.flags = !{!0, !1} -!llvm.ident = !{!2} - -!0 = !{i32 1, !"wchar_size", i32 4} -!1 = !{i32 1, !"min_enum_size", i32 4} -!2 = !{!"Ubuntu clang version 3.6.2-3ubuntu2 (tags/RELEASE_362/final) (based on LLVM 3.6.2)"} diff --git a/translator/gradlew b/translator/gradlew index 9d82f789151..2f205f5ba69 100755 --- a/translator/gradlew +++ b/translator/gradlew @@ -102,7 +102,7 @@ fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:function=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index 27580a26269..fa9479b1786 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -1,22 +1,22 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.KtUserType import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.kotlinnative.translator.exceptions.TranslationException import org.kotlinnative.translator.llvm.* -import org.kotlinnative.translator.llvm.types.* +import org.kotlinnative.translator.llvm.types.LLVMCharType +import org.kotlinnative.translator.llvm.types.LLVMReferenceType +import org.kotlinnative.translator.llvm.types.LLVMType +import org.kotlinnative.translator.llvm.types.LLVMVoidType import java.util.* class ClassCodegen(val state: TranslationState, val variableManager: VariableManager, val clazz: KtClass, val codeBuilder: LLVMBuilder) { val annotation: Boolean - val native: Boolean + val plain: Boolean = false // TODO val fields = ArrayList() val fieldsIndex = HashMap() val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", byRef = true) @@ -33,8 +33,7 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan if (!annotation) { for (field in parameterList) { - val type = getNativeType(field) ?: parseLLVMType((field.typeReference?.typeElement as KtUserType).referencedName!!) - val item = LLVMClassVariable(field.name!!, type, offset) + val item = resolveType(field) fields.add(item) fieldsIndex[item.label] = item @@ -44,7 +43,6 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan } } - native = isNative(descriptor.annotations) size = currentSize } @@ -65,7 +63,7 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan } } val classVal = LLVMVariable("classvariable.this", type, pointer = 1) - variableManager.addVariable("this", classVal, 0); + variableManager.addVariable("this", classVal, 0) for (function in methods.values) { function.generate(classVal) } @@ -84,7 +82,7 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan refType.byRef = true val classVal = LLVMVariable("classvariable.this", type, pointer = 1) - variableManager.addVariable("this", classVal, 0); + variableManager.addVariable("this", classVal, 0) argFields.add(classVal) argFields.addAll(fields) @@ -124,34 +122,40 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan val dst = LLVMVariable("classvariable.this", type, scope = LLVMRegisterScope(), pointer = 1) val src = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1) - val castedDst = codeBuilder.bitcast(dst, LLVMCharType()) - val castedSrc = codeBuilder.bitcast(src, LLVMCharType()) + val castedDst = codeBuilder.bitcast(dst, LLVMVariable("", LLVMCharType(), pointer = 1)) + val castedSrc = codeBuilder.bitcast(src, LLVMVariable("", LLVMCharType(), pointer = 1)) codeBuilder.memcpy(castedDst, castedSrc, size) } - private fun getNativeType(field: KtParameter): LLVMType? { + private fun resolveType(field: KtParameter): LLVMClassVariable { + val annotations = parseFieldAnnotations(field) + + val ktType = state.bindingContext.get(BindingContext.TYPE, field.typeReference)!! + val result = LLVMMapStandardType(field.name!!, ktType, LLVMRegisterScope()) + + if (result.type is LLVMReferenceType) { + (result.type as LLVMReferenceType).prefix = "class" + } + + if (annotations.contains("Plain")) { + result.pointer = 0 + } + + return LLVMClassVariable(result.label, result.type, result.pointer) + } + + private fun parseFieldAnnotations(field: KtParameter): Set { + val result = HashSet() + for (annotation in field.annotationEntries) { val annotationDescriptor = state.bindingContext.get(BindingContext.ANNOTATION, annotation) val type = annotationDescriptor?.type.toString() - if (type == "Native") { - return parseLLVMType(annotationDescriptor!!.argumentValue("type").toString()) - } + + result.add(type) } - return null - } - - private fun isNative(annotations: Annotations?): Boolean { - annotations ?: return false - - for (i in annotations) { - if (i.type.toString() == "Native") { - return true - } - } - - return false + return result } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 1ab7540777d..db14840d093 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -228,7 +228,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable if (state.classes.containsKey(function)) { val descriptor = state.classes[function] ?: return null - return evaluateConstructorCallExpression(function, names, descriptor.type) + return evaluateConstructorCallExpression(LLVMVariable(function, descriptor.type, scope = LLVMVariableScope()), names) } val localFunction = variableManager.getLLVMvalue(function) @@ -259,9 +259,8 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable codeBuilder.addLLVMCode(LLVMCall(LLVMVoidType(), function.toString(), names).toString()) } is LLVMReferenceType -> { - val result = codeBuilder.getNewVariable(returnType) - codeBuilder.allocVar(result) - result.pointer = 1 + val result = codeBuilder.getNewVariable(returnType, pointer = 1) + codeBuilder.allocStaticVar(result) val args = ArrayList() args.add(result) @@ -276,7 +275,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable codeBuilder.addAssignment(result, LLVMCall(returnType, function.toString(), names)) val resultPtr = codeBuilder.getNewVariable(returnType) - codeBuilder.allocVar(resultPtr) + codeBuilder.allocStackVar(resultPtr) resultPtr.pointer = 1 codeBuilder.storeVariable(resultPtr, result) return resultPtr @@ -286,10 +285,9 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable return null } - private fun evaluateConstructorCallExpression(name: String, names: ArrayList, retType: LLVMType): LLVMSingleValue? { - val result = codeBuilder.getNewVariable(retType) - codeBuilder.allocVar(result) - result.pointer = 1 + private fun evaluateConstructorCallExpression(function: LLVMVariable, names: ArrayList): LLVMSingleValue? { + val result = codeBuilder.getNewVariable(function.type, pointer = 1) + codeBuilder.allocStaticVar(result) val args = ArrayList() args.add(result) @@ -297,7 +295,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable codeBuilder.addLLVMCode(LLVMCall( LLVMVoidType(), - name, + function.toString(), args ).toString()) @@ -356,10 +354,6 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable } } - private fun evaluateTypeReferenceAssignment(type: KtUserType, expr: KtConstantExpression) { - - } - private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? { return when (element.elementType) { KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth) @@ -414,7 +408,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable private fun executeIfExpression(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? { val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) val variable = codeBuilder.getNewVariable(LLVMIntType(), pointer = 1) - codeBuilder.allocVar(variable) + codeBuilder.allocStackVar(variable) val thenLabel = codeBuilder.getNewLabel(prefix = "if") val elseLabel = codeBuilder.getNewLabel(prefix = "if") val endLabel = codeBuilder.getNewLabel(prefix = "if") @@ -462,7 +456,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable when (assignExpression) { is LLVMVariable -> { val allocVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type, LLVMRegisterScope(), pointer = 1) - codeBuilder.allocVar(allocVar) + codeBuilder.allocStackVar(allocVar) variableManager.addVariable(identifier.text, allocVar, scopeDepth) copyVariable(assignExpression, allocVar) } @@ -485,8 +479,8 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable when (returnType.type) { is LLVMReferenceType -> { - val src = codeBuilder.bitcast(retVar as LLVMVariable, LLVMCharType()) - val dst = codeBuilder.bitcast(returnType, LLVMCharType()) + val src = codeBuilder.bitcast(retVar as LLVMVariable, LLVMVariable("", LLVMCharType(), pointer = 1)) + val dst = codeBuilder.bitcast(returnType, LLVMVariable("", LLVMCharType(), pointer = 1)) val size = state.classes[(retVar.type as LLVMReferenceType).type]!!.size codeBuilder.memcpy(dst, src, size) codeBuilder.addAnyReturn(LLVMVoidType()) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index f84bc2084cc..bfc33772362 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -2,13 +2,16 @@ package org.kotlinnative.translator.llvm import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.lexer.KtTokens +import org.kotlinnative.translator.llvm.types.LLVMCharType import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMStringType import org.kotlinnative.translator.llvm.types.LLVMType class LLVMBuilder(val arm: Boolean) { - private var llvmLocalCode: StringBuilder = StringBuilder() - private var llvmGlobalCode: StringBuilder = StringBuilder() + private val POINTER_SIZE = 4 + + private var localCode: StringBuilder = StringBuilder() + private var globalCode: StringBuilder = StringBuilder() private var variableCount = 0 private var labelCount = 0 @@ -17,12 +20,15 @@ class LLVMBuilder(val arm: Boolean) { } private fun initBuilder() { - val memcpy = "declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)" - val funcAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }""" - llvmLocalCode.appendln(memcpy) + val declares = arrayOf( + "declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)", + "declare i8* @malloc_static(i32)") + declares.forEach { globalCode.appendln(it) } + + val funcAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }""" if (arm) { - llvmLocalCode.appendln(funcAttributes) + globalCode.appendln(funcAttributes) } } @@ -37,15 +43,15 @@ class LLVMBuilder(val arm: Boolean) { } fun addLLVMCode(code: String) { - llvmLocalCode.appendln(code) + localCode.appendln(code) } fun addStartExpression() { - llvmLocalCode.appendln("{") + localCode.appendln("{") } fun addEndExpression() { - llvmLocalCode.appendln("}") + localCode.appendln("}") } fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue = when (firstOp) { @@ -81,65 +87,66 @@ class LLVMBuilder(val arm: Boolean) { } fun clean() { - llvmLocalCode = StringBuilder() + localCode = StringBuilder() + globalCode = StringBuilder() initBuilder() } fun addAssignment(llvmVariable: LLVMVariable, rhs: LLVMNode) { - llvmLocalCode.appendln("$llvmVariable = $rhs") + localCode.appendln("$llvmVariable = $rhs") } fun addReturnOperator(llvmVariable: LLVMSingleValue) { - llvmLocalCode.appendln("ret ${llvmVariable.type} $llvmVariable") + localCode.appendln("ret ${llvmVariable.type} $llvmVariable") } fun addAnyReturn(type: LLVMType, value: String = type.defaultValue) { - llvmLocalCode.appendln("ret $type $value") + localCode.appendln("ret $type $value") } fun addStringConstant(variable: LLVMVariable, value: String) { val type = variable.type as LLVMStringType - llvmGlobalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1") + globalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1") } fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) { val stringType = source.type as LLVMStringType val code = "store ${target.type} getelementptr inbounds (${stringType.fullType()}, " + "${stringType.fullType()}* $source, i32 0, i32 $offset), ${target.getType()} $target, align ${stringType.align}" - llvmLocalCode.appendln(code) + localCode.appendln(code) } fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) { val code = "$target = getelementptr inbounds ${source.type}* $source, i32 0, i32 $offset" - llvmLocalCode.appendln(code) + localCode.appendln(code) } fun markWithLabel(label: LLVMLabel?) { if (label != null) - llvmLocalCode.appendln("${label.label}:") + localCode.appendln("${label.label}:") } fun addNopInstruction() { - llvmLocalCode.appendln(getNewVariable(LLVMIntType()).toString() + " = add i1 0, 0 ; nop instruction") + localCode.appendln(getNewVariable(LLVMIntType()).toString() + " = add i1 0, 0 ; nop instruction") } fun storeVariable(target: LLVMVariable, source: LLVMSingleValue) { val code = "store ${source.type} $source, ${target.getType()} $target, align ${source.type?.align!!}" - llvmLocalCode.appendln(code) + localCode.appendln(code) } fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) { val code = "$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}" - llvmLocalCode.appendln(code) + localCode.appendln(code) } fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) { var from = source if (source.pointer > 0) { from = getNewVariable(source.type, source.pointer) - llvmLocalCode.appendln("$from = load ${source.getType()} $source, align ${from.type.align}") + localCode.appendln("$from = load ${source.getType()} $source, align ${from.type.align}") } - llvmLocalCode.appendln("store ${target.type} $from, ${target.getType()} $target, align ${from.type.align}") + localCode.appendln("store ${target.type} $from, ${target.getType()} $target, align ${from.type.align}") } fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable { @@ -150,62 +157,73 @@ class LLVMBuilder(val arm: Boolean) { fun loadVariable(target: LLVMVariable, source: LLVMVariable) { val code = "$target = load ${source.getType()} $source, align ${target.type.align}" - llvmLocalCode.appendln(code) + localCode.appendln(code) } - fun allocVar(target: LLVMVariable) { - llvmLocalCode.appendln("$target = alloca ${target.type}, align ${target.type.align}") + fun allocStackVar(target: LLVMVariable) { + localCode.appendln("$target = alloca ${target.type}, align ${target.type.align}") + } + + fun allocStaticVar(target: LLVMVariable) { + val allocedVar = getNewVariable(LLVMCharType(), pointer = 1) + + val size = if (target.pointer > 0) POINTER_SIZE else target.type.size + val alloc = "$allocedVar = call i8* @malloc_static(i32 $size)" + localCode.appendln(alloc) + + val cast = "$target = bitcast ${allocedVar.getType()} $allocedVar to ${target.getType()}" + localCode.appendln(cast) } fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable, store: Boolean) { - llvmLocalCode.appendln("$targetVariable = alloca ${sourceVariable.type}${"*".repeat(sourceVariable.pointer)}, align ${sourceVariable.type.align}") + localCode.appendln("$targetVariable = alloca ${sourceVariable.type}${"*".repeat(sourceVariable.pointer)}, align ${sourceVariable.type.align}") if (store) { - llvmLocalCode.appendln("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type.align}") + localCode.appendln("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type.align}") } } fun addConstant(allocVariable: LLVMVariable, constantValue: LLVMConstant) { - llvmLocalCode.appendln("$allocVariable = alloca ${allocVariable.type}, align ${allocVariable.type.align}") - llvmLocalCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type.align}") + localCode.appendln("$allocVariable = alloca ${allocVariable.type}, align ${allocVariable.type.align}") + localCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type.align}") } fun declareGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) { - llvmLocalCode.appendln("$variable = global ${variable.type} $defaultValue, align ${variable.type.align}") + localCode.appendln("$variable = global ${variable.type} $defaultValue, align ${variable.type.align}") } fun loadAndGetVariable(source: LLVMVariable): LLVMVariable { assert(source.pointer > 0) val target = getNewVariable(source.type, source.pointer, source.kotlinName) val code = "$target = load ${source.getType()} $source, align ${target.type.align}" - llvmLocalCode.appendln(code) + localCode.appendln(code) return target } fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) { - llvmLocalCode.appendln("br ${condition.getType()} $condition, label $thenLabel, label $elseLabel") + localCode.appendln("br ${condition.getType()} $condition, label $thenLabel, label $elseLabel") } fun addUnconditionalJump(label: LLVMLabel) { - llvmLocalCode.appendln("br label $label") + localCode.appendln("br label $label") } fun createClass(name: String, fields: List) { - val code = "%class.$name = type { ${fields.map { it.type }.joinToString()} }" - llvmLocalCode.appendln(code) + val code = "%class.$name = type { ${fields.map { it.getType() }.joinToString()} }" + localCode.appendln(code) } - fun bitcast(src: LLVMVariable, llvmType: LLVMType): LLVMVariable { - val empty = getNewVariable(llvmType, pointer = 1) - val code = "$empty = bitcast ${src.getType()} $src to $llvmType*" - llvmLocalCode.appendln(code) + fun bitcast(src: LLVMVariable, llvmType: LLVMVariable): LLVMVariable { + val empty = getNewVariable(llvmType.type, pointer = llvmType.pointer) + val code = "$empty = bitcast ${src.getType()} $src to ${llvmType.getType()}" + localCode.appendln(code) return empty } fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) { val code = "call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)" - llvmLocalCode.appendln(code) + localCode.appendln(code) } - override fun toString() = llvmGlobalCode.toString() + llvmLocalCode.toString() + override fun toString() = globalCode.toString() + localCode.toString() } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt index b1a0b19593f..fbb697f9616 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt @@ -3,4 +3,4 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.LLVMType -class LLVMClassVariable(label: String, type: LLVMType, val offset: Int = 0) : LLVMVariable(label, type) +class LLVMClassVariable(label: String, type: LLVMType, pointer: Int = 0, val offset: Int = 0) : LLVMVariable(label, type, pointer = pointer) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstructorCall.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstructorCall.kt deleted file mode 100644 index 273ba199631..00000000000 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMConstructorCall.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.kotlinnative.translator.llvm - -import org.kotlinnative.translator.llvm.types.LLVMType - -class LLVMConstructorCall(override val type: LLVMType, val call: (LLVMVariable) -> LLVMCall) : LLVMSingleValue() - diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index c567649f3d6..c771a198549 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -18,4 +18,4 @@ fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMR type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString(), scope) type.isUnit() -> LLVMVariable("", LLVMVoidType(), "", scope) else -> LLVMVariable(name, LLVMReferenceType("$type"), name, scope, pointer = 1) -} \ No newline at end of file +}