Skip to content

Commit be8718a

Browse files
authored
Rollup merge of #111547 - tmiasko:immediate-dominator, r=cjgillot
Start node has no immediate dominator Change the immediate_dominator return type to Option, and use None to indicate that node has no immediate dominator. Also fix the issue where the start node would be returned as its own immediate dominator.
2 parents 7a1f3e7 + f16d2b1 commit be8718a

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

Diff for: compiler/rustc_const_eval/src/transform/validate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
164164
if let Some(root) = post_contract_node.get(&bb) {
165165
break *root;
166166
}
167-
let parent = doms.immediate_dominator(bb);
167+
let parent = doms.immediate_dominator(bb).unwrap();
168168
dom_path.push(bb);
169169
if !self.body.basic_blocks[parent].is_cleanup {
170170
break bb;

Diff for: compiler/rustc_data_structures/src/graph/dominators/mod.rs

+10-12
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
242242
immediate_dominators[*node] = Some(pre_order_to_real[idom[idx]]);
243243
}
244244

245-
Dominators { post_order_rank, immediate_dominators }
245+
let start_node = graph.start_node();
246+
immediate_dominators[start_node] = None;
247+
Dominators { start_node, post_order_rank, immediate_dominators }
246248
}
247249

248250
/// Evaluate the link-eval virtual forest, providing the currently minimum semi
@@ -308,6 +310,7 @@ fn compress(
308310
/// Tracks the list of dominators for each node.
309311
#[derive(Clone, Debug)]
310312
pub struct Dominators<N: Idx> {
313+
start_node: N,
311314
post_order_rank: IndexVec<N, usize>,
312315
// Even though we track only the immediate dominator of each node, it's
313316
// possible to get its full list of dominators by looking up the dominator
@@ -316,14 +319,14 @@ pub struct Dominators<N: Idx> {
316319
}
317320

318321
impl<Node: Idx> Dominators<Node> {
319-
/// Whether the given Node has an immediate dominator.
322+
/// Returns true if node is reachable from the start node.
320323
pub fn is_reachable(&self, node: Node) -> bool {
321-
self.immediate_dominators[node].is_some()
324+
node == self.start_node || self.immediate_dominators[node].is_some()
322325
}
323326

324-
pub fn immediate_dominator(&self, node: Node) -> Node {
325-
assert!(self.is_reachable(node), "node {node:?} is not reachable");
326-
self.immediate_dominators[node].unwrap()
327+
/// Returns the immediate dominator of node, if any.
328+
pub fn immediate_dominator(&self, node: Node) -> Option<Node> {
329+
self.immediate_dominators[node]
327330
}
328331

329332
/// Provides an iterator over each dominator up the CFG, for the given Node.
@@ -357,12 +360,7 @@ impl<'dom, Node: Idx> Iterator for Iter<'dom, Node> {
357360

358361
fn next(&mut self) -> Option<Self::Item> {
359362
if let Some(node) = self.node {
360-
let dom = self.dominators.immediate_dominator(node);
361-
if dom == node {
362-
self.node = None; // reached the root
363-
} else {
364-
self.node = Some(dom);
365-
}
363+
self.node = self.dominators.immediate_dominator(node);
366364
Some(node)
367365
} else {
368366
None

Diff for: compiler/rustc_data_structures/src/graph/dominators/tests.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn diamond() {
88

99
let dominators = dominators(&graph);
1010
let immediate_dominators = &dominators.immediate_dominators;
11-
assert_eq!(immediate_dominators[0], Some(0));
11+
assert_eq!(immediate_dominators[0], None);
1212
assert_eq!(immediate_dominators[1], Some(0));
1313
assert_eq!(immediate_dominators[2], Some(0));
1414
assert_eq!(immediate_dominators[3], Some(0));
@@ -30,7 +30,7 @@ fn paper() {
3030
assert_eq!(immediate_dominators[3], Some(6));
3131
assert_eq!(immediate_dominators[4], Some(6));
3232
assert_eq!(immediate_dominators[5], Some(6));
33-
assert_eq!(immediate_dominators[6], Some(6));
33+
assert_eq!(immediate_dominators[6], None);
3434
}
3535

3636
#[test]
@@ -43,3 +43,13 @@ fn paper_slt() {
4343

4444
dominators(&graph);
4545
}
46+
47+
#[test]
48+
fn immediate_dominator() {
49+
let graph = TestGraph::new(1, &[(1, 2), (2, 3)]);
50+
let dominators = dominators(&graph);
51+
assert_eq!(dominators.immediate_dominator(0), None);
52+
assert_eq!(dominators.immediate_dominator(1), None);
53+
assert_eq!(dominators.immediate_dominator(2), Some(1));
54+
assert_eq!(dominators.immediate_dominator(3), Some(2));
55+
}

0 commit comments

Comments
 (0)