From 22b74c0a3a6b24f0181ad35eb63c5ec4024fdbff Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Tue, 14 Mar 2017 17:19:06 +0700 Subject: [PATCH] New tests added --- .../backend/konan/lower/FunctionInlining.kt | 64 +++++++++---------- backend.native/tests/build.gradle | 10 +++ .../tests/codegen/inline/inline13.kt | 15 +++++ .../tests/codegen/inline/inline22.kt | 15 +++++ 4 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 backend.native/tests/codegen/inline/inline13.kt create mode 100644 backend.native/tests/codegen/inline/inline22.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 9f0c6f97f9e..e54cf68d914 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 @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.util.DeepCopyIrTree import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.types.KotlinType //-----------------------------------------------------------------------------// @@ -70,7 +71,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( val functionDescriptor = expression.descriptor as FunctionDescriptor if (functionDescriptor.isInline) { val inlineFunctionBody = inlineFunction(expression) -// inlineFunctionBody.accept(this, null) // +// inlineFunctionBody.transformChildrenVoid(this) // TODO return inlineFunctionBody // Return newly created IrInlineBody instead of IrCall. } @@ -86,9 +87,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( .functions[functionDescriptor.original] // Get FunctionDeclaration by FunctionDescriptor. if (functionDeclaration == null) return irCall // Function is declared in another module. - print(" inline file: ${currentFile!!.fileEntry.name} ") // TODO debug output - print("function: ${currentFunction!!.descriptor.name} ") // TODO debug output - println("call: ${functionDescriptor.name} ${irCall.startOffset}") // TODO debug output +// print(" inline file: ${currentFile!!.fileEntry.name} ") // TODO debug output +// print("function: ${currentFunction!!.descriptor.name} ") // TODO debug output +// println("call: ${functionDescriptor.name} ${irCall.startOffset}") // TODO debug output val copyFuncDeclaration = functionDeclaration.accept(DeepCopyIrTree(), // Create copy of the function. null) as IrFunction @@ -102,17 +103,16 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( val statements = blockBody.statements val inlineBody = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements) - val parameterToArgument: MutableList > = irCall.getArguments().toMutableList() - val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments // If there are no type args - do nothing. + val lambdaInliner = LambdaInliner(parameterToArgument) + inlineBody.transformChildrenVoid(lambdaInliner) + + val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments val statementsBuf = mutableListOf() val transformer = ParametersTransformer(parameterToArgument, typeArgsMap, statementsBuf) - inlineBody.accept(transformer, null) // Replace parameters with expression. + inlineBody.transformChildrenVoid(transformer) // Replace parameters with expression. inlineBody.statements.addAll(0, statementsBuf) - val lambdaInliner = LambdaInliner(parameterToArgument) - inlineBody.accept(lambdaInliner, null) - return inlineBody } @@ -251,51 +251,51 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// - fun getLambdaFunction(lambdaArgument: IrExpression): IrFunction? { - if (lambdaArgument !is IrBlock) return null + fun getLambdaFunction(lambdaArgument: IrExpression): IrFunction? { + if (lambdaArgument !is IrBlock) return null - if (lambdaArgument.origin != IrStatementOrigin.ANONYMOUS_FUNCTION && - lambdaArgument.origin != IrStatementOrigin.LAMBDA) { + if (lambdaArgument.origin != IrStatementOrigin.ANONYMOUS_FUNCTION && + lambdaArgument.origin != IrStatementOrigin.LAMBDA) { - return null - } + return null + } - // TODO: the following checks must be asserts, however it is not sane until the bugs are fixed. + // TODO: the following checks must be asserts, however it is not sane until the bugs are fixed. - val statements = lambdaArgument.statements - if (statements.size != 2) return null + val statements = lambdaArgument.statements + if (statements.size != 2) return null - val irFunction = statements[0] - if (irFunction !is IrFunction) return null // TODO + val irFunction = statements[0] + if (irFunction !is IrFunction) return null // TODO - val irCallableReference = statements[1] - if (irCallableReference !is IrCallableReference || + val irCallableReference = statements[1] + if (irCallableReference !is IrCallableReference || irCallableReference.descriptor.original != irFunction.descriptor || irCallableReference.getArguments().isNotEmpty()) { - return null - } + return null + } - return irFunction - } + return irFunction + } //---------------------------------------------------------------------// fun inlineLambda(irCall: IrCall): IrExpression { val dispatchReceiver = irCall.dispatchReceiver as IrGetValue // - val substitute = substituteMap.find { // Find expression to replace this parameter. + val substitute = substituteMap.find { // Find expression to replace this parameter. it.first == dispatchReceiver.descriptor } if (substitute == null) return super.visitCall(irCall) // It is not function parameter - nothing to substitute. - val lambdaArgument = substitute.second - val lambdaFunction = getLambdaFunction(lambdaArgument) + val lambdaArgument = substitute.second + val lambdaFunction = getLambdaFunction(lambdaArgument) - if (lambdaFunction == null) return super.visitCall(irCall) // TODO + if (lambdaFunction == null) return super.visitCall(irCall) // TODO val parameters = lambdaFunction.descriptor.valueParameters // Get lambda function parameters. - val substituteMap = parameters.map { // Iterate parameters. + val substituteMap = parameters.map { // Iterate parameters. val parameter = it as ValueDescriptor val argument = irCall.getValueArgument(it.index) // Get corresponding argument. parameter to argument!! // Create (parameter -> argument) pair. diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 5de5e7e6f48..ac24fa906f8 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1454,6 +1454,11 @@ task inline10(type: RunKonanTest) { source = "codegen/inline/inline10.kt" } +task inline13(type: RunKonanTest) { + goldValue = "true\n" + source = "codegen/inline/inline13.kt" +} + task inline14(type: RunKonanTest) { goldValue = "9\n" source = "codegen/inline/inline14.kt" @@ -1498,6 +1503,11 @@ task inline21(type: RunKonanTest) { source = "codegen/inline/inline21.kt" } +task inline22(type: RunKonanTest) { + goldValue = "14\n" + source = "codegen/inline/inline22.kt" +} + kotlinNativeInterop { sysstat { pkg 'sysstat' diff --git a/backend.native/tests/codegen/inline/inline13.kt b/backend.native/tests/codegen/inline/inline13.kt new file mode 100644 index 00000000000..5770496d1f2 --- /dev/null +++ b/backend.native/tests/codegen/inline/inline13.kt @@ -0,0 +1,15 @@ +open class A() +class B() : A() + +@Suppress("NOTHING_TO_INLINE") +inline fun > foo(f: Any?): Boolean { + return f is T? +} + +fun bar(): Boolean { + return foo>(B()) +} + +fun main(args: Array) { + println(bar().toString()) +} diff --git a/backend.native/tests/codegen/inline/inline22.kt b/backend.native/tests/codegen/inline/inline22.kt new file mode 100644 index 00000000000..ed5e046c586 --- /dev/null +++ b/backend.native/tests/codegen/inline/inline22.kt @@ -0,0 +1,15 @@ +inline fun foo2(i2: Int): Int { + return i2 + 3 +} + +inline fun foo1(i1: Int): Int { + return foo2(i1) +} + +fun bar(): Int { + return foo1(11) +} + +fun main(args: Array) { + println(bar().toString()) +}