Skip to content

Commit 2b63059

Browse files
Create newtype around the pre order index
1 parent cc63ec3 commit 2b63059

File tree

1 file changed

+41
-32
lines changed
  • compiler/rustc_data_structures/src/graph/dominators

1 file changed

+41
-32
lines changed

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

+41-32
Original file line numberDiff line numberDiff line change
@@ -11,53 +11,59 @@ use std::cmp::Ordering;
1111
#[cfg(test)]
1212
mod tests;
1313

14-
struct PreOrderFrame<Node, Iter> {
15-
node: Node,
14+
struct PreOrderFrame<Iter> {
15+
pre_order_idx: PreorderIndex,
1616
iter: Iter,
1717
}
1818

19+
rustc_index::newtype_index! {
20+
struct PreorderIndex { .. }
21+
}
22+
1923
pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
2024
// compute the post order index (rank) for each node
2125
let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes());
22-
let mut parent: IndexVec<usize, Option<usize>> = IndexVec::from_elem_n(None, graph.num_nodes());
26+
let mut parent: IndexVec<PreorderIndex, Option<PreorderIndex>> =
27+
IndexVec::from_elem_n(None, graph.num_nodes());
2328

24-
let mut stack = vec![PreOrderFrame { node: 0, iter: graph.successors(graph.start_node()) }];
25-
let mut pre_order_to_real = Vec::with_capacity(graph.num_nodes());
26-
let mut real_to_pre_order: IndexVec<G::Node, Option<usize>> =
29+
let mut stack = vec![PreOrderFrame {
30+
pre_order_idx: PreorderIndex::new(0),
31+
iter: graph.successors(graph.start_node()),
32+
}];
33+
let mut pre_order_to_real: IndexVec<PreorderIndex, G::Node> =
34+
IndexVec::with_capacity(graph.num_nodes());
35+
let mut real_to_pre_order: IndexVec<G::Node, Option<PreorderIndex>> =
2736
IndexVec::from_elem_n(None, graph.num_nodes());
2837
pre_order_to_real.push(graph.start_node());
29-
real_to_pre_order[graph.start_node()] = Some(0);
38+
real_to_pre_order[graph.start_node()] = Some(PreorderIndex::new(0));
3039
let mut post_order_idx = 0;
3140

3241
'recurse: while let Some(frame) = stack.last_mut() {
3342
while let Some(successor) = frame.iter.next() {
3443
if real_to_pre_order[successor].is_none() {
35-
let pre_order_idx = pre_order_to_real.len();
36-
44+
let pre_order_idx = pre_order_to_real.push(successor);
3745
real_to_pre_order[successor] = Some(pre_order_idx);
38-
parent[pre_order_idx] = Some(frame.node);
39-
pre_order_to_real.push(successor);
40-
stack
41-
.push(PreOrderFrame { node: pre_order_idx, iter: graph.successors(successor) });
46+
parent[pre_order_idx] = Some(frame.pre_order_idx);
47+
stack.push(PreOrderFrame { pre_order_idx, iter: graph.successors(successor) });
4248

4349
continue 'recurse;
4450
}
4551
}
46-
post_order_rank[pre_order_to_real[frame.node]] = post_order_idx;
52+
post_order_rank[pre_order_to_real[frame.pre_order_idx]] = post_order_idx;
4753
post_order_idx += 1;
4854

4955
stack.pop();
5056
}
5157

5258
let reachable_vertices = pre_order_to_real.len();
5359

54-
let mut idom = IndexVec::from_elem_n(0, reachable_vertices);
60+
let mut idom = IndexVec::from_elem_n(PreorderIndex::new(0), reachable_vertices);
5561
let mut semi = IndexVec::from_fn_n(std::convert::identity, reachable_vertices);
5662
let mut label = semi.clone();
5763
let mut bucket = IndexVec::from_elem_n(vec![], reachable_vertices);
5864
let mut lastlinked = None;
5965

60-
for w in (1..reachable_vertices).rev() {
66+
for w in (PreorderIndex::new(1)..PreorderIndex::new(reachable_vertices)).rev() {
6167
// Optimization: process buckets just once, at the start of the
6268
// iteration. Do not explicitly empty the bucket (even though it will
6369
// not be used again), to save some instructions.
@@ -87,27 +93,28 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
8793
// processed elements; lastlinked represents the divider.
8894
lastlinked = Some(w);
8995
}
90-
for w in 1..reachable_vertices {
96+
for w in PreorderIndex::new(1)..PreorderIndex::new(reachable_vertices) {
9197
if idom[w] != semi[w] {
9298
idom[w] = idom[idom[w]];
9399
}
94100
}
95101

96102
let mut immediate_dominators = IndexVec::from_elem_n(None, graph.num_nodes());
97-
for (idx, node) in pre_order_to_real.iter().enumerate() {
103+
for (idx, node) in pre_order_to_real.iter_enumerated() {
98104
immediate_dominators[*node] = Some(pre_order_to_real[idom[idx]]);
99105
}
100106

101107
Dominators { post_order_rank, immediate_dominators }
102108
}
103109

104-
fn eval<N: Idx>(
105-
ancestor: &mut IndexVec<N, Option<N>>,
106-
lastlinked: Option<N>,
107-
semi: &IndexVec<N, N>,
108-
label: &mut IndexVec<N, N>,
109-
node: N,
110-
) -> N {
110+
#[inline]
111+
fn eval(
112+
ancestor: &mut IndexVec<PreorderIndex, Option<PreorderIndex>>,
113+
lastlinked: Option<PreorderIndex>,
114+
semi: &IndexVec<PreorderIndex, PreorderIndex>,
115+
label: &mut IndexVec<PreorderIndex, PreorderIndex>,
116+
node: PreorderIndex,
117+
) -> PreorderIndex {
111118
if is_processed(node, lastlinked) {
112119
compress(ancestor, lastlinked, semi, label, node);
113120
label[node]
@@ -116,16 +123,18 @@ fn eval<N: Idx>(
116123
}
117124
}
118125

119-
fn is_processed<N: Idx>(v: N, lastlinked: Option<N>) -> bool {
126+
#[inline]
127+
fn is_processed(v: PreorderIndex, lastlinked: Option<PreorderIndex>) -> bool {
120128
if let Some(ll) = lastlinked { v >= ll } else { false }
121129
}
122130

123-
fn compress<N: Idx>(
124-
ancestor: &mut IndexVec<N, Option<N>>,
125-
lastlinked: Option<N>,
126-
semi: &IndexVec<N, N>,
127-
label: &mut IndexVec<N, N>,
128-
v: N,
131+
#[inline]
132+
fn compress(
133+
ancestor: &mut IndexVec<PreorderIndex, Option<PreorderIndex>>,
134+
lastlinked: Option<PreorderIndex>,
135+
semi: &IndexVec<PreorderIndex, PreorderIndex>,
136+
label: &mut IndexVec<PreorderIndex, PreorderIndex>,
137+
v: PreorderIndex,
129138
) {
130139
assert!(is_processed(v, lastlinked));
131140
let u = ancestor[v].unwrap();

0 commit comments

Comments
 (0)