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) {
|
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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user