4
4
//! "Linear-Time Algorithms for Dominators and Related Problems",
5
5
//! ftp://ftp.cs.princeton.edu/techreports/2005/737.pdf
6
6
7
- use super :: iterate:: reverse_post_order;
8
7
use super :: ControlFlowGraph ;
9
8
use rustc_index:: vec:: { Idx , IndexVec } ;
10
9
use std:: cmp:: Ordering ;
11
10
12
11
#[ cfg( test) ]
13
12
mod tests;
14
13
15
- pub fn dominators < G : ControlFlowGraph > ( graph : G ) -> Dominators < G :: Node > {
16
- let start_node = graph. start_node ( ) ;
17
- let rpo = reverse_post_order ( & graph, start_node) ;
18
- dominators_given_rpo ( graph, & rpo)
19
- }
20
-
21
14
struct PreOrderFrame < Node , Iter > {
22
15
node : Node ,
23
16
iter : Iter ,
24
17
}
25
18
26
- fn dominators_given_rpo < G : ControlFlowGraph > ( graph : G , rpo : & [ G :: Node ] ) -> Dominators < G :: Node > {
27
- let start_node = graph. start_node ( ) ;
28
- assert_eq ! ( rpo[ 0 ] , start_node) ;
29
-
19
+ pub fn dominators < G : ControlFlowGraph > ( graph : G ) -> Dominators < G :: Node > {
30
20
// compute the post order index (rank) for each node
31
21
let mut post_order_rank = IndexVec :: from_elem_n ( 0 , graph. num_nodes ( ) ) ;
32
- for ( index, node) in rpo. iter ( ) . rev ( ) . cloned ( ) . enumerate ( ) {
33
- post_order_rank[ node] = index;
34
- }
35
-
36
22
let mut visited = BitSet :: new_empty ( graph. num_nodes ( ) ) ;
37
- let mut parent: IndexVec < usize , Option < usize > > = IndexVec :: from_elem_n ( None , rpo . len ( ) ) ;
23
+ let mut parent: IndexVec < usize , Option < usize > > = IndexVec :: from_elem_n ( None , graph . num_nodes ( ) ) ;
38
24
39
25
let mut stack = vec ! [ PreOrderFrame { node: 0 , iter: graph. successors( graph. start_node( ) ) } ] ;
40
26
visited. insert ( graph. start_node ( ) ) ;
41
- let mut pre_order_to_real = Vec :: with_capacity ( rpo . len ( ) ) ;
27
+ let mut pre_order_to_real = Vec :: with_capacity ( graph . num_nodes ( ) ) ;
42
28
let mut real_to_pre_order: IndexVec < G :: Node , Option < usize > > =
43
29
IndexVec :: from_elem_n ( None , graph. num_nodes ( ) ) ;
44
30
pre_order_to_real. push ( graph. start_node ( ) ) ;
45
31
real_to_pre_order[ graph. start_node ( ) ] = Some ( 0 ) ;
46
32
let mut idx = 1 ;
33
+ let mut post_order_idx = 0 ;
47
34
48
35
' recurse: while let Some ( frame) = stack. last_mut ( ) {
49
36
while let Some ( successor) = frame. iter . next ( ) {
@@ -57,6 +44,9 @@ fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Domin
57
44
continue ' recurse;
58
45
}
59
46
}
47
+ post_order_rank[ pre_order_to_real[ frame. node ] ] = post_order_idx;
48
+ post_order_idx += 1 ;
49
+
60
50
stack. pop ( ) ;
61
51
}
62
52
0 commit comments