@@ -34,60 +34,53 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
3434 }
3535
3636 let mut visited = BitSet :: new_empty ( graph. num_nodes ( ) ) ;
37- let mut parent: IndexVec < G :: Node , Option < G :: Node > > =
38- IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
39- let mut pre_order_index: IndexVec < G :: Node , Option < usize > > =
40- IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
41- let mut pre_order_nodes = Vec :: with_capacity ( rpo. len ( ) ) ;
37+ let mut parent: IndexVec < usize , Option < usize > > = IndexVec :: from_elem_n ( None , rpo. len ( ) ) ;
4238
43- let mut stack = vec ! [ PreOrderFrame {
44- node: graph. start_node( ) ,
45- iter: graph. successors( graph. start_node( ) ) ,
46- } ] ;
39+ let mut stack = vec ! [ PreOrderFrame { node: 0 , iter: graph. successors( graph. start_node( ) ) } ] ;
4740 visited. insert ( graph. start_node ( ) ) ;
48- let mut idx = 0 ;
49- pre_order_index[ graph. start_node ( ) ] = Some ( 0 ) ;
50- idx += 1 ;
51- pre_order_nodes. push ( graph. start_node ( ) ) ;
41+ let mut pre_order_to_real = Vec :: with_capacity ( rpo. len ( ) ) ;
42+ let mut real_to_pre_order: IndexVec < G :: Node , Option < usize > > =
43+ IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
44+ pre_order_to_real. push ( graph. start_node ( ) ) ;
45+ real_to_pre_order[ graph. start_node ( ) ] = Some ( 0 ) ;
46+ let mut idx = 1 ;
5247
5348 ' recurse: while let Some ( frame) = stack. last_mut ( ) {
5449 while let Some ( successor) = frame. iter . next ( ) {
5550 if visited. insert ( successor) {
56- parent[ successor] = Some ( frame. node ) ;
57- pre_order_index[ successor] = Some ( idx) ;
58- pre_order_nodes. push ( successor) ;
59- idx += 1 ;
51+ parent[ idx] = Some ( frame. node ) ;
52+ pre_order_to_real. push ( successor) ;
53+ real_to_pre_order[ successor] = Some ( idx) ;
6054
61- stack. push ( PreOrderFrame { node : successor, iter : graph. successors ( successor) } ) ;
55+ stack. push ( PreOrderFrame { node : idx, iter : graph. successors ( successor) } ) ;
56+ idx += 1 ;
6257 continue ' recurse;
6358 }
6459 }
6560 stack. pop ( ) ;
6661 }
6762
68- let mut idom = IndexVec :: from_elem_n ( graph . start_node ( ) , graph . num_nodes ( ) ) ;
69- let mut semi = IndexVec :: from_fn_n ( std:: convert:: identity, graph . num_nodes ( ) ) ;
63+ let mut idom = IndexVec :: from_elem_n ( 0 , pre_order_to_real . len ( ) ) ;
64+ let mut semi = IndexVec :: from_fn_n ( std:: convert:: identity, pre_order_to_real . len ( ) ) ;
7065 let mut label = semi. clone ( ) ;
71- let mut bucket = IndexVec :: from_elem_n ( vec ! [ ] , graph . num_nodes ( ) ) ;
66+ let mut bucket = IndexVec :: from_elem_n ( vec ! [ ] , pre_order_to_real . len ( ) ) ;
7267 let mut lastlinked = None ;
7368
74- for & w in pre_order_nodes[ 1 ..] . iter ( ) . rev ( ) {
75- // Optimization: process buckets just once. We need not explicitly empty
76- // the bucket here, but mem::take is pretty cheap.
69+ for w in ( 1 ..pre_order_to_real. len ( ) ) . rev ( ) {
70+ // Optimization: process buckets just once, at the start of the
71+ // iteration. Do not explicitly empty the bucket (even though it will
72+ // not be used again), to save some instructions.
7773 let z = parent[ w] . unwrap ( ) ;
78- for v in std :: mem :: take ( & mut bucket[ z] ) {
79- let y = eval ( & pre_order_index , & mut parent, lastlinked, & semi, & mut label, v) ;
80- idom[ v] = if pre_order_index [ semi[ y] ] < pre_order_index [ z ] { y } else { z } ;
74+ for & v in bucket[ z] . iter ( ) {
75+ let y = eval ( & mut parent, lastlinked, & semi, & mut label, v) ;
76+ idom[ v] = if semi[ y] < z { y } else { z } ;
8177 }
8278
8379 semi[ w] = w;
84- for v in graph. predecessors ( w) {
85- let x = eval ( & pre_order_index, & mut parent, lastlinked, & semi, & mut label, v) ;
86- semi[ w] = if pre_order_index[ semi[ w] ] . unwrap ( ) < pre_order_index[ semi[ x] ] . unwrap ( ) {
87- semi[ w]
88- } else {
89- semi[ x]
90- } ;
80+ for v in graph. predecessors ( pre_order_to_real[ w] ) {
81+ let v = real_to_pre_order[ v] . unwrap ( ) ;
82+ let x = eval ( & mut parent, lastlinked, & semi, & mut label, v) ;
83+ semi[ w] = std:: cmp:: min ( semi[ w] , semi[ x] ) ;
9184 }
9285 // semi[w] is now semidominator(w).
9386
@@ -103,59 +96,51 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
10396 // processed elements; lastlinked represents the divider.
10497 lastlinked = Some ( w) ;
10598 }
106- for & w in pre_order_nodes . iter ( ) . skip ( 1 ) {
99+ for w in 1 ..pre_order_to_real . len ( ) {
107100 if idom[ w] != semi[ w] {
108101 idom[ w] = idom[ idom[ w] ] ;
109102 }
110103 }
111104
112105 let mut immediate_dominators = IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
113- for ( node, idom_slot) in immediate_dominators. iter_enumerated_mut ( ) {
114- if pre_order_index[ node] . is_some ( ) {
115- * idom_slot = Some ( idom[ node] ) ;
116- }
106+ for ( idx, node) in pre_order_to_real. iter ( ) . enumerate ( ) {
107+ immediate_dominators[ * node] = Some ( pre_order_to_real[ idom[ idx] ] ) ;
117108 }
118109
119110 Dominators { post_order_rank, immediate_dominators }
120111}
121112
122113fn eval < N : Idx > (
123- pre_order_index : & IndexVec < N , Option < usize > > ,
124114 ancestor : & mut IndexVec < N , Option < N > > ,
125115 lastlinked : Option < N > ,
126116 semi : & IndexVec < N , N > ,
127117 label : & mut IndexVec < N , N > ,
128118 node : N ,
129119) -> N {
130- if is_processed ( pre_order_index , node, lastlinked) {
131- compress ( pre_order_index , ancestor, lastlinked, semi, label, node) ;
120+ if is_processed ( node, lastlinked) {
121+ compress ( ancestor, lastlinked, semi, label, node) ;
132122 label[ node]
133123 } else {
134124 node
135125 }
136126}
137127
138- fn is_processed < N : Idx > (
139- pre_order_index : & IndexVec < N , Option < usize > > ,
140- v : N ,
141- lastlinked : Option < N > ,
142- ) -> bool {
143- if let Some ( ll) = lastlinked { pre_order_index[ v] >= pre_order_index[ ll] } else { false }
128+ fn is_processed < N : Idx > ( v : N , lastlinked : Option < N > ) -> bool {
129+ if let Some ( ll) = lastlinked { v >= ll } else { false }
144130}
145131
146132fn compress < N : Idx > (
147- pre_order_index : & IndexVec < N , Option < usize > > ,
148133 ancestor : & mut IndexVec < N , Option < N > > ,
149134 lastlinked : Option < N > ,
150135 semi : & IndexVec < N , N > ,
151136 label : & mut IndexVec < N , N > ,
152137 v : N ,
153138) {
154- assert ! ( is_processed( pre_order_index , v, lastlinked) ) ;
139+ assert ! ( is_processed( v, lastlinked) ) ;
155140 let u = ancestor[ v] . unwrap ( ) ;
156- if is_processed ( pre_order_index , u, lastlinked) {
157- compress ( pre_order_index , ancestor, lastlinked, semi, label, u) ;
158- if pre_order_index [ semi[ label[ u] ] ] < pre_order_index [ semi[ label[ v] ] ] {
141+ if is_processed ( u, lastlinked) {
142+ compress ( ancestor, lastlinked, semi, label, u) ;
143+ if semi[ label[ u] ] < semi[ label[ v] ] {
159144 label[ v] = label[ u] ;
160145 }
161146 ancestor[ v] = ancestor[ u] ;
0 commit comments