137
137
//! [attempt 3]: https://github.com/rust-lang/rust/pull/72632
138
138
//! [attempt 4]: https://github.com/rust-lang/rust/pull/96451
139
139
140
- use rustc_data_structures:: fx:: FxIndexMap ;
141
140
use rustc_index:: bit_set:: DenseBitSet ;
142
141
use rustc_index:: interval:: SparseIntervalMatrix ;
143
142
use rustc_index:: { IndexVec , newtype_index} ;
@@ -187,48 +186,47 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
187
186
188
187
let mut merged_locals = DenseBitSet :: new_empty ( body. local_decls . len ( ) ) ;
189
188
190
- for ( src, candidates) in candidates. c . into_iter ( ) {
191
- trace ! ( ?src, ?candidates) ;
192
-
193
- for dst in candidates {
194
- // We call `relevant.find(src)` inside the loop, as a previous iteration may have
195
- // renamed `src` to one of the locals in `dst`.
196
- let Some ( mut src) = relevant. find ( src) else { continue } ;
197
- let Some ( src_live_ranges) = live. row ( src) else { continue } ;
198
- trace ! ( ?src, ?src_live_ranges) ;
199
-
200
- let Some ( mut dst) = relevant. find ( dst) else { continue } ;
201
- let Some ( dst_live_ranges) = live. row ( dst) else { continue } ;
202
- trace ! ( ?dst, ?dst_live_ranges) ;
203
-
204
- if src_live_ranges. disjoint ( dst_live_ranges) {
205
- // We want to replace `src` by `dst`.
206
- let mut orig_src = relevant. original [ src] ;
207
- let mut orig_dst = relevant. original [ dst] ;
208
-
209
- // The return place and function arguments are required and cannot be renamed.
210
- // This check cannot be made during candidate collection, as we may want to
211
- // unify the same non-required local with several required locals.
212
- match ( is_local_required ( orig_src, body) , is_local_required ( orig_dst, body) ) {
213
- // Renaming `src` is ok.
214
- ( false , _) => { }
215
- // Renaming `src` is wrong, but renaming `dst` is ok.
216
- ( true , false ) => {
217
- std:: mem:: swap ( & mut src, & mut dst) ;
218
- std:: mem:: swap ( & mut orig_src, & mut orig_dst) ;
219
- }
220
- // Neither local can be renamed, so skip this case.
221
- ( true , true ) => continue ,
222
- }
189
+ for ( src, dst) in candidates. c . into_iter ( ) {
190
+ trace ! ( ?src, ?dst) ;
223
191
224
- trace ! ( ?src, ?dst, "merge" ) ;
225
- merged_locals. insert ( orig_src) ;
226
- merged_locals. insert ( orig_dst) ;
192
+ let Some ( mut src) = relevant. find ( src) else { continue } ;
193
+ let Some ( mut dst) = relevant. find ( dst) else { continue } ;
194
+ if src == dst {
195
+ continue ;
196
+ }
227
197
228
- // Replace `src` by `dst`.
229
- relevant. union ( src, dst) ;
230
- live. union_rows ( /* read */ src, /* write */ dst) ;
198
+ let Some ( src_live_ranges) = live. row ( src) else { continue } ;
199
+ let Some ( dst_live_ranges) = live. row ( dst) else { continue } ;
200
+ trace ! ( ?src, ?src_live_ranges) ;
201
+ trace ! ( ?dst, ?dst_live_ranges) ;
202
+
203
+ if src_live_ranges. disjoint ( dst_live_ranges) {
204
+ // We want to replace `src` by `dst`.
205
+ let mut orig_src = relevant. original [ src] ;
206
+ let mut orig_dst = relevant. original [ dst] ;
207
+
208
+ // The return place and function arguments are required and cannot be renamed.
209
+ // This check cannot be made during candidate collection, as we may want to
210
+ // unify the same non-required local with several required locals.
211
+ match ( is_local_required ( orig_src, body) , is_local_required ( orig_dst, body) ) {
212
+ // Renaming `src` is ok.
213
+ ( false , _) => { }
214
+ // Renaming `src` is wrong, but renaming `dst` is ok.
215
+ ( true , false ) => {
216
+ std:: mem:: swap ( & mut src, & mut dst) ;
217
+ std:: mem:: swap ( & mut orig_src, & mut orig_dst) ;
218
+ }
219
+ // Neither local can be renamed, so skip this case.
220
+ ( true , true ) => continue ,
231
221
}
222
+
223
+ trace ! ( ?src, ?dst, "merge" ) ;
224
+ merged_locals. insert ( orig_src) ;
225
+ merged_locals. insert ( orig_dst) ;
226
+
227
+ // Replace `src` by `dst`.
228
+ relevant. union ( src, dst) ;
229
+ live. union_rows ( /* read */ src, /* write */ dst) ;
232
230
}
233
231
}
234
232
trace ! ( ?merged_locals) ;
@@ -342,11 +340,9 @@ impl RelevantLocals {
342
340
shrink. get_or_insert_with ( local, || original. push ( local) ) ;
343
341
} ;
344
342
345
- for ( & src, destinations ) in candidates. c . iter ( ) {
343
+ for & ( src, dest ) in candidates. c . iter ( ) {
346
344
declare ( src) ;
347
- for & dest in destinations {
348
- declare ( dest)
349
- }
345
+ declare ( dest)
350
346
}
351
347
352
348
let renames = IndexVec :: from_fn_n ( |l| l, original. len ( ) ) ;
@@ -388,8 +384,6 @@ impl RelevantLocals {
388
384
struct Candidates {
389
385
/// The set of candidates we are considering in this optimization.
390
386
///
391
- /// We will always merge the key into at most one of its values.
392
- ///
393
387
/// Whether a place ends up in the key or the value does not correspond to whether it appears as
394
388
/// the lhs or rhs of any assignment. As a matter of fact, the places in here might never appear
395
389
/// in an assignment at all. This happens because if we see an assignment like this:
@@ -400,7 +394,7 @@ struct Candidates {
400
394
///
401
395
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
402
396
/// remove that assignment.
403
- c : FxIndexMap < Local , Vec < Local > > ,
397
+ c : Vec < ( Local , Local ) > ,
404
398
}
405
399
406
400
// We first implement some utility functions which we will expose removing candidates according to
@@ -414,19 +408,13 @@ impl Candidates {
414
408
let mut visitor = FindAssignments { body, candidates : Default :: default ( ) , borrowed } ;
415
409
visitor. visit_body ( body) ;
416
410
417
- // Deduplicate candidates.
418
- for ( _, cands) in visitor. candidates . iter_mut ( ) {
419
- cands. sort ( ) ;
420
- cands. dedup ( ) ;
421
- }
422
-
423
411
Candidates { c : visitor. candidates }
424
412
}
425
413
}
426
414
427
415
struct FindAssignments < ' a , ' tcx > {
428
416
body : & ' a Body < ' tcx > ,
429
- candidates : FxIndexMap < Local , Vec < Local > > ,
417
+ candidates : Vec < ( Local , Local ) > ,
430
418
borrowed : & ' a DenseBitSet < Local > ,
431
419
}
432
420
@@ -456,7 +444,7 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
456
444
}
457
445
458
446
// We may insert duplicates here, but that's fine
459
- self . candidates . entry ( src ) . or_default ( ) . push ( dest) ;
447
+ self . candidates . push ( ( src , dest) ) ;
460
448
}
461
449
}
462
450
}
0 commit comments