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:: union_find:: UnionFind ;
140
141
use rustc_index:: bit_set:: DenseBitSet ;
141
142
use rustc_index:: interval:: SparseIntervalMatrix ;
142
143
use rustc_index:: { IndexVec , newtype_index} ;
@@ -225,13 +226,12 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
225
226
merged_locals. insert ( orig_dst) ;
226
227
227
228
// Replace `src` by `dst`.
228
- relevant. union ( src, dst) ;
229
- live. union_rows ( /* read */ src, /* write */ dst) ;
229
+ let head = relevant. union ( src, dst) ;
230
+ live. union_rows ( /* read */ src, /* write */ head) ;
231
+ live. union_rows ( /* read */ dst, /* write */ head) ;
230
232
}
231
233
}
232
234
trace ! ( ?merged_locals) ;
233
-
234
- relevant. make_idempotent ( ) ;
235
235
trace ! ( ?relevant. renames) ;
236
236
237
237
if merged_locals. is_empty ( ) {
@@ -326,7 +326,7 @@ newtype_index! {
326
326
struct RelevantLocals {
327
327
original : IndexVec < RelevantLocal , Local > ,
328
328
shrink : IndexVec < Local , Option < RelevantLocal > > ,
329
- renames : IndexVec < RelevantLocal , RelevantLocal > ,
329
+ renames : UnionFind < RelevantLocal > ,
330
330
}
331
331
332
332
impl RelevantLocals {
@@ -345,35 +345,21 @@ impl RelevantLocals {
345
345
declare ( dest)
346
346
}
347
347
348
- let renames = IndexVec :: from_fn_n ( |l| l , original. len ( ) ) ;
348
+ let renames = UnionFind :: new ( original. len ( ) ) ;
349
349
RelevantLocals { original, shrink, renames }
350
350
}
351
351
352
- fn find ( & self , src : Local ) -> Option < RelevantLocal > {
353
- let mut src = self . shrink [ src] ?;
354
- while let s2 = self . renames [ src]
355
- && src != s2
356
- {
357
- src = s2
358
- }
352
+ fn find ( & mut self , src : Local ) -> Option < RelevantLocal > {
353
+ let src = self . shrink [ src] ?;
354
+ let src = self . renames . find ( src) ;
359
355
Some ( src)
360
356
}
361
357
362
- fn union ( & mut self , lhs : RelevantLocal , rhs : RelevantLocal ) {
363
- self . renames [ lhs] = rhs;
364
- }
365
-
366
- fn make_idempotent ( & mut self ) {
367
- for l in self . renames . indices ( ) {
368
- let mut h = self . renames [ l] ;
369
- while let h2 = self . renames [ h]
370
- && h != h2
371
- {
372
- h = h2
373
- }
374
- self . renames [ l] = h;
375
- debug_assert_eq ! ( h, self . renames[ h] , "non-idempotent for {l:?}" ) ;
376
- }
358
+ fn union ( & mut self , lhs : RelevantLocal , rhs : RelevantLocal ) -> RelevantLocal {
359
+ let head = self . renames . unify ( lhs, rhs) ;
360
+ // We need to ensure we keep the original local of the RHS, as it may be a required local.
361
+ self . original [ head] = self . original [ rhs] ;
362
+ head
377
363
}
378
364
}
379
365
0 commit comments