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 1d2aa054279..666c41d2208 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 @@ -25,12 +25,12 @@ import org.jetbrains.kotlin.types.typeUtil.makeNullable internal class FunctionInlining(val context: Context): IrElementTransformerVoid() { - var currentFile : IrFile? = null - var currentFunction : IrFunction? = null - var currentScope : Scope? = null + private var currentFile : IrFile? = null + private var currentFunction : IrFunction? = null + private var currentScope : Scope? = null //-------------------------------------------------------------------------// - val deserializer = DeserializerDriver(context) + private val deserializer = DeserializerDriver(context) fun inline(irFile: IrFile) = irFile.accept(this, null) @@ -79,7 +79,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// - fun isLambdaExpression(expression: IrExpression) : Boolean { + private fun isLambdaExpression(expression: IrExpression) : Boolean { if (expression !is IrContainerExpressionBase) return false if (expression.origin != IrStatementOrigin.LAMBDA) return false return true @@ -87,7 +87,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// - fun needsEvaluation(expression: IrExpression): Boolean { + private fun needsEvaluation(expression: IrExpression): Boolean { if (expression is IrGetValue) return false // Parameter is already GetValue - nothing to evaluate. if (expression is IrConst<*>) return false // Parameter is constant - nothing to evaluate. if (expression is IrCallableReference) return false // Parameter is CallableReference - nothing to evaluate. @@ -98,25 +98,27 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// - fun getArguments(irCall: IrCall, declaration: IrFunction): MutableMap { - val result = mutableMapOf() + private class ArgumentWithValue(val descriptor: ValueDescriptor, val value: IrExpression) + + private fun getArguments(irCall: IrCall, declaration: IrFunction): MutableList { + val result = mutableListOf() val descriptor = irCall.descriptor.original irCall.dispatchReceiver?.let { - result[descriptor.dispatchReceiverParameter!!] = it + result += ArgumentWithValue(descriptor.dispatchReceiverParameter!!, it) } irCall.extensionReceiver?.let { - result[descriptor.extensionReceiverParameter!!] = it + result += ArgumentWithValue(descriptor.extensionReceiverParameter!!, it) } descriptor.valueParameters.forEach { parameter -> val argument = irCall.getValueArgument(parameter.index) if (argument != null) { - result[parameter] = argument + result += ArgumentWithValue(parameter, argument) } else { val defaultArgument = declaration.getDefault(parameter)!!.expression - result[parameter] = defaultArgument + result += ArgumentWithValue(parameter, defaultArgument) } } @@ -125,12 +127,14 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// - fun evaluateParameters(parametersOld: MutableMap, - statements: MutableList): MutableMap { + private class EvaluatedParameters(val parameters: MutableMap, val statements: MutableList) + + private fun evaluateParameters(parametersOld: MutableList): EvaluatedParameters { val parametersNew = mutableMapOf () + val statements = mutableListOf() parametersOld.forEach { - val parameter = it.key.original as ValueDescriptor + val parameter = it.descriptor.original as ValueDescriptor val argument = it.value if (!needsEvaluation(argument)) { @@ -140,17 +144,16 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( val varName = currentScope!!.scopeOwner.name.toString() + "_inline" val newVar = currentScope!!.createTemporaryVariable(argument, varName, false) // Create new variable and init it with the parameter expression. - statements.add(0, newVar) // Add initialization of the new variable in statement list. + statements.add(newVar) // Add initialization of the new variable in statement list. val getVal = IrGetValueImpl(0, 0, newVar.descriptor) // Create new IR element representing access the new variable. parametersNew[parameter] = getVal // Parameter will be replaced with the new variable. } - return parametersNew + return EvaluatedParameters(parametersNew, statements) } //-------------------------------------------------------------------------// - - fun inlineFunction(irCall: IrCall): IrExpression { + private fun inlineFunction(irCall: IrCall): IrExpression { val functionDescriptor = irCall.descriptor as FunctionDescriptor val originalDescriptor = functionDescriptor.original val functionDeclaration = @@ -169,9 +172,10 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( val statements = blockBody.statements val inlineBody = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements) - val evaluationStatements = mutableListOf() val parametersOld = getArguments(irCall, copyFuncDeclaration) // Create map call_site_argument -> inline_function_parameter. - val parameterToArgument = evaluateParameters(parametersOld, evaluationStatements) + val evaluatedParameters = evaluateParameters(parametersOld) + val parameterToArgument = evaluatedParameters.parameters + val evaluationStatements = evaluatedParameters.statements val lambdaInliner = LambdaInliner(parameterToArgument) inlineBody.transformChildrenVoid(lambdaInliner) @@ -185,7 +189,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// - inner class ParametersTransformer(val substituteMap: MutableMap , + private inner class ParametersTransformer(val substituteMap: MutableMap , val typeArgsMap: Map ?, val statements: MutableList): IrElementTransformerVoid() { @@ -243,7 +247,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// - fun newVariable(oldVariable: IrVariable): IrVariable { + private fun newVariable(oldVariable: IrVariable): IrVariable { val initializer = oldVariable.initializer!! val isMutable = oldVariable.descriptor.isVar val varName = currentScope!!.scopeOwner.name.toString() + "_inline" @@ -324,13 +328,13 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //-------------------------------------------------------------------------// - inner class LambdaInliner(val substituteMap: MutableMap ): IrElementTransformerVoid() { + private inner class LambdaInliner(val substituteMap: MutableMap ): IrElementTransformerVoid() { override fun visitElement(element: IrElement) = element.accept(this, null) //---------------------------------------------------------------------// - fun isLambdaCall(irCall: IrCall) : Boolean { + private fun isLambdaCall(irCall: IrCall) : Boolean { if (!(irCall.descriptor as FunctionDescriptor).isFunctionInvoke) return false // If it is lambda call. if (irCall.dispatchReceiver !is IrGetValue) return false // Do not process such dispatch receiver. return true @@ -338,7 +342,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// - fun getLambdaFunction(lambdaArgument: IrExpression): IrFunction? { + private fun getLambdaFunction(lambdaArgument: IrExpression): IrFunction? { if (lambdaArgument !is IrBlock) return null if (lambdaArgument.origin != IrStatementOrigin.ANONYMOUS_FUNCTION && @@ -368,28 +372,25 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( //---------------------------------------------------------------------// - fun buildParameterToArgument(lambdaFunction: IrFunction, irCall: IrCall): MutableMap { + private fun buildParameterToArgument(lambdaFunction: IrFunction, irCall: IrCall): MutableList { val descriptor = lambdaFunction.descriptor - val parameterToArgument = mutableMapOf() + val parameterToArgument = mutableListOf() irCall.extensionReceiver?.let { - val parameter = descriptor.extensionReceiverParameter!! - val argument = it - parameterToArgument[parameter] = argument + parameterToArgument += ArgumentWithValue(descriptor.extensionReceiverParameter!!, it) } val parameters = descriptor.valueParameters // Get lambda function parameters. parameters.forEach { // Iterate parameters. - val parameter = it val argument = irCall.getValueArgument(it.index) // Get corresponding argument. - parameterToArgument[parameter] = argument!! // Create (parameter -> argument) pair. + parameterToArgument += ArgumentWithValue(it, argument!!) // Create (parameter -> argument) pair. } return parameterToArgument } //---------------------------------------------------------------------// - fun inlineLambda(irCall: IrCall): IrExpression { + private fun inlineLambda(irCall: IrCall): IrExpression { val dispatchReceiver = irCall.dispatchReceiver as IrGetValue // val lambdaArgument = substituteMap[dispatchReceiver.descriptor] // Find expression to replace this parameter. @@ -403,8 +404,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid( if (lambdaFunction == null) return super.visitCall(irCall) // TODO val parametersOld = buildParameterToArgument(lambdaFunction, irCall) - val evaluationStatements = mutableListOf() - val parameterToArgument = evaluateParameters(parametersOld, evaluationStatements) + val evaluatedParameters = evaluateParameters(parametersOld) + val parameterToArgument = evaluatedParameters.parameters + val evaluationStatements = evaluatedParameters.statements val copyLambdaFunction = lambdaFunction.accept(InlineCopyIr(), // Create copy of the function. null) as IrFunction