Skip to content

Commit 843e6f8

Browse files
committed
Simplify candidate collection.
1 parent 33b8687 commit 843e6f8

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};
@@ -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());
@@ -380,8 +376,6 @@ impl RelevantLocals {
380376
struct Candidates {
381377
/// The set of candidates we are considering in this optimization.
382378
///
383-
/// We will always merge the key into at most one of its values.
384-
///
385379
/// Whether a place ends up in the key or the value does not correspond to whether it appears as
386380
/// the lhs or rhs of any assignment. As a matter of fact, the places in here might never appear
387381
/// in an assignment at all. This happens because if we see an assignment like this:
@@ -392,7 +386,7 @@ struct Candidates {
392386
///
393387
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
394388
/// remove that assignment.
395-
c: FxIndexMap<Local, Vec<Local>>,
389+
c: Vec<(Local, Local)>,
396390
}
397391

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

409-
// Deduplicate candidates.
410-
for (_, cands) in visitor.candidates.iter_mut() {
411-
cands.sort();
412-
cands.dedup();
413-
}
414-
415403
Candidates { c: visitor.candidates }
416404
}
417405
}
418406

419407
struct FindAssignments<'a, 'tcx> {
420408
body: &'a Body<'tcx>,
421-
candidates: FxIndexMap<Local, Vec<Local>>,
409+
candidates: Vec<(Local, Local)>,
422410
borrowed: &'a DenseBitSet<Local>,
423411
}
424412

@@ -448,7 +436,7 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
448436
}
449437

450438
// We may insert duplicates here, but that's fine
451-
self.candidates.entry(src).or_default().push(dest);
439+
self.candidates.push((src, dest));
452440
}
453441
}
454442
}

0 commit comments

Comments
 (0)