Fix node splitting algorithm

This commit is contained in:
Alexey Andreev 2015-03-04 16:43:06 +04:00
parent 043d6f587f
commit 5ea55675f1
2 changed files with 46 additions and 47 deletions

View File

@ -114,10 +114,9 @@ public final class GraphUtils {
int[] headerIndex = new int[graph.size()]; int[] headerIndex = new int[graph.size()];
int lastIndex = 0; int lastIndex = 0;
IntegerStack stack = new IntegerStack(graph.size()); IntegerStack stack = new IntegerStack(graph.size());
for (int startNode : start) { for (int startNode : start) {
stack.push(startNode); stack.push(startNode);
}
IntegerArray currentComponent = new IntegerArray(1); IntegerArray currentComponent = new IntegerArray(1);
while (!stack.isEmpty()) { while (!stack.isEmpty()) {
int node = stack.pop(); int node = stack.pop();
@ -153,6 +152,13 @@ public final class GraphUtils {
} }
} }
} }
for (int i = 0; i < headerIndex.length; ++i) {
if (visitIndex[i] > 0) {
headerIndex[i] = graph.size() + 1;
}
}
}
return components.toArray(new int[0][]); return components.toArray(new int[0][]);
} }

View File

@ -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) { private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[][] nodeMap) {
// Find shared dominator // Find shared dominator
int sharedDom = scc[0]; int sharedDom = scc[0];
@ -104,6 +88,13 @@ public class IrreducibleGraphConverter {
sharedDom = djGraph.getDomTree().commonDominatorOf(sharedDom, scc[i]); 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 // Partition SCC into domains
DisjointSet partitions = new DisjointSet(); DisjointSet partitions = new DisjointSet();
int[] sccBack = new int[djGraph.getGraph().size()]; int[] sccBack = new int[djGraph.getGraph().size()];
@ -154,7 +145,9 @@ public class IrreducibleGraphConverter {
splitStronglyConnectedComponent(djGraph, domainNodes, sharedDom, scc, nodeMap); splitStronglyConnectedComponent(djGraph, domainNodes, sharedDom, scc, nodeMap);
// Collapse // 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, private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom,