Two passes inline scheme implemented
This commit is contained in:
+35
-3
@@ -1,5 +1,37 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.ir
|
package org.jetbrains.kotlin.backend.konan.ir
|
||||||
|
|
||||||
/**
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
* Created by jetbrains on 13/01/2017.
|
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||||
*/
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
class IrInlineFunctionBody(startOffset: Int, endOffset: Int, type: KotlinType, origin: IrStatementOrigin? = null):
|
||||||
|
IrContainerExpressionBase(startOffset, endOffset, type, origin), IrBlock {
|
||||||
|
constructor(startOffset: Int, endOffset: Int, type: KotlinType, origin: IrStatementOrigin?, statements: List<IrStatement>) :
|
||||||
|
this(startOffset, endOffset, type, origin) {
|
||||||
|
this.statements.addAll(statements)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitBlock(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
statements.forEach { it.accept(visitor, data) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||||
|
statements.forEachIndexed { i, irStatement ->
|
||||||
|
statements[i] = irStatement.transform(transformer, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
|||||||
+61
-1
@@ -629,6 +629,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
is IrThrow -> return evaluateThrow (value)
|
is IrThrow -> return evaluateThrow (value)
|
||||||
is IrTry -> return evaluateTry (value)
|
is IrTry -> return evaluateTry (value)
|
||||||
is IrStringConcatenation -> return evaluateStringConcatenation(value)
|
is IrStringConcatenation -> return evaluateStringConcatenation(value)
|
||||||
|
is IrInlineFunctionBody -> return evaluateInlineFunction (value)
|
||||||
is IrContainerExpression -> return evaluateContainerExpression(value)
|
is IrContainerExpression -> return evaluateContainerExpression(value)
|
||||||
is IrWhileLoop -> return evaluateWhileLoop (value)
|
is IrWhileLoop -> return evaluateWhileLoop (value)
|
||||||
is IrDoWhileLoop -> return evaluateDoWhileLoop (value)
|
is IrDoWhileLoop -> return evaluateDoWhileLoop (value)
|
||||||
@@ -741,7 +742,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
*/
|
*/
|
||||||
private fun continuationBlock(type: KotlinType,
|
private fun continuationBlock(type: KotlinType,
|
||||||
code: (ContinuationBlock) -> Unit = {}): ContinuationBlock {
|
code: (ContinuationBlock) -> Unit = {}): ContinuationBlock {
|
||||||
val entry = codegen.basicBlock()
|
val entry = codegen.basicBlock("continuation_block")
|
||||||
|
|
||||||
codegen.appendingTo(entry) {
|
codegen.appendingTo(entry) {
|
||||||
val valuePhi = if (type.isUnit()) {
|
val valuePhi = if (type.isUnit()) {
|
||||||
@@ -1479,6 +1480,65 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private inner class InlinedFunctionScope(val inlineBody: IrInlineFunctionBody) : InnerScopeImpl() {
|
||||||
|
|
||||||
|
var bbExit : LLVMBasicBlockRef? = null
|
||||||
|
var resultPhi : LLVMValueRef? = null
|
||||||
|
|
||||||
|
fun getExit(): LLVMBasicBlockRef? {
|
||||||
|
if (bbExit == null) bbExit = codegen.basicBlock("inline_body_exit")
|
||||||
|
return bbExit
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResult(): LLVMValueRef? {
|
||||||
|
if (resultPhi == null) {
|
||||||
|
val bbCurrent = codegen.currentBlock
|
||||||
|
codegen.positionAtEnd(getExit()!!)
|
||||||
|
resultPhi = codegen.phi(codegen.getLLVMType(inlineBody.type))
|
||||||
|
codegen.positionAtEnd(bbCurrent)
|
||||||
|
}
|
||||||
|
return resultPhi
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) {
|
||||||
|
if (KotlinBuiltIns.isUnit(inlineBody.type) == false) {
|
||||||
|
codegen.assignPhis(getResult()!! to value!!)
|
||||||
|
}
|
||||||
|
codegen.br(getExit()!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun evaluateInlineFunction(value: IrInlineFunctionBody): LLVMValueRef {
|
||||||
|
context.log("evaluateInlineFunction : ${value.statements.forEach { ir2string(it) }}")
|
||||||
|
|
||||||
|
val inlinedFunctionScope = InlinedFunctionScope(value)
|
||||||
|
using(inlinedFunctionScope) {
|
||||||
|
value.statements.forEach {
|
||||||
|
generateStatement(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!codegen.isAfterTerminator()) { // TODO should we solve this problem once and for all
|
||||||
|
if (inlinedFunctionScope.resultPhi != null) {
|
||||||
|
codegen.unreachable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inlinedFunctionScope.bbExit != null) {
|
||||||
|
codegen.positionAtEnd(inlinedFunctionScope.bbExit!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inlinedFunctionScope.resultPhi != null) {
|
||||||
|
return inlinedFunctionScope.resultPhi!!
|
||||||
|
} else {
|
||||||
|
return codegen.theUnitInstanceRef.llvm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun evaluateContainerExpression(value: IrContainerExpression): LLVMValueRef {
|
private fun evaluateContainerExpression(value: IrContainerExpression): LLVMValueRef {
|
||||||
context.log("evaluateContainerExpression : ${value.statements.forEach { ir2string(it) }}")
|
context.log("evaluateContainerExpression : ${value.statements.forEach { ir2string(it) }}")
|
||||||
|
|
||||||
|
|||||||
+2
-11
@@ -1,15 +1,14 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.lower
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.getArguments
|
import org.jetbrains.kotlin.backend.konan.ir.getArguments
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
|
||||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
val endOffset = copyFuncDeclaration.endOffset
|
val endOffset = copyFuncDeclaration.endOffset
|
||||||
val returnType = copyFuncDeclaration.descriptor.returnType!!
|
val returnType = copyFuncDeclaration.descriptor.returnType!!
|
||||||
val statements = body.statements
|
val statements = body.statements
|
||||||
val irBlock = IrBlockImpl(startOffset, endOffset, returnType, null, statements) // Create IrBlock containing function statements.
|
val irBlock = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements)
|
||||||
|
|
||||||
val parameterToExpression = expression.getArguments() // Build map parameter -> expression.
|
val parameterToExpression = expression.getArguments() // Build map parameter -> expression.
|
||||||
val parametersTransformer = ParametersTransformer(parameterToExpression)
|
val parametersTransformer = ParametersTransformer(parameterToExpression)
|
||||||
@@ -56,14 +55,6 @@ internal class ParametersTransformer(val parameterToExpression: List <Pair<Param
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
|
||||||
|
|
||||||
val transformedExpression = super.visitReturn(expression) as IrReturn
|
|
||||||
return transformedExpression.value
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
if (descriptor !is ParameterDescriptor) { // TODO do we need this check?
|
if (descriptor !is ParameterDescriptor) { // TODO do we need this check?
|
||||||
|
|||||||
Reference in New Issue
Block a user