11use crate :: dataflow;
2- use crate :: dataflow:: generic:: { Analysis , Results } ;
2+ use crate :: dataflow:: generic:: { Analysis , ResultsCursor } ;
33use crate :: dataflow:: move_paths:: { LookupResult , MoveData , MovePathIndex } ;
4+ use crate :: dataflow:: on_lookup_result_bits;
45use crate :: dataflow:: MoveDataParamEnv ;
5- use crate :: dataflow:: { drop_flag_effects_for_location, on_lookup_result_bits} ;
66use crate :: dataflow:: { on_all_children_bits, on_all_drop_children_bits} ;
77use crate :: dataflow:: { MaybeInitializedPlaces , MaybeUninitializedPlaces } ;
88use crate :: transform:: { MirPass , MirSource } ;
@@ -41,22 +41,23 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
4141 let env = MoveDataParamEnv { move_data, param_env } ;
4242 let dead_unwinds = find_dead_unwinds ( tcx, body, def_id, & env) ;
4343
44- let flow_inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
44+ let inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
4545 . into_engine ( tcx, body, def_id)
4646 . dead_unwinds ( & dead_unwinds)
47- . iterate_to_fixpoint ( ) ;
47+ . iterate_to_fixpoint ( )
48+ . into_results_cursor ( body) ;
4849
49- let flow_uninits = MaybeUninitializedPlaces :: new ( tcx, body, & env)
50+ let uninits = MaybeUninitializedPlaces :: new ( tcx, body, & env)
5051 . into_engine ( tcx, body, def_id)
5152 . dead_unwinds ( & dead_unwinds)
52- . iterate_to_fixpoint ( ) ;
53+ . iterate_to_fixpoint ( )
54+ . into_results_cursor ( body) ;
5355
5456 ElaborateDropsCtxt {
5557 tcx,
5658 body,
5759 env : & env,
58- flow_inits,
59- flow_uninits,
60+ init_data : InitializationData { inits, uninits } ,
6061 drop_flags : Default :: default ( ) ,
6162 patch : MirPatch :: new ( body) ,
6263 }
@@ -79,25 +80,18 @@ fn find_dead_unwinds<'tcx>(
7980 // We only need to do this pass once, because unwind edges can only
8081 // reach cleanup blocks, which can't have unwind edges themselves.
8182 let mut dead_unwinds = BitSet :: new_empty ( body. basic_blocks ( ) . len ( ) ) ;
82- let flow_inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
83+ let mut flow_inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
8384 . into_engine ( tcx, body, def_id)
84- . iterate_to_fixpoint ( ) ;
85+ . iterate_to_fixpoint ( )
86+ . into_results_cursor ( body) ;
8587 for ( bb, bb_data) in body. basic_blocks ( ) . iter_enumerated ( ) {
8688 let location = match bb_data. terminator ( ) . kind {
8789 TerminatorKind :: Drop { ref location, unwind : Some ( _) , .. }
8890 | TerminatorKind :: DropAndReplace { ref location, unwind : Some ( _) , .. } => location,
8991 _ => continue ,
9092 } ;
9193
92- let mut init_data = InitializationData {
93- live : flow_inits. entry_set_for_block ( bb) . clone ( ) ,
94- dead : BitSet :: new_empty ( env. move_data . move_paths . len ( ) ) ,
95- } ;
96- debug ! ( "find_dead_unwinds @ {:?}: {:?}; init_data={:?}" , bb, bb_data, init_data. live) ;
97- for stmt in 0 ..bb_data. statements . len ( ) {
98- let loc = Location { block : bb, statement_index : stmt } ;
99- init_data. apply_location ( tcx, body, env, loc) ;
100- }
94+ debug ! ( "find_dead_unwinds @ {:?}: {:?}; init_data={:?}" , bb, bb_data, flow_inits. get( ) ) ;
10195
10296 let path = match env. move_data . rev_lookup . find ( location. as_ref ( ) ) {
10397 LookupResult :: Exact ( e) => e,
@@ -109,10 +103,10 @@ fn find_dead_unwinds<'tcx>(
109103
110104 debug ! ( "find_dead_unwinds @ {:?}: path({:?})={:?}" , bb, location, path) ;
111105
106+ flow_inits. seek_after ( body. terminator_loc ( bb) ) ;
112107 let mut maybe_live = false ;
113108 on_all_drop_children_bits ( tcx, body, & env, path, |child| {
114- let ( child_maybe_live, _) = init_data. state ( child) ;
115- maybe_live |= child_maybe_live;
109+ maybe_live |= flow_inits. contains ( child) ;
116110 } ) ;
117111
118112 debug ! ( "find_dead_unwinds @ {:?}: maybe_live={}" , bb, maybe_live) ;
@@ -124,41 +118,23 @@ fn find_dead_unwinds<'tcx>(
124118 dead_unwinds
125119}
126120
127- struct InitializationData {
128- live : BitSet < MovePathIndex > ,
129- dead : BitSet < MovePathIndex > ,
121+ struct InitializationData < ' mir , ' tcx > {
122+ inits : ResultsCursor < ' mir , ' tcx , MaybeInitializedPlaces < ' mir , ' tcx > > ,
123+ uninits : ResultsCursor < ' mir , ' tcx , MaybeUninitializedPlaces < ' mir , ' tcx > > ,
130124}
131125
132- impl InitializationData {
133- fn apply_location < ' tcx > (
134- & mut self ,
135- tcx : TyCtxt < ' tcx > ,
136- body : & Body < ' tcx > ,
137- env : & MoveDataParamEnv < ' tcx > ,
138- loc : Location ,
139- ) {
140- drop_flag_effects_for_location ( tcx, body, env, loc, |path, df| {
141- debug ! ( "at location {:?}: setting {:?} to {:?}" , loc, path, df) ;
142- match df {
143- DropFlagState :: Present => {
144- self . live . insert ( path) ;
145- self . dead . remove ( path) ;
146- }
147- DropFlagState :: Absent => {
148- self . dead . insert ( path) ;
149- self . live . remove ( path) ;
150- }
151- }
152- } ) ;
126+ impl InitializationData < ' _ , ' _ > {
127+ fn seek_after ( & mut self , loc : Location ) {
128+ self . inits . seek_after ( loc) ;
129+ self . uninits . seek_after ( loc) ;
153130 }
154131
155132 fn state ( & self , path : MovePathIndex ) -> ( bool , bool ) {
156- ( self . live . contains ( path) , self . dead . contains ( path) )
133+ ( self . inits . contains ( path) , self . uninits . contains ( path) )
157134 }
158135}
159136
160137struct Elaborator < ' a , ' b , ' tcx > {
161- init_data : & ' a InitializationData ,
162138 ctxt : & ' a mut ElaborateDropsCtxt < ' b , ' tcx > ,
163139}
164140
@@ -189,13 +165,13 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
189165
190166 fn drop_style ( & self , path : Self :: Path , mode : DropFlagMode ) -> DropStyle {
191167 let ( ( maybe_live, maybe_dead) , multipart) = match mode {
192- DropFlagMode :: Shallow => ( self . init_data . state ( path) , false ) ,
168+ DropFlagMode :: Shallow => ( self . ctxt . init_data . state ( path) , false ) ,
193169 DropFlagMode :: Deep => {
194170 let mut some_live = false ;
195171 let mut some_dead = false ;
196172 let mut children_count = 0 ;
197173 on_all_drop_children_bits ( self . tcx ( ) , self . body ( ) , self . ctxt . env , path, |child| {
198- let ( live, dead) = self . init_data . state ( child) ;
174+ let ( live, dead) = self . ctxt . init_data . state ( child) ;
199175 debug ! ( "elaborate_drop: state({:?}) = {:?}" , child, ( live, dead) ) ;
200176 some_live |= live;
201177 some_dead |= dead;
@@ -269,8 +245,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
269245 tcx : TyCtxt < ' tcx > ,
270246 body : & ' a Body < ' tcx > ,
271247 env : & ' a MoveDataParamEnv < ' tcx > ,
272- flow_inits : Results < ' tcx , MaybeInitializedPlaces < ' a , ' tcx > > ,
273- flow_uninits : Results < ' tcx , MaybeUninitializedPlaces < ' a , ' tcx > > ,
248+ init_data : InitializationData < ' a , ' tcx > ,
274249 drop_flags : FxHashMap < MovePathIndex , Local > ,
275250 patch : MirPatch < ' tcx > ,
276251}
@@ -284,25 +259,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
284259 self . env . param_env
285260 }
286261
287- // FIXME(ecstaticmorse): This duplicates `dataflow::ResultsCursor` but hardcodes the transfer
288- // function for `Maybe{Un,}InitializedPlaces` directly. It should be replaced by a a pair of
289- // `ResultsCursor`s.
290- fn initialization_data_at ( & self , loc : Location ) -> InitializationData {
291- let mut data = InitializationData {
292- live : self . flow_inits . entry_set_for_block ( loc. block ) . to_owned ( ) ,
293- dead : self . flow_uninits . entry_set_for_block ( loc. block ) . to_owned ( ) ,
294- } ;
295- for stmt in 0 ..loc. statement_index {
296- data. apply_location (
297- self . tcx ,
298- self . body ,
299- self . env ,
300- Location { block : loc. block , statement_index : stmt } ,
301- ) ;
302- }
303- data
304- }
305-
306262 fn create_drop_flag ( & mut self , index : MovePathIndex , span : Span ) {
307263 let tcx = self . tcx ;
308264 let patch = & mut self . patch ;
@@ -338,10 +294,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
338294 _ => continue ,
339295 } ;
340296
341- let init_data = self . initialization_data_at ( Location {
342- block : bb,
343- statement_index : data. statements . len ( ) ,
344- } ) ;
297+ self . init_data . seek_after ( self . body . terminator_loc ( bb) ) ;
345298
346299 let path = self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) ;
347300 debug ! ( "collect_drop_flags: {:?}, place {:?} ({:?})" , bb, location, path) ;
@@ -350,7 +303,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
350303 LookupResult :: Exact ( e) => e,
351304 LookupResult :: Parent ( None ) => continue ,
352305 LookupResult :: Parent ( Some ( parent) ) => {
353- let ( _maybe_live, maybe_dead) = init_data. state ( parent) ;
306+ let ( _maybe_live, maybe_dead) = self . init_data . state ( parent) ;
354307 if maybe_dead {
355308 span_bug ! (
356309 terminator. source_info. span,
@@ -365,7 +318,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
365318 } ;
366319
367320 on_all_drop_children_bits ( self . tcx , self . body , self . env , path, |child| {
368- let ( maybe_live, maybe_dead) = init_data. state ( child) ;
321+ let ( maybe_live, maybe_dead) = self . init_data . state ( child) ;
369322 debug ! (
370323 "collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}" ,
371324 child,
@@ -388,10 +341,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
388341 let resume_block = self . patch . resume_block ( ) ;
389342 match terminator. kind {
390343 TerminatorKind :: Drop { ref location, target, unwind } => {
391- let init_data = self . initialization_data_at ( loc) ;
344+ self . init_data . seek_after ( loc) ;
392345 match self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) {
393346 LookupResult :: Exact ( path) => elaborate_drop (
394- & mut Elaborator { init_data : & init_data , ctxt : self } ,
347+ & mut Elaborator { ctxt : self } ,
395348 terminator. source_info ,
396349 location,
397350 path,
@@ -471,10 +424,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
471424 match self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) {
472425 LookupResult :: Exact ( path) => {
473426 debug ! ( "elaborate_drop_and_replace({:?}) - tracked {:?}" , terminator, path) ;
474- let init_data = self . initialization_data_at ( loc) ;
475-
427+ self . init_data . seek_after ( loc) ;
476428 elaborate_drop (
477- & mut Elaborator { init_data : & init_data , ctxt : self } ,
429+ & mut Elaborator { ctxt : self } ,
478430 terminator. source_info ,
479431 location,
480432 path,
0 commit comments