From 31c2937acccb785e5647145ce6b0f1d26972a87d Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Tue, 12 Jul 2016 12:07:03 +0300 Subject: [PATCH] translator: add stack variable allocation, refactoring, llvmVariable starts storing Kotlin Name --- translator/src/main/kotlin/main.kt | 1 + .../kotlinnative/translator/FileTranslator.kt | 2 -- .../translator/FunctionCodegen.kt | 12 ++++++---- .../translator/TranslationState.kt | 3 +-- .../translator/VariableManager.kt | 6 ++--- .../translator/llvm/LLVMBuilder.kt | 22 +++++++++++++++++-- .../translator/llvm/LLVMVariable.kt | 2 +- .../translator/llvm/generators.kt | 2 +- .../translator/llvm/types/LLVMTypes.kt | 2 +- 9 files changed, 36 insertions(+), 16 deletions(-) diff --git a/translator/src/main/kotlin/main.kt b/translator/src/main/kotlin/main.kt index 150924f27eb..3fb59218284 100644 --- a/translator/src/main/kotlin/main.kt +++ b/translator/src/main/kotlin/main.kt @@ -21,3 +21,4 @@ fun main(args: Array) { println(FileTranslator(state, files[0]).generateCode()) } + \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index f7e77676d8a..ea4288641ba 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -3,9 +3,7 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.kotlinnative.translator.llvm.LLVMBuilder -import org.kotlinnative.translator.llvm.LLVMVariable import org.kotlinnative.translator.utils.FunctionDescriptor -import java.util.* class FileTranslator(val state: TranslationState, val file: KtFile) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index ab1985e495a..b4cd1255653 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -66,7 +66,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun generateLoadArguments(function: KtNamedFunction) { args?.forEach { - val loadVariable = LLVMVariable("%${it.name}", it.type) + val loadVariable = LLVMVariable("%${it.name}", it.type, it.name) codeBuilder.loadVariable(loadVariable) variableManager.addVariable(it.name, loadVariable, 2) } @@ -76,6 +76,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction when (expr) { is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1) is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth) + is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth) is PsiElement -> evaluateExpression(expr.firstChild, scopeDepth + 1) null -> { variableManager.pullUpwardsLevel(scopeDepth) @@ -141,7 +142,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable { val node = expr.node - return LLVMVariable(node.firstChildNode.text, ::LLVMIntType.invoke()) + return codeBuilder.addConstant(LLVMVariable(node.firstChildNode.text, LLVMIntType())) } private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMVariable? { @@ -168,9 +169,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null when (assignExpression) { - is LLVMVariable -> variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth); + is LLVMVariable -> { + variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth) + return null + } } - codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}"), assignExpression) + codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}", null, identifier.text), assignExpression) return null } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index ac4819ef97c..25ba4de6ab0 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.utils.PathUtil import org.kotlinnative.translator.exceptions.TranslationException -import org.kotlinnative.translator.llvm.LLVMVariable import org.kotlinnative.translator.utils.FunctionDescriptor import java.util.* @@ -36,7 +35,7 @@ class TranslationState(sources: List, disposer: Disposable) { private var hasError = false override fun hasErrors(): Boolean { - return hasError; + return hasError } override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt index 868f536dba8..3490a8d3a99 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt @@ -16,9 +16,9 @@ class VariableManager { fileVariableCollectionTree.forEach { s, stack -> if (!stack.empty() && stack.peek().second >= level) stack.pop() else Unit } } - fun addVariable(name: String, variable: LLVMVariable, level: Int){ - val stack = fileVariableCollectionTree.getOrDefault(String, Stack>()); - stack.push(Pair(variable, level)); + fun addVariable(name: String, variable: LLVMVariable, level: Int) { + val stack = fileVariableCollectionTree.getOrDefault(String, Stack>()) + stack.push(Pair(variable, level)) fileVariableCollectionTree.put(name, stack) } 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 42792ac6d9f..ef8db9da1fc 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -32,6 +32,7 @@ class LLVMBuilder { KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp) KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp) KtTokens.MUL -> firstOp.type!!.operatorTimes(newVar, firstOp, secondOp) + KtTokens.EQ -> throw UnsupportedOperationException() else -> throw UnsupportedOperationException("Unknown binary operator") } @@ -61,8 +62,25 @@ class LLVMBuilder { } fun loadVariable(llvmVariable: LLVMVariable) { - llvmCode.appendln("$llvmVariable.addr = alloca ${llvmVariable.type}, align ${llvmVariable.type?.getAlign()}") - llvmCode.appendln("store ${llvmVariable.type} $llvmVariable, ${llvmVariable.type}* ${llvmVariable.type}.addr, align ${llvmVariable.type?.getAlign()}") + addVariableByRef(llvmVariable, LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName)) + } + + fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) { + llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.getAlign()}") + llvmCode.appendln("store ${targetVariable.type} $targetVariable, ${targetVariable.type}* ${sourceVariable}, align ${targetVariable.type?.getAlign()}") + } + + fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) { + val tmp = getNewVariable(targetVariable.type) + llvmCode.appendln("$tmp = alloca ${tmp.type}, align ${tmp.type?.getAlign()}") + llvmCode.appendln("store ${tmp.type} $sourceVariable, ${tmp.type}* ${tmp}, align ${tmp.type?.getAlign()}") + llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${targetVariable.type}* $tmp, align ${targetVariable.type?.getAlign()}") + } + + fun addConstant(sourceVariable: LLVMVariable): LLVMVariable { + val target = getNewVariable(sourceVariable.type) + addVariableByValue(target, sourceVariable) + return target } override fun toString(): String { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt index f1b59b167d8..c75276444b6 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.LLVMType -class LLVMVariable(val label: String, val type: LLVMType? = null) : LLVMNode() { +class LLVMVariable(val label: String, val type: LLVMType? = null, val kotlinName: String? = null) : LLVMNode() { override fun toString(): String = label 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 04e21709d3e..e3af6ca9de8 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -7,7 +7,7 @@ import org.kotlinnative.translator.utils.FunctionArgument fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnType: LLVMType, declare: Boolean = false) = "${if (declare) "declare" else "define"} $returnType @$name(${ argTypes?.mapIndexed { i: Int, s: FunctionArgument -> - "${s.type} %tmp.${s.name}" + "${s.type} %${s.name}" }?.joinToString() ?: ""})" fun LLVMMapStandardType(type: String): LLVMType = when (type) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMTypes.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMTypes.kt index d08f35c5e38..f66b9bc5504 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMTypes.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMTypes.kt @@ -6,4 +6,4 @@ enum class LLVMTypes { int, double, float, char } -val typesMap = mapOf(Pair(LLVMTypes.int, ::LLVMIntType)); +val typesMap = mapOf(Pair(LLVMTypes.int, ::LLVMIntType))