1
1
use crate :: dataflow;
2
- use crate :: dataflow:: generic:: { Analysis , Results } ;
2
+ use crate :: dataflow:: generic:: { Analysis , ResultsCursor } ;
3
3
use crate :: dataflow:: move_paths:: { LookupResult , MoveData , MovePathIndex } ;
4
+ use crate :: dataflow:: on_lookup_result_bits;
4
5
use crate :: dataflow:: MoveDataParamEnv ;
5
- use crate :: dataflow:: { drop_flag_effects_for_location, on_lookup_result_bits} ;
6
6
use crate :: dataflow:: { on_all_children_bits, on_all_drop_children_bits} ;
7
7
use crate :: dataflow:: { MaybeInitializedPlaces , MaybeUninitializedPlaces } ;
8
8
use crate :: transform:: { MirPass , MirSource } ;
@@ -41,22 +41,23 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
41
41
let env = MoveDataParamEnv { move_data, param_env } ;
42
42
let dead_unwinds = find_dead_unwinds ( tcx, body, def_id, & env) ;
43
43
44
- let flow_inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
44
+ let inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
45
45
. into_engine ( tcx, body, def_id)
46
46
. dead_unwinds ( & dead_unwinds)
47
- . iterate_to_fixpoint ( ) ;
47
+ . iterate_to_fixpoint ( )
48
+ . into_results_cursor ( body) ;
48
49
49
- let flow_uninits = MaybeUninitializedPlaces :: new ( tcx, body, & env)
50
+ let uninits = MaybeUninitializedPlaces :: new ( tcx, body, & env)
50
51
. into_engine ( tcx, body, def_id)
51
52
. dead_unwinds ( & dead_unwinds)
52
- . iterate_to_fixpoint ( ) ;
53
+ . iterate_to_fixpoint ( )
54
+ . into_results_cursor ( body) ;
53
55
54
56
ElaborateDropsCtxt {
55
57
tcx,
56
58
body,
57
59
env : & env,
58
- flow_inits,
59
- flow_uninits,
60
+ init_data : InitializationData { inits, uninits } ,
60
61
drop_flags : Default :: default ( ) ,
61
62
patch : MirPatch :: new ( body) ,
62
63
}
@@ -79,25 +80,18 @@ fn find_dead_unwinds<'tcx>(
79
80
// We only need to do this pass once, because unwind edges can only
80
81
// reach cleanup blocks, which can't have unwind edges themselves.
81
82
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)
83
84
. into_engine ( tcx, body, def_id)
84
- . iterate_to_fixpoint ( ) ;
85
+ . iterate_to_fixpoint ( )
86
+ . into_results_cursor ( body) ;
85
87
for ( bb, bb_data) in body. basic_blocks ( ) . iter_enumerated ( ) {
86
88
let location = match bb_data. terminator ( ) . kind {
87
89
TerminatorKind :: Drop { ref location, unwind : Some ( _) , .. }
88
90
| TerminatorKind :: DropAndReplace { ref location, unwind : Some ( _) , .. } => location,
89
91
_ => continue ,
90
92
} ;
91
93
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) ;
101
95
102
96
let path = match env. move_data . rev_lookup . find ( location. as_ref ( ) ) {
103
97
LookupResult :: Exact ( e) => e,
@@ -107,12 +101,18 @@ fn find_dead_unwinds<'tcx>(
107
101
}
108
102
} ;
109
103
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
+ ) ;
111
112
112
113
let mut maybe_live = false ;
113
114
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) ;
116
116
} ) ;
117
117
118
118
debug ! ( "find_dead_unwinds @ {:?}: maybe_live={}" , bb, maybe_live) ;
@@ -124,41 +124,23 @@ fn find_dead_unwinds<'tcx>(
124
124
dead_unwinds
125
125
}
126
126
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 > > ,
130
130
}
131
131
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) ;
153
136
}
154
137
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) )
157
140
}
158
141
}
159
142
160
143
struct Elaborator < ' a , ' b , ' tcx > {
161
- init_data : & ' a InitializationData ,
162
144
ctxt : & ' a mut ElaborateDropsCtxt < ' b , ' tcx > ,
163
145
}
164
146
@@ -189,13 +171,13 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
189
171
190
172
fn drop_style ( & self , path : Self :: Path , mode : DropFlagMode ) -> DropStyle {
191
173
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 ) ,
193
175
DropFlagMode :: Deep => {
194
176
let mut some_live = false ;
195
177
let mut some_dead = false ;
196
178
let mut children_count = 0 ;
197
179
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) ;
199
181
debug ! ( "elaborate_drop: state({:?}) = {:?}" , child, ( live, dead) ) ;
200
182
some_live |= live;
201
183
some_dead |= dead;
@@ -269,8 +251,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
269
251
tcx : TyCtxt < ' tcx > ,
270
252
body : & ' a Body < ' tcx > ,
271
253
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 > ,
274
255
drop_flags : FxHashMap < MovePathIndex , Local > ,
275
256
patch : MirPatch < ' tcx > ,
276
257
}
@@ -284,25 +265,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
284
265
self . env . param_env
285
266
}
286
267
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
-
306
268
fn create_drop_flag ( & mut self , index : MovePathIndex , span : Span ) {
307
269
let tcx = self . tcx ;
308
270
let patch = & mut self . patch ;
@@ -338,10 +300,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
338
300
_ => continue ,
339
301
} ;
340
302
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) ) ;
345
304
346
305
let path = self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) ;
347
306
debug ! ( "collect_drop_flags: {:?}, place {:?} ({:?})" , bb, location, path) ;
@@ -350,7 +309,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
350
309
LookupResult :: Exact ( e) => e,
351
310
LookupResult :: Parent ( None ) => continue ,
352
311
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) ;
354
313
if maybe_dead {
355
314
span_bug ! (
356
315
terminator. source_info. span,
@@ -365,7 +324,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
365
324
} ;
366
325
367
326
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) ;
369
328
debug ! (
370
329
"collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}" ,
371
330
child,
@@ -388,10 +347,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
388
347
let resume_block = self . patch . resume_block ( ) ;
389
348
match terminator. kind {
390
349
TerminatorKind :: Drop { ref location, target, unwind } => {
391
- let init_data = self . initialization_data_at ( loc) ;
350
+ self . init_data . seek_before ( loc) ;
392
351
match self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) {
393
352
LookupResult :: Exact ( path) => elaborate_drop (
394
- & mut Elaborator { init_data : & init_data , ctxt : self } ,
353
+ & mut Elaborator { ctxt : self } ,
395
354
terminator. source_info ,
396
355
location,
397
356
path,
@@ -471,10 +430,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
471
430
match self . move_data ( ) . rev_lookup . find ( location. as_ref ( ) ) {
472
431
LookupResult :: Exact ( path) => {
473
432
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) ;
476
434
elaborate_drop (
477
- & mut Elaborator { init_data : & init_data , ctxt : self } ,
435
+ & mut Elaborator { ctxt : self } ,
478
436
terminator. source_info ,
479
437
location,
480
438
path,
0 commit comments