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 @ {:?}: {:?}" , bb, bb_data) ;
10195
10296 let path = match env. move_data . rev_lookup . find ( location. as_ref ( ) ) {
10397 LookupResult :: Exact ( e) => e,
@@ -107,12 +101,18 @@ fn find_dead_unwinds<'tcx>(
107101 }
108102 } ;
109103
110- debug ! ( "find_dead_unwinds @ {:?}: path({:?})={:?}" , bb, location, path) ;
104+ flow_inits. seek_before ( body. terminator_loc ( bb) ) ;
105+ debug ! (
106+ "find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}" ,
107+ bb,
108+ location,
109+ path,
110+ flow_inits. get( )
111+ ) ;
111112
112113 let mut maybe_live = false ;
113114 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;
115+ maybe_live |= flow_inits. contains ( child) ;
116116 } ) ;
117117
118118 debug ! ( "find_dead_unwinds @ {:?}: maybe_live={}" , bb, maybe_live) ;
@@ -124,41 +124,23 @@ fn find_dead_unwinds<'tcx>(
124124 dead_unwinds
125125}
126126
127- struct InitializationData {
128- live : BitSet < MovePathIndex > ,
129- dead : BitSet < MovePathIndex > ,
127+ struct InitializationData < ' mir , ' tcx > {
128+ inits : ResultsCursor < ' mir , ' tcx , MaybeInitializedPlaces < ' mir , ' tcx > > ,
129+ uninits : ResultsCursor < ' mir , ' tcx , MaybeUninitializedPlaces < ' mir , ' tcx > > ,
130130}
131131
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- } ) ;
132+ impl InitializationData < ' _ , ' _ > {
133+ fn seek_before ( & mut self , loc : Location ) {
134+ self . inits . seek_before ( loc) ;
135+ self . uninits . seek_before ( loc) ;
153136 }
154137
155- fn state ( & self , path : MovePathIndex ) -> ( bool , bool ) {
156- ( self . live . contains ( path) , self . dead . contains ( path) )
138+ fn maybe_live_dead ( & self , path : MovePathIndex ) -> ( bool , bool ) {
139+ ( self . inits . contains ( path) , self . uninits . contains ( path) )
157140 }
158141}
159142
160143struct Elaborator < ' a , ' b , ' tcx > {
161- init_data : & ' a InitializationData ,
162144 ctxt : & ' a mut ElaborateDropsCtxt < ' b , ' tcx > ,
163145}
164146
@@ -189,13 +171,13 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
189171
190172 fn drop_style ( & self , path : Self :: Path , mode : DropFlagMode ) -> DropStyle {
191173 let ( ( maybe_live, maybe_dead) , multipart) = match mode {
192- DropFlagMode :: Shallow => ( self . init_data . state ( path) , false ) ,
174+ DropFlagMode :: Shallow => ( self . ctxt . init_data . maybe_live_dead ( path) , false ) ,
193175 DropFlagMode :: Deep => {
194176 let mut some_live = false ;
195177 let mut some_dead = false ;
196178 let mut children_count = 0 ;
197179 on_all_drop_children_bits ( self . tcx ( ) , self . body ( ) , self . ctxt . env , path, |child| {
198- let ( live, dead) = self . init_data . state ( child) ;
180+ let ( live, dead) = self . ctxt . init_data . maybe_live_dead ( child) ;
199181 debug ! ( "elaborate_drop: state({:?}) = {:?}" , child, ( live, dead) ) ;
200182 some_live |= live;
201183 some_dead |= dead;
@@ -269,8 +251,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
269251 tcx : TyCtxt < ' tcx > ,
270252 body : & ' a Body < ' tcx > ,
271253 env : & ' a MoveDataParamEnv < ' tcx > ,
272- flow_inits : Results < ' tcx , MaybeInitializedPlaces < ' a , ' tcx > > ,
273- flow_uninits : Results < ' tcx , MaybeUninitializedPlaces < ' a , ' tcx > > ,
254+ init_data : InitializationData < ' a , ' tcx > ,
274255 drop_flags : FxHashMap < MovePathIndex , Local > ,
275256 patch : MirPatch < ' tcx > ,
276257}
@@ -284,25 +265,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
284265 self . env . param_env
285266 }
286267
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-
306268 fn create_drop_flag ( & mut self , index : MovePathIndex , span : Span ) {
307269 let tcx = self . tcx ;
308270 let patch = & mut self . patch ;
@@ -338,10 +300,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
338300 _ => continue ,
339301 } ;
340302
341- let init_data = self . initialization_data_at ( Location {
342- block : bb,
343- statement_index : data. statements . len ( ) ,
344- } ) ;
303+ self . init_data . seek_before ( self . body . terminator_loc ( bb) ) ;
345304
346305 let path = self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) ;
347306 debug ! ( "collect_drop_flags: {:?}, place {:?} ({:?})" , bb, location, path) ;
@@ -350,7 +309,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
350309 LookupResult :: Exact ( e) => e,
351310 LookupResult :: Parent ( None ) => continue ,
352311 LookupResult :: Parent ( Some ( parent) ) => {
353- let ( _maybe_live, maybe_dead) = init_data. state ( parent) ;
312+ let ( _maybe_live, maybe_dead) = self . init_data . maybe_live_dead ( parent) ;
354313 if maybe_dead {
355314 span_bug ! (
356315 terminator. source_info. span,
@@ -365,7 +324,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
365324 } ;
366325
367326 on_all_drop_children_bits ( self . tcx , self . body , self . env , path, |child| {
368- let ( maybe_live, maybe_dead) = init_data. state ( child) ;
327+ let ( maybe_live, maybe_dead) = self . init_data . maybe_live_dead ( child) ;
369328 debug ! (
370329 "collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}" ,
371330 child,
@@ -388,10 +347,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
388347 let resume_block = self . patch . resume_block ( ) ;
389348 match terminator. kind {
390349 TerminatorKind :: Drop { ref location, target, unwind } => {
391- let init_data = self . initialization_data_at ( loc) ;
350+ self . init_data . seek_before ( loc) ;
392351 match self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) {
393352 LookupResult :: Exact ( path) => elaborate_drop (
394- & mut Elaborator { init_data : & init_data , ctxt : self } ,
353+ & mut Elaborator { ctxt : self } ,
395354 terminator. source_info ,
396355 location,
397356 path,
@@ -471,10 +430,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
471430 match self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) {
472431 LookupResult :: Exact ( path) => {
473432 debug ! ( "elaborate_drop_and_replace({:?}) - tracked {:?}" , terminator, path) ;
474- let init_data = self . initialization_data_at ( loc) ;
475-
433+ self . init_data . seek_before ( loc) ;
476434 elaborate_drop (
477- & mut Elaborator { init_data : & init_data , ctxt : self } ,
435+ & mut Elaborator { ctxt : self } ,
478436 terminator. source_info ,
479437 location,
480438 path,
0 commit comments