Skip to content

Commit 6f1127e

Browse files
author
Michael Emmi
committed
Compute topological sort using post-order traversal
* fixes #2080
1 parent e4365f6 commit 6f1127e

File tree

2 files changed

+68
-9
lines changed

2 files changed

+68
-9
lines changed

src/main/java/soot/jimple/spark/solver/TopoSorter.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222
* #L%
2323
*/
2424

25-
import java.util.ArrayList;
2625
import java.util.HashSet;
27-
import java.util.List;
26+
import java.util.Stack;
2827

2928
import soot.jimple.spark.pag.Node;
3029
import soot.jimple.spark.pag.PAG;
@@ -64,23 +63,21 @@ protected void dfsVisit(VarNode n) {
6463
if (visited.contains(n)) {
6564
return;
6665
}
67-
List<VarNode> stack = new ArrayList<>();
68-
List<VarNode> all = new ArrayList<>();
66+
Stack<VarNode> stack = new Stack<>();
6967
stack.add(n);
7068
while (!stack.isEmpty()) {
71-
VarNode s = stack.remove(stack.size() - 1);
69+
VarNode s = stack.peek();
7270
if (visited.add(s)) {
73-
all.add(s);
7471
Node[] succs = pag.simpleLookup(s);
7572
for (Node element : succs) {
7673
if (ignoreTypes || pag.getTypeManager().castNeverFails(n.getType(), element.getType())) {
7774
stack.add((VarNode) element);
7875
}
7976
}
77+
} else {
78+
stack.pop();
79+
s.setFinishingNumber(nextFinishNumber++);
8080
}
8181
}
82-
for (int i = all.size() - 1; i >= 0; i--) {
83-
all.get(i).setFinishingNumber(nextFinishNumber++);
84-
}
8582
}
8683
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package soot.jimple.spark.solver;
2+
3+
/*-
4+
* #%L
5+
* Soot - a J*va Optimization Framework
6+
* %%
7+
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
8+
* %%
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as
11+
* published by the Free Software Foundation, either version 2.1 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Lesser Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Lesser Public
20+
* License along with this program. If not, see
21+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
22+
* #L%
23+
*/
24+
25+
import java.util.Collections;
26+
27+
import org.junit.Test;
28+
29+
import static org.junit.Assert.assertEquals;
30+
31+
import soot.Scene;
32+
import soot.Type;
33+
import soot.jimple.spark.pag.PAG;
34+
import soot.jimple.spark.pag.VarNode;
35+
import soot.options.SparkOptions;
36+
37+
public class SCCCollapserTest {
38+
39+
@Test
40+
public void testSeparateComponents() {
41+
Scene.v().loadBasicClasses();
42+
Type type = Scene.v().getObjectType();
43+
44+
SparkOptions sparkOptions = new SparkOptions(Collections.emptyMap());
45+
PAG pag = new PAG(sparkOptions);
46+
47+
VarNode a = pag.makeGlobalVarNode("a", type);
48+
VarNode b = pag.makeGlobalVarNode("b", type);
49+
VarNode c = pag.makeGlobalVarNode("c", type);
50+
pag.addEdge(a, b);
51+
pag.addEdge(a, c);
52+
pag.addEdge(b, c);
53+
54+
SCCCollapser sccCollapser = new SCCCollapser(pag, false);
55+
sccCollapser.collapse();
56+
pag.cleanUpMerges();
57+
58+
assertEquals(a, a.getReplacement());
59+
assertEquals(b, b.getReplacement());
60+
assertEquals(c, c.getReplacement());
61+
}
62+
}

0 commit comments

Comments
 (0)