diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDeclarations.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDeclarations.kt index a7c1b46db2a..a09224e0166 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDeclarations.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDeclarations.kt @@ -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, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt index b63e6ef02c6..d59fa939dc0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt @@ -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, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/DumpIrTreeWithDescriptorsVisitor.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/DumpIrTreeWithDescriptorsVisitor.kt index 65367104254..1d73a41c02a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/DumpIrTreeWithDescriptorsVisitor.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/DumpIrTreeWithDescriptorsVisitor.kt @@ -230,8 +230,8 @@ class DumpIrTreeWithDescriptorsVisitor(out: Appendable): IrElementVisitor) : +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) : this(startOffset, endOffset, type, descriptor, origin) { this.statements.addAll(statements) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 6e0a18c9229..ca3e07d9cf6 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -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 } //-------------------------------------------------------------------------// diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FinallyBlocksLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FinallyBlocksLowering.kt index b5170f98f73..d4c77f5bc07 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FinallyBlocksLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FinallyBlocksLowering.kt @@ -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) } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 6139c84fd95..c2c4664b4b5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -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,