After inlining remove unreachable basic blocks and unused variables. When removing unreachable basic blocks, remove corresponding phi inputs as well.

This commit is contained in:
Alexey Andreev 2016-11-06 21:12:59 +03:00
parent aebfe7d165
commit f61cfb23b5
4 changed files with 44 additions and 6 deletions

View File

@ -51,6 +51,7 @@ public class Inlining {
public void apply(Program program, ClassReaderSource classSource) { public void apply(Program program, ClassReaderSource classSource) {
List<PlanEntry> plan = buildPlan(program, classSource, 0); List<PlanEntry> plan = buildPlan(program, classSource, 0);
execPlan(program, plan, 0); execPlan(program, plan, 0);
new UnreachableBasicBlockEliminator().optimize(program);
} }
private void execPlan(Program program, List<PlanEntry> plan, int offset) { private void execPlan(Program program, List<PlanEntry> plan, int offset) {

View File

@ -15,16 +15,15 @@
*/ */
package org.teavm.model.optimization; package org.teavm.model.optimization;
import java.util.List;
import org.teavm.common.IntegerStack; import org.teavm.common.IntegerStack;
import org.teavm.model.BasicBlock; import org.teavm.model.BasicBlock;
import org.teavm.model.Incoming;
import org.teavm.model.Phi;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.TryCatchBlock; import org.teavm.model.TryCatchBlock;
import org.teavm.model.util.InstructionTransitionExtractor; import org.teavm.model.util.InstructionTransitionExtractor;
/**
*
* @author Alexey Andreev
*/
public class UnreachableBasicBlockEliminator { public class UnreachableBasicBlockEliminator {
public void optimize(Program program) { public void optimize(Program program) {
if (program.basicBlockCount() == 0) { if (program.basicBlockCount() == 0) {
@ -51,6 +50,7 @@ public class UnreachableBasicBlockEliminator {
stack.push(tryCatch.getHandler().getIndex()); stack.push(tryCatch.getHandler().getIndex());
} }
} }
for (int i = 0; i < reachable.length; ++i) { for (int i = 0; i < reachable.length; ++i) {
if (!reachable[i]) { if (!reachable[i]) {
BasicBlock block = program.basicBlockAt(i); BasicBlock block = program.basicBlockAt(i);
@ -66,6 +66,23 @@ public class UnreachableBasicBlockEliminator {
program.deleteBasicBlock(i); 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<Incoming> 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(); program.pack();
} }
} }

View File

@ -444,6 +444,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
for (MethodHolder method : cls.getMethods()) { for (MethodHolder method : cls.getMethods()) {
if (method.getProgram() != null) { if (method.getProgram() != null) {
inlining.apply(method.getProgram(), classes); inlining.apply(method.getProgram(), classes);
new UnusedVariableElimination().optimize(method, method.getProgram());
} }
} }
if (wasCancelled()) { if (wasCancelled()) {
@ -481,10 +482,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
for (MethodOptimization optimization : getOptimizations()) { for (MethodOptimization optimization : getOptimizations()) {
try { try {
changed |= optimization.optimize(method, optimizedProgram); changed |= optimization.optimize(method, optimizedProgram);
} catch (Exception e) { } catch (Exception | AssertionError e) {
ListingBuilder listingBuilder = new ListingBuilder(); ListingBuilder listingBuilder = new ListingBuilder();
String listing = listingBuilder.buildListing(optimizedProgram, ""); 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); + ":\n" + listing);
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -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 { private static class ClassWithStaticField {
public final static String CONST1 = "FIRST"; public final static String CONST1 = "FIRST";
public final static String CONST2 = "SECOND"; public final static String CONST2 = "SECOND";