Improve performance of PhiUpdater

This commit is contained in:
Alexey Andreev 2023-09-27 19:36:02 +02:00
parent 7fd3166f9b
commit 219de85e24

View File

@ -87,6 +87,7 @@ public class PhiUpdater {
private int[][] domFrontiers; private int[][] domFrontiers;
private Variable[] variableMap; private Variable[] variableMap;
private boolean[] variableDefined; private boolean[] variableDefined;
private int[] variableDefinitionCount;
private List<List<Variable>> definedVersions = new ArrayList<>(); private List<List<Variable>> definedVersions = new ArrayList<>();
private BasicBlock currentBlock; private BasicBlock currentBlock;
private Phi[][] phiMap; private Phi[][] phiMap;
@ -143,9 +144,11 @@ public class PhiUpdater {
variableMap = new Variable[program.variableCount()]; variableMap = new Variable[program.variableCount()];
usedDefinitions = new boolean[program.variableCount()]; usedDefinitions = new boolean[program.variableCount()];
variableDefinitionCount = new int[program.variableCount()];
for (int i = 0; i < parameters.length; ++i) { for (int i = 0; i < parameters.length; ++i) {
variableMap[i] = parameters[i]; variableMap[i] = parameters[i];
usedDefinitions[i] = true; usedDefinitions[i] = true;
variableDefinitionCount[i] = 1;
} }
for (int i = 0; i < program.variableCount(); ++i) { for (int i = 0; i < program.variableCount(); ++i) {
@ -217,6 +220,8 @@ public class PhiUpdater {
} }
private void estimatePhis() { private void estimatePhis() {
calculateDefinitions();
DefinitionExtractor definitionExtractor = new DefinitionExtractor(); DefinitionExtractor definitionExtractor = new DefinitionExtractor();
variableDefined = new boolean[program.variableCount()]; variableDefined = new boolean[program.variableCount()];
@ -271,6 +276,37 @@ public class PhiUpdater {
} }
} }
private void calculateDefinitions() {
var defExtractor = new DefinitionExtractor();
for (var block : program.getBasicBlocks()) {
increaseDefinitionCount(block.getExceptionVariable());
for (var phi : block.getPhis()) {
increaseDefinitionCount(phi.getReceiver());
}
for (var instruction : block) {
instruction.acceptVisitor(defExtractor);
for (var definedVar : defExtractor.getDefinedVariables()) {
increaseDefinitionCount(definedVar);
}
}
var sigmas = getSigmasAt(block.getIndex());
if (sigmas != null) {
for (var sigma : sigmas) {
increaseDefinitionCount(sigma.getValue());
for (var i = 0; i < sigma.getOutgoings().size(); ++i) {
increaseDefinitionCount(sigma.getValue());
}
}
}
}
}
private void increaseDefinitionCount(Variable var) {
if (var != null) {
variableDefinitionCount[var.getIndex()]++;
}
}
private static class Task { private static class Task {
Variable[] variables; Variable[] variables;
BasicBlock block; BasicBlock block;
@ -451,6 +487,11 @@ public class PhiUpdater {
} }
private void markAssignment(Variable var) { private void markAssignment(Variable var) {
if (variableDefinitionCount[var.getIndex()] < 2) {
variableDefined[var.getIndex()] = true;
return;
}
Deque<BasicBlock> worklist = new ArrayDeque<>(); Deque<BasicBlock> worklist = new ArrayDeque<>();
worklist.push(currentBlock); worklist.push(currentBlock);