From 279684f6aaf7bd0c9e01a32e4d73948f6d7a64ca Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Tue, 31 Jan 2017 16:04:57 +0700 Subject: [PATCH] Intermediate results --- .../backend/konan/lower/FunctionInlining.kt | 76 +++++++++++++------ 1 file changed, 54 insertions(+), 22 deletions(-) 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 bb8b55c8e0c..98512ab8939 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 @@ -10,13 +10,14 @@ import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.expressions.IrBlockBody -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrGetValue +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl +import org.jetbrains.kotlin.ir.expressions.impl.inlineStatement import org.jetbrains.kotlin.ir.util.DeepCopyIrTree import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.types.KotlinType //-----------------------------------------------------------------------------// @@ -26,7 +27,25 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// - fun evaluateExpressionParameters(callExpression: IrCall, + fun isLambda(value: IrExpression) : Boolean { + if (value !is IrContainerExpressionBase) return false + if (value.origin != IrStatementOrigin.LAMBDA) return false + return true + } + + //-------------------------------------------------------------------------// + + fun getLambdaStatements(value: IrExpression) : MutableList { + + val statements = (value as IrContainerExpressionBase).statements + val lambdaFunction = statements[0] as IrFunction + val lambdaBody = lambdaFunction.body as IrBlockBody + return lambdaBody.statements + } + + //-------------------------------------------------------------------------// + + fun evaluateParameters(callExpression: IrCall, statements: MutableList): List> { val scope = Scope(callExpression.descriptor as FunctionDescriptor) @@ -35,6 +54,10 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( val parameter = it.first val value = it.second if (value is IrGetValue) return@map it // If value is not an expression - do nothing. + if (isLambda(value)) { + val lambdaStatements = getLambdaStatements(value) + return@map it + } // If value is lambda - d val newVar = scope.createTemporaryVariable(value, "inline", false) // Create new variable and init it with the expression. statements.add(0, newVar) // Add initialization of the new variable in statement list. @@ -46,29 +69,36 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( } + //-------------------------------------------------------------------------// + + fun inlineFunction(irCall: IrCall): IrBlock { + + val functionDescriptor = irCall.descriptor as FunctionDescriptor + val functionDeclaration = context.ir.moduleIndex.functions[functionDescriptor] // Get FunctionDeclaration by FunctionDescriptor. + val copyFuncDeclaration = functionDeclaration!!.accept(DeepCopyIrTree(), null) as IrFunction // Create copy of the function. + + val startOffset = copyFuncDeclaration.startOffset + val endOffset = copyFuncDeclaration.endOffset + val returnType = copyFuncDeclaration.descriptor.returnType!! + val inlineBody = copyFuncDeclaration.body!! as IrBlockBody + val statements = inlineBody.statements + val parameters = evaluateParameters(irCall, statements) // Evaluate parameters representing expression. + + val transformer = ParametersTransformer(parameters) + val irBlock = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements) + irBlock.accept(transformer, null) // Replace parameters with expression. + return irBlock + } + //-------------------------------------------------------------------------// override fun visitCall(expression: IrCall): IrExpression { val functionDescriptor = expression.descriptor as FunctionDescriptor if (!functionDescriptor.isInline) return super.visitCall(expression) // Function is not to be inlined - do nothing. - val functionDeclaration = context.ir.originalModuleIndex - .functions[functionDescriptor] // Get FunctionDeclaration by FunctionDescriptor. + val functionDeclaration = context.ir.moduleIndex.functions[functionDescriptor] // Get FunctionDeclaration by FunctionDescriptor. if (functionDeclaration == null) return super.visitCall(expression) // Function is declared in another module. - val copyFuncDeclaration = functionDeclaration.accept(DeepCopyIrTree(), null) as IrFunction // Create copy of the function. - - val body = copyFuncDeclaration.body!! as IrBlockBody - val startOffset = copyFuncDeclaration.startOffset - val endOffset = copyFuncDeclaration.endOffset - val returnType = copyFuncDeclaration.descriptor.returnType!! - val statements = body.statements - - val parameters = evaluateExpressionParameters(expression, statements) // Evaluate parameters representing expression. - val transformer = ParametersTransformer(parameters) - val irBlock = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements) - irBlock.accept(transformer, null) // Replace parameters with expression. - - return irBlock // Return newly created IrBlock instead of IrCall. + return inlineFunction(expression) // Return newly created IrBlock instead of IrCall. } //-------------------------------------------------------------------------// @@ -90,6 +120,8 @@ internal class ParametersTransformer(val parameterToExpression: List