KT-14357 Run RedundantCoercionToUnitTransformer before DeadCodeEliminatingMethodTransformer.

Remove empty try-catch blocks in DeadCodeEliminatingMethodTransformer.
This commit is contained in:
Dmitry Petrov
2016-10-14 16:06:39 +03:00
parent 932e6753e5
commit ac675784c1
6 changed files with 40 additions and 4 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.common.removeEmptyCatchBlocks
class DeadCodeEliminationMethodTransformer : MethodTransformer() { class DeadCodeEliminationMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) { override fun transform(internalClassName: String, methodNode: MethodNode) {
@@ -28,10 +29,12 @@ class DeadCodeEliminationMethodTransformer : MethodTransformer() {
val insnsArray = insnList.toArray() val insnsArray = insnList.toArray()
// Do not remove not meaningful nodes (labels/linenumbers) because they can be referred // Do not remove not meaningful nodes (labels/linenumbers) because they can be referred
// by try/catch blocks or local variables table // by try/catch blocks or local variables table.
// We remove unneeded ones further after all optimizations by calling CommonPackage.prepareForEmitting(methodNode)
insnsArray.zip(frames).filter { insnsArray.zip(frames).filter {
it.second == null && it.first.isMeaningful it.second == null && it.first.isMeaningful
}.forEach { insnList.remove(it.first) } }.forEach { insnList.remove(it.first) }
// Remove empty try-catch blocks to make sure we don't break data flow analysis invariants by dead code elimination.
methodNode.removeEmptyCatchBlocks()
} }
} }
@@ -35,9 +35,9 @@ public class OptimizationMethodVisitor extends TransformationMethodVisitor {
private static final MethodTransformer[] OPTIMIZATION_TRANSFORMERS = new MethodTransformer[] { private static final MethodTransformer[] OPTIMIZATION_TRANSFORMERS = new MethodTransformer[] {
new RedundantNullCheckMethodTransformer(), new RedundantNullCheckMethodTransformer(),
new RedundantBoxingMethodTransformer(), new RedundantBoxingMethodTransformer(),
new RedundantCoercionToUnitTransformer(),
new DeadCodeEliminationMethodTransformer(), new DeadCodeEliminationMethodTransformer(),
new RedundantGotoMethodTransformer(), new RedundantGotoMethodTransformer()
new RedundantCoercionToUnitTransformer()
}; };
private final boolean disableOptimization; private final boolean disableOptimization;
@@ -0,0 +1,10 @@
fun box(): String {
if (false) {
try {
null!!
} catch (e: Exception) {
throw e
}
}
return "OK"
}
@@ -0,0 +1,11 @@
fun test() {
if (false) {
try {
println("Hello Kotlin")
} catch (e: Exception) {
e.printStackTrace()
}
}
}
// 0 INVOKE
@@ -5079,6 +5079,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/deadCodeElimination/intersectingVariableRangeInFinally.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/deadCodeElimination/intersectingVariableRangeInFinally.kt");
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt14357.kt")
public void testKt14357() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/deadCodeElimination/kt14357.kt");
doTest(fileName);
}
} }
@TestMetadata("compiler/testData/codegen/box/defaultArguments") @TestMetadata("compiler/testData/codegen/box/defaultArguments")
@@ -889,6 +889,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("kt14357.kt")
public void testKt14357() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination/kt14357.kt");
doTest(fileName);
}
@TestMetadata("lastReturn.kt") @TestMetadata("lastReturn.kt")
public void testLastReturn() throws Exception { public void testLastReturn() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination/lastReturn.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination/lastReturn.kt");