Separate inlined by IR inliner arguments into two categories

First category of arguments is those that present at call site, and
second category is for those that are default.
This commit is contained in:
Ivan Kylchik
2022-12-15 15:57:02 +01:00
committed by Space Team
parent ebf6e69ef3
commit 1d30a68285
@@ -453,7 +453,8 @@ class FunctionInlining(
private inner class ParameterToArgument( private inner class ParameterToArgument(
val parameter: IrValueParameter, val parameter: IrValueParameter,
val argumentExpression: IrExpression val argumentExpression: IrExpression,
val isDefaultArg: Boolean = false
) { ) {
val isInlinableLambdaArgument: Boolean val isInlinableLambdaArgument: Boolean
@@ -550,7 +551,8 @@ class FunctionInlining(
parameter.defaultValue != null -> { // There is no argument - try default value. parameter.defaultValue != null -> { // There is no argument - try default value.
parametersWithDefaultToArgument += ParameterToArgument( parametersWithDefaultToArgument += ParameterToArgument(
parameter = parameter, parameter = parameter,
argumentExpression = parameter.defaultValue!!.expression argumentExpression = parameter.defaultValue!!.expression,
isDefaultArg = true
) )
} }
@@ -581,9 +583,9 @@ class FunctionInlining(
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun evaluateArguments(reference: IrCallableReference<*>): List<IrStatement> { private fun evaluateArguments(reference: IrCallableReference<*>): List<IrVariable> {
val arguments = reference.getArgumentsWithIr().map { ParameterToArgument(it.first, it.second) } val arguments = reference.getArgumentsWithIr().map { ParameterToArgument(it.first, it.second) }
val evaluationStatements = mutableListOf<IrStatement>() val evaluationStatements = mutableListOf<IrVariable>()
val substitutor = ParameterSubstitutor() val substitutor = ParameterSubstitutor()
val referenced = when (reference) { val referenced = when (reference) {
is IrFunctionReference -> reference.symbol.owner is IrFunctionReference -> reference.symbol.owner
@@ -622,7 +624,8 @@ class FunctionInlining(
private fun evaluateArguments(callSite: IrFunctionAccessExpression, callee: IrFunction): List<IrStatement> { private fun evaluateArguments(callSite: IrFunctionAccessExpression, callee: IrFunction): List<IrStatement> {
val arguments = buildParameterToArgument(callSite, callee) val arguments = buildParameterToArgument(callSite, callee)
val evaluationStatements = mutableListOf<IrStatement>() val evaluationStatements = mutableListOf<IrVariable>()
val evaluationStatementsFromDefault = mutableListOf<IrVariable>()
val substitutor = ParameterSubstitutor() val substitutor = ParameterSubstitutor()
arguments.forEach { argument -> arguments.forEach { argument ->
val parameter = argument.parameter val parameter = argument.parameter
@@ -645,13 +648,32 @@ class FunctionInlining(
argument.shouldBeSubstitutedViaTemporaryVariable() argument.shouldBeSubstitutedViaTemporaryVariable()
if (shouldCreateTemporaryVariable) { if (shouldCreateTemporaryVariable) {
val newVariable = createTemporaryVariable(parameter, variableInitializer, callee) val newVariable = createTemporaryVariable(parameter, variableInitializer, callee)
evaluationStatements.add(newVariable)
if (argument.isDefaultArg) evaluationStatementsFromDefault.add(newVariable) else evaluationStatements.add(newVariable)
substituteMap[parameter] = IrGetValueWithoutLocation(newVariable.symbol) substituteMap[parameter] = IrGetValueWithoutLocation(newVariable.symbol)
} else { } else {
substituteMap[parameter] = variableInitializer substituteMap[parameter] = variableInitializer
} }
} }
return evaluationStatements
// Next two composite blocks are used just as containers for two types of variables.
// First one store temp variables that represent non default arguments of inline call and second one store defaults.
// This is needed because these two groups of variables need slightly different processing on (JVM) backend.
val blockForNewStatements = IrCompositeImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType,
INLINED_FUNCTION_ARGUMENTS, statements = evaluationStatements
)
val blockForNewStatementsFromDefault = IrCompositeImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType,
INLINED_FUNCTION_DEFAULT_ARGUMENTS, statements = evaluationStatementsFromDefault
)
return listOfNotNull(
blockForNewStatements.takeIf { evaluationStatements.isNotEmpty() },
blockForNewStatementsFromDefault.takeIf { evaluationStatementsFromDefault.isNotEmpty() }
)
} }
private fun ParameterToArgument.shouldBeSubstitutedViaTemporaryVariable(): Boolean = private fun ParameterToArgument.shouldBeSubstitutedViaTemporaryVariable(): Boolean =
@@ -705,6 +727,9 @@ class FunctionInlining(
} }
} }
object INLINED_FUNCTION_ARGUMENTS : IrStatementOriginImpl("INLINED_FUNCTION_ARGUMENTS")
object INLINED_FUNCTION_DEFAULT_ARGUMENTS : IrStatementOriginImpl("INLINED_FUNCTION_DEFAULT_ARGUMENTS")
class InlinerExpressionLocationHint(val inlineAtSymbol: IrSymbol) : IrStatementOrigin { class InlinerExpressionLocationHint(val inlineAtSymbol: IrSymbol) : IrStatementOrigin {
override fun toString(): String = override fun toString(): String =
"(${this.javaClass.simpleName} : $functionNameOrDefaultToString @${functionFileOrNull?.fileEntry?.name})" "(${this.javaClass.simpleName} : $functionNameOrDefaultToString @${functionFileOrNull?.fileEntry?.name})"