Skip to content

Commit 28ff5cf

Browse files
committed
Simplify candidate collection.
1 parent 99f6bcf commit 28ff5cf

File tree

1 file changed

+43
-55
lines changed

1 file changed

+43
-55
lines changed

compiler/rustc_mir_transform/src/dest_prop.rs

Lines changed: 43 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@
137137
//! [attempt 3]: https://github.com/rust-lang/rust/pull/72632
138138
//! [attempt 4]: https://github.com/rust-lang/rust/pull/96451
139139
140-
use rustc_data_structures::fx::FxIndexMap;
141140
use rustc_index::bit_set::DenseBitSet;
142141
use rustc_index::interval::SparseIntervalMatrix;
143142
use rustc_index::{IndexVec, newtype_index};
@@ -187,48 +186,47 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
187186

188187
let mut merged_locals = DenseBitSet::new_empty(body.local_decls.len());
189188

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);
223191

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+
}
227197

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,
231221
}
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);
232230
}
233231
}
234232
trace!(?merged_locals);
@@ -342,11 +340,9 @@ impl RelevantLocals {
342340
shrink.get_or_insert_with(local, || original.push(local));
343341
};
344342

345-
for (&src, destinations) in candidates.c.iter() {
343+
for &(src, dest) in candidates.c.iter() {
346344
declare(src);
347-
for &dest in destinations {
348-
declare(dest)
349-
}
345+
declare(dest)
350346
}
351347

352348
let renames = IndexVec::from_fn_n(|l| l, original.len());
@@ -388,8 +384,6 @@ impl RelevantLocals {
388384
struct Candidates {
389385
/// The set of candidates we are considering in this optimization.
390386
///
391-
/// We will always merge the key into at most one of its values.
392-
///
393387
/// Whether a place ends up in the key or the value does not correspond to whether it appears as
394388
/// the lhs or rhs of any assignment. As a matter of fact, the places in here might never appear
395389
/// in an assignment at all. This happens because if we see an assignment like this:
@@ -400,7 +394,7 @@ struct Candidates {
400394
///
401395
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
402396
/// remove that assignment.
403-
c: FxIndexMap<Local, Vec<Local>>,
397+
c: Vec<(Local, Local)>,
404398
}
405399

406400
// We first implement some utility functions which we will expose removing candidates according to
@@ -414,19 +408,13 @@ impl Candidates {
414408
let mut visitor = FindAssignments { body, candidates: Default::default(), borrowed };
415409
visitor.visit_body(body);
416410

417-
// Deduplicate candidates.
418-
for (_, cands) in visitor.candidates.iter_mut() {
419-
cands.sort();
420-
cands.dedup();
421-
}
422-
423411
Candidates { c: visitor.candidates }
424412
}
425413
}
426414

427415
struct FindAssignments<'a, 'tcx> {
428416
body: &'a Body<'tcx>,
429-
candidates: FxIndexMap<Local, Vec<Local>>,
417+
candidates: Vec<(Local, Local)>,
430418
borrowed: &'a DenseBitSet<Local>,
431419
}
432420

@@ -456,7 +444,7 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
456444
}
457445

458446
// We may insert duplicates here, but that's fine
459-
self.candidates.entry(src).or_default().push(dest);
447+
self.candidates.push((src, dest));
460448
}
461449
}
462450
}

0 commit comments

Comments
 (0)