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 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.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.ir.expressions.IrBlock import org.jetbrains.kotlin.ir.expressions.IrBlock
@@ -77,8 +78,8 @@ open class DeepCopyIrTreeWithDeclarations : DeepCopyIrTree() {
copiedVariables[descriptor] ?: descriptor copiedVariables[descriptor] ?: descriptor
override fun visitBlock(expression: IrBlock): IrBlock { override fun visitBlock(expression: IrBlock): IrBlock {
return if (expression is IrInlineFunctionBody) { return if (expression is IrReturnableBlock) {
IrInlineFunctionBody( IrReturnableBlockImpl(
startOffset = expression.startOffset, startOffset = expression.startOffset,
endOffset = expression.endOffset, endOffset = expression.endOffset,
type = expression.type, 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.common.lower.SimpleMemberScope
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.IrReturnableBlock
import org.jetbrains.kotlin.backend.konan.ir.IrReturnableBlockImpl
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
@@ -484,8 +485,8 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: DeclarationDe
//---------------------------------------------------------------------// //---------------------------------------------------------------------//
override fun visitBlock(expression: IrBlock): IrBlock { override fun visitBlock(expression: IrBlock): IrBlock {
return if (expression is IrInlineFunctionBody) { return if (expression is IrReturnableBlock) {
IrInlineFunctionBody( IrReturnableBlockImpl(
startOffset = expression.startOffset, startOffset = expression.startOffset,
endOffset = expression.endOffset, endOffset = expression.endOffset,
type = expression.type, type = expression.type,
@@ -230,8 +230,8 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor<Unit,
} }
override fun visitBlock(expression: IrBlock, data: String) { override fun visitBlock(expression: IrBlock, data: String) {
if (expression is IrInlineFunctionBody) { if (expression is IrReturnableBlockImpl) {
printer.println("INLINE FUNCTION BODY " + expression.descriptor) printer.println("RETURNABLE BLOCK " + expression.descriptor)
indented { super.visitBlock(expression, data) } indented { super.visitBlock(expression, data) }
return return
} }
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.backend.konan.ir 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.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrBlock 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): interface IrReturnableBlock: IrBlock {
IrContainerExpressionBase(startOffset, endOffset, type, origin), IrBlock { val descriptor: CallableDescriptor
constructor(startOffset: Int, endOffset: Int, type: KotlinType, descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List<IrStatement>) : }
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(startOffset, endOffset, type, descriptor, origin) {
this.statements.addAll(statements) this.statements.addAll(statements)
} }
@@ -632,7 +632,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
is IrWhen -> return evaluateWhen (value) is IrWhen -> return evaluateWhen (value)
is IrThrow -> return evaluateThrow (value) is IrThrow -> return evaluateThrow (value)
is IrTry -> return evaluateTry (value) is IrTry -> return evaluateTry (value)
is IrInlineFunctionBody -> return evaluateInlineFunction (value) is IrReturnableBlockImpl -> return evaluateReturnableBlock (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)
@@ -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 bbExit : LLVMBasicBlockRef? = null
var resultPhi : LLVMValueRef? = null var resultPhi : LLVMValueRef? = null
private fun getExit(): LLVMBasicBlockRef { private fun getExit(): LLVMBasicBlockRef {
if (bbExit == null) bbExit = codegen.basicBlock("inline_body_exit") if (bbExit == null) bbExit = codegen.basicBlock("returnable_block_exit")
return bbExit!! return bbExit!!
} }
@@ -1357,14 +1357,14 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
if (resultPhi == null) { if (resultPhi == null) {
val bbCurrent = codegen.currentBlock val bbCurrent = codegen.currentBlock
codegen.positionAtEnd(getExit()) codegen.positionAtEnd(getExit())
resultPhi = codegen.phi(codegen.getLLVMType(inlineBody.type)) resultPhi = codegen.phi(codegen.getLLVMType(returnableBlock.type))
codegen.positionAtEnd(bbCurrent) codegen.positionAtEnd(bbCurrent)
} }
return resultPhi!! return resultPhi!!
} }
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) { 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) super.genReturn(target, value)
return return
} }
@@ -1385,11 +1385,11 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun evaluateInlineFunction(value: IrInlineFunctionBody): LLVMValueRef { private fun evaluateReturnableBlock(value: IrReturnableBlockImpl): LLVMValueRef {
context.log{"evaluateInlineFunction : ${value.statements.forEach { ir2string(it) }}"} context.log{"evaluateReturnableBlock : ${value.statements.forEach { ir2string(it) }}"}
val inlinedFunctionScope = InlinedFunctionScope(value) val returnableBlockScope = ReturnableBlockScope(value)
using(inlinedFunctionScope) { using(returnableBlockScope) {
using(VariableScope()) { using(VariableScope()) {
value.statements.forEach { value.statements.forEach {
generateStatement(it) 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 (bbExit != null) {
if (!codegen.isAfterTerminator()) { // TODO should we solve this problem once and for all if (!codegen.isAfterTerminator()) { // TODO should we solve this problem once and for all
if (inlinedFunctionScope.resultPhi != null) { if (returnableBlockScope.resultPhi != null) {
codegen.unreachable() codegen.unreachable()
} else { } else {
codegen.br(bbExit) codegen.br(bbExit)
@@ -1409,7 +1409,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
codegen.positionAtEnd(bbExit) 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.common.lower.*
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName 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.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
@@ -61,7 +61,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
private abstract class Scope 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() private class LoopScope(val loop: IrLoop): Scope()
@@ -84,14 +84,14 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
override fun lower(irFunction: IrFunction) { override fun lower(irFunction: IrFunction) {
val functionDescriptor = irFunction.descriptor val functionDescriptor = irFunction.descriptor
using(FunctionScope(functionDescriptor)) { using(ReturnableScope(functionDescriptor)) {
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { override fun visitContainerExpression(expression: IrContainerExpression): IrExpression {
if (expression !is IrInlineFunctionBody) if (expression !is IrReturnableBlockImpl)
return super.visitContainerExpression(expression) return super.visitContainerExpression(expression)
using(FunctionScope(expression.descriptor)) { using(ReturnableScope(expression.descriptor)) {
return super.visitContainerExpression(expression) return super.visitContainerExpression(expression)
} }
} }
@@ -132,7 +132,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
expression.transformChildrenVoid(this) expression.transformChildrenVoid(this)
return performHighLevelJump( return performHighLevelJump(
targetScopePredicate = { it is FunctionScope && it.descriptor == expression.returnTarget }, targetScopePredicate = { it is ReturnableScope && it.descriptor == expression.returnTarget },
jump = Return(expression.returnTarget), jump = Return(expression.returnTarget),
startOffset = expression.startOffset, startOffset = expression.startOffset,
endOffset = expression.endOffset, endOffset = expression.endOffset,
@@ -242,7 +242,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
val returnType = descriptor.returnType!! val returnType = descriptor.returnType!!
return when { return when {
returnType.isUnit() || returnType.isNothing() -> irBlock(value, null, returnType) { returnType.isUnit() || returnType.isNothing() -> irBlock(value, null, returnType) {
+irInlineFunctionBody(descriptor) { +irReturnableBlock(descriptor) {
+value +value
} }
+finallyExpression.copy() +finallyExpression.copy()
@@ -253,7 +253,7 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
"tmp${tempIndex++}".synthesizedName, "tmp${tempIndex++}".synthesizedName,
returnType returnType
) )
+irVar(tmp, irInlineFunctionBody(descriptor) { +irVar(tmp, irReturnableBlock(descriptor) {
+irReturn(descriptor, value) +irReturn(descriptor, value)
}) })
+finallyExpression.copy() +finallyExpression.copy()
@@ -290,8 +290,8 @@ internal class FinallyBlocksLowering(val context: Context): FunctionLoweringPass
fun IrBuilderWithScope.irReturn(target: CallableDescriptor, value: IrExpression) = fun IrBuilderWithScope.irReturn(target: CallableDescriptor, value: IrExpression) =
IrReturnImpl(startOffset, endOffset, target, value) IrReturnImpl(startOffset, endOffset, target, value)
inline fun IrBuilderWithScope.irInlineFunctionBody(descriptor: FunctionDescriptor, body: IrBlockBuilder.() -> Unit) = inline fun IrBuilderWithScope.irReturnableBlock(descriptor: FunctionDescriptor, body: IrBlockBuilder.() -> Unit) =
IrInlineFunctionBody(startOffset, endOffset, descriptor.returnType!!, descriptor, null, IrReturnableBlockImpl(startOffset, endOffset, descriptor.returnType!!, descriptor, null,
IrBlockBuilder(context, scope, startOffset, endOffset, null, descriptor.returnType!!) IrBlockBuilder(context, scope, startOffset, endOffset, null, descriptor.returnType!!)
.block(body).statements) .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.isFunctionInvoke
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver 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.descriptors.*
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement 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. 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 inlineFunctionBody = inlineFunction(irCall, functionDeclaration)
val descriptorSubstitutor = copyIrElement.descriptorSubstitutorForExternalScope 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. 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 argumentEvaluationResult = evaluateArguments(irCall, functionDeclaration) // Evaluate expressions passed as arguments.
val parameterSubstituteMap = argumentEvaluationResult.parameterSubstituteMap // As a result we get parameter -> argument map 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 statements = (copyFunctionDeclaration.body as IrBlockBody).statements // IR statements from function copy.
val returnType = copyFunctionDeclaration.descriptor.returnType!! // Substituted return type. 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, startOffset = copyFunctionDeclaration.startOffset,
endOffset = copyFunctionDeclaration.endOffset, endOffset = copyFunctionDeclaration.endOffset,
type = returnType, type = returnType,