@@ -164,8 +164,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
164
164
165
165
fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
166
166
let def_id = body. source . def_id ( ) ;
167
- let mut candidates = FxIndexMap :: default ( ) ;
168
- let mut candidates_reverse = FxIndexMap :: default ( ) ;
167
+ let mut candidates = Candidates :: default ( ) ;
169
168
let mut write_info = WriteInfo :: default ( ) ;
170
169
trace ! ( func = ?tcx. def_path_str( def_id) ) ;
171
170
@@ -194,12 +193,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
194
193
loop {
195
194
// PERF: Can we do something smarter than recalculating the candidates and liveness
196
195
// results?
197
- let mut candidates = find_candidates (
198
- body,
199
- & borrowed,
200
- & mut candidates,
201
- & mut candidates_reverse,
202
- ) ;
196
+ candidates. reset_and_find ( body, & borrowed) ;
203
197
trace ! ( ?candidates) ;
204
198
dest_prop_mir_dump ( tcx, body, & points, & live, round_count) ;
205
199
@@ -256,8 +250,8 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
256
250
}
257
251
}
258
252
259
- #[ derive( Debug ) ]
260
- struct Candidates < ' alloc > {
253
+ #[ derive( Debug , Default ) ]
254
+ struct Candidates {
261
255
/// The set of candidates we are considering in this optimization.
262
256
///
263
257
/// We will always merge the key into at most one of its values.
@@ -272,11 +266,12 @@ struct Candidates<'alloc> {
272
266
///
273
267
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
274
268
/// remove that assignment.
275
- c : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
269
+ c : FxIndexMap < Local , Vec < Local > > ,
270
+
276
271
/// A reverse index of the `c` set; if the `c` set contains `a => Place { local: b, proj }`,
277
272
/// then this contains `b => a`.
278
273
// PERF: Possibly these should be `SmallVec`s?
279
- reverse : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
274
+ reverse : FxIndexMap < Local , Vec < Local > > ,
280
275
}
281
276
282
277
//////////////////////////////////////////////////////////
@@ -349,19 +344,40 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
349
344
//
350
345
// This section enforces bullet point 2
351
346
352
- struct FilterInformation < ' a , ' alloc , ' tcx > {
347
+ struct FilterInformation < ' a , ' tcx > {
353
348
body : & ' a Body < ' tcx > ,
354
349
points : & ' a DenseLocationMap ,
355
350
live : & ' a SparseIntervalMatrix < Local , PointIndex > ,
356
- candidates : & ' a mut Candidates < ' alloc > ,
351
+ candidates : & ' a mut Candidates ,
357
352
write_info : & ' a mut WriteInfo ,
358
353
at : Location ,
359
354
}
360
355
361
356
// We first implement some utility functions which we will expose removing candidates according to
362
357
// different needs. Throughout the liveness filtering, the `candidates` are only ever accessed
363
358
// through these methods, and not directly.
364
- impl < ' alloc > Candidates < ' alloc > {
359
+ impl Candidates {
360
+ /// Collects the candidates for merging
361
+ ///
362
+ /// This is responsible for enforcing the first and third bullet point.
363
+ fn reset_and_find < ' tcx > ( & mut self , body : & Body < ' tcx > , borrowed : & BitSet < Local > ) {
364
+ self . c . clear ( ) ;
365
+ self . reverse . clear ( ) ;
366
+ let mut visitor = FindAssignments { body, candidates : & mut self . c , borrowed } ;
367
+ visitor. visit_body ( body) ;
368
+ // Deduplicate candidates
369
+ for ( _, cands) in self . c . iter_mut ( ) {
370
+ cands. sort ( ) ;
371
+ cands. dedup ( ) ;
372
+ }
373
+ // Generate the reverse map
374
+ for ( src, cands) in self . c . iter ( ) {
375
+ for dest in cands. iter ( ) . copied ( ) {
376
+ self . reverse . entry ( dest) . or_default ( ) . push ( * src) ;
377
+ }
378
+ }
379
+ }
380
+
365
381
/// Just `Vec::retain`, but the condition is inverted and we add debugging output
366
382
fn vec_filter_candidates (
367
383
src : Local ,
@@ -436,7 +452,7 @@ enum CandidateFilter {
436
452
Remove ,
437
453
}
438
454
439
- impl < ' a , ' alloc , ' tcx > FilterInformation < ' a , ' alloc , ' tcx > {
455
+ impl < ' a , ' tcx > FilterInformation < ' a , ' tcx > {
440
456
/// Filters the set of candidates to remove those that conflict.
441
457
///
442
458
/// The steps we take are exactly those that are outlined at the top of the file. For each
@@ -455,7 +471,7 @@ impl<'a, 'alloc, 'tcx> FilterInformation<'a, 'alloc, 'tcx> {
455
471
/// statement/terminator to be live. We are additionally conservative by treating all written to
456
472
/// locals as also being read from.
457
473
fn filter_liveness (
458
- candidates : & mut Candidates < ' alloc > ,
474
+ candidates : & mut Candidates ,
459
475
points : & DenseLocationMap ,
460
476
live : & SparseIntervalMatrix < Local , PointIndex > ,
461
477
write_info : & mut WriteInfo ,
@@ -725,40 +741,13 @@ fn places_to_candidate_pair<'tcx>(
725
741
Some ( ( a, b) )
726
742
}
727
743
728
- /// Collects the candidates for merging
729
- ///
730
- /// This is responsible for enforcing the first and third bullet point.
731
- fn find_candidates < ' alloc , ' tcx > (
732
- body : & Body < ' tcx > ,
733
- borrowed : & BitSet < Local > ,
734
- candidates : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
735
- candidates_reverse : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
736
- ) -> Candidates < ' alloc > {
737
- candidates. clear ( ) ;
738
- candidates_reverse. clear ( ) ;
739
- let mut visitor = FindAssignments { body, candidates, borrowed } ;
740
- visitor. visit_body ( body) ;
741
- // Deduplicate candidates
742
- for ( _, cands) in candidates. iter_mut ( ) {
743
- cands. sort ( ) ;
744
- cands. dedup ( ) ;
745
- }
746
- // Generate the reverse map
747
- for ( src, cands) in candidates. iter ( ) {
748
- for dest in cands. iter ( ) . copied ( ) {
749
- candidates_reverse. entry ( dest) . or_default ( ) . push ( * src) ;
750
- }
751
- }
752
- Candidates { c : candidates, reverse : candidates_reverse }
753
- }
754
-
755
- struct FindAssignments < ' a , ' alloc , ' tcx > {
744
+ struct FindAssignments < ' a , ' tcx > {
756
745
body : & ' a Body < ' tcx > ,
757
- candidates : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
746
+ candidates : & ' a mut FxIndexMap < Local , Vec < Local > > ,
758
747
borrowed : & ' a BitSet < Local > ,
759
748
}
760
749
761
- impl < ' tcx > Visitor < ' tcx > for FindAssignments < ' _ , ' _ , ' tcx > {
750
+ impl < ' tcx > Visitor < ' tcx > for FindAssignments < ' _ , ' tcx > {
762
751
fn visit_statement ( & mut self , statement : & Statement < ' tcx > , _: Location ) {
763
752
if let StatementKind :: Assign ( box (
764
753
lhs,
0 commit comments