Fix possible bug with exceptions in GVN

This commit is contained in:
Alexey Andreev 2024-09-26 20:39:29 +02:00
parent 054d4c2a24
commit 1d81b7004f
3 changed files with 71 additions and 44 deletions

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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"
} }