mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
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:
parent
aebfe7d165
commit
f61cfb23b5
|
@ -51,6 +51,7 @@ public class Inlining {
|
|||
public void apply(Program program, ClassReaderSource classSource) {
|
||||
List<PlanEntry> plan = buildPlan(program, classSource, 0);
|
||||
execPlan(program, plan, 0);
|
||||
new UnreachableBasicBlockEliminator().optimize(program);
|
||||
}
|
||||
|
||||
private void execPlan(Program program, List<PlanEntry> plan, int offset) {
|
||||
|
|
|
@ -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<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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue
Block a user