@@ -23,8 +23,11 @@ rustc_index::newtype_index! {
2323pub fn dominators < G : ControlFlowGraph > ( graph : G ) -> Dominators < G :: Node > {
2424 // compute the post order index (rank) for each node
2525 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 ( ) ) ;
2831
2932 let mut stack = vec ! [ PreOrderFrame {
3033 pre_order_idx: PreorderIndex :: new( 0 ) ,
@@ -35,6 +38,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
3538 let mut real_to_pre_order: IndexVec < G :: Node , Option < PreorderIndex > > =
3639 IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
3740 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.
3842 real_to_pre_order[ graph. start_node ( ) ] = Some ( PreorderIndex :: new ( 0 ) ) ;
3943 let mut post_order_idx = 0 ;
4044
@@ -43,7 +47,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
4347 if real_to_pre_order[ successor] . is_none ( ) {
4448 let pre_order_idx = pre_order_to_real. push ( successor) ;
4549 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 ) ;
4751 stack. push ( PreOrderFrame { pre_order_idx, iter : graph. successors ( successor) } ) ;
4852
4953 continue ' recurse;
@@ -67,7 +71,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
6771 // Optimization: process buckets just once, at the start of the
6872 // iteration. Do not explicitly empty the bucket (even though it will
6973 // not be used again), to save some instructions.
70- let z = parent[ w] . unwrap ( ) ;
74+ let z = parent[ w] ;
7175 for & v in bucket[ z] . iter ( ) {
7276 let y = eval ( & mut parent, lastlinked, & semi, & mut label, v) ;
7377 idom[ v] = if semi[ y] < z { y } else { z } ;
@@ -83,10 +87,10 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
8387
8488 // Optimization: Do not insert into buckets if parent[w] = semi[w], as
8589 // we then immediately know the idom.
86- if parent[ w] . unwrap ( ) != semi[ w] {
90+ if parent[ w] != semi[ w] {
8791 bucket[ semi[ w] ] . push ( w) ;
8892 } else {
89- idom[ w] = parent[ w] . unwrap ( ) ;
93+ idom[ w] = parent[ w] ;
9094 }
9195
9296 // Optimization: We share the parent array between processed and not
@@ -109,7 +113,7 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
109113
110114#[ inline]
111115fn eval (
112- ancestor : & mut IndexVec < PreorderIndex , Option < PreorderIndex > > ,
116+ ancestor : & mut IndexVec < PreorderIndex , PreorderIndex > ,
113117 lastlinked : Option < PreorderIndex > ,
114118 semi : & IndexVec < PreorderIndex , PreorderIndex > ,
115119 label : & mut IndexVec < PreorderIndex , PreorderIndex > ,
@@ -130,14 +134,14 @@ fn is_processed(v: PreorderIndex, lastlinked: Option<PreorderIndex>) -> bool {
130134
131135#[ inline]
132136fn compress (
133- ancestor : & mut IndexVec < PreorderIndex , Option < PreorderIndex > > ,
137+ ancestor : & mut IndexVec < PreorderIndex , PreorderIndex > ,
134138 lastlinked : Option < PreorderIndex > ,
135139 semi : & IndexVec < PreorderIndex , PreorderIndex > ,
136140 label : & mut IndexVec < PreorderIndex , PreorderIndex > ,
137141 v : PreorderIndex ,
138142) {
139143 assert ! ( is_processed( v, lastlinked) ) ;
140- let u = ancestor[ v] . unwrap ( ) ;
144+ let u = ancestor[ v] ;
141145 if is_processed ( u, lastlinked) {
142146 compress ( ancestor, lastlinked, semi, label, u) ;
143147 if semi[ label[ u] ] < semi[ label[ v] ] {
0 commit comments