@@ -17,7 +17,8 @@ use rustc_serialize as serialize;
17
17
18
18
#[ derive( Clone , Debug ) ]
19
19
pub struct Cache {
20
- predecessors : RefCell < Option < IndexVec < Block , Vec < Block > > > >
20
+ predecessors : RefCell < Option < IndexVec < Block , Vec < Block > > > > ,
21
+ successors : RefCell < Option < IndexVec < Block , Vec < Block > > > > ,
21
22
}
22
23
23
24
@@ -37,13 +38,15 @@ impl serialize::Decodable for Cache {
37
38
impl Cache {
38
39
pub fn new ( ) -> Self {
39
40
Cache {
40
- predecessors : RefCell :: new ( None )
41
+ predecessors : RefCell :: new ( None ) ,
42
+ successors : RefCell :: new ( None )
41
43
}
42
44
}
43
45
44
46
pub fn invalidate ( & self ) {
45
47
// FIXME: consider being more fine-grained
46
48
* self . predecessors . borrow_mut ( ) = None ;
49
+ * self . successors . borrow_mut ( ) = None ;
47
50
}
48
51
49
52
pub fn predecessors ( & self , mir : & Mir ) -> Ref < IndexVec < Block , Vec < Block > > > {
@@ -53,11 +56,25 @@ impl Cache {
53
56
54
57
Ref :: map ( self . predecessors . borrow ( ) , |p| p. as_ref ( ) . unwrap ( ) )
55
58
}
59
+
60
+ pub fn successors ( & self , mir : & Mir ) -> Ref < IndexVec < Block , Vec < Block > > > {
61
+ if self . successors . borrow ( ) . is_none ( ) {
62
+ * self . successors . borrow_mut ( ) = Some ( calculate_successors ( mir) ) ;
63
+ }
64
+
65
+ Ref :: map ( self . successors . borrow ( ) , |p| p. as_ref ( ) . unwrap ( ) )
66
+ }
56
67
}
57
68
58
69
fn calculate_predecessors ( mir : & Mir ) -> IndexVec < Block , Vec < Block > > {
59
70
let mut result = IndexVec :: from_elem ( vec ! [ ] , mir. basic_blocks ( ) ) ;
60
71
for ( bb, data) in mir. basic_blocks ( ) . iter_enumerated ( ) {
72
+ for stmt in & data. statements {
73
+ for & tgt in stmt. successors ( ) . iter ( ) {
74
+ result[ tgt] . push ( bb) ;
75
+ }
76
+ }
77
+
61
78
if let Some ( ref term) = data. terminator {
62
79
for & tgt in term. successors ( ) . iter ( ) {
63
80
result[ tgt] . push ( bb) ;
@@ -67,3 +84,22 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec<Block, Vec<Block>> {
67
84
68
85
result
69
86
}
87
+
88
+ fn calculate_successors ( mir : & Mir ) -> IndexVec < Block , Vec < Block > > {
89
+ let mut result = IndexVec :: from_elem ( vec ! [ ] , mir. basic_blocks ( ) ) ;
90
+ for ( bb, data) in mir. basic_blocks ( ) . iter_enumerated ( ) {
91
+ for stmt in & data. statements {
92
+ for & tgt in stmt. successors ( ) . iter ( ) {
93
+ result[ bb] . push ( tgt) ;
94
+ }
95
+ }
96
+
97
+ if let Some ( ref term) = data. terminator {
98
+ for & tgt in term. successors ( ) . iter ( ) {
99
+ result[ bb] . push ( tgt) ;
100
+ }
101
+ }
102
+ }
103
+
104
+ result
105
+ }
0 commit comments