@@ -164,8 +164,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
164164
165165 fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
166166 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 ( ) ;
169168 let mut write_info = WriteInfo :: default ( ) ;
170169 trace ! ( func = ?tcx. def_path_str( def_id) ) ;
171170
@@ -194,12 +193,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
194193 loop {
195194 // PERF: Can we do something smarter than recalculating the candidates and liveness
196195 // 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) ;
203197 trace ! ( ?candidates) ;
204198 dest_prop_mir_dump ( tcx, body, & points, & live, round_count) ;
205199
@@ -256,8 +250,8 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
256250 }
257251}
258252
259- #[ derive( Debug ) ]
260- struct Candidates < ' alloc > {
253+ #[ derive( Debug , Default ) ]
254+ struct Candidates {
261255 /// The set of candidates we are considering in this optimization.
262256 ///
263257 /// We will always merge the key into at most one of its values.
@@ -272,11 +266,12 @@ struct Candidates<'alloc> {
272266 ///
273267 /// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
274268 /// remove that assignment.
275- c : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
269+ c : FxIndexMap < Local , Vec < Local > > ,
270+
276271 /// A reverse index of the `c` set; if the `c` set contains `a => Place { local: b, proj }`,
277272 /// then this contains `b => a`.
278273 // PERF: Possibly these should be `SmallVec`s?
279- reverse : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
274+ reverse : FxIndexMap < Local , Vec < Local > > ,
280275}
281276
282277//////////////////////////////////////////////////////////
@@ -349,19 +344,40 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
349344//
350345// This section enforces bullet point 2
351346
352- struct FilterInformation < ' a , ' alloc , ' tcx > {
347+ struct FilterInformation < ' a , ' tcx > {
353348 body : & ' a Body < ' tcx > ,
354349 points : & ' a DenseLocationMap ,
355350 live : & ' a SparseIntervalMatrix < Local , PointIndex > ,
356- candidates : & ' a mut Candidates < ' alloc > ,
351+ candidates : & ' a mut Candidates ,
357352 write_info : & ' a mut WriteInfo ,
358353 at : Location ,
359354}
360355
361356// We first implement some utility functions which we will expose removing candidates according to
362357// different needs. Throughout the liveness filtering, the `candidates` are only ever accessed
363358// 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+
365381 /// Just `Vec::retain`, but the condition is inverted and we add debugging output
366382 fn vec_filter_candidates (
367383 src : Local ,
@@ -436,7 +452,7 @@ enum CandidateFilter {
436452 Remove ,
437453}
438454
439- impl < ' a , ' alloc , ' tcx > FilterInformation < ' a , ' alloc , ' tcx > {
455+ impl < ' a , ' tcx > FilterInformation < ' a , ' tcx > {
440456 /// Filters the set of candidates to remove those that conflict.
441457 ///
442458 /// 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> {
455471 /// statement/terminator to be live. We are additionally conservative by treating all written to
456472 /// locals as also being read from.
457473 fn filter_liveness (
458- candidates : & mut Candidates < ' alloc > ,
474+ candidates : & mut Candidates ,
459475 points : & DenseLocationMap ,
460476 live : & SparseIntervalMatrix < Local , PointIndex > ,
461477 write_info : & mut WriteInfo ,
@@ -725,40 +741,13 @@ fn places_to_candidate_pair<'tcx>(
725741 Some ( ( a, b) )
726742}
727743
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 > {
756745 body : & ' a Body < ' tcx > ,
757- candidates : & ' alloc mut FxIndexMap < Local , Vec < Local > > ,
746+ candidates : & ' a mut FxIndexMap < Local , Vec < Local > > ,
758747 borrowed : & ' a BitSet < Local > ,
759748}
760749
761- impl < ' tcx > Visitor < ' tcx > for FindAssignments < ' _ , ' _ , ' tcx > {
750+ impl < ' tcx > Visitor < ' tcx > for FindAssignments < ' _ , ' tcx > {
762751 fn visit_statement ( & mut self , statement : & Statement < ' tcx > , _: Location ) {
763752 if let StatementKind :: Assign ( box (
764753 lhs,
0 commit comments