about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform
diff options
context:
space:
mode:
authorCamille Gillot <gillot.camille@gmail.com>2025-08-27 01:40:16 +0000
committerCamille Gillot <gillot.camille@gmail.com>2025-09-07 16:46:34 +0000
commit5d0e66d451b0da5e7a712d5f9e041e5bbbbb0255 (patch)
treeb9923a2b564a21724a2b2e360ea9c2efcb95a17e /compiler/rustc_mir_transform
parent28ff5cf502a0132a4eed8aa46fa7371c7e7ed3f1 (diff)
downloadrust-5d0e66d451b0da5e7a712d5f9e041e5bbbbb0255.tar.gz
rust-5d0e66d451b0da5e7a712d5f9e041e5bbbbb0255.zip
Use rustc_data_structures::union_find.
Diffstat (limited to 'compiler/rustc_mir_transform')
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs42
1 files changed, 14 insertions, 28 deletions
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index b6306c4869b..9ba2d274691 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -137,6 +137,7 @@
 //! [attempt 3]: https://github.com/rust-lang/rust/pull/72632
 //! [attempt 4]: https://github.com/rust-lang/rust/pull/96451
 
+use rustc_data_structures::union_find::UnionFind;
 use rustc_index::bit_set::DenseBitSet;
 use rustc_index::interval::SparseIntervalMatrix;
 use rustc_index::{IndexVec, newtype_index};
@@ -225,13 +226,12 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
                 merged_locals.insert(orig_dst);
 
                 // Replace `src` by `dst`.
-                relevant.union(src, dst);
-                live.union_rows(/* read */ src, /* write */ dst);
+                let head = relevant.union(src, dst);
+                live.union_rows(/* read */ src, /* write */ head);
+                live.union_rows(/* read */ dst, /* write */ head);
             }
         }
         trace!(?merged_locals);
-
-        relevant.make_idempotent();
         trace!(?relevant.renames);
 
         if merged_locals.is_empty() {
@@ -326,7 +326,7 @@ newtype_index! {
 struct RelevantLocals {
     original: IndexVec<RelevantLocal, Local>,
     shrink: IndexVec<Local, Option<RelevantLocal>>,
-    renames: IndexVec<RelevantLocal, RelevantLocal>,
+    renames: UnionFind<RelevantLocal>,
 }
 
 impl RelevantLocals {
@@ -345,35 +345,21 @@ impl RelevantLocals {
             declare(dest)
         }
 
-        let renames = IndexVec::from_fn_n(|l| l, original.len());
+        let renames = UnionFind::new(original.len());
         RelevantLocals { original, shrink, renames }
     }
 
-    fn find(&self, src: Local) -> Option<RelevantLocal> {
-        let mut src = self.shrink[src]?;
-        while let s2 = self.renames[src]
-            && src != s2
-        {
-            src = s2
-        }
+    fn find(&mut self, src: Local) -> Option<RelevantLocal> {
+        let src = self.shrink[src]?;
+        let src = self.renames.find(src);
         Some(src)
     }
 
-    fn union(&mut self, lhs: RelevantLocal, rhs: RelevantLocal) {
-        self.renames[lhs] = rhs;
-    }
-
-    fn make_idempotent(&mut self) {
-        for l in self.renames.indices() {
-            let mut h = self.renames[l];
-            while let h2 = self.renames[h]
-                && h != h2
-            {
-                h = h2
-            }
-            self.renames[l] = h;
-            debug_assert_eq!(h, self.renames[h], "non-idempotent for {l:?}");
-        }
+    fn union(&mut self, lhs: RelevantLocal, rhs: RelevantLocal) -> RelevantLocal {
+        let head = self.renames.unify(lhs, rhs);
+        // We need to ensure we keep the original local of the RHS, as it may be a required local.
+        self.original[head] = self.original[rhs];
+        head
     }
 }