From fdbcb64d398f78bf396480f3f93a47f3ec47db18 Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Tue, 25 Jan 2022 23:06:49 +0800 Subject: [PATCH] JVM_IR: frame optimization for cast to IntProgression #KT-29199 --- .../optimization/boxing/BoxingInterpreter.kt | 16 +++++++++++++++- .../codegen/FirBytecodeTextTestGenerated.java | 6 ++++++ .../codegen/bytecodeText/mergedProgression.kt | 7 +++++++ .../codegen/IrBytecodeTextTestGenerated.java | 6 ++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/bytecodeText/mergedProgression.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt index 30f8992f0f6..5b18f7bd2bb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.kt @@ -35,6 +35,7 @@ import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode import org.jetbrains.org.objectweb.asm.tree.InsnList import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode +import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue open class BoxingInterpreter( @@ -136,7 +137,10 @@ open class BoxingInterpreter( override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue): BasicValue? { checkUsedValue(value) - return if (insn.opcode == Opcodes.CHECKCAST && isExactValue(value)) + return if (insn.opcode == Opcodes.CHECKCAST + && isExactValue(value) + && !isCastToProgression(insn) // operations such as cast kotlin/ranges/IntRange to kotlin/ranges/IntProgression, should be allowed + ) value else super.unaryOperation(insn, value) @@ -147,6 +151,16 @@ open class BoxingInterpreter( value is CleanBoxedValue || value.type != null && isProgressionClass(value.type) + private fun isCastToProgression(insn: AbstractInsnNode): Boolean { + assert(insn.opcode == Opcodes.CHECKCAST) { "Expected opcode Opcodes.CHECKCAST, but ${insn.opcode} found" } + val desc = (insn as TypeInsnNode).desc + return desc in setOf( + "kotlin/ranges/CharProgression", + "kotlin/ranges/IntProgression", + "kotlin/ranges/LongProgression" + ) + } + override fun merge(v: BasicValue, w: BasicValue) = mergeStackValues(v, w) diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java index 91e194203cf..2fc1f051761 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java @@ -367,6 +367,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/maxStackAfterOptimizations.kt"); } + @Test + @TestMetadata("mergedProgression.kt") + public void testMergedProgression() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/mergedProgression.kt"); + } + @Test @TestMetadata("noAccessorForProtectedInSamePackageCrossinline.kt") public void testNoAccessorForProtectedInSamePackageCrossinline() throws Exception { diff --git a/compiler/testData/codegen/bytecodeText/mergedProgression.kt b/compiler/testData/codegen/bytecodeText/mergedProgression.kt new file mode 100644 index 00000000000..fbfd9e4bcea --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/mergedProgression.kt @@ -0,0 +1,7 @@ +// TARGET_BACKEND: JVM_IR + +fun test(a: Int, b: Int, flag: Boolean) = + (if (flag) a..b else a downTo b).map { it + 1 } + +// 0 java/util/Iterator.next \(\)Ljava/lang/Object; +// 1 kotlin/collections/IntIterator.nextInt \(\)I diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java index 9fc2223c142..9cf47372f2c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java @@ -367,6 +367,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/maxStackAfterOptimizations.kt"); } + @Test + @TestMetadata("mergedProgression.kt") + public void testMergedProgression() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/mergedProgression.kt"); + } + @Test @TestMetadata("noAccessorForProtectedInSamePackageCrossinline.kt") public void testNoAccessorForProtectedInSamePackageCrossinline() throws Exception {