diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt index abcb92800f5..62096a4acc2 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt @@ -1,5 +1,6 @@ package org.jetbrains.kotlin.backend.konan.ir +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.expressions.IrBlock import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin @@ -10,10 +11,10 @@ import org.jetbrains.kotlin.types.KotlinType //-----------------------------------------------------------------------------// -class IrInlineFunctionBody(startOffset: Int, endOffset: Int, type: KotlinType, origin: IrStatementOrigin? = null): +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, origin: IrStatementOrigin?, statements: List) : - this(startOffset, endOffset, type, origin) { + constructor(startOffset: Int, endOffset: Int, type: KotlinType, descriptor: FunctionDescriptor, 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 7e44fa0bd11..85728355451 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 @@ -152,6 +152,16 @@ internal interface CodeContext { */ fun genGetValue(descriptor: ValueDescriptor): LLVMValueRef + /** + * Gets the exit block for the context owned by specified descriptor. + */ + fun getExit(descriptor: CallableDescriptor): LLVMBasicBlockRef + + /** + * Gets the result value for the context owned by specified descriptor. + */ + fun getResult(descriptor: CallableDescriptor): LLVMValueRef + /** * Returns owning function scope. * @@ -198,6 +208,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid override fun genGetValue(descriptor: ValueDescriptor) = unsupported(descriptor) + override fun getExit(descriptor: CallableDescriptor): LLVMBasicBlockRef = unsupported(descriptor) + + override fun getResult(descriptor: CallableDescriptor): LLVMValueRef = unsupported(descriptor) + override fun functionScope(): CodeContext = unsupported() } @@ -1381,15 +1395,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid var bbExit : LLVMBasicBlockRef? = null var resultPhi : LLVMValueRef? = null - fun getExit(): LLVMBasicBlockRef { + override fun getExit(descriptor: CallableDescriptor): LLVMBasicBlockRef { + if (descriptor != inlineBody.descriptor) + return super.getExit(descriptor) if (bbExit == null) bbExit = codegen.basicBlock("inline_body_exit") return bbExit!! } - fun getResult(): LLVMValueRef { + override fun getResult(descriptor: CallableDescriptor): LLVMValueRef { + if (descriptor != inlineBody.descriptor) + return super.getResult(descriptor) if (resultPhi == null) { val bbCurrent = codegen.currentBlock - codegen.positionAtEnd(getExit()) + codegen.positionAtEnd(getExit(descriptor)) resultPhi = codegen.phi(codegen.getLLVMType(inlineBody.type)) codegen.positionAtEnd(bbCurrent) } @@ -1402,10 +1420,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid return } // It is local return. - codegen.br(getExit()!!) // Generate branch on exit block. + codegen.br(getExit(target)!!) // Generate branch on exit block. - if (KotlinBuiltIns.isUnit(inlineBody.type) == false) { // If function returns more then "unit" - codegen.assignPhis(getResult() to value!!) // Assign return value to result PHI node. + if (!KotlinBuiltIns.isUnit(inlineBody.type)) { // If function returns more then "unit" + codegen.assignPhis(getResult(target) to value!!) // Assign return value to result PHI node. } } } 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 666c41d2208..90100496ac6 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 @@ -170,7 +170,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( if (copyFuncDeclaration.body == null) return irCall // TODO workaround val blockBody = copyFuncDeclaration.body!! as IrBlockBody val statements = blockBody.statements - val inlineBody = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements) + val inlineBody = IrInlineFunctionBody(startOffset, endOffset, returnType, originalDescriptor, null, statements) val parametersOld = getArguments(irCall, copyFuncDeclaration) // Create map call_site_argument -> inline_function_parameter. val evaluatedParameters = evaluateParameters(parametersOld) @@ -412,7 +412,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( null) as IrFunction val lambdaStatements = (copyLambdaFunction.body as IrBlockBody).statements val lambdaReturnType = copyLambdaFunction.descriptor.returnType!! - val inlineBody = IrInlineFunctionBody(0, 0, lambdaReturnType, null, lambdaStatements) + val inlineBody = IrInlineFunctionBody(0, 0, lambdaReturnType, lambdaFunction.descriptor, null, lambdaStatements) val transformer = ParametersTransformer(parameterToArgument, null, lambdaStatements) inlineBody.accept(transformer, null) // Replace parameters with expression. @@ -442,6 +442,7 @@ class InlineCopyIr() : DeepCopyIrTree() { IrInlineFunctionBody( expression.startOffset, expression.endOffset, expression.type, + expression.descriptor, mapStatementOrigin(expression.origin), expression.statements.map { it.transform(this, null) } )