@@ -65,16 +65,16 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
6565 stack. pop ( ) ;
6666 }
6767
68- let mut ancestor = IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
6968 let mut idom = IndexVec :: from_elem_n ( graph. start_node ( ) , graph. num_nodes ( ) ) ;
7069 let mut semi = IndexVec :: from_fn_n ( std:: convert:: identity, graph. num_nodes ( ) ) ;
7170 let mut label = semi. clone ( ) ;
7271 let mut bucket = IndexVec :: from_elem_n ( vec ! [ ] , graph. num_nodes ( ) ) ;
72+ let mut lastlinked = None ;
7373
7474 for & w in pre_order_nodes[ 1 ..] . iter ( ) . rev ( ) {
7575 semi[ w] = w;
7676 for v in graph. predecessors ( w) {
77- let x = eval ( & pre_order_index, & mut ancestor , & semi, & mut label, v) ;
77+ let x = eval ( & pre_order_index, & mut parent , lastlinked , & semi, & mut label, v) ;
7878 semi[ w] = if pre_order_index[ semi[ w] ] . unwrap ( ) < pre_order_index[ semi[ x] ] . unwrap ( ) {
7979 semi[ w]
8080 } else {
@@ -91,6 +91,10 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
9191 let y = eval ( & pre_order_index, & mut ancestor, & semi, & mut label, v) ;
9292 idom[ v] = if pre_order_index[ semi[ y] ] < pre_order_index[ z] { y } else { z } ;
9393 }
94+
95+ // Optimization: We share the parent array between processed and not
96+ // processed elements; lastlinked represents the divider.
97+ lastlinked = Some ( w) ;
9498 }
9599 for & w in pre_order_nodes. iter ( ) . skip ( 1 ) {
96100 if idom[ w] != semi[ w] {
@@ -111,39 +115,46 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
111115fn eval < N : Idx > (
112116 pre_order_index : & IndexVec < N , Option < usize > > ,
113117 ancestor : & mut IndexVec < N , Option < N > > ,
118+ lastlinked : Option < N > ,
114119 semi : & IndexVec < N , N > ,
115120 label : & mut IndexVec < N , N > ,
116121 node : N ,
117122) -> N {
118- if ancestor [ node ] . is_some ( ) {
119- compress ( pre_order_index, ancestor, semi, label, node) ;
123+ if is_processed ( pre_order_index , node , lastlinked ) {
124+ compress ( pre_order_index, ancestor, lastlinked , semi, label, node) ;
120125 label[ node]
121126 } else {
122127 node
123128 }
124129}
125130
131+ fn is_processed < N : Idx > (
132+ pre_order_index : & IndexVec < N , Option < usize > > ,
133+ v : N ,
134+ lastlinked : Option < N > ,
135+ ) -> bool {
136+ if let Some ( ll) = lastlinked { pre_order_index[ v] >= pre_order_index[ ll] } else { false }
137+ }
138+
126139fn compress < N : Idx > (
127140 pre_order_index : & IndexVec < N , Option < usize > > ,
128141 ancestor : & mut IndexVec < N , Option < N > > ,
142+ lastlinked : Option < N > ,
129143 semi : & IndexVec < N , N > ,
130144 label : & mut IndexVec < N , N > ,
131145 v : N ,
132146) {
147+ assert ! ( is_processed( pre_order_index, v, lastlinked) ) ;
133148 let u = ancestor[ v] . unwrap ( ) ;
134- if ancestor [ u ] . is_some ( ) {
135- compress ( pre_order_index, ancestor, semi, label, u) ;
149+ if is_processed ( pre_order_index , u , lastlinked ) {
150+ compress ( pre_order_index, ancestor, lastlinked , semi, label, u) ;
136151 if pre_order_index[ semi[ label[ u] ] ] < pre_order_index[ semi[ label[ v] ] ] {
137152 label[ v] = label[ u] ;
138153 }
139154 ancestor[ v] = ancestor[ u] ;
140155 }
141156}
142157
143- fn link < N : Idx > ( ancestor : & mut IndexVec < N , Option < N > > , parent : & IndexVec < N , Option < N > > , w : N ) {
144- ancestor[ w] = Some ( parent[ w] . unwrap ( ) ) ;
145- }
146-
147158#[ derive( Clone , Debug ) ]
148159pub struct Dominators < N : Idx > {
149160 post_order_rank : IndexVec < N , usize > ,
0 commit comments