mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-02 13:24:11 -08:00
Fix possible bug with exceptions in GVN
This commit is contained in:
parent
054d4c2a24
commit
1d81b7004f
|
@ -100,7 +100,7 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
boolean affected = false;
|
boolean affected = false;
|
||||||
this.program = program;
|
this.program = program;
|
||||||
knownValues.clear();
|
knownValues.clear();
|
||||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
Graph cfg = ProgramUtils.buildControlFlowGraph2(program);
|
||||||
domTree = GraphUtils.buildDominatorTree(cfg);
|
domTree = GraphUtils.buildDominatorTree(cfg);
|
||||||
Graph dom = GraphUtils.buildDominatorGraph(domTree, cfg.size());
|
Graph dom = GraphUtils.buildDominatorGraph(domTree, cfg.size());
|
||||||
map = new int[program.variableCount()];
|
map = new int[program.variableCount()];
|
||||||
|
@ -123,52 +123,55 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
}
|
}
|
||||||
while (top > 0) {
|
while (top > 0) {
|
||||||
int v = stack[--top];
|
int v = stack[--top];
|
||||||
currentBlockIndex = v;
|
if (v % 2 == 0) {
|
||||||
BasicBlock block = program.basicBlockAt(v);
|
var blockIndex = v / 2;
|
||||||
|
currentBlockIndex = blockIndex;
|
||||||
|
BasicBlock block = program.basicBlockAt(blockIndex);
|
||||||
|
|
||||||
if (block.getExceptionVariable() != null) {
|
if (block.getExceptionVariable() != null) {
|
||||||
int var = map[block.getExceptionVariable().getIndex()];
|
int var = map[block.getExceptionVariable().getIndex()];
|
||||||
block.setExceptionVariable(program.variableAt(var));
|
block.setExceptionVariable(program.variableAt(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Instruction currentInsn : block) {
|
for (Instruction currentInsn : block) {
|
||||||
evaluatedConstant = null;
|
evaluatedConstant = null;
|
||||||
currentInsn.acceptVisitor(optimizer);
|
currentInsn.acceptVisitor(optimizer);
|
||||||
if (eliminate) {
|
if (eliminate) {
|
||||||
affected = true;
|
affected = true;
|
||||||
currentInsn.delete();
|
currentInsn.delete();
|
||||||
eliminate = false;
|
eliminate = false;
|
||||||
} else if (evaluatedConstant != null) {
|
} else if (evaluatedConstant != null) {
|
||||||
if (evaluatedConstant instanceof Integer) {
|
if (evaluatedConstant instanceof Integer) {
|
||||||
IntegerConstantInstruction newInsn = new IntegerConstantInstruction();
|
IntegerConstantInstruction newInsn = new IntegerConstantInstruction();
|
||||||
newInsn.setConstant((Integer) evaluatedConstant);
|
newInsn.setConstant((Integer) evaluatedConstant);
|
||||||
newInsn.setReceiver(program.variableAt(receiver));
|
newInsn.setReceiver(program.variableAt(receiver));
|
||||||
newInsn.setLocation(currentInsn.getLocation());
|
newInsn.setLocation(currentInsn.getLocation());
|
||||||
currentInsn.replace(newInsn);
|
currentInsn.replace(newInsn);
|
||||||
} else if (evaluatedConstant instanceof Long) {
|
} else if (evaluatedConstant instanceof Long) {
|
||||||
LongConstantInstruction newInsn = new LongConstantInstruction();
|
LongConstantInstruction newInsn = new LongConstantInstruction();
|
||||||
newInsn.setConstant((Long) evaluatedConstant);
|
newInsn.setConstant((Long) evaluatedConstant);
|
||||||
newInsn.setReceiver(program.variableAt(receiver));
|
newInsn.setReceiver(program.variableAt(receiver));
|
||||||
newInsn.setLocation(currentInsn.getLocation());
|
newInsn.setLocation(currentInsn.getLocation());
|
||||||
currentInsn.replace(newInsn);
|
currentInsn.replace(newInsn);
|
||||||
} else if (evaluatedConstant instanceof Float) {
|
} else if (evaluatedConstant instanceof Float) {
|
||||||
FloatConstantInstruction newInsn = new FloatConstantInstruction();
|
FloatConstantInstruction newInsn = new FloatConstantInstruction();
|
||||||
newInsn.setConstant((Float) evaluatedConstant);
|
newInsn.setConstant((Float) evaluatedConstant);
|
||||||
newInsn.setReceiver(program.variableAt(receiver));
|
newInsn.setReceiver(program.variableAt(receiver));
|
||||||
newInsn.setLocation(currentInsn.getLocation());
|
newInsn.setLocation(currentInsn.getLocation());
|
||||||
currentInsn.replace(newInsn);
|
currentInsn.replace(newInsn);
|
||||||
} else if (evaluatedConstant instanceof Double) {
|
} else if (evaluatedConstant instanceof Double) {
|
||||||
DoubleConstantInstruction newInsn = new DoubleConstantInstruction();
|
DoubleConstantInstruction newInsn = new DoubleConstantInstruction();
|
||||||
newInsn.setConstant((Double) evaluatedConstant);
|
newInsn.setConstant((Double) evaluatedConstant);
|
||||||
newInsn.setReceiver(program.variableAt(receiver));
|
newInsn.setReceiver(program.variableAt(receiver));
|
||||||
newInsn.setLocation(currentInsn.getLocation());
|
newInsn.setLocation(currentInsn.getLocation());
|
||||||
currentInsn.replace(newInsn);
|
currentInsn.replace(newInsn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
for (Incoming incoming : outgoings.get(blockIndex)) {
|
||||||
for (Incoming incoming : outgoings.get(v)) {
|
int value = replaceMap[incoming.getValue().getIndex()];
|
||||||
int value = replaceMap[incoming.getValue().getIndex()];
|
incoming.setValue(program.variableAt(value));
|
||||||
incoming.setValue(program.variableAt(value));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int succ : dom.outgoingEdges(v)) {
|
for (int succ : dom.outgoingEdges(v)) {
|
||||||
|
@ -216,7 +219,7 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
}
|
}
|
||||||
namesCompatible = knownName.isEmpty() || name.isEmpty() || knownName.equals(name);
|
namesCompatible = knownName.isEmpty() || name.isEmpty() || knownName.equals(name);
|
||||||
}
|
}
|
||||||
if (known != null && domTree.dominates(known.location, currentBlockIndex) && known.value != var
|
if (known != null && domTree.dominates(known.location * 2 + 1, currentBlockIndex * 2) && known.value != var
|
||||||
&& namesCompatible) {
|
&& namesCompatible) {
|
||||||
map[var] = known.value;
|
map[var] = known.value;
|
||||||
if (!noReplace) {
|
if (!noReplace) {
|
||||||
|
|
|
@ -73,6 +73,29 @@ public final class ProgramUtils {
|
||||||
return graphBuilder.build();
|
return graphBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Graph buildControlFlowGraph2(Program program) {
|
||||||
|
var graphBuilder = new GraphBuilder(program.basicBlockCount());
|
||||||
|
TransitionExtractor transitionExtractor = new TransitionExtractor();
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
graphBuilder.addEdge(i * 2, i * 2 + 1);
|
||||||
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
Instruction insn = block.getLastInstruction();
|
||||||
|
if (insn != null) {
|
||||||
|
insn.acceptVisitor(transitionExtractor);
|
||||||
|
if (transitionExtractor.getTargets() != null) {
|
||||||
|
for (BasicBlock successor : transitionExtractor.getTargets()) {
|
||||||
|
graphBuilder.addEdge(i * 2 + 1, successor.getIndex() * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
|
graphBuilder.addEdge(i * 2, tryCatch.getHandler().getIndex() * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return graphBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
public static ControlFlowEntry[] getLocationCFG(Program program) {
|
public static ControlFlowEntry[] getLocationCFG(Program program) {
|
||||||
return new LocationGraphBuilder().build(program);
|
return new LocationGraphBuilder().build(program);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,4 +93,5 @@ tasks.test {
|
||||||
.joinToString(File.pathSeparator))
|
.joinToString(File.pathSeparator))
|
||||||
|
|
||||||
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
|
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
|
||||||
|
maxHeapSize = "800m"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user