@@ -65,16 +65,16 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
65
65
stack. pop ( ) ;
66
66
}
67
67
68
- let mut ancestor = IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
69
68
let mut idom = IndexVec :: from_elem_n ( graph. start_node ( ) , graph. num_nodes ( ) ) ;
70
69
let mut semi = IndexVec :: from_fn_n ( std:: convert:: identity, graph. num_nodes ( ) ) ;
71
70
let mut label = semi. clone ( ) ;
72
71
let mut bucket = IndexVec :: from_elem_n ( vec ! [ ] , graph. num_nodes ( ) ) ;
72
+ let mut lastlinked = None ;
73
73
74
74
for & w in pre_order_nodes[ 1 ..] . iter ( ) . rev ( ) {
75
75
semi[ w] = w;
76
76
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) ;
78
78
semi[ w] = if pre_order_index[ semi[ w] ] . unwrap ( ) < pre_order_index[ semi[ x] ] . unwrap ( ) {
79
79
semi[ w]
80
80
} else {
@@ -91,6 +91,10 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
91
91
let y = eval ( & pre_order_index, & mut ancestor, & semi, & mut label, v) ;
92
92
idom[ v] = if pre_order_index[ semi[ y] ] < pre_order_index[ z] { y } else { z } ;
93
93
}
94
+
95
+ // Optimization: We share the parent array between processed and not
96
+ // processed elements; lastlinked represents the divider.
97
+ lastlinked = Some ( w) ;
94
98
}
95
99
for & w in pre_order_nodes. iter ( ) . skip ( 1 ) {
96
100
if idom[ w] != semi[ w] {
@@ -111,39 +115,46 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
111
115
fn eval < N : Idx > (
112
116
pre_order_index : & IndexVec < N , Option < usize > > ,
113
117
ancestor : & mut IndexVec < N , Option < N > > ,
118
+ lastlinked : Option < N > ,
114
119
semi : & IndexVec < N , N > ,
115
120
label : & mut IndexVec < N , N > ,
116
121
node : N ,
117
122
) -> 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) ;
120
125
label[ node]
121
126
} else {
122
127
node
123
128
}
124
129
}
125
130
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
+
126
139
fn compress < N : Idx > (
127
140
pre_order_index : & IndexVec < N , Option < usize > > ,
128
141
ancestor : & mut IndexVec < N , Option < N > > ,
142
+ lastlinked : Option < N > ,
129
143
semi : & IndexVec < N , N > ,
130
144
label : & mut IndexVec < N , N > ,
131
145
v : N ,
132
146
) {
147
+ assert ! ( is_processed( pre_order_index, v, lastlinked) ) ;
133
148
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) ;
136
151
if pre_order_index[ semi[ label[ u] ] ] < pre_order_index[ semi[ label[ v] ] ] {
137
152
label[ v] = label[ u] ;
138
153
}
139
154
ancestor[ v] = ancestor[ u] ;
140
155
}
141
156
}
142
157
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
-
147
158
#[ derive( Clone , Debug ) ]
148
159
pub struct Dominators < N : Idx > {
149
160
post_order_rank : IndexVec < N , usize > ,
0 commit comments