@@ -37,6 +37,7 @@ use rustc::mir::*;
37
37
use rustc:: mir:: visit:: { PlaceContext , Visitor } ;
38
38
use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
39
39
use rustc_data_structures:: indexed_set:: IdxSetBuf ;
40
+ use rustc_data_structures:: work_queue:: WorkQueue ;
40
41
use util:: pretty:: { dump_enabled, write_basic_block, write_mir_intro} ;
41
42
use rustc:: ty:: item_path;
42
43
use rustc:: mir:: visit:: MirVisitable ;
@@ -130,26 +131,32 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
130
131
. collect ( ) ;
131
132
let mut outs = ins. clone ( ) ;
132
133
133
- let mut changed = true ;
134
134
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) ;
145
135
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) ;
148
157
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) ;
153
160
}
154
161
}
155
162
}
0 commit comments