@@ -37,6 +37,7 @@ use rustc::mir::*;
3737use rustc:: mir:: visit:: { PlaceContext , Visitor } ;
3838use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
3939use rustc_data_structures:: indexed_set:: IdxSetBuf ;
40+ use rustc_data_structures:: work_queue:: WorkQueue ;
4041use util:: pretty:: { dump_enabled, write_basic_block, write_mir_intro} ;
4142use rustc:: ty:: item_path;
4243use rustc:: mir:: visit:: MirVisitable ;
@@ -130,26 +131,32 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
130131 . collect ( ) ;
131132 let mut outs = ins. clone ( ) ;
132133
133- let mut changed = true ;
134134 let mut bits = LocalSet :: new_empty ( locals) ;
135- while changed {
136- changed = false ;
137-
138- for b in mir. basic_blocks ( ) . indices ( ) . rev ( ) {
139- // outs[b] = ∪ {ins of successors}
140- bits. clear ( ) ;
141- for & successor in mir. basic_blocks ( ) [ b] . terminator ( ) . successors ( ) {
142- bits. union ( & ins[ successor] ) ;
143- }
144- outs[ b] . overwrite ( & bits) ;
145135
146- // bits = use ∪ (bits - def)
147- def_use[ b] . apply ( & mut bits) ;
136+ // queue of things that need to be re-processed, and a set containing
137+ // the things currently in the queue
138+ let mut dirty_queue: WorkQueue < BasicBlock > = WorkQueue :: with_all ( mir. basic_blocks ( ) . len ( ) ) ;
139+
140+ let predecessors = mir. predecessors ( ) ;
141+
142+ while let Some ( bb) = dirty_queue. pop ( ) {
143+ // outs[b] = ∪ {ins of successors}
144+ bits. clear ( ) ;
145+ for & successor in mir[ bb] . terminator ( ) . successors ( ) {
146+ bits. union ( & ins[ successor] ) ;
147+ }
148+ outs[ bb] . overwrite ( & bits) ;
149+
150+ // bits = use ∪ (bits - def)
151+ def_use[ bb] . apply ( & mut bits) ;
152+
153+ // update bits on entry and, if they have changed, enqueue all
154+ // of our predecessors, since their inputs have now changed
155+ if ins[ bb] != bits {
156+ ins[ bb] . overwrite ( & bits) ;
148157
149- // update bits on entry and flag if they have changed
150- if ins[ b] != bits {
151- ins[ b] . overwrite ( & bits) ;
152- changed = true ;
158+ for & pred_bb in & predecessors[ bb] {
159+ dirty_queue. insert ( pred_bb) ;
153160 }
154161 }
155162 }
0 commit comments