about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src/graph
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-05-15 13:09:21 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-05-15 16:16:34 +0000
commit84339a6f0577b2bd9526383d2a6e3bda7b59c920 (patch)
treed5fb133b6ae0b4235595b823760e85a4b6989412 /compiler/rustc_data_structures/src/graph
parent2913ad6db0f72fed5139253faed73200c7af3535 (diff)
downloadrust-84339a6f0577b2bd9526383d2a6e3bda7b59c920.tar.gz
rust-84339a6f0577b2bd9526383d2a6e3bda7b59c920.zip
Process current bucket instead of parent's bucket when starting loop for dominators.
Diffstat (limited to 'compiler/rustc_data_structures/src/graph')
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs16
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/tests.rs27
2 files changed, 35 insertions, 8 deletions
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index a7de709ba72..594ed1ad2e7 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -109,28 +109,27 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
         // they have been placed in the bucket.
         //
         // We compute a partial set of immediate dominators here.
-        let z = parent[w];
-        for &v in bucket[z].iter() {
+        for &v in bucket[w].iter() {
             // This uses the result of Lemma 5 from section 2 from the original
             // 1979 paper, to compute either the immediate or relative dominator
             // for a given vertex v.
             //
             // eval returns a vertex y, for which semi[y] is minimum among
-            // vertices semi[v] +> y *> v. Note that semi[v] = z as we're in the
-            // z bucket.
+            // vertices semi[v] +> y *> v. Note that semi[v] = w as we're in the
+            // w bucket.
             //
             // Given such a vertex y, semi[y] <= semi[v] and idom[y] = idom[v].
             // If semi[y] = semi[v], though, idom[v] = semi[v].
             //
             // Using this, we can either set idom[v] to be:
-            //  * semi[v] (i.e. z), if semi[y] is z
+            //  * semi[v] (i.e. w), if semi[y] is w
             //  * idom[y], otherwise
             //
             // We don't directly set to idom[y] though as it's not necessarily
             // known yet. The second preorder traversal will cleanup by updating
             // the idom for any that were missed in this pass.
             let y = eval(&mut parent, lastlinked, &semi, &mut label, v);
-            idom[v] = if semi[y] < z { y } else { z };
+            idom[v] = if semi[y] < w { y } else { w };
         }
 
         // This loop computes the semi[w] for w.
@@ -213,10 +212,11 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
         // If we don't yet know the idom directly, then push this vertex into
         // our semidominator's bucket, where it will get processed at a later
         // stage to compute its immediate dominator.
-        if parent[w] != semi[w] {
+        let z = parent[w];
+        if z != semi[w] {
             bucket[semi[w]].push(w);
         } else {
-            idom[w] = parent[w];
+            idom[w] = z;
         }
 
         // Optimization: We share the parent array between processed and not
diff --git a/compiler/rustc_data_structures/src/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
index 8b124516623..5472bb8087e 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
@@ -53,3 +53,30 @@ fn immediate_dominator() {
     assert_eq!(dominators.immediate_dominator(2), Some(1));
     assert_eq!(dominators.immediate_dominator(3), Some(2));
 }
+
+#[test]
+fn transitive_dominator() {
+    let graph = TestGraph::new(
+        0,
+        &[
+            // First tree branch.
+            (0, 1),
+            (1, 2),
+            (2, 3),
+            (3, 4),
+            // Second tree branch.
+            (1, 5),
+            (5, 6),
+            // Third tree branch.
+            (0, 7),
+            // These links make 0 the dominator for 2 and 3.
+            (7, 2),
+            (5, 3),
+        ],
+    );
+
+    let dom_tree = dominators(&graph);
+    let immediate_dominators = &dom_tree.immediate_dominators;
+    assert_eq!(immediate_dominators[2], Some(0));
+    assert_eq!(immediate_dominators[3], Some(0)); // This used to return Some(1).
+}