@@ -13,6 +13,7 @@ use syntax::ast::{self, MetaItem};
1313use rustc_data_structures:: indexed_set:: { IdxSet , IdxSetBuf } ;
1414use rustc_data_structures:: indexed_vec:: Idx ;
1515use rustc_data_structures:: bitslice:: { bitwise, BitwiseOperator } ;
16+ use rustc_data_structures:: work_queue:: WorkQueue ;
1617
1718use rustc:: ty:: { self , TyCtxt } ;
1819use rustc:: mir:: { self , Mir , BasicBlock , BasicBlockData , Location , Statement , Terminator } ;
@@ -176,7 +177,6 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD
176177struct PropagationContext < ' b , ' a : ' b , ' tcx : ' a , O > where O : ' b + BitDenotation
177178{
178179 builder : & ' b mut DataflowAnalysis < ' a , ' tcx , O > ,
179- changed : bool ,
180180}
181181
182182impl < ' a , ' tcx : ' a , BD > DataflowAnalysis < ' a , ' tcx , BD > where BD : BitDenotation
@@ -185,12 +185,9 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
185185 let mut temp = IdxSetBuf :: new_empty ( self . flow_state . sets . bits_per_block ) ;
186186 let mut propcx = PropagationContext {
187187 builder : self ,
188- changed : true ,
189188 } ;
190- while propcx. changed {
191- propcx. changed = false ;
192- propcx. walk_cfg ( & mut temp) ;
193- }
189+ propcx. walk_cfg ( & mut temp) ;
190+
194191 }
195192
196193 fn build_sets ( & mut self ) {
@@ -236,18 +233,20 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
236233impl < ' b , ' a : ' b , ' tcx : ' a , BD > PropagationContext < ' b , ' a , ' tcx , BD > where BD : BitDenotation
237234{
238235 fn walk_cfg ( & mut self , in_out : & mut IdxSet < BD :: Idx > ) {
236+ let mut dirty_queue: WorkQueue < mir:: BasicBlock > =
237+ WorkQueue :: with_all ( self . builder . mir . basic_blocks ( ) . len ( ) ) ;
239238 let mir = self . builder . mir ;
240- for ( bb_idx , bb_data ) in mir . basic_blocks ( ) . iter ( ) . enumerate ( ) {
241- let builder = & mut self . builder ;
239+ while let Some ( bb ) = dirty_queue . pop ( ) {
240+ let bb_data = & mir [ bb ] ;
242241 {
243- let sets = builder. flow_state . sets . for_block ( bb_idx ) ;
242+ let sets = self . builder . flow_state . sets . for_block ( bb . index ( ) ) ;
244243 debug_assert ! ( in_out. words( ) . len( ) == sets. on_entry. words( ) . len( ) ) ;
245244 in_out. overwrite ( sets. on_entry ) ;
246245 in_out. union ( sets. gen_set ) ;
247246 in_out. subtract ( sets. kill_set ) ;
248247 }
249- builder. propagate_bits_into_graph_successors_of (
250- in_out, & mut self . changed , ( mir :: BasicBlock :: new ( bb_idx ) , bb_data) ) ;
248+ self . builder . propagate_bits_into_graph_successors_of (
249+ in_out, ( bb , bb_data) , & mut dirty_queue ) ;
251250 }
252251 }
253252}
@@ -806,68 +805,68 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
806805 fn propagate_bits_into_graph_successors_of (
807806 & mut self ,
808807 in_out : & mut IdxSet < D :: Idx > ,
809- changed : & mut bool ,
810- ( bb , bb_data ) : ( mir :: BasicBlock , & mir:: BasicBlockData ) )
808+ ( bb , bb_data ) : ( mir :: BasicBlock , & mir :: BasicBlockData ) ,
809+ dirty_list : & mut WorkQueue < mir:: BasicBlock > )
811810 {
812811 match bb_data. terminator ( ) . kind {
813812 mir:: TerminatorKind :: Return |
814813 mir:: TerminatorKind :: Resume |
815814 mir:: TerminatorKind :: Abort |
816815 mir:: TerminatorKind :: GeneratorDrop |
817816 mir:: TerminatorKind :: Unreachable => { }
818- mir:: TerminatorKind :: Goto { ref target } |
819- mir:: TerminatorKind :: Assert { ref target, cleanup : None , .. } |
820- mir:: TerminatorKind :: Yield { resume : ref target, drop : None , .. } |
821- mir:: TerminatorKind :: Drop { ref target, location : _, unwind : None } |
817+ mir:: TerminatorKind :: Goto { target } |
818+ mir:: TerminatorKind :: Assert { target, cleanup : None , .. } |
819+ mir:: TerminatorKind :: Yield { resume : target, drop : None , .. } |
820+ mir:: TerminatorKind :: Drop { target, location : _, unwind : None } |
822821 mir:: TerminatorKind :: DropAndReplace {
823- ref target, value : _, location : _, unwind : None
822+ target, value : _, location : _, unwind : None
824823 } => {
825- self . propagate_bits_into_entry_set_for ( in_out, changed , target ) ;
824+ self . propagate_bits_into_entry_set_for ( in_out, target , dirty_list ) ;
826825 }
827- mir:: TerminatorKind :: Yield { resume : ref target, drop : Some ( ref drop) , .. } => {
828- self . propagate_bits_into_entry_set_for ( in_out, changed , target ) ;
829- self . propagate_bits_into_entry_set_for ( in_out, changed , drop ) ;
826+ mir:: TerminatorKind :: Yield { resume : target, drop : Some ( drop) , .. } => {
827+ self . propagate_bits_into_entry_set_for ( in_out, target , dirty_list ) ;
828+ self . propagate_bits_into_entry_set_for ( in_out, drop , dirty_list ) ;
830829 }
831- mir:: TerminatorKind :: Assert { ref target, cleanup : Some ( ref unwind) , .. } |
832- mir:: TerminatorKind :: Drop { ref target, location : _, unwind : Some ( ref unwind) } |
830+ mir:: TerminatorKind :: Assert { target, cleanup : Some ( unwind) , .. } |
831+ mir:: TerminatorKind :: Drop { target, location : _, unwind : Some ( unwind) } |
833832 mir:: TerminatorKind :: DropAndReplace {
834- ref target, value : _, location : _, unwind : Some ( ref unwind)
833+ target, value : _, location : _, unwind : Some ( unwind)
835834 } => {
836- self . propagate_bits_into_entry_set_for ( in_out, changed , target ) ;
835+ self . propagate_bits_into_entry_set_for ( in_out, target , dirty_list ) ;
837836 if !self . dead_unwinds . contains ( & bb) {
838- self . propagate_bits_into_entry_set_for ( in_out, changed , unwind ) ;
837+ self . propagate_bits_into_entry_set_for ( in_out, unwind , dirty_list ) ;
839838 }
840839 }
841840 mir:: TerminatorKind :: SwitchInt { ref targets, .. } => {
842841 for target in targets {
843- self . propagate_bits_into_entry_set_for ( in_out, changed , target ) ;
842+ self . propagate_bits_into_entry_set_for ( in_out, * target , dirty_list ) ;
844843 }
845844 }
846- mir:: TerminatorKind :: Call { ref cleanup, ref destination, func : _, args : _ } => {
847- if let Some ( ref unwind) = * cleanup {
845+ mir:: TerminatorKind :: Call { cleanup, ref destination, func : _, args : _ } => {
846+ if let Some ( unwind) = cleanup {
848847 if !self . dead_unwinds . contains ( & bb) {
849- self . propagate_bits_into_entry_set_for ( in_out, changed , unwind ) ;
848+ self . propagate_bits_into_entry_set_for ( in_out, unwind , dirty_list ) ;
850849 }
851850 }
852- if let Some ( ( ref dest_place, ref dest_bb) ) = * destination {
851+ if let Some ( ( ref dest_place, dest_bb) ) = * destination {
853852 // N.B.: This must be done *last*, after all other
854853 // propagation, as documented in comment above.
855854 self . flow_state . operator . propagate_call_return (
856- in_out, bb, * dest_bb, dest_place) ;
857- self . propagate_bits_into_entry_set_for ( in_out, changed , dest_bb ) ;
855+ in_out, bb, dest_bb, dest_place) ;
856+ self . propagate_bits_into_entry_set_for ( in_out, dest_bb , dirty_list ) ;
858857 }
859858 }
860- mir:: TerminatorKind :: FalseEdges { ref real_target, ref imaginary_targets } => {
861- self . propagate_bits_into_entry_set_for ( in_out, changed , real_target ) ;
859+ mir:: TerminatorKind :: FalseEdges { real_target, ref imaginary_targets } => {
860+ self . propagate_bits_into_entry_set_for ( in_out, real_target , dirty_list ) ;
862861 for target in imaginary_targets {
863- self . propagate_bits_into_entry_set_for ( in_out, changed , target ) ;
862+ self . propagate_bits_into_entry_set_for ( in_out, * target , dirty_list ) ;
864863 }
865864 }
866- mir:: TerminatorKind :: FalseUnwind { ref real_target, unwind } => {
867- self . propagate_bits_into_entry_set_for ( in_out, changed , real_target ) ;
868- if let Some ( ref unwind) = unwind {
865+ mir:: TerminatorKind :: FalseUnwind { real_target, unwind } => {
866+ self . propagate_bits_into_entry_set_for ( in_out, real_target , dirty_list ) ;
867+ if let Some ( unwind) = unwind {
869868 if !self . dead_unwinds . contains ( & bb) {
870- self . propagate_bits_into_entry_set_for ( in_out, changed , unwind ) ;
869+ self . propagate_bits_into_entry_set_for ( in_out, unwind , dirty_list ) ;
871870 }
872871 }
873872 }
@@ -876,14 +875,15 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
876875
877876 fn propagate_bits_into_entry_set_for ( & mut self ,
878877 in_out : & IdxSet < D :: Idx > ,
879- changed : & mut bool ,
880- bb : & mir:: BasicBlock ) {
878+ bb : mir :: BasicBlock ,
879+ dirty_queue : & mut WorkQueue < mir:: BasicBlock > ) {
881880 let entry_set = self . flow_state . sets . for_block ( bb. index ( ) ) . on_entry ;
882881 let set_changed = bitwise ( entry_set. words_mut ( ) ,
883882 in_out. words ( ) ,
884883 & self . flow_state . operator ) ;
885884 if set_changed {
886- * changed = true ;
885+ dirty_queue . insert ( bb ) ;
887886 }
888887 }
888+
889889}
0 commit comments