From ab9747ed6df158a70def3d6a2b977ca4f303d97d Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 15 Dec 2021 14:41:56 +0300 Subject: [PATCH] JVM_IR KT-50277 skip temporary var elimination on inline suspend lambda --- .../codegen/inline/inlineCodegenUtils.kt | 3 +++ ...emporaryVariablesEliminationTransformer.kt | 4 ++++ .../FirBlackBoxCodegenTestGenerated.java | 6 +++++ .../codegen/box/coroutines/kt50277.kt | 24 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ 7 files changed, 54 insertions(+) create mode 100644 compiler/testData/codegen/box/coroutines/kt50277.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt index 0ed48ff1221..0aa0bc65e35 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt @@ -637,6 +637,9 @@ internal fun isBeforeFakeContinuationConstructorCallMarker(insn: AbstractInsnNod internal fun isAfterFakeContinuationConstructorCallMarker(insn: AbstractInsnNode) = isSuspendMarker(insn, INLINE_MARKER_AFTER_FAKE_CONTINUATION_CONSTRUCTOR_CALL) +internal fun isSuspendInlineMarker(insn: AbstractInsnNode) = + isInlineMarker(insn, "mark") + private fun isSuspendMarker(insn: AbstractInsnNode, id: Int) = isInlineMarker(insn, "mark") && insn.previous.intConstant == id diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt index 402f639f11b..4112d74e2cc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.codegen.optimization.temporaryVals +import org.jetbrains.kotlin.codegen.inline.isSuspendInlineMarker import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables @@ -23,6 +24,9 @@ class TemporaryVariablesEliminationTransformer(private val state: GenerationStat override fun transform(internalClassName: String, methodNode: MethodNode) { if (!state.isIrBackend) return + // If there are any suspend inline markers, don't touch anything now. + if (methodNode.instructions.any { isSuspendInlineMarker(it) }) return + simplifyTrivialInstructions(methodNode) val cfg = ControlFlowGraph(methodNode) diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index a7e376b4298..ebbd022f9eb 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -9899,6 +9899,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/coroutines/kt49645.kt"); } + @Test + @TestMetadata("kt50277.kt") + public void testKt50277() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt50277.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { diff --git a/compiler/testData/codegen/box/coroutines/kt50277.kt b/compiler/testData/codegen/box/coroutines/kt50277.kt new file mode 100644 index 00000000000..c402d405655 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/kt50277.kt @@ -0,0 +1,24 @@ +// WITH_STDLIB +// WITH_COROUTINES +// TARGET_BACKEND: JVM + +import helpers.* +import kotlin.coroutines.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +suspend fun g(): Int = 42 + +suspend fun f(block: suspend (a: Int) -> Unit) { + listOf(0).map { block(g()) } +} + +fun box(): String { + var result = "Failed" + builder { + f { result = "OK" } + } + return result +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 98fdfe0419e..d676861b479 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -9797,6 +9797,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/coroutines/kt49645.kt"); } + @Test + @TestMetadata("kt50277.kt") + public void testKt50277() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt50277.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 66f2f5df4ba..56891922a0f 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -9899,6 +9899,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/coroutines/kt49645.kt"); } + @Test + @TestMetadata("kt50277.kt") + public void testKt50277() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt50277.kt"); + } + @Test @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 775f6a418bd..da7bcdf828a 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7682,6 +7682,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/coroutines/kt49645.kt"); } + @TestMetadata("kt50277.kt") + public void testKt50277() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt50277.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt");