diff --git a/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java b/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java index 21f1b94c6..f1b2707c2 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java @@ -37,11 +37,14 @@ public class GraphIndexer { private DominatorTree domTree; private int lastIndex; private int[] weights; + private int[] priorities; - public GraphIndexer(Graph graph, int[] weights) { + public GraphIndexer(Graph graph, int[] weights, int[] priorities) { int sz = graph.size(); - this.weights = weights; - propagateWeights(graph, weights); + this.weights = weights.clone(); + propagateWeights(graph, this.weights); + this.priorities = priorities.clone(); + propagatePriorities(graph, this.priorities); indexToNode = new int[sz + 1]; nodeToIndex = new int[sz + 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) { int sz = graph.size(); byte[] state = new byte[sz]; @@ -128,7 +164,7 @@ public class GraphIndexer { IntSet loopNodes = IntOpenHashSet.from(findNaturalLoop(node, terminalNodes.getAll())); for (int succ : successors) { if (loopNodes.contains(succ)) { - succList.add(new WeightedNode(succ, weights[succ])); + succList.add(new WeightedNode(succ, priorities[succ], weights[succ])); } } Collections.sort(succList); @@ -142,7 +178,7 @@ public class GraphIndexer { for (int succ : graph.outgoingEdges(loopNode.value)) { if (!loopNodes.contains(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 { for (int succ : successors) { - succList.add(new WeightedNode(succ, weights[succ])); + succList.add(new WeightedNode(succ, priorities[succ], weights[succ])); } Collections.sort(succList); for (WeightedNode wnode : succList) { @@ -209,15 +245,21 @@ public class GraphIndexer { static class WeightedNode implements Comparable { int index; + int priority; int weight; - public WeightedNode(int index, int weight) { + public WeightedNode(int index, int priority, int weight) { this.index = index; + this.priority = priority; this.weight = weight; } @Override public int compareTo(WeightedNode o) { + int r = Integer.compare(priority, o.priority); + if (r != 0) { + return r; + } return Integer.compare(weight, o.weight); } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index 97e19d484..ca3ba41be 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -338,7 +338,13 @@ public class Decompiler { for (int i = 0; i < weights.length; ++i) { 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(); loopGraph = new LoopGraph(this.graph); unflatCode(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 41591f971..3451cd4c8 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -2079,8 +2079,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext @Override public void visit(GotoPartStatement statement) { try { - writer.append(pointerName()).ws().append("=").ws().append(statement.getPart()).append(";") - .softNewLine(); + if (statement.getPart() != currentPart) { + writer.append(pointerName()).ws().append("=").ws().append(statement.getPart()).append(";") + .softNewLine(); + } if (!end || statement.getPart() != currentPart + 1) { writer.append("continue ").append(mainLoopName()).append(";").softNewLine(); }