@@ -23,8 +23,11 @@ rustc_index::newtype_index! {
23
23
pub fn dominators < G : ControlFlowGraph > ( graph : G ) -> Dominators < G :: Node > {
24
24
// compute the post order index (rank) for each node
25
25
let mut post_order_rank = IndexVec :: from_elem_n ( 0 , graph. num_nodes ( ) ) ;
26
- let mut parent: IndexVec < PreorderIndex , Option < PreorderIndex > > =
27
- IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
26
+
27
+ // We allocate capacity for the full set of nodes, because most of the time
28
+ // most of the nodes *are* reachable.
29
+ let mut parent: IndexVec < PreorderIndex , PreorderIndex > =
30
+ IndexVec :: with_capacity ( graph. num_nodes ( ) ) ;
28
31
29
32
let mut stack = vec ! [ PreOrderFrame {
30
33
pre_order_idx: PreorderIndex :: new( 0 ) ,
@@ -35,6 +38,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
35
38
let mut real_to_pre_order: IndexVec < G :: Node , Option < PreorderIndex > > =
36
39
IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
37
40
pre_order_to_real. push ( graph. start_node ( ) ) ;
41
+ parent. push ( PreorderIndex :: new ( 0 ) ) ; // the parent of the root node is the root for now.
38
42
real_to_pre_order[ graph. start_node ( ) ] = Some ( PreorderIndex :: new ( 0 ) ) ;
39
43
let mut post_order_idx = 0 ;
40
44
@@ -43,7 +47,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
43
47
if real_to_pre_order[ successor] . is_none ( ) {
44
48
let pre_order_idx = pre_order_to_real. push ( successor) ;
45
49
real_to_pre_order[ successor] = Some ( pre_order_idx) ;
46
- parent[ pre_order_idx ] = Some ( frame. pre_order_idx ) ;
50
+ parent. push ( frame. pre_order_idx ) ;
47
51
stack. push ( PreOrderFrame { pre_order_idx, iter : graph. successors ( successor) } ) ;
48
52
49
53
continue ' recurse;
@@ -67,7 +71,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
67
71
// Optimization: process buckets just once, at the start of the
68
72
// iteration. Do not explicitly empty the bucket (even though it will
69
73
// not be used again), to save some instructions.
70
- let z = parent[ w] . unwrap ( ) ;
74
+ let z = parent[ w] ;
71
75
for & v in bucket[ z] . iter ( ) {
72
76
let y = eval ( & mut parent, lastlinked, & semi, & mut label, v) ;
73
77
idom[ v] = if semi[ y] < z { y } else { z } ;
@@ -83,10 +87,10 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
83
87
84
88
// Optimization: Do not insert into buckets if parent[w] = semi[w], as
85
89
// we then immediately know the idom.
86
- if parent[ w] . unwrap ( ) != semi[ w] {
90
+ if parent[ w] != semi[ w] {
87
91
bucket[ semi[ w] ] . push ( w) ;
88
92
} else {
89
- idom[ w] = parent[ w] . unwrap ( ) ;
93
+ idom[ w] = parent[ w] ;
90
94
}
91
95
92
96
// Optimization: We share the parent array between processed and not
@@ -109,7 +113,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
109
113
110
114
#[ inline]
111
115
fn eval (
112
- ancestor : & mut IndexVec < PreorderIndex , Option < PreorderIndex > > ,
116
+ ancestor : & mut IndexVec < PreorderIndex , PreorderIndex > ,
113
117
lastlinked : Option < PreorderIndex > ,
114
118
semi : & IndexVec < PreorderIndex , PreorderIndex > ,
115
119
label : & mut IndexVec < PreorderIndex , PreorderIndex > ,
@@ -130,14 +134,14 @@ fn is_processed(v: PreorderIndex, lastlinked: Option<PreorderIndex>) -> bool {
130
134
131
135
#[ inline]
132
136
fn compress (
133
- ancestor : & mut IndexVec < PreorderIndex , Option < PreorderIndex > > ,
137
+ ancestor : & mut IndexVec < PreorderIndex , PreorderIndex > ,
134
138
lastlinked : Option < PreorderIndex > ,
135
139
semi : & IndexVec < PreorderIndex , PreorderIndex > ,
136
140
label : & mut IndexVec < PreorderIndex , PreorderIndex > ,
137
141
v : PreorderIndex ,
138
142
) {
139
143
assert ! ( is_processed( v, lastlinked) ) ;
140
- let u = ancestor[ v] . unwrap ( ) ;
144
+ let u = ancestor[ v] ;
141
145
if is_processed ( u, lastlinked) {
142
146
compress ( ancestor, lastlinked, semi, label, u) ;
143
147
if semi[ label[ u] ] < semi[ label[ v] ] {
0 commit comments