From f6c9a4ad6b40f345d1b169125bde087e5731628e Mon Sep 17 00:00:00 2001 From: Vasily Levchenko Date: Fri, 23 Sep 2016 18:18:41 +0300 Subject: [PATCH] translator-bc: takeplacers for bc/ir generators (to move from desktop to laptop) --- .../translator/llvm/LLVMBuilder.kt | 489 ++++++++++-------- .../translator/llvm/bc/BcLlvmBuilder.kt | 104 ++++ .../translator/llvm/ir/IrLlvmBuilder.kt | 141 +++++ 3 files changed, 513 insertions(+), 221 deletions(-) create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/bc/BcLlvmBuilder.kt create mode 100644 experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/ir/IrLlvmBuilder.kt diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index 894419bdc56..7db2931a596 100644 --- a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -1,252 +1,299 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.TranslationState +import org.kotlinnative.translator.llvm.bc.BcLlvmBuilder +import org.kotlinnative.translator.llvm.ir.IrLlvmBuilder import org.kotlinnative.translator.llvm.types.* import java.rmi.UnexpectedException import java.util.* class LLVMBuilder(arm: Boolean = false) { - - private val localCode: StringBuilder = StringBuilder() - private val globalCode: StringBuilder = StringBuilder() private var variableCount = 0 private var labelCount = 0 - private val exceptions = mapOf( - Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException"))) + val ir = IrLlvmBuilder() + val bc = BcLlvmBuilder() - init { - val declares = arrayOf( - "declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)", - "declare i8* @malloc_heap(i32)", - "declare i32 @printf(i8*, ...)", - "declare void @abort()", - "%class.Nothing = type { }") + fun addComment(comment: String) { + ir.comment(comment) + bc.comment(comment) + //addLLVMCodeToLocalPlace("; " + comment) + } - declares.forEach { addLLVMCodeToGlobalPlace(it) } + fun addStartExpression() { + ir.startExpression() + bc.startExpression() + //addLLVMCodeToLocalPlace("{") + } - if (arm) { - val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }""" - addLLVMCodeToGlobalPlace(functionAttributes) + fun addEndExpression() { + ir.endExpression() + bc.endExpression() + //addLLVMCodeToLocalPlace("unreachable\n}") + } + + fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) { + ir.assignment(lhs, rhs) + bc.assignment(lhs, rhs) + //addLLVMCodeToLocalPlace("$lhs = $rhs") + } + + fun addReturnOperator(llvmVariable: LLVMSingleValue) { + ir.returnOperation(llvmVariable) + bc.returnOperation(llvmVariable) + //addLLVMCodeToLocalPlace("ret ${llvmVariable.type} $llvmVariable") + } + + fun addAnyReturn(type: LLVMType, value: String = type.defaultValue, pointer: Int = 0) { + ir.anyReturn(type, value, pointer) + bc.anyReturn(type, value, pointer) + //addLLVMCodeToLocalPlace("ret $type${"*".repeat(pointer)} $value") + } + + fun addStringConstant(variable: LLVMVariable, value: String) { + ir.stringConstant(variable, value) + bc.stringConstant(variable, value) + //addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1") + } + + fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) { + ir.conditionalBranch(condition, thenLabel, elseLabel) + bc.conditionalBranch(condition, thenLabel, elseLabel) + //addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel") } - } - fun addLLVMCodeToLocalPlace(code: String) = - localCode.appendln(code) - - fun addLLVMCodeToGlobalPlace(code: String) = - globalCode.appendln(code) - - fun addComment(comment: String) = - addLLVMCodeToLocalPlace("; " + comment) - - fun addStartExpression() = - addLLVMCodeToLocalPlace("{") - - fun addEndExpression() = - addLLVMCodeToLocalPlace("unreachable\n}") - - fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) = - addLLVMCodeToLocalPlace("$lhs = $rhs") - - fun addReturnOperator(llvmVariable: LLVMSingleValue) = - addLLVMCodeToLocalPlace("ret ${llvmVariable.type} $llvmVariable") - - fun addAnyReturn(type: LLVMType, value: String = type.defaultValue, pointer: Int = 0) = - addLLVMCodeToLocalPlace("ret $type${"*".repeat(pointer)} $value") - - fun addStringConstant(variable: LLVMVariable, value: String) = - addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1") - - fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) = - addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel") - - fun addUnconditionalJump(label: LLVMLabel) = - addLLVMCodeToLocalPlace("br label $label") - - fun addExceptionCall(exceptionName: String) { - val exception = exceptions[exceptionName] - val printResult = getNewVariable(LLVMIntType(), pointer = 0) - addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))") - addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList()) - } - - fun addFunctionCall(functionName: LLVMVariable, arguments: List) = - addLLVMCodeToLocalPlace("call ${functionName.type} $functionName(${arguments.joinToString { it -> "${it.type} $it" }})") - - fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) { - val type = if (asValue) target.type.toString() else target.pointedType - addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}") - } - - fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) { - val allocated = getNewVariable(LLVMCharType(), pointer = 1) - val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.POINTER_SIZE else target.type.size - - addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)") - addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*") - } - - fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList, initializers: Map, classType: LLVMType) { - val code = "$target = internal global $classType { ${ - fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString() - } }, align ${classType.align}" - addLLVMCodeToGlobalPlace(code) - } - - fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int): LLVMVariable { - val empty = getNewVariable(llvmType, pointer = pointer) - addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.toString() + "*".repeat(pointer)}") - return empty - } - - fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue { - var resultVariable = variable - if (variable.type != targetType) { - val convertedExpression = targetType.convertFrom(variable) - resultVariable = saveExpression(convertedExpression) + fun addUnconditionalJump(label: LLVMLabel) { + ir.unconditionalBranch(label) + bc.unconditionalBranch(label) + //addLLVMCodeToLocalPlace("br label $label") } - return resultVariable - } - fun copyVariable(from: LLVMVariable, to: LLVMVariable) = - when { - from.type is LLVMStringType && !from.type.isLoaded -> storeString(to, from, 0) - else -> copyVariableValue(to, from) + fun addExceptionCall(exceptionName: String) { + ir.abort(exceptionName) + bc.abort(exceptionName) + /* + val exception = exceptions[exceptionName] + val printResult = getNewVariable(LLVMIntType(), pointer = 0) + addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))") + addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList()) + */ + } + + fun addFunctionCall(functionName: LLVMVariable, arguments: List) { + ir.call(functionName, arguments) + bc.call(functionName, arguments) + //addLLVMCodeToLocalPlace("call ${functionName.type} $functionName(${arguments.joinToString { it -> "${it.type} $it" }})") + } + + fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) { + ir.alloca(target, asValue, pointer) + bc.alloca(target, asValue, pointer) + /* + val type = if (asValue) target.type.toString() else target.pointedType + addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}") + */ + } + + fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) { + ir.heapAndCast(target, asValue, pointer) + bc.heapAndCall(target, asValue, pointer) + /* + val allocated = getNewVariable(LLVMCharType(), pointer = 1) + val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.POINTER_SIZE else target.type.size + + addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)") + addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*") + */ + } + + fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList, initializers: Map, classType: LLVMType) { + ir.globalinitialize(target, fields, initializers, classType) + bc.globalInitialize(target, fields, initializers, classType) + /* + val code = "$target = internal global $classType { ${ + fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString() + } }, align ${classType.align}" + addLLVMCodeToGlobalPlace(code) + */ + } + + fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int): LLVMVariable { + ir.bitcast(src, llvmType, pointer) + bc.bitcast(src, llvmType, pointer) + /* + val empty = getNewVariable(llvmType, pointer = pointer) + addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.toString() + "*".repeat(pointer)}") + return empty + */ + } + + fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue { + var resultVariable = variable + if (variable.type != targetType) { + val convertedExpression = targetType.convertFrom(variable) + resultVariable = saveExpression(convertedExpression) + } + return resultVariable + } + + fun copyVariable(from: LLVMVariable, to: LLVMVariable) = + when { + from.type is LLVMStringType && !from.type.isLoaded -> storeString(to, from, 0) + else -> copyVariableValue(to, from) + } + + fun createClass(name: String, fields: List) { + ir.classDeclaration(name, fields) + bc.classDeclaration(name, fields) + //addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }") + } + + fun declareEntryPoint(name: String) { + TODO("not that it's required") + /* + addLLVMCodeToLocalPlace("define weak void @main()") + addStartExpression() + addFunctionCall(LLVMVariable(name, LLVMVoidType(), scope = LLVMVariableScope()), listOf()) + addAnyReturn(LLVMVoidType()) + addEndExpression() + */ + } + + fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) { + ir.globalDeclaration(variable, defaultValue) + bc.globalDeclaration(variable, defaultValue) + //addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}") + } + + fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null, scope: LLVMScope = LLVMRegisterScope(), prefix: String = "var"): LLVMVariable { + variableCount++ + return LLVMVariable("$prefix$variableCount", type, kotlinName, scope, pointer) + } + + fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel { + labelCount++ + return LLVMLabel("label.$prefix.$labelCount", scope) + } + + fun loadArgsIfRequired(names: List, args: List) = + names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue { + return receivePointedArgument(value, args[i].pointer) + }).toList() + + fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable { + val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1) + allocStackVar(allocVar, asValue = false, pointer = true) + if (store) { + storeVariable(allocVar, llvmVariable) + } + return allocVar + } + + fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) { + ir.loadClassField(target, source, offset) + bc.loadClassField(target, source, offset) + //addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset") + } + + fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) { + ir.loadVariableOffset(target, source, index) + bc.loadVariableOffset(target, source, index) + //addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}") + } + + fun loadAndGetVariable(source: LLVMVariable): LLVMVariable { + assert(source.pointer > 0) + val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName) + ir.load(source) + bc.load(source) + //addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}") + + return target + } + + fun makeStructInitializer(args: List, values: List) { + ir.structInitializer(args, values) + bc.structInitializer(args, values) + // = "{ ${args.mapIndexed { i: Int, variable: LLVMVariable -> "${variable.type} ${values[i]}" }.joinToString()} }" + } + + fun markWithLabel(label: LLVMLabel?) { + label ?: return + ir.label(label) + bc.label(label) + //addLLVMCodeToLocalPlace("${label.label}:") + } + + fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) { + //addLLVMCodeToLocalPlace("call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)") + ir.memcpy(castedDst, castedSrc, size, align, volatile) + bc.memcpy(castedDst, castedSrc, size, align, volatile) + } + + fun nullCheck(variable: LLVMVariable): LLVMVariable { + val result = getNewVariable(LLVMBooleanType(), pointer = 0) + val loaded = loadAndGetVariable(variable) + addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded") + return result + } + + fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue = + when { + firstOp is LLVMConstant || firstOp.pointer == 0 -> firstOp + firstOp is LLVMVariable -> loadAndGetVariable(firstOp) + else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue") + } + + fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue { + var result = value + + while (result.pointer > requirePointer) { + result = receiveNativeValue(result) } - fun createClass(name: String, fields: List) = - addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }") - - fun declareEntryPoint(name: String) { - addLLVMCodeToLocalPlace("define weak void @main()") - addStartExpression() - addFunctionCall(LLVMVariable(name, LLVMVoidType(), scope = LLVMVariableScope()), listOf()) - addAnyReturn(LLVMVoidType()) - addEndExpression() - } - - fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) = - addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}") - - fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null, scope: LLVMScope = LLVMRegisterScope(), prefix: String = "var"): LLVMVariable { - variableCount++ - return LLVMVariable("$prefix$variableCount", type, kotlinName, scope, pointer) - } - - fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel { - labelCount++ - return LLVMLabel("label.$prefix.$labelCount", scope) - } - - fun loadArgsIfRequired(names: List, args: List) = - names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue { - return receivePointedArgument(value, args[i].pointer) - }).toList() - - fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable { - val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1) - allocStackVar(allocVar, asValue = false, pointer = true) - if (store) { - storeVariable(allocVar, llvmVariable) - } - return allocVar - } - - fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) = - addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset") - - fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) = - addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}") - - fun loadAndGetVariable(source: LLVMVariable): LLVMVariable { - assert(source.pointer > 0) - val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName) - addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}") - return target - } - - fun makeStructInitializer(args: List, values: List) - = "{ ${args.mapIndexed { i: Int, variable: LLVMVariable -> "${variable.type} ${values[i]}" }.joinToString()} }" - - fun markWithLabel(label: LLVMLabel?) { - if (label != null) - addLLVMCodeToLocalPlace("${label.label}:") - } - - fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) = - addLLVMCodeToLocalPlace("call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)") - - fun nullCheck(variable: LLVMVariable): LLVMVariable { - val result = getNewVariable(LLVMBooleanType(), pointer = 0) - val loaded = loadAndGetVariable(variable) - addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded") - return result - } - - fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue = - when { - firstOp is LLVMConstant || firstOp.pointer == 0 -> firstOp - firstOp is LLVMVariable -> loadAndGetVariable(firstOp) - else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue") + if ((value.type is LLVMStringType) && !(value.type.isLoaded)) { + val newVariable = getNewVariable(value.type, pointer = result.pointer + 1) + allocStackVar(newVariable, asValue = true) + copyVariable(result as LLVMVariable, newVariable) + result = loadAndGetVariable(newVariable) } - fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue { - var result = value - - while (result.pointer > requirePointer) { - result = receiveNativeValue(result) + return result } - if ((value.type is LLVMStringType) && !(value.type.isLoaded)) { - val newVariable = getNewVariable(value.type, pointer = result.pointer + 1) - allocStackVar(newVariable, asValue = true) - copyVariable(result as LLVMVariable, newVariable) - result = loadAndGetVariable(newVariable) + fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) { + val code = "store ${target.type} getelementptr inbounds (" + + "${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}" + (target.type as LLVMStringType).isLoaded = true + addLLVMCodeToLocalPlace(code) } - return result - } + fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) { + if ((source.type is LLVMStringType) && !(source.type.isLoaded)) { + storeString(target as LLVMVariable, source as LLVMVariable, 0) + } else { + addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}") + } + } - fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) { - val code = "store ${target.type} getelementptr inbounds (" + - "${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}" - (target.type as LLVMStringType).isLoaded = true - addLLVMCodeToLocalPlace(code) - } + fun saveExpression(expression: LLVMSingleValue): LLVMVariable { + val resultOp = getNewVariable(expression.type, pointer = expression.pointer) + addAssignment(resultOp, expression) + return resultOp + } - fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) { - if ((source.type is LLVMStringType) && !(source.type.isLoaded)) { - storeString(target as LLVMVariable, source as LLVMVariable, 0) - } else { - addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}") + fun storeNull(result: LLVMVariable) = + addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.POINTER_ALIGN}") + + override fun toString() = globalCode.toString() + localCode.toString() + + private fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) { + var from = source + if (source.pointer > 0) { + from = getNewVariable(source.type, source.pointer) + addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}") + } + addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}") } } - - fun saveExpression(expression: LLVMSingleValue): LLVMVariable { - val resultOp = getNewVariable(expression.type, pointer = expression.pointer) - addAssignment(resultOp, expression) - return resultOp - } - - fun storeNull(result: LLVMVariable) = - addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.POINTER_ALIGN}") - - override fun toString() = globalCode.toString() + localCode.toString() - - private fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) { - var from = source - if (source.pointer > 0) { - from = getNewVariable(source.type, source.pointer) - addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}") - } - addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}") - } - - private fun initializeExceptionString(string: String): LLVMVariable { - val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.") - addStringConstant(result, string) - return result - } - } \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/bc/BcLlvmBuilder.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/bc/BcLlvmBuilder.kt new file mode 100644 index 00000000000..ecf84e4a8f5 --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/bc/BcLlvmBuilder.kt @@ -0,0 +1,104 @@ +package org.kotlinnative.translator.llvm.bc + +import org.kotlinnative.translator.llvm.* +import org.kotlinnative.translator.llvm.types.LLVMType +import java.util.* + +/** + * Created by minamoto on 23/09/2016. + */ +class BcLlvmBuilder { + fun comment(comment: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun startExpression() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun endExpression() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun assignment(lhs: LLVMVariable, rhs: LLVMNode) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun returnOperation(llvmVariable: LLVMSingleValue) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun anyReturn(type: LLVMType, value: String, pointer: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun stringConstant(variable: LLVMVariable, value: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun conditionalBranch(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun unconditionalBranch(label: LLVMLabel) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun abort(exceptionName: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun call(functionName: LLVMVariable, arguments: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun alloca(target: LLVMVariable, asValue: Boolean, pointer: Boolean) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun heapAndCall(target: LLVMVariable, asValue: Boolean, pointer: Boolean) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun globalInitialize(target: LLVMVariable, fields: ArrayList, initializers: Map, classType: LLVMType) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun classDeclaration(name: String, fields: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun globalDeclaration(variable: LLVMVariable, defaultValue: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun load(source: LLVMVariable) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun label(label: LLVMLabel) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun structInitializer(args: List, values: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int, volatile: Boolean) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + +} \ No newline at end of file diff --git a/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/ir/IrLlvmBuilder.kt b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/ir/IrLlvmBuilder.kt new file mode 100644 index 00000000000..1ce88f4994e --- /dev/null +++ b/experiments/translator-bc/src/main/kotlin/org/kotlinnative/translator/llvm/ir/IrLlvmBuilder.kt @@ -0,0 +1,141 @@ +package org.kotlinnative.translator.llvm.ir + +import org.kotlinnative.translator.llvm.* +import org.kotlinnative.translator.llvm.types.LLVMStringType +import org.kotlinnative.translator.llvm.types.LLVMType +import java.util.* + +/** + * Created by minamoto on 23/09/2016. + */ +class IrLlvmBuilder { + private val localCode: StringBuilder = StringBuilder() + private val globalCode: StringBuilder = StringBuilder() + private val arm = true /* architecture specific TBD */ + private val exceptions = mapOf( + Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException"))) + + + init { + val declares = arrayOf( + "declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)", + "declare i8* @malloc_heap(i32)", + "declare i32 @printf(i8*, ...)", + "declare void @abort()", + "%class.Nothing = type { }") + + declares.forEach { addLLVMCodeToGlobalPlace(it) } + + if (arm) { + val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }""" + addLLVMCodeToGlobalPlace(functionAttributes) + } + } + + fun addLLVMCodeToLocalPlace(code: String) = + localCode.appendln(code) + + fun addLLVMCodeToGlobalPlace(code: String) = + globalCode.appendln(code) + + private fun initializeExceptionString(string: String): LLVMVariable { + TODO() + /* + val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.") + addStringConstant(result, string) + return result + */ + } + + fun comment(comment: String) { + TODO() + } + + fun startExpression() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun endExpression() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun assignment(lhs: LLVMVariable, rhs: LLVMNode) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun returnOperation(llvmVariable: LLVMSingleValue) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun anyReturn(type: LLVMType, value: String, pointer: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun stringConstant(variable: LLVMVariable, value: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun conditionalBranch(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun unconditionalBranch(label: LLVMLabel) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun abort(exceptionName: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun call(functionName: LLVMVariable, arguments: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun alloca(target: LLVMVariable, asValue: Boolean, pointer: Boolean) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun heapAndCast(target: LLVMVariable, asValue: Boolean, pointer: Boolean) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun globalinitialize(target: LLVMVariable, fields: ArrayList, initializers: Map, classType: LLVMType) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun classDeclaration(name: String, fields: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun globalDeclaration(variable: LLVMVariable, defaultValue: String) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun load(source: LLVMVariable) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun label(label: LLVMLabel) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun structInitializer(args: List, values: List) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int, volatile: Boolean) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} \ No newline at end of file