Renamed IrInlineFunctionBody to IrReturnableBlock

This commit is contained in:
Igor Chevdar
2017-05-04 15:07:26 +05:00
parent 667b5fb936
commit 1d9ccb36f3
7 changed files with 46 additions and 38 deletions
@@ -16,7 +16,8 @@
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlock
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlockImpl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.ir.expressions.IrBlock
@@ -77,8 +78,8 @@ open class DeepCopyIrTreeWithDeclarations : DeepCopyIrTree() {
copiedVariables[descriptor] ?: descriptor
override fun visitBlock(expression: IrBlock): IrBlock {
return if (expression is IrInlineFunctionBody) {
IrInlineFunctionBody(
return if (expression is IrReturnableBlock) {
IrReturnableBlockImpl(
startOffset = expression.startOffset,
endOffset = expression.endOffset,
type = expression.type,
@@ -18,7 +18,8 @@ package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.backend.common.lower.SimpleMemberScope
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlock
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlockImpl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.ir.IrElement
@@ -484,8 +485,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: DeclarationDe
//---------------------------------------------------------------------//
override fun visitBlock(expression: IrBlock): IrBlock {
return if (expression is IrInlineFunctionBody) {
IrInlineFunctionBody(
return if (expression is IrReturnableBlock) {
IrReturnableBlockImpl(
startOffset = expression.startOffset,
endOffset = expression.endOffset,
type = expression.type,
@@ -230,8 +230,8 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor<Unit,
}
override fun visitBlock(expression: IrBlock, data: String) {
if (expression is IrInlineFunctionBody) {
printer.println("INLINE FUNCTION BODY " + expression.descriptor)
if (expression is IrReturnableBlockImpl) {
printer.println("RETURNABLE BLOCK " + expression.descriptor)
indented { super.visitBlock(expression, data) }
return
}
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.backend.konan.ir
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrBlock
@@ -30,9 +30,15 @@ import org.jetbrains.kotlin.types.KotlinType
//-----------------------------------------------------------------------------//
class IrInlineFunctionBody(startOffset: Int, endOffset: Int, type: KotlinType, val descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null):
IrContainerExpressionBase(startOffset, endOffset, type, origin), IrBlock {
constructor(startOffset: Int, endOffset: Int, type: KotlinType, descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List<IrStatement>) :
interface IrReturnableBlock: IrBlock {
val descriptor: CallableDescriptor
}
class IrReturnableBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType,
override val descriptor: CallableDescriptor, origin: IrStatementOrigin? = null)
: IrContainerExpressionBase(startOffset, endOffset, type, origin), IrReturnableBlock {
constructor(startOffset: Int, endOffset: Int, type: KotlinType,
descriptor: CallableDescriptor, origin: IrStatementOrigin?, statements: List<IrStatement>) :
this(startOffset, endOffset, type, descriptor, origin) {
this.statements.addAll(statements)
}
@@ -632,7 +632,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
is IrWhen -> return evaluateWhen (value)
is IrThrow -> return evaluateThrow (value)
is IrTry -> return evaluateTry (value)
is IrInlineFunctionBody -> return evaluateInlineFunction (value)
is IrReturnableBlockImpl -> return evaluateReturnableBlock (value)
is IrContainerExpression -> return evaluateContainerExpression (value)
is IrWhileLoop -> return evaluateWhileLoop (value)
is IrDoWhileLoop -> return evaluateDoWhileLoop (value)
@@ -1343,13 +1343,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private inner class InlinedFunctionScope(val inlineBody: IrInlineFunctionBody) : InnerScopeImpl() {
private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : InnerScopeImpl() {
var bbExit : LLVMBasicBlockRef? = null
var resultPhi : LLVMValueRef? = null
private fun getExit(): LLVMBasicBlockRef {
if (bbExit == null) bbExit = codegen.basicBlock("inline_body_exit")
if (bbExit == null) bbExit = codegen.basicBlock("returnable_block_exit")
return bbExit!!
}
@@ -1357,14 +1357,14 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
if (resultPhi == null) {
val bbCurrent = codegen.currentBlock
codegen.positionAtEnd(getExit())
resultPhi = codegen.phi(codegen.getLLVMType(inlineBody.type))
resultPhi = codegen.phi(codegen.getLLVMType(returnableBlock.type))
codegen.positionAtEnd(bbCurrent)
}
return resultPhi!!
}
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) {
if (target != inlineBody.descriptor) { // It is not our "local return".
if (target != returnableBlock.descriptor) { // It is not our "local return".
super.genReturn(target, value)
return
}
@@ -1385,11 +1385,11 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------//
private fun evaluateInlineFunction(value: IrInlineFunctionBody): LLVMValueRef {
context.log{"evaluateInlineFunction : ${value.statements.forEach { ir2string(it) }}"}
private fun evaluateReturnableBlock(value: IrReturnableBlockImpl): LLVMValueRef {
context.log{"evaluateReturnableBlock : ${value.statements.forEach { ir2string(it) }}"}
val inlinedFunctionScope = InlinedFunctionScope(value)
using(inlinedFunctionScope) {
val returnableBlockScope = ReturnableBlockScope(value)
using(returnableBlockScope) {
using(VariableScope()) {
value.statements.forEach {
generateStatement(it)
@@ -1397,10 +1397,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
}
}
val bbExit = inlinedFunctionScope.bbExit
val bbExit = returnableBlockScope.bbExit
if (bbExit != null) {
if (!codegen.isAfterTerminator()) { // TODO should we solve this problem once and for all
if (inlinedFunctionScope.resultPhi != null) {
if (returnableBlockScope.resultPhi != null) {
codegen.unreachable()
} else {
codegen.br(bbExit)
@@ -1409,7 +1409,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
codegen.positionAtEnd(bbExit)
}
return inlinedFunctionScope.resultPhi ?: codegen.theUnitInstanceRef.llvm
return returnableBlockScope.resultPhi ?: codegen.theUnitInstanceRef.llvm
}
//-------------------------------------------------------------------------//
@@ -5,7 +5,7 @@ import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlockImpl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
@@ -61,7 +61,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
private abstract class Scope
private class FunctionScope(val descriptor: FunctionDescriptor): Scope()
private class ReturnableScope(val descriptor: CallableDescriptor): Scope()
private class LoopScope(val loop: IrLoop): Scope()
@@ -84,14 +84,14 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
override fun lower(irFunction: IrFunction) {
val functionDescriptor = irFunction.descriptor
using(FunctionScope(functionDescriptor)) {
using(ReturnableScope(functionDescriptor)) {
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitContainerExpression(expression: IrContainerExpression): IrExpression {
if (expression !is IrInlineFunctionBody)
if (expression !is IrReturnableBlockImpl)
return super.visitContainerExpression(expression)
using(FunctionScope(expression.descriptor)) {
using(ReturnableScope(expression.descriptor)) {
return super.visitContainerExpression(expression)
}
}
@@ -132,7 +132,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
expression.transformChildrenVoid(this)
return performHighLevelJump(
targetScopePredicate = { it is FunctionScope && it.descriptor == expression.returnTarget },
targetScopePredicate = { it is ReturnableScope && it.descriptor == expression.returnTarget },
jump = Return(expression.returnTarget),
startOffset = expression.startOffset,
endOffset = expression.endOffset,
@@ -242,7 +242,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
val returnType = descriptor.returnType!!
return when {
returnType.isUnit() || returnType.isNothing() -> irBlock(value, null, returnType) {
+irInlineFunctionBody(descriptor) {
+irReturnableBlock(descriptor) {
+value
}
+finallyExpression.copy()
@@ -253,7 +253,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
"tmp${tempIndex++}".synthesizedName,
returnType
)
+irVar(tmp, irInlineFunctionBody(descriptor) {
+irVar(tmp, irReturnableBlock(descriptor) {
+irReturn(descriptor, value)
})
+finallyExpression.copy()
@@ -290,8 +290,8 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
fun IrBuilderWithScope.irReturn(target: CallableDescriptor, value: IrExpression) =
IrReturnImpl(startOffset, endOffset, target, value)
inline fun IrBuilderWithScope.irInlineFunctionBody(descriptor: FunctionDescriptor, body: IrBlockBuilder.() -> Unit) =
IrInlineFunctionBody(startOffset, endOffset, descriptor.returnType!!, descriptor, null,
inline fun IrBuilderWithScope.irReturnableBlock(descriptor: FunctionDescriptor, body: IrBlockBuilder.() -> Unit) =
IrReturnableBlockImpl(startOffset, endOffset, descriptor.returnType!!, descriptor, null,
IrBlockBuilder(context, scope, startOffset, endOffset, null, descriptor.returnType!!)
.block(body).statements)
}
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlockImpl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
@@ -97,7 +97,7 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
//-------------------------------------------------------------------------//
fun inline(irCall : IrCall, // Call to be substituted.
functionDeclaration: IrFunction): IrInlineFunctionBody { // Function to substitute.
functionDeclaration: IrFunction): IrReturnableBlockImpl { // Function to substitute.
val inlineFunctionBody = inlineFunction(irCall, functionDeclaration)
val descriptorSubstitutor = copyIrElement.descriptorSubstitutorForExternalScope
@@ -108,7 +108,7 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
//-------------------------------------------------------------------------//
private fun inlineFunction(irCall : IrCall, // Call to be substituted.
functionDeclaration: IrFunction): IrInlineFunctionBody { // Function to substitute.
functionDeclaration: IrFunction): IrReturnableBlockImpl { // Function to substitute.
val argumentEvaluationResult = evaluateArguments(irCall, functionDeclaration) // Evaluate expressions passed as arguments.
val parameterSubstituteMap = argumentEvaluationResult.parameterSubstituteMap // As a result we get parameter -> argument map
@@ -121,7 +121,7 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
val statements = (copyFunctionDeclaration.body as IrBlockBody).statements // IR statements from function copy.
val returnType = copyFunctionDeclaration.descriptor.returnType!! // Substituted return type.
val inlineFunctionBody = IrInlineFunctionBody( // Create new IR element to replace "call".
val inlineFunctionBody = IrReturnableBlockImpl( // Create new IR element to replace "call".
startOffset = copyFunctionDeclaration.startOffset,
endOffset = copyFunctionDeclaration.endOffset,
type = returnType,