Skip to content

Commit fa8598c

Browse files
committed
Merge DominatorTree and Dominators.
1 parent 4bbdb64 commit fa8598c

File tree

6 files changed

+40
-61
lines changed

6 files changed

+40
-61
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
155155
if self.unwind_edge_count <= 1 {
156156
return;
157157
}
158-
let dom_tree = self.body.basic_blocks.dominator_tree();
158+
let dom_tree = self.body.basic_blocks.dominators();
159159
let mut post_contract_node = FxHashMap::default();
160160
// Reusing the allocation across invocations of the closure
161161
let mut dom_path = vec![];

compiler/rustc_data_structures/src/graph/dominators/mod.rs

+26-32
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ rustc_index::newtype_index! {
2626
struct PreorderIndex {}
2727
}
2828

29-
pub fn dominator_tree<G: ControlFlowGraph>(graph: G) -> DominatorTree<G::Node> {
29+
pub fn dominators<G: ControlFlowGraph>(graph: &G) -> Dominators<G::Node> {
3030
// compute the post order index (rank) for each node
3131
let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes());
3232

@@ -244,7 +244,10 @@ pub fn dominator_tree<G: ControlFlowGraph>(graph: G) -> DominatorTree<G::Node> {
244244

245245
let start_node = graph.start_node();
246246
immediate_dominators[start_node] = None;
247-
DominatorTree { start_node, post_order_rank, immediate_dominators }
247+
248+
let time = compute_access_time(start_node, &immediate_dominators);
249+
250+
Dominators { start_node, post_order_rank, immediate_dominators, time }
248251
}
249252

250253
/// Evaluate the link-eval virtual forest, providing the currently minimum semi
@@ -309,16 +312,17 @@ fn compress(
309312

310313
/// Tracks the list of dominators for each node.
311314
#[derive(Clone, Debug)]
312-
pub struct DominatorTree<N: Idx> {
315+
pub struct Dominators<N: Idx> {
313316
start_node: N,
314317
post_order_rank: IndexVec<N, usize>,
315318
// Even though we track only the immediate dominator of each node, it's
316319
// possible to get its full list of dominators by looking up the dominator
317320
// of each dominator. (See the `impl Iterator for Iter` definition).
318321
immediate_dominators: IndexVec<N, Option<N>>,
322+
time: IndexVec<N, Time>,
319323
}
320324

321-
impl<Node: Idx> DominatorTree<Node> {
325+
impl<Node: Idx> Dominators<Node> {
322326
/// Returns true if node is reachable from the start node.
323327
pub fn is_reachable(&self, node: Node) -> bool {
324328
node == self.start_node || self.immediate_dominators[node].is_some()
@@ -343,10 +347,22 @@ impl<Node: Idx> DominatorTree<Node> {
343347
pub fn rank_partial_cmp(&self, lhs: Node, rhs: Node) -> Option<Ordering> {
344348
self.post_order_rank[rhs].partial_cmp(&self.post_order_rank[lhs])
345349
}
350+
351+
/// Returns true if `a` dominates `b`.
352+
///
353+
/// # Panics
354+
///
355+
/// Panics if `b` is unreachable.
356+
pub fn dominates(&self, a: Node, b: Node) -> bool {
357+
let a = self.time[a];
358+
let b = self.time[b];
359+
assert!(b.start != 0, "node {b:?} is not reachable");
360+
a.start <= b.start && b.finish <= a.finish
361+
}
346362
}
347363

348364
pub struct Iter<'dom, Node: Idx> {
349-
dom_tree: &'dom DominatorTree<Node>,
365+
dom_tree: &'dom Dominators<Node>,
350366
node: Option<Node>,
351367
}
352368

@@ -363,11 +379,6 @@ impl<'dom, Node: Idx> Iterator for Iter<'dom, Node> {
363379
}
364380
}
365381

366-
#[derive(Clone, Debug)]
367-
pub struct Dominators<Node: Idx> {
368-
time: IndexVec<Node, Time>,
369-
}
370-
371382
/// Describes the number of vertices discovered at the time when processing of a particular vertex
372383
/// started and when it finished. Both values are zero for unreachable vertices.
373384
#[derive(Copy, Clone, Default, Debug)]
@@ -376,27 +387,10 @@ struct Time {
376387
finish: u32,
377388
}
378389

379-
impl<Node: Idx> Dominators<Node> {
380-
pub fn dummy() -> Self {
381-
Self { time: Default::default() }
382-
}
383-
384-
/// Returns true if `a` dominates `b`.
385-
///
386-
/// # Panics
387-
///
388-
/// Panics if `b` is unreachable.
389-
pub fn dominates(&self, a: Node, b: Node) -> bool {
390-
let a = self.time[a];
391-
let b = self.time[b];
392-
assert!(b.start != 0, "node {b:?} is not reachable");
393-
a.start <= b.start && b.finish <= a.finish
394-
}
395-
}
396-
397-
pub fn dominators<N: Idx>(tree: &DominatorTree<N>) -> Dominators<N> {
398-
let DominatorTree { start_node, ref immediate_dominators, post_order_rank: _ } = *tree;
399-
390+
fn compute_access_time<N: Idx>(
391+
start_node: N,
392+
immediate_dominators: &IndexSlice<N, Option<N>>,
393+
) -> IndexVec<N, Time> {
400394
// Transpose the dominator tree edges, so that child nodes of vertex v are stored in
401395
// node[edges[v].start..edges[v].end].
402396
let mut edges: IndexVec<N, std::ops::Range<u32>> =
@@ -446,5 +440,5 @@ pub fn dominators<N: Idx>(tree: &DominatorTree<N>) -> Dominators<N> {
446440
}
447441
}
448442

449-
Dominators { time }
443+
time
450444
}

compiler/rustc_data_structures/src/graph/dominators/tests.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use super::super::tests::TestGraph;
66
fn diamond() {
77
let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]);
88

9-
let tree = dominator_tree(&graph);
9+
let tree = dominators(&graph);
1010
let immediate_dominators = &tree.immediate_dominators;
1111
assert_eq!(immediate_dominators[0], None);
1212
assert_eq!(immediate_dominators[1], Some(0));
@@ -22,7 +22,7 @@ fn paper() {
2222
&[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2), (2, 1)],
2323
);
2424

25-
let dom_tree = dominator_tree(&graph);
25+
let dom_tree = dominators(&graph);
2626
let immediate_dominators = &dom_tree.immediate_dominators;
2727
assert_eq!(immediate_dominators[0], None); // <-- note that 0 is not in graph
2828
assert_eq!(immediate_dominators[1], Some(6));
@@ -41,13 +41,13 @@ fn paper_slt() {
4141
&[(1, 2), (1, 3), (2, 3), (2, 7), (3, 4), (3, 6), (4, 5), (5, 4), (6, 7), (7, 8), (8, 5)],
4242
);
4343

44-
dominator_tree(&graph);
44+
dominators(&graph);
4545
}
4646

4747
#[test]
4848
fn immediate_dominator() {
4949
let graph = TestGraph::new(1, &[(1, 2), (2, 3)]);
50-
let tree = dominator_tree(&graph);
50+
let tree = dominators(&graph);
5151
assert_eq!(tree.immediate_dominator(0), None);
5252
assert_eq!(tree.immediate_dominator(1), None);
5353
assert_eq!(tree.immediate_dominator(2), Some(1));

compiler/rustc_middle/src/mir/basic_blocks.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::mir::{BasicBlock, BasicBlockData, Successors, Terminator, TerminatorK
33

44
use rustc_data_structures::fx::FxHashMap;
55
use rustc_data_structures::graph;
6-
use rustc_data_structures::graph::dominators::{dominator_tree, DominatorTree};
76
use rustc_data_structures::graph::dominators::{dominators, Dominators};
87
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
98
use rustc_data_structures::sync::OnceCell;
@@ -28,7 +27,6 @@ struct Cache {
2827
switch_sources: OnceCell<SwitchSources>,
2928
is_cyclic: OnceCell<bool>,
3029
postorder: OnceCell<Vec<BasicBlock>>,
31-
dominator_tree: OnceCell<DominatorTree<BasicBlock>>,
3230
dominators: OnceCell<Dominators<BasicBlock>>,
3331
}
3432

@@ -44,12 +42,8 @@ impl<'tcx> BasicBlocks<'tcx> {
4442
*self.cache.is_cyclic.get_or_init(|| graph::is_cyclic(self))
4543
}
4644

47-
pub fn dominator_tree(&self) -> &DominatorTree<BasicBlock> {
48-
self.cache.dominator_tree.get_or_init(|| dominator_tree(&self))
49-
}
50-
5145
pub fn dominators(&self) -> &Dominators<BasicBlock> {
52-
self.cache.dominators.get_or_init(|| dominators(self.dominator_tree()))
46+
self.cache.dominators.get_or_init(|| dominators(self))
5347
}
5448

5549
/// Returns predecessors for each basic block.

compiler/rustc_mir_transform/src/coverage/graph.rs

+5-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::Error;
22

33
use itertools::Itertools;
44
use rustc_data_structures::fx::FxHashMap;
5-
use rustc_data_structures::graph::dominators::{self, DominatorTree, Dominators};
5+
use rustc_data_structures::graph::dominators::{self, Dominators};
66
use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode};
77
use rustc_index::bit_set::BitSet;
88
use rustc_index::{IndexSlice, IndexVec};
@@ -25,7 +25,6 @@ pub(super) struct CoverageGraph {
2525
bb_to_bcb: IndexVec<BasicBlock, Option<BasicCoverageBlock>>,
2626
pub successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
2727
pub predecessors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
28-
dominator_tree: Option<DominatorTree<BasicCoverageBlock>>,
2928
dominators: Option<Dominators<BasicCoverageBlock>>,
3029
}
3130

@@ -68,17 +67,9 @@ impl CoverageGraph {
6867
}
6968
}
7069

71-
let mut basic_coverage_blocks = Self {
72-
bcbs,
73-
bb_to_bcb,
74-
successors,
75-
predecessors,
76-
dominator_tree: None,
77-
dominators: None,
78-
};
79-
let dominator_tree = dominators::dominator_tree(&basic_coverage_blocks);
80-
let dominators = dominators::dominators(&dominator_tree);
81-
basic_coverage_blocks.dominator_tree = Some(dominator_tree);
70+
let mut basic_coverage_blocks =
71+
Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None };
72+
let dominators = dominators::dominators(&basic_coverage_blocks);
8273
basic_coverage_blocks.dominators = Some(dominators);
8374
basic_coverage_blocks
8475
}
@@ -227,7 +218,7 @@ impl CoverageGraph {
227218
a: BasicCoverageBlock,
228219
b: BasicCoverageBlock,
229220
) -> Option<Ordering> {
230-
self.dominator_tree.as_ref().unwrap().rank_partial_cmp(a, b)
221+
self.dominators.as_ref().unwrap().rank_partial_cmp(a, b)
231222
}
232223
}
233224

compiler/rustc_mir_transform/src/ctfe_limit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! (thus indicating there is a loop in the CFG), or whose terminator is a function call.
33
use crate::MirPass;
44

5-
use rustc_data_structures::graph::dominators::DominatorTree;
5+
use rustc_data_structures::graph::dominators::Dominators;
66
use rustc_middle::mir::{
77
BasicBlock, BasicBlockData, Body, Statement, StatementKind, TerminatorKind,
88
};
@@ -13,7 +13,7 @@ pub struct CtfeLimit;
1313
impl<'tcx> MirPass<'tcx> for CtfeLimit {
1414
#[instrument(skip(self, _tcx, body))]
1515
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
16-
let doms = body.basic_blocks.dominator_tree();
16+
let doms = body.basic_blocks.dominators();
1717
let indices: Vec<BasicBlock> = body
1818
.basic_blocks
1919
.iter_enumerated()
@@ -39,7 +39,7 @@ impl<'tcx> MirPass<'tcx> for CtfeLimit {
3939
}
4040

4141
fn has_back_edge(
42-
doms: &DominatorTree<BasicBlock>,
42+
doms: &Dominators<BasicBlock>,
4343
node: BasicBlock,
4444
node_data: &BasicBlockData<'_>,
4545
) -> bool {

0 commit comments

Comments
 (0)