Skip to content

Commit f16d2b1

Browse files
committed
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.
1 parent 3603a84 commit f16d2b1

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

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;

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

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)