Improve compilation performance of low-level backends

This commit is contained in:
Alexey Andreev 2019-04-05 14:37:02 +03:00
parent 7551cd1ec6
commit 83d041d55b
2 changed files with 45 additions and 3 deletions

View File

@ -100,6 +100,7 @@ public class PhiUpdater {
private List<Phi> synthesizedPhis = new ArrayList<>(); private List<Phi> synthesizedPhis = new ArrayList<>();
private Sigma[][] sigmas; private Sigma[][] sigmas;
private Predicate<Instruction> sigmaPredicate = instruction -> false; private Predicate<Instruction> sigmaPredicate = instruction -> false;
private int[][][] frontierVariableCache;
public int getSourceVariable(int var) { public int getSourceVariable(int var) {
if (var >= variableToSourceMap.size()) { if (var >= variableToSourceMap.size()) {
@ -133,6 +134,7 @@ public class PhiUpdater {
if (program.basicBlockCount() == 0) { if (program.basicBlockCount() == 0) {
return; return;
} }
frontierVariableCache = new int[program.basicBlockCount()][][];
this.program = program; this.program = program;
phisByReceiver.clear(); phisByReceiver.clear();
cfg = ProgramUtils.buildControlFlowGraph(program); cfg = ProgramUtils.buildControlFlowGraph(program);
@ -473,15 +475,49 @@ public class PhiUpdater {
} }
} }
private int[][] getIncomingVariablesForFrontier(int frontier) {
int[][] result = frontierVariableCache[frontier];
if (result == null) {
List<List<Variable>> builder = new ArrayList<>(Collections.nCopies(program.basicBlockCount(), null));
for (Phi phi : program.basicBlockAt(frontier).getPhis()) {
for (Incoming incoming : phi.getIncomings()) {
List<Variable> variables = builder.get(incoming.getSource().getIndex());
if (variables == null) {
variables = new ArrayList<>();
builder.set(incoming.getSource().getIndex(), variables);
}
variables.add(incoming.getValue());
}
}
result = new int[program.basicBlockCount()][];
for (int i = 0; i < result.length; ++i) {
List<Variable> builderVariables = builder.get(i);
if (builderVariables == null) {
continue;
}
int[] resultVariables = new int[builderVariables.size()];
for (int j = 0; j < resultVariables.length; ++j) {
resultVariables[j] = builderVariables.get(j).getIndex();
}
result[i] = resultVariables;
}
frontierVariableCache[frontier] = result;
}
return result;
}
private void placePhi(int frontier, Variable var, BasicBlock block, Deque<BasicBlock> worklist) { private void placePhi(int frontier, Variable var, BasicBlock block, Deque<BasicBlock> worklist) {
BasicBlock frontierBlock = program.basicBlockAt(frontier); BasicBlock frontierBlock = program.basicBlockAt(frontier);
if (frontierBlock.getExceptionVariable() == var) { if (frontierBlock.getExceptionVariable() == var) {
return; return;
} }
for (Phi phi : frontierBlock.getPhis()) { int[] frontierIncomingVariables = getIncomingVariablesForFrontier(frontier)[block.getIndex()];
for (Incoming incoming : phi.getIncomings()) { if (frontierIncomingVariables != null) {
if (incoming.getSource() == block && incoming.getValue() == var) { for (int incoming : frontierIncomingVariables) {
if (incoming == var.getIndex()) {
return; return;
} }
} }

View File

@ -634,7 +634,13 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
for (int i = 0; i < methodReferences.size(); i++) { for (int i = 0; i < methodReferences.size(); i++) {
MethodReference methodReference = methodReferences.get(i); MethodReference methodReference = methodReferences.get(i);
ClassHolder cls = classes.get(methodReference.getClassName()); ClassHolder cls = classes.get(methodReference.getClassName());
if (cls == null) {
continue;
}
MethodHolder method = cls.getMethod(methodReference.getDescriptor()); MethodHolder method = cls.getMethod(methodReference.getDescriptor());
if (method == null) {
continue;
}
if (method.getProgram() != null) { if (method.getProgram() != null) {
if (!inlining.hasUsages(methodReference)) { if (!inlining.hasUsages(methodReference)) {