From 53b243c9f8279b378ff7ea30fbc02936332fbb19 Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Thu, 30 Nov 2017 17:52:19 +0300 Subject: [PATCH] 1) Do not inline in function declared as "inline" 2) Evaluate all arguments except lambdas --- .../backend/konan/lower/FunctionInlining.kt | 68 +++++++++++++------ backend.native/tests/build.gradle | 5 ++ .../tests/codegen/inline/inline26.kt | 13 ++++ 3 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 backend.native/tests/codegen/inline/inline26.kt 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 0e79a92804b..0f1cd14227f 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 @@ -68,21 +68,31 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW override fun visitCall(expression: IrCall): IrExpression { - val irCall = super.visitCall(expression) as IrCall - val functionDescriptor = irCall.descriptor - if (!functionDescriptor.needsInlining) return irCall // This call does not need inlining. + val functionDescriptor = expression.descriptor + if (!functionDescriptor.needsInlining) return super.visitCall(expression) // This call does not need inlining. + if (isInlineFunctionScope()) return super.visitCall(expression) // Ignore inlining in functions declared as "inline" - val functionDeclaration = getFunctionDeclaration(irCall) // Get declaration of the function to be inlined. + val functionDeclaration = getFunctionDeclaration(expression) // Get declaration of the function to be inlined. if (functionDeclaration == null) { // We failed to get the declaration. val message = "Inliner failed to obtain function declaration: " + functionDescriptor.fqNameSafe.toString() - context.reportWarning(message, currentFile, irCall) // Report warning. - return irCall + context.reportWarning(message, currentFile, expression) // Report warning. + return super.visitCall(expression) } - functionDeclaration.transformChildrenVoid(this) // Process recursive inline. val inliner = Inliner(globalSubstituteMap, functionDeclaration, currentScope!!, context) // Create inliner for this scope. - return inliner.inline(irCall ) // Return newly created IrInlineBody instead of IrCall. + val inlinedFunctionBody = inliner.inline(expression) // Return newly created IrInlineBody instead of IrCall. + inlinedFunctionBody.transformChildrenVoid(this) + return inlinedFunctionBody + } + + //-------------------------------------------------------------------------// + + private fun isInlineFunctionScope(): Boolean { + if (currentFunction == null) return false + val scopeOwner = currentFunction!!.scope.scopeOwner + if (scopeOwner !is FunctionDescriptor) return false + return scopeOwner.isInline } //-------------------------------------------------------------------------// @@ -226,21 +236,35 @@ private class Inliner(val globalSubstituteMap: MutableMap Unit, noinline block2: () -> Int): Int { + block1() + return block2() +} + +@Test fun runTest() { + var x = 5 + println(call({ x = 7 }, x::toInt)) +}