diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index ea78e32dc..d9a8d55fb 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -114,45 +114,51 @@ public final class GraphUtils { int[] headerIndex = new int[graph.size()]; int lastIndex = 0; IntegerStack stack = new IntegerStack(graph.size()); + for (int startNode : start) { stack.push(startNode); - } - - IntegerArray currentComponent = new IntegerArray(1); - while (!stack.isEmpty()) { - int node = stack.pop(); - if (visitIndex[node] > 0) { - if (headerIndex[node] > 0) { - continue; - } - currentComponent.add(node); - int hdr = visitIndex[node]; - for (int successor : graph.outgoingEdges(node)) { - if (!filter.match(successor)) { + IntegerArray currentComponent = new IntegerArray(1); + while (!stack.isEmpty()) { + int node = stack.pop(); + if (visitIndex[node] > 0) { + if (headerIndex[node] > 0) { continue; } - if (headerIndex[successor] == 0) { - hdr = Math.min(hdr, visitIndex[successor]); - } else { - hdr = Math.min(hdr, headerIndex[successor]); + currentComponent.add(node); + int hdr = visitIndex[node]; + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor)) { + continue; + } + if (headerIndex[successor] == 0) { + hdr = Math.min(hdr, visitIndex[successor]); + } else { + hdr = Math.min(hdr, headerIndex[successor]); + } + } + if (hdr == visitIndex[node]) { + components.add(currentComponent.getAll()); + currentComponent.clear(); + } + headerIndex[node] = hdr; + } else { + visitIndex[node] = ++lastIndex; + stack.push(node); + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor) || visitIndex[successor] > 0) { + continue; + } + stack.push(successor); } } - if (hdr == visitIndex[node]) { - components.add(currentComponent.getAll()); - currentComponent.clear(); - } - headerIndex[node] = hdr; - } else { - visitIndex[node] = ++lastIndex; - stack.push(node); - for (int successor : graph.outgoingEdges(node)) { - if (!filter.match(successor) || visitIndex[successor] > 0) { - continue; - } - stack.push(successor); + } + for (int i = 0; i < headerIndex.length; ++i) { + if (visitIndex[i] > 0) { + headerIndex[i] = graph.size() + 1; } } } + return components.toArray(new int[0][]); } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index 68d2cd91b..b5e06125b 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -81,22 +81,6 @@ public class IrreducibleGraphConverter { } } - private int[] reachUnder(DJGraph djGraph, int back, int header) { - IntSet naturalLoop = IntOpenHashSet.from(header); - IntegerStack stack = new IntegerStack(djGraph.getGraph().size()); - stack.push(back); - while (!stack.isEmpty()) { - int node = stack.pop(); - if (!naturalLoop.add(node)) { - continue; - } - for (int pred : djGraph.getGraph().incomingEdges(node)) { - stack.push(pred); - } - } - return naturalLoop.toArray(); - } - private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[][] nodeMap) { // Find shared dominator int sharedDom = scc[0]; @@ -104,6 +88,13 @@ public class IrreducibleGraphConverter { sharedDom = djGraph.getDomTree().commonDominatorOf(sharedDom, scc[i]); } + for (int i = 0; i < scc.length; ++i) { + if (scc[i] == sharedDom) { + djGraph.collapse(scc); + return; + } + } + // Partition SCC into domains DisjointSet partitions = new DisjointSet(); int[] sccBack = new int[djGraph.getGraph().size()]; @@ -154,7 +145,9 @@ public class IrreducibleGraphConverter { splitStronglyConnectedComponent(djGraph, domainNodes, sharedDom, scc, nodeMap); // Collapse - djGraph.collapse(scc); + int[] sccAndTop = Arrays.copyOf(scc, scc.length + 1); + sccAndTop[scc.length] = sharedDom; + djGraph.collapse(sccAndTop); } private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom,