132132//! [attempt 3]: https://github.com/rust-lang/rust/pull/72632
133133
134134use crate :: MirPass ;
135- use rustc_data_structures:: fx:: { FxIndexMap , IndexEntry , IndexOccupiedEntry } ;
135+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , IndexEntry , IndexOccupiedEntry } ;
136136use rustc_index:: bit_set:: BitSet ;
137137use rustc_index:: interval:: SparseIntervalMatrix ;
138138use rustc_middle:: mir:: visit:: { MutVisitor , PlaceContext , Visitor } ;
@@ -216,6 +216,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
216216
217217 // This is the set of merges we will apply this round. It is a subset of the candidates.
218218 let mut merges = FxIndexMap :: default ( ) ;
219+ let mut remove_writes = FxHashMap :: default ( ) ;
219220
220221 for ( src, candidates) in candidates. c . drain ( ..) {
221222 if merged_locals. contains ( src) {
@@ -239,8 +240,10 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
239240 // Replace `src` by `dest` everywhere.
240241 merged_locals. insert ( src) ;
241242 merged_locals. insert ( dest. 0 ) ;
242- merges. insert ( src, dest. clone ( ) ) ;
243- merges. insert ( dest. 0 , dest) ;
243+ merges. insert ( src, dest. 0 ) ;
244+ if !dest. 1 . is_empty ( ) {
245+ remove_writes. insert ( dest. 0 , dest. 1 ) ;
246+ }
244247 }
245248 trace ! ( merging = ?merges) ;
246249
@@ -249,7 +252,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
249252 }
250253 round_count += 1 ;
251254
252- apply_merges ( body, tcx, & merges, & merged_locals) ;
255+ apply_merges ( body, tcx, & merges, & remove_writes , & merged_locals) ;
253256 }
254257
255258 trace ! ( round_count) ;
@@ -299,22 +302,24 @@ struct Candidates<'alloc> {
299302fn apply_merges < ' tcx > (
300303 body : & mut Body < ' tcx > ,
301304 tcx : TyCtxt < ' tcx > ,
302- merges : & FxIndexMap < Local , ( Local , Vec < Location > ) > ,
305+ merges : & FxIndexMap < Local , Local > ,
306+ remove_writes : & FxHashMap < Local , Vec < Location > > ,
303307 merged_locals : & BitSet < Local > ,
304308) {
305- let mut merger = Merger { tcx, merges, merged_locals } ;
309+ let mut merger = Merger { tcx, merges, remove_writes , merged_locals } ;
306310 merger. visit_body_preserves_cfg ( body) ;
307311}
308312
309313struct Merger < ' a , ' tcx > {
310314 tcx : TyCtxt < ' tcx > ,
311- merges : & ' a FxIndexMap < Local , ( Local , Vec < Location > ) > ,
315+ merges : & ' a FxIndexMap < Local , Local > ,
316+ remove_writes : & ' a FxHashMap < Local , Vec < Location > > ,
312317 merged_locals : & ' a BitSet < Local > ,
313318}
314319
315320impl < ' a , ' tcx > Merger < ' a , ' tcx > {
316321 fn should_remove_write_at ( & self , local : Local , location : Location ) -> bool {
317- let Some ( ( _ , to_remove) ) = self . merges . get ( & local) else {
322+ let Some ( to_remove) = self . remove_writes . get ( & local) else {
318323 return false ;
319324 } ;
320325 to_remove. contains ( & location)
@@ -328,7 +333,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
328333
329334 fn visit_local ( & mut self , local : & mut Local , _: PlaceContext , _location : Location ) {
330335 if let Some ( dest) = self . merges . get ( local) {
331- * local = dest. 0 ;
336+ * local = * dest;
332337 }
333338 }
334339
0 commit comments