132
132
//! [attempt 3]: https://github.com/rust-lang/rust/pull/72632
133
133
134
134
use crate :: MirPass ;
135
- use rustc_data_structures:: fx:: { FxIndexMap , IndexEntry , IndexOccupiedEntry } ;
135
+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , IndexEntry , IndexOccupiedEntry } ;
136
136
use rustc_index:: bit_set:: BitSet ;
137
137
use rustc_index:: interval:: SparseIntervalMatrix ;
138
138
use rustc_middle:: mir:: visit:: { MutVisitor , PlaceContext , Visitor } ;
@@ -216,6 +216,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
216
216
217
217
// This is the set of merges we will apply this round. It is a subset of the candidates.
218
218
let mut merges = FxIndexMap :: default ( ) ;
219
+ let mut remove_writes = FxHashMap :: default ( ) ;
219
220
220
221
for ( src, candidates) in candidates. c . drain ( ..) {
221
222
if merged_locals. contains ( src) {
@@ -239,8 +240,10 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
239
240
// Replace `src` by `dest` everywhere.
240
241
merged_locals. insert ( src) ;
241
242
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
+ }
244
247
}
245
248
trace ! ( merging = ?merges) ;
246
249
@@ -249,7 +252,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
249
252
}
250
253
round_count += 1 ;
251
254
252
- apply_merges ( body, tcx, & merges, & merged_locals) ;
255
+ apply_merges ( body, tcx, & merges, & remove_writes , & merged_locals) ;
253
256
}
254
257
255
258
trace ! ( round_count) ;
@@ -299,22 +302,24 @@ struct Candidates<'alloc> {
299
302
fn apply_merges < ' tcx > (
300
303
body : & mut Body < ' tcx > ,
301
304
tcx : TyCtxt < ' tcx > ,
302
- merges : & FxIndexMap < Local , ( Local , Vec < Location > ) > ,
305
+ merges : & FxIndexMap < Local , Local > ,
306
+ remove_writes : & FxHashMap < Local , Vec < Location > > ,
303
307
merged_locals : & BitSet < Local > ,
304
308
) {
305
- let mut merger = Merger { tcx, merges, merged_locals } ;
309
+ let mut merger = Merger { tcx, merges, remove_writes , merged_locals } ;
306
310
merger. visit_body_preserves_cfg ( body) ;
307
311
}
308
312
309
313
struct Merger < ' a , ' tcx > {
310
314
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 > > ,
312
317
merged_locals : & ' a BitSet < Local > ,
313
318
}
314
319
315
320
impl < ' a , ' tcx > Merger < ' a , ' tcx > {
316
321
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 {
318
323
return false ;
319
324
} ;
320
325
to_remove. contains ( & location)
@@ -328,7 +333,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
328
333
329
334
fn visit_local ( & mut self , local : & mut Local , _: PlaceContext , _location : Location ) {
330
335
if let Some ( dest) = self . merges . get ( local) {
331
- * local = dest. 0 ;
336
+ * local = * dest;
332
337
}
333
338
}
334
339
0 commit comments