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.
This commit is contained in:
commit
be8718a80b
@ -164,7 +164,7 @@ fn check_cleanup_control_flow(&self) {
|
||||
if let Some(root) = post_contract_node.get(&bb) {
|
||||
break *root;
|
||||
}
|
||||
let parent = doms.immediate_dominator(bb);
|
||||
let parent = doms.immediate_dominator(bb).unwrap();
|
||||
dom_path.push(bb);
|
||||
if !self.body.basic_blocks[parent].is_cleanup {
|
||||
break bb;
|
||||
|
@ -242,7 +242,9 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
|
||||
immediate_dominators[*node] = Some(pre_order_to_real[idom[idx]]);
|
||||
}
|
||||
|
||||
Dominators { post_order_rank, immediate_dominators }
|
||||
let start_node = graph.start_node();
|
||||
immediate_dominators[start_node] = None;
|
||||
Dominators { start_node, post_order_rank, immediate_dominators }
|
||||
}
|
||||
|
||||
/// Evaluate the link-eval virtual forest, providing the currently minimum semi
|
||||
@ -308,6 +310,7 @@ fn compress(
|
||||
/// Tracks the list of dominators for each node.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Dominators<N: Idx> {
|
||||
start_node: N,
|
||||
post_order_rank: IndexVec<N, usize>,
|
||||
// Even though we track only the immediate dominator of each node, it's
|
||||
// possible to get its full list of dominators by looking up the dominator
|
||||
@ -316,14 +319,14 @@ pub struct Dominators<N: Idx> {
|
||||
}
|
||||
|
||||
impl<Node: Idx> Dominators<Node> {
|
||||
/// Whether the given Node has an immediate dominator.
|
||||
/// Returns true if node is reachable from the start node.
|
||||
pub fn is_reachable(&self, node: Node) -> bool {
|
||||
self.immediate_dominators[node].is_some()
|
||||
node == self.start_node || self.immediate_dominators[node].is_some()
|
||||
}
|
||||
|
||||
pub fn immediate_dominator(&self, node: Node) -> Node {
|
||||
assert!(self.is_reachable(node), "node {node:?} is not reachable");
|
||||
self.immediate_dominators[node].unwrap()
|
||||
/// Returns the immediate dominator of node, if any.
|
||||
pub fn immediate_dominator(&self, node: Node) -> Option<Node> {
|
||||
self.immediate_dominators[node]
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(node) = self.node {
|
||||
let dom = self.dominators.immediate_dominator(node);
|
||||
if dom == node {
|
||||
self.node = None; // reached the root
|
||||
} else {
|
||||
self.node = Some(dom);
|
||||
}
|
||||
self.node = self.dominators.immediate_dominator(node);
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
|
@ -8,7 +8,7 @@ fn diamond() {
|
||||
|
||||
let dominators = dominators(&graph);
|
||||
let immediate_dominators = &dominators.immediate_dominators;
|
||||
assert_eq!(immediate_dominators[0], Some(0));
|
||||
assert_eq!(immediate_dominators[0], None);
|
||||
assert_eq!(immediate_dominators[1], Some(0));
|
||||
assert_eq!(immediate_dominators[2], Some(0));
|
||||
assert_eq!(immediate_dominators[3], Some(0));
|
||||
@ -30,7 +30,7 @@ fn paper() {
|
||||
assert_eq!(immediate_dominators[3], Some(6));
|
||||
assert_eq!(immediate_dominators[4], Some(6));
|
||||
assert_eq!(immediate_dominators[5], Some(6));
|
||||
assert_eq!(immediate_dominators[6], Some(6));
|
||||
assert_eq!(immediate_dominators[6], None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -43,3 +43,13 @@ fn paper_slt() {
|
||||
|
||||
dominators(&graph);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immediate_dominator() {
|
||||
let graph = TestGraph::new(1, &[(1, 2), (2, 3)]);
|
||||
let dominators = dominators(&graph);
|
||||
assert_eq!(dominators.immediate_dominator(0), None);
|
||||
assert_eq!(dominators.immediate_dominator(1), None);
|
||||
assert_eq!(dominators.immediate_dominator(2), Some(1));
|
||||
assert_eq!(dominators.immediate_dominator(3), Some(2));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user