@@ -11,53 +11,59 @@ use std::cmp::Ordering;
1111#[ cfg( test) ]
1212mod 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+
1923pub 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