If possible, move continue $main to the end of the async part, giving a

chance to eliminate it.
This commit is contained in:
Alexey Andreev 2015-05-04 16:50:36 +03:00
parent b4e4dd8d43
commit 11d69f15c9
3 changed files with 60 additions and 10 deletions

View File

@ -37,11 +37,14 @@ public class GraphIndexer {
private DominatorTree domTree; private DominatorTree domTree;
private int lastIndex; private int lastIndex;
private int[] weights; private int[] weights;
private int[] priorities;
public GraphIndexer(Graph graph, int[] weights) { public GraphIndexer(Graph graph, int[] weights, int[] priorities) {
int sz = graph.size(); int sz = graph.size();
this.weights = weights; this.weights = weights.clone();
propagateWeights(graph, weights); propagateWeights(graph, this.weights);
this.priorities = priorities.clone();
propagatePriorities(graph, this.priorities);
indexToNode = new int[sz + 1]; indexToNode = new int[sz + 1];
nodeToIndex = new int[sz + 1]; nodeToIndex = new int[sz + 1];
Arrays.fill(nodeToIndex, -1); Arrays.fill(nodeToIndex, -1);
@ -99,6 +102,39 @@ public class GraphIndexer {
} }
} }
private void propagatePriorities(Graph graph, int[] priorities) {
boolean allZero = true;
for (int i = 0; i < priorities.length; ++i) {
if (priorities[i] != 0) {
allZero = false;
break;
}
}
if (allZero) {
return;
}
DominatorTree domTree = GraphUtils.buildDominatorTree(graph);
Graph domGraph = GraphUtils.buildDominatorGraph(domTree, graph.size());
IntegerStack stack = new IntegerStack(graph.size() * 2);
for (int i = 0; i < domGraph.size(); ++i) {
if (domGraph.outgoingEdgesCount(i) == 0) {
stack.push(i);
}
}
while (!stack.isEmpty()) {
int node = stack.pop();
int parent = domTree.immediateDominatorOf(node);
if (parent < 0) {
continue;
}
if (priorities[parent] < priorities[node]) {
priorities[parent] = priorities[node];
stack.push(parent);
}
}
}
private void sort(Graph graph) { private void sort(Graph graph) {
int sz = graph.size(); int sz = graph.size();
byte[] state = new byte[sz]; byte[] state = new byte[sz];
@ -128,7 +164,7 @@ public class GraphIndexer {
IntSet loopNodes = IntOpenHashSet.from(findNaturalLoop(node, terminalNodes.getAll())); IntSet loopNodes = IntOpenHashSet.from(findNaturalLoop(node, terminalNodes.getAll()));
for (int succ : successors) { for (int succ : successors) {
if (loopNodes.contains(succ)) { if (loopNodes.contains(succ)) {
succList.add(new WeightedNode(succ, weights[succ])); succList.add(new WeightedNode(succ, priorities[succ], weights[succ]));
} }
} }
Collections.sort(succList); Collections.sort(succList);
@ -142,7 +178,7 @@ public class GraphIndexer {
for (int succ : graph.outgoingEdges(loopNode.value)) { for (int succ : graph.outgoingEdges(loopNode.value)) {
if (!loopNodes.contains(succ)) { if (!loopNodes.contains(succ)) {
if (outerSuccessors.add(succ)) { if (outerSuccessors.add(succ)) {
succList.add(new WeightedNode(succ, weights[succ])); succList.add(new WeightedNode(succ, priorities[succ], weights[succ]));
} }
} }
} }
@ -153,7 +189,7 @@ public class GraphIndexer {
} }
} else { } else {
for (int succ : successors) { for (int succ : successors) {
succList.add(new WeightedNode(succ, weights[succ])); succList.add(new WeightedNode(succ, priorities[succ], weights[succ]));
} }
Collections.sort(succList); Collections.sort(succList);
for (WeightedNode wnode : succList) { for (WeightedNode wnode : succList) {
@ -209,15 +245,21 @@ public class GraphIndexer {
static class WeightedNode implements Comparable<WeightedNode> { static class WeightedNode implements Comparable<WeightedNode> {
int index; int index;
int priority;
int weight; int weight;
public WeightedNode(int index, int weight) { public WeightedNode(int index, int priority, int weight) {
this.index = index; this.index = index;
this.priority = priority;
this.weight = weight; this.weight = weight;
} }
@Override @Override
public int compareTo(WeightedNode o) { public int compareTo(WeightedNode o) {
int r = Integer.compare(priority, o.priority);
if (r != 0) {
return r;
}
return Integer.compare(weight, o.weight); return Integer.compare(weight, o.weight);
} }
} }

View File

@ -338,7 +338,13 @@ public class Decompiler {
for (int i = 0; i < weights.length; ++i) { for (int i = 0; i < weights.length; ++i) {
weights[i] = program.basicBlockAt(i).getInstructions().size(); weights[i] = program.basicBlockAt(i).getInstructions().size();
} }
indexer = new GraphIndexer(graph, weights); int[] priorities = new int[graph.size()];
for (int i = 0; i < targetBlocks.length; ++i) {
if (targetBlocks[i] >= 0) {
priorities[i] = 1;
}
}
indexer = new GraphIndexer(graph, weights, priorities);
graph = indexer.getGraph(); graph = indexer.getGraph();
loopGraph = new LoopGraph(this.graph); loopGraph = new LoopGraph(this.graph);
unflatCode(); unflatCode();

View File

@ -2079,8 +2079,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(GotoPartStatement statement) { public void visit(GotoPartStatement statement) {
try { try {
if (statement.getPart() != currentPart) {
writer.append(pointerName()).ws().append("=").ws().append(statement.getPart()).append(";") writer.append(pointerName()).ws().append("=").ws().append(statement.getPart()).append(";")
.softNewLine(); .softNewLine();
}
if (!end || statement.getPart() != currentPart + 1) { if (!end || statement.getPart() != currentPart + 1) {
writer.append("continue ").append(mainLoopName()).append(";").softNewLine(); writer.append("continue ").append(mainLoopName()).append(";").softNewLine();
} }