IR: generate lambdas in place in Psi2Ir

even when arguments are to be rearranged.
Lambdas have no side effects, and storing them in temporary variables
prevents processing in the backend
(such as inserting continuation parameter in AddContinuationLowering).
This commit is contained in:
Georgy Bronnikov
2020-03-19 11:45:23 +03:00
parent 915e6107d1
commit 4742057b51
9 changed files with 84 additions and 5 deletions
@@ -384,7 +384,10 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
for (valueArgument in valueArgumentsInEvaluationOrder) {
val valueParameter = valueArgumentsToValueParameters[valueArgument]!!
val irArgument = call.getValueArgument(valueParameter) ?: continue
val irArgumentValue = scope.createTemporaryVariableInBlock(context, irArgument, irBlock, valueParameter.name.asString())
val irArgumentValue = if (irArgument.hasNoSideEffects())
generateExpressionValue(irArgument.type) { irArgument } // Computing a lambda has no side effects, can generate in place
else
scope.createTemporaryVariableInBlock(context, irArgument, irBlock, valueParameter.name.asString())
irArgumentValues[valueParameter] = irArgumentValue
}
@@ -399,6 +402,12 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
}
}
fun IrExpression.hasNoSideEffects() =
this is IrFunctionExpression ||
(this is IrCallableReference && dispatchReceiver == null && extensionReceiver == null) ||
this is IrClassReference ||
this is IrConst<*>
fun CallGenerator.generateCall(ktElement: KtElement, call: CallBuilder, origin: IrStatementOrigin? = null) =
generateCall(ktElement.startOffsetSkippingComments, ktElement.endOffset, call, origin)