@@ -17,7 +17,8 @@ use rustc_serialize as serialize;
1717
1818#[ derive( Clone , Debug ) ]
1919pub 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 > > > > ,
2122}
2223
2324
@@ -37,13 +38,15 @@ impl serialize::Decodable for Cache {
3738impl Cache {
3839 pub fn new ( ) -> Self {
3940 Cache {
40- predecessors : RefCell :: new ( None )
41+ predecessors : RefCell :: new ( None ) ,
42+ successors : RefCell :: new ( None )
4143 }
4244 }
4345
4446 pub fn invalidate ( & self ) {
4547 // FIXME: consider being more fine-grained
4648 * self . predecessors . borrow_mut ( ) = None ;
49+ * self . successors . borrow_mut ( ) = None ;
4750 }
4851
4952 pub fn predecessors ( & self , mir : & Mir ) -> Ref < IndexVec < Block , Vec < Block > > > {
@@ -53,11 +56,25 @@ impl Cache {
5356
5457 Ref :: map ( self . predecessors . borrow ( ) , |p| p. as_ref ( ) . unwrap ( ) )
5558 }
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+ }
5667}
5768
5869fn calculate_predecessors ( mir : & Mir ) -> IndexVec < Block , Vec < Block > > {
5970 let mut result = IndexVec :: from_elem ( vec ! [ ] , mir. basic_blocks ( ) ) ;
6071 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+
6178 if let Some ( ref term) = data. terminator {
6279 for & tgt in term. successors ( ) . iter ( ) {
6380 result[ tgt] . push ( bb) ;
@@ -67,3 +84,22 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec<Block, Vec<Block>> {
6784
6885 result
6986}
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