diff --git a/core/src/main/java/org/teavm/model/optimization/Inlining.java b/core/src/main/java/org/teavm/model/optimization/Inlining.java index 1d040e81a..e9a3e80e3 100644 --- a/core/src/main/java/org/teavm/model/optimization/Inlining.java +++ b/core/src/main/java/org/teavm/model/optimization/Inlining.java @@ -51,6 +51,7 @@ public class Inlining { public void apply(Program program, ClassReaderSource classSource) { List plan = buildPlan(program, classSource, 0); execPlan(program, plan, 0); + new UnreachableBasicBlockEliminator().optimize(program); } private void execPlan(Program program, List plan, int offset) { diff --git a/core/src/main/java/org/teavm/model/optimization/UnreachableBasicBlockEliminator.java b/core/src/main/java/org/teavm/model/optimization/UnreachableBasicBlockEliminator.java index 5eab5e13b..fbd6c6002 100644 --- a/core/src/main/java/org/teavm/model/optimization/UnreachableBasicBlockEliminator.java +++ b/core/src/main/java/org/teavm/model/optimization/UnreachableBasicBlockEliminator.java @@ -15,16 +15,15 @@ */ package org.teavm.model.optimization; +import java.util.List; import org.teavm.common.IntegerStack; import org.teavm.model.BasicBlock; +import org.teavm.model.Incoming; +import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.TryCatchBlock; import org.teavm.model.util.InstructionTransitionExtractor; -/** - * - * @author Alexey Andreev - */ public class UnreachableBasicBlockEliminator { public void optimize(Program program) { if (program.basicBlockCount() == 0) { @@ -51,6 +50,7 @@ public class UnreachableBasicBlockEliminator { stack.push(tryCatch.getHandler().getIndex()); } } + for (int i = 0; i < reachable.length; ++i) { if (!reachable[i]) { BasicBlock block = program.basicBlockAt(i); @@ -66,6 +66,23 @@ public class UnreachableBasicBlockEliminator { program.deleteBasicBlock(i); } } + + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + if (block == null) { + continue; + } + for (Phi phi : block.getPhis()) { + List incomingList = phi.getIncomings(); + for (int j = 0; j < incomingList.size(); ++j) { + Incoming incoming = incomingList.get(j); + if (!reachable[incoming.getSource().getIndex()]) { + incomingList.remove(j--); + } + } + } + } + program.pack(); } } diff --git a/core/src/main/java/org/teavm/vm/TeaVM.java b/core/src/main/java/org/teavm/vm/TeaVM.java index d61b5c434..71ccf7f87 100644 --- a/core/src/main/java/org/teavm/vm/TeaVM.java +++ b/core/src/main/java/org/teavm/vm/TeaVM.java @@ -444,6 +444,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { for (MethodHolder method : cls.getMethods()) { if (method.getProgram() != null) { inlining.apply(method.getProgram(), classes); + new UnusedVariableElimination().optimize(method, method.getProgram()); } } if (wasCancelled()) { @@ -481,10 +482,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository { for (MethodOptimization optimization : getOptimizations()) { try { changed |= optimization.optimize(method, optimizedProgram); - } catch (Exception e) { + } catch (Exception | AssertionError e) { ListingBuilder listingBuilder = new ListingBuilder(); String listing = listingBuilder.buildListing(optimizedProgram, ""); - System.err.println("Error optimizing program for method" + method.getReference() + System.err.println("Error optimizing program for method " + method.getReference() + ":\n" + listing); throw new RuntimeException(e); } diff --git a/tests/src/test/java/org/teavm/vm/VMTest.java b/tests/src/test/java/org/teavm/vm/VMTest.java index fe2367b86..b5dfc8169 100644 --- a/tests/src/test/java/org/teavm/vm/VMTest.java +++ b/tests/src/test/java/org/teavm/vm/VMTest.java @@ -105,6 +105,25 @@ public class VMTest { } } + @Test + public void inlineThrow() { + int x = id(23); + if (x == 42) { + x++; + throwException(); + x++; + } + assertEquals(x, id(23)); + } + + private void throwException() { + throw new RuntimeException(); + } + + private int id(int value) { + return value; + } + private static class ClassWithStaticField { public final static String CONST1 = "FIRST"; public final static String CONST2 = "SECOND";