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
@@ -6465,6 +6465,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines");
}
@TestMetadata("suspendReturningPlatformType.kt")
public void testSuspendReturningPlatformType() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/suspendReturningPlatformType.kt");
@@ -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)
@@ -0,0 +1,32 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
import helpers.*
import COROUTINES_PACKAGE.*
import COROUTINES_PACKAGE.intrinsics.*
inline fun callAction(aux: Int, action: () -> String): String {
return action()
}
suspend fun get() = "OK"
suspend fun callSuspend(): String {
return callAction(action = {
get()
}, aux = 0)
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var v = "fail"
builder {
v = callSuspend()
}
return v
}
@@ -34,9 +34,7 @@ FILE fqName:<root> fileName:/callWithReorderedArguments.kt
b: GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
BLOCK type=kotlin.Unit origin=ARGUMENTS_REORDERING_FOR_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val]
CONST Int type=kotlin.Int value=1
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val]
CALL 'public final fun reordered2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
CALL 'public final fun foo (a: kotlin.Int, b: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
a: GET_VAR 'val tmp_3: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
b: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
a: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
b: CONST Int type=kotlin.Int value=1
@@ -6880,6 +6880,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines");
}
@TestMetadata("suspendReturningPlatformType.kt")
public void testSuspendReturningPlatformType() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/suspendReturningPlatformType.kt");
@@ -6880,6 +6880,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines.experimental");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines");
}
@TestMetadata("suspendReturningPlatformType.kt")
public void testSuspendReturningPlatformType() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/suspendReturningPlatformType.kt");
@@ -6465,6 +6465,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines");
}
@TestMetadata("suspendReturningPlatformType.kt")
public void testSuspendReturningPlatformType() throws Exception {
runTest("compiler/testData/codegen/box/coroutines/suspendReturningPlatformType.kt");
@@ -5455,6 +5455,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendInTheMiddleOfObjectConstruction.kt", "kotlin.coroutines");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines");
}
@TestMetadata("suspensionInsideSafeCallWithElvis.kt")
public void testSuspensionInsideSafeCallWithElvis_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt", "kotlin.coroutines");
@@ -5455,6 +5455,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendInTheMiddleOfObjectConstruction.kt", "kotlin.coroutines");
}
@TestMetadata("suspendLambdaWithArgumentRearrangement.kt")
public void testSuspendLambdaWithArgumentRearrangement_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendLambdaWithArgumentRearrangement.kt", "kotlin.coroutines");
}
@TestMetadata("suspensionInsideSafeCallWithElvis.kt")
public void testSuspensionInsideSafeCallWithElvis_1_3() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt", "kotlin.coroutines");