Skip to content

Commit 369ea93

Browse files
committed
Simplify candidate collection.
1 parent 33b8687 commit 369ea93

File tree

1 file changed

+43
-53
lines changed

1 file changed

+43
-53
lines changed

compiler/rustc_mir_transform/src/dest_prop.rs

Lines changed: 43 additions & 53 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};
@@ -179,48 +178,47 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
179178

180179
let mut merged_locals = DenseBitSet::new_empty(body.local_decls.len());
181180

182-
for (src, candidates) in candidates.c.into_iter() {
183-
trace!(?src, ?candidates);
184-
185-
for dst in candidates {
186-
// We call `relevant.find(src)` inside the loop, as a previous iteration may have
187-
// renamed `src` to one of the locals in `dst`.
188-
let Some(mut src) = relevant.find(src) else { continue };
189-
let Some(src_live_ranges) = live.row(src) else { continue };
190-
trace!(?src, ?src_live_ranges);
191-
192-
let Some(mut dst) = relevant.find(dst) else { continue };
193-
let Some(dst_live_ranges) = live.row(dst) else { continue };
194-
trace!(?dst, ?dst_live_ranges);
195-
196-
if src_live_ranges.disjoint(dst_live_ranges) {
197-
// We want to replace `src` by `dst`.
198-
let mut orig_src = relevant.original[src];
199-
let mut orig_dst = relevant.original[dst];
200-
201-
// The return place and function arguments are required and cannot be renamed.
202-
// This check cannot be made during candidate collection, as we may want to
203-
// unify the same non-required local with several required locals.
204-
match (is_local_required(orig_src, body), is_local_required(orig_dst, body)) {
205-
// Renaming `src` is ok.
206-
(false, _) => {}
207-
// Renaming `src` is wrong, but renaming `dst` is ok.
208-
(true, false) => {
209-
std::mem::swap(&mut src, &mut dst);
210-
std::mem::swap(&mut orig_src, &mut orig_dst);
211-
}
212-
// Neither local can be renamed, so skip this case.
213-
(true, true) => continue,
214-
}
181+
for (src, dst) in candidates.c.into_iter() {
182+
trace!(?src, ?dst);
215183

216-
trace!(?src, ?dst, "merge");
217-
merged_locals.insert(orig_src);
218-
merged_locals.insert(orig_dst);
184+
let Some(mut src) = relevant.find(src) else { continue };
185+
let Some(mut dst) = relevant.find(dst) else { continue };
186+
if src == dst {
187+
continue;
188+
}
219189

220-
// Replace `src` by `dst`.
221-
relevant.union(src, dst);
222-
live.union_rows(/* read */ src, /* write */ dst);
190+
let Some(src_live_ranges) = live.row(src) else { continue };
191+
let Some(dst_live_ranges) = live.row(dst) else { continue };
192+
trace!(?src, ?src_live_ranges);
193+
trace!(?dst, ?dst_live_ranges);
194+
195+
if src_live_ranges.disjoint(dst_live_ranges) {
196+
// We want to replace `src` by `dst`.
197+
let mut orig_src = relevant.original[src];
198+
let mut orig_dst = relevant.original[dst];
199+
200+
// The return place and function arguments are required and cannot be renamed.
201+
// This check cannot be made during candidate collection, as we may want to
202+
// unify the same non-required local with several required locals.
203+
match (is_local_required(orig_src, body), is_local_required(orig_dst, body)) {
204+
// Renaming `src` is ok.
205+
(false, _) => {}
206+
// Renaming `src` is wrong, but renaming `dst` is ok.
207+
(true, false) => {
208+
std::mem::swap(&mut src, &mut dst);
209+
std::mem::swap(&mut orig_src, &mut orig_dst);
210+
}
211+
// Neither local can be renamed, so skip this case.
212+
(true, true) => continue,
223213
}
214+
215+
trace!(?src, ?dst, "merge");
216+
merged_locals.insert(orig_src);
217+
merged_locals.insert(orig_dst);
218+
219+
// Replace `src` by `dst`.
220+
relevant.union(src, dst);
221+
live.union_rows(/* read */ src, /* write */ dst);
224222
}
225223
}
226224
trace!(?merged_locals);
@@ -334,11 +332,9 @@ impl RelevantLocals {
334332
shrink.get_or_insert_with(local, || original.push(local));
335333
};
336334

337-
for (&src, destinations) in candidates.c.iter() {
335+
for &(src, dest) in candidates.c.iter() {
338336
declare(src);
339-
for &dest in destinations {
340-
declare(dest)
341-
}
337+
declare(dest)
342338
}
343339

344340
let renames = IndexVec::from_fn_n(|l| l, original.len());
@@ -392,7 +388,7 @@ struct Candidates {
392388
///
393389
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
394390
/// remove that assignment.
395-
c: FxIndexMap<Local, Vec<Local>>,
391+
c: Vec<(Local, Local)>,
396392
}
397393

398394
// We first implement some utility functions which we will expose removing candidates according to
@@ -406,19 +402,13 @@ impl Candidates {
406402
let mut visitor = FindAssignments { body, candidates: Default::default(), borrowed };
407403
visitor.visit_body(body);
408404

409-
// Deduplicate candidates.
410-
for (_, cands) in visitor.candidates.iter_mut() {
411-
cands.sort();
412-
cands.dedup();
413-
}
414-
415405
Candidates { c: visitor.candidates }
416406
}
417407
}
418408

419409
struct FindAssignments<'a, 'tcx> {
420410
body: &'a Body<'tcx>,
421-
candidates: FxIndexMap<Local, Vec<Local>>,
411+
candidates: Vec<(Local, Local)>,
422412
borrowed: &'a DenseBitSet<Local>,
423413
}
424414

@@ -448,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
448438
}
449439

450440
// We may insert duplicates here, but that's fine
451-
self.candidates.entry(src).or_default().push(dest);
441+
self.candidates.push((src, dest));
452442
}
453443
}
454444
}

0 commit comments

Comments
 (0)