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:
+32
-7
@@ -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})"
|
||||||
|
|||||||
Reference in New Issue
Block a user