diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.java index 1b85e107bae..d21b629c999 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/BoxingInterpreter.java @@ -210,6 +210,10 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter { @Override @NotNull public BasicValue merge(@NotNull BasicValue v, @NotNull BasicValue w) { + if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) { + return BasicValue.UNINITIALIZED_VALUE; + } + if (v instanceof BoxedBasicValue && ((BoxedBasicValue) v).typeEquals(w)) { onMergeSuccess((BoxedBasicValue) v, (BoxedBasicValue) w); return v; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.java index 1a802c4869d..b4083e61589 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.java @@ -114,6 +114,7 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer { if (CollectionsKt.any(usedValues, new Function1() { @Override public Boolean invoke(BasicValue input) { + if (input == BasicValue.UNINITIALIZED_VALUE) return false; return input == null || !(input instanceof BoxedBasicValue) || !((BoxedBasicValue) input).isSafeToRemove() || diff --git a/compiler/testData/codegen/boxWithStdlib/boxingOptimization/foldRange.kt b/compiler/testData/codegen/boxWithStdlib/boxingOptimization/foldRange.kt new file mode 100644 index 00000000000..984591735ed --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/boxingOptimization/foldRange.kt @@ -0,0 +1,9 @@ +import kotlin.test.assertEquals + +fun box(): String { + val result = (1..5).fold(0) { x, y -> x + y } + + assertEquals(15, result) + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/boxingOptimization/kt6842.kt b/compiler/testData/codegen/boxWithStdlib/boxingOptimization/kt6842.kt new file mode 100644 index 00000000000..6e384506e69 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/boxingOptimization/kt6842.kt @@ -0,0 +1,7 @@ +import kotlin.test.assertEquals + +fun box(): String { + val x = (10L..50).map { it * 40L } + assertEquals(400L, x.first()) + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/boxingOptimization/simpleUninitializedMerge.kt b/compiler/testData/codegen/boxWithStdlib/boxingOptimization/simpleUninitializedMerge.kt new file mode 100644 index 00000000000..ab73e3a2da7 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/boxingOptimization/simpleUninitializedMerge.kt @@ -0,0 +1,12 @@ +import kotlin.test.assertEquals + +fun box(): String { + var result = 0 + if (1 == 1) { + val x: Int? = 1 + result += x!! + } + + assertEquals(1, result) + return "OK" +} diff --git a/compiler/testData/codegen/bytecodeText/boxingOptimization/kt6842.kt b/compiler/testData/codegen/bytecodeText/boxingOptimization/kt6842.kt new file mode 100644 index 00000000000..07e1ce06133 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/boxingOptimization/kt6842.kt @@ -0,0 +1,17 @@ +fun box(): Long { + val x1 = (1..5).map { it * 40 } + val x2 = (1..5).fold(0) { x, y -> x + y } + val x3 = (1..5).reduce { x, y -> x + y } + val x4 = (1..5).count { it > 0 } + + val y1 = (1L..5L).map { it * 40L } + val y2 = (1L..5L).fold(0L) { x, y -> x + y } + val y3 = (1L..5L).reduce { x, y -> x + y } + val y4 = (1L..5L).count { it > 0L } + + return (x1.first() + x2 + x3 + x4).toLong() + y1.first() + y2 + y3 + y4.toLong() +} + +// 5 nextLong +// 5 nextInt +// 0 next\s*\( diff --git a/compiler/testData/codegen/bytecodeText/boxingOptimization/simpleUninitializedMerge.kt b/compiler/testData/codegen/bytecodeText/boxingOptimization/simpleUninitializedMerge.kt new file mode 100644 index 00000000000..9e839ce1920 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/boxingOptimization/simpleUninitializedMerge.kt @@ -0,0 +1,10 @@ +fun box(): String { + var result = 0 + if (1 == 1) { + val x: Int? = 1 + result += x!! + } + return "OK" +} + +// 0 java/lang/Integer.valueOf diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index f1a1c44b137..c76def7f920 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -376,6 +376,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("kt6842.kt") + public void testKt6842() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/boxingOptimization/kt6842.kt"); + doTest(fileName); + } + @TestMetadata("kt7224.kt") public void testKt7224() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/boxingOptimization/kt7224.kt"); @@ -412,6 +418,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("simpleUninitializedMerge.kt") + public void testSimpleUninitializedMerge() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/boxingOptimization/simpleUninitializedMerge.kt"); + doTest(fileName); + } + @TestMetadata("unsafeRemoving.kt") public void testUnsafeRemoving() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/boxingOptimization/unsafeRemoving.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 9dcb416a542..b3913342108 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -337,6 +337,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("foldRange.kt") + public void testFoldRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/boxingOptimization/foldRange.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("kt5493.kt") public void testKt5493() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/boxingOptimization/kt5493.kt"); @@ -361,6 +367,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("kt6842.kt") + public void testKt6842() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/boxingOptimization/kt6842.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("nullCheck.kt") public void testNullCheck() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/boxingOptimization/nullCheck.kt"); @@ -385,6 +397,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("simpleUninitializedMerge.kt") + public void testSimpleUninitializedMerge() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/boxingOptimization/simpleUninitializedMerge.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("unsafeRemoving.kt") public void testUnsafeRemoving() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/boxingOptimization/unsafeRemoving.kt");