translator: add pointer modificator, fixes for stack allocation, refactoring

This commit is contained in:
Alexey Stepanov
2016-07-12 13:54:10 +03:00
parent d17c8922b8
commit 1a76a916a6
12 changed files with 52 additions and 30 deletions
-1
View File
@@ -21,4 +21,3 @@ fun main(args: Array<String>) {
println(FileTranslator(state, files[0]).generateCode()) println(FileTranslator(state, files[0]).generateCode())
} }
@@ -66,7 +66,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
private fun generateLoadArguments(function: KtNamedFunction) { private fun generateLoadArguments(function: KtNamedFunction) {
args?.forEach { args?.forEach {
val loadVariable = LLVMVariable("%${it.name}", it.type, it.name) val loadVariable = LLVMVariable("%${it.name}", it.type, it.name, true)
codeBuilder.loadVariable(loadVariable) codeBuilder.loadVariable(loadVariable)
variableManager.addVariable(it.name, loadVariable, 2) variableManager.addVariable(it.name, loadVariable, 2)
} }
@@ -142,7 +142,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable { private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable {
val node = expr.node val node = expr.node
return codeBuilder.addConstant(LLVMVariable(node.firstChildNode.text, LLVMIntType())) return codeBuilder.addConstant(LLVMVariable(node.firstChildNode.text, LLVMIntType(), pointer = false))
} }
private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMVariable? { private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMVariable? {
@@ -168,9 +168,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
val eq = identifier?.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val eq = identifier?.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
when (assignExpression) { when (assignExpression) {
is LLVMVariable -> { is LLVMVariable -> {
variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth) assignExpression.kotlinName = identifier!!.text
assignExpression.pointer = false
variableManager.addVariable(identifier.text, assignExpression, scopeDepth)
return null return null
} }
} }
@@ -34,9 +34,7 @@ class TranslationState(sources: List<String>, disposer: Disposable) {
val messageCollector = GroupingMessageCollector(object : MessageCollector { val messageCollector = GroupingMessageCollector(object : MessageCollector {
private var hasError = false private var hasError = false
override fun hasErrors(): Boolean { override fun hasErrors(): Boolean = hasError
return hasError
}
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
println("[report] $message") println("[report] $message")
@@ -9,9 +9,9 @@ class LLVMBuilder {
private var llvmCode: StringBuilder = StringBuilder() private var llvmCode: StringBuilder = StringBuilder()
private var variableCount = 0 private var variableCount = 0
fun getNewVariable(type: LLVMType?): LLVMVariable { fun getNewVariable(type: LLVMType?, pointer: Boolean = false): LLVMVariable {
variableCount++ variableCount++
return LLVMVariable("%var$variableCount", type) return LLVMVariable("%var$variableCount", type, pointer = pointer)
} }
fun addLLVMCode(code: String) { fun addLLVMCode(code: String) {
@@ -32,7 +32,7 @@ class LLVMBuilder {
KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp) KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp)
KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp) KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp)
KtTokens.MUL -> firstOp.type!!.operatorTimes(newVar, firstOp, secondOp) KtTokens.MUL -> firstOp.type!!.operatorTimes(newVar, firstOp, secondOp)
KtTokens.EQ -> throw UnsupportedOperationException() KtTokens.EQ -> return moveVariableValue(secondOp, firstOp)
else -> throw UnsupportedOperationException("Unknown binary operator") else -> throw UnsupportedOperationException("Unknown binary operator")
} }
@@ -41,6 +41,21 @@ class LLVMBuilder {
return newVar return newVar
} }
private fun moveVariableValue(from: LLVMVariable, to: LLVMVariable): LLVMVariable {
//%0 = load i32, i32* %y, align 4
//store i32 %0, i32* %z, align 4
//%1 = load i32, i32* %z, align 4
llvmCode.appendln("VARIABLE from $from TO $to")
/*
val tmp1 = getNewVariable(from.type)
val tmp2 = getNewVariable(to.type)
llvmCode.appendln("$tmp1 = load ${tmp1.type}, ${tmp1.type}* $from, align ${tmp1.type?.align}")
llvmCode.appendln("store ${tmp1.type} $tmp1, ${to.type}* $to, align ${to.type?.align}")
llvmCode.appendln("$tmp2 = load ${tmp2.type}, ${tmp2.type}* $to, align ${to.type?.align}")*/
return from
}
fun clean() { fun clean() {
llvmCode = StringBuilder() llvmCode = StringBuilder()
} }
@@ -50,7 +65,7 @@ class LLVMBuilder {
} }
fun addReturnOperator(llvmVariable: LLVMVariable) { fun addReturnOperator(llvmVariable: LLVMVariable) {
llvmCode.appendln("ret i32 $llvmVariable") llvmCode.appendln("ret ${llvmVariable.type} $llvmVariable")
} }
fun addVoidReturn() { fun addVoidReturn() {
@@ -58,30 +73,32 @@ class LLVMBuilder {
} }
fun loadVariable(llvmVariable: LLVMVariable) { fun loadVariable(llvmVariable: LLVMVariable) {
addVariableByRef(llvmVariable, LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName)) addVariableByRef(llvmVariable, LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, true))
} }
fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) { fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.getAlign()}") llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.align}")
llvmCode.appendln("store ${targetVariable.type} $targetVariable, ${targetVariable.type}* $sourceVariable, align ${targetVariable.type?.getAlign()}") llvmCode.appendln("store ${sourceVariable.type} $targetVariable, ${targetVariable.getType()} $sourceVariable, align ${targetVariable.type?.align}")
} }
fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) { fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
val tmp = getNewVariable(targetVariable.type) val tmp = getNewVariable(targetVariable.type, pointer = true)
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("$tmp = alloca ${tmp.type}, align ${tmp.type?.align}")
llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${targetVariable.type}* $tmp, align ${targetVariable.type?.getAlign()}") llvmCode.appendln("store ${tmp.type} $sourceVariable, ${tmp.getType()} $tmp, align ${tmp.type?.align}")
llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${tmp.getType()} $tmp, align ${targetVariable.type?.align}")
} }
fun addConstant(sourceVariable: LLVMVariable): LLVMVariable { fun addConstant(sourceVariable: LLVMVariable): LLVMVariable {
val target = getNewVariable(sourceVariable.type) val target = getNewVariable(sourceVariable.type, pointer = sourceVariable.pointer)
addVariableByValue(target, sourceVariable) addVariableByValue(target, sourceVariable)
return target return target
} }
fun createClass(name: String, fields: List<LLVMVariable>) { fun createClass(name: String, fields: List<LLVMVariable>) {
val code = "@class.$name = type { ${ fields.map { it.type }.joinToString() } }" val code = "@class.$name = type { ${fields.map { it.type }.joinToString()} }"
llvmCode.appendln(code) llvmCode.appendln(code)
} }
@@ -2,8 +2,10 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMType
open class LLVMVariable(val label: String, val type: LLVMType? = null, val kotlinName: String? = null) : LLVMNode() { open class LLVMVariable(val label: String, val type: LLVMType? = null, var kotlinName: String? = null, var pointer: Boolean = false) : LLVMNode() {
override fun toString(): String = label override fun toString(): String = label
fun getType(): String = type.toString() + if (pointer) "*" else ""
} }
@@ -4,4 +4,6 @@ class LLVMCharType() : LLVMType() {
override fun toString(): String = "i8" override fun toString(): String = "i8"
override val align = 1
} }
@@ -20,5 +20,5 @@ class LLVMDoubleType() : LLVMType() {
override fun toString() = "double" override fun toString() = "double"
override fun getAlign() = 8 override val align = 8
} }
@@ -20,5 +20,6 @@ class LLVMIntType() : LLVMType() {
override fun toString() = "i32" override fun toString() = "i32"
override fun getAlign() = 4 override val align = 4
} }
@@ -12,13 +12,11 @@ class LLVMReferenceType(val type: String) : LLVMType() {
throw UnsupportedOperationException("not implemented") throw UnsupportedOperationException("not implemented")
} }
override fun getAlign(): Int {
throw UnsupportedOperationException("not implemented")
}
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
throw UnsupportedOperationException("not implemented") throw UnsupportedOperationException("not implemented")
} }
override fun toString() = type override fun toString() = type
override val align = -1
} }
@@ -4,4 +4,5 @@ class LLVMShortType() : LLVMType() {
override fun toString(): String = "i16" override fun toString(): String = "i16"
override val align = 1
} }
@@ -11,7 +11,7 @@ abstract class LLVMType() {
open fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException() open fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
open fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException() open fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
open fun getAlign(): Int = throw UnimplementedException() abstract val align: Int
} }
fun parseLLVMType(type: String): LLVMType = when (type) { fun parseLLVMType(type: String): LLVMType = when (type) {
@@ -2,7 +2,8 @@ package org.kotlinnative.translator.llvm.types
class LLVMVoidType() : LLVMType() { class LLVMVoidType() : LLVMType() {
override fun getAlign(): Int = 0 override val align = 0
override fun toString(): String = "void" override fun toString(): String = "void"
} }