Skip to content

Commit 9419f5f

Browse files
committed
Simplify Candidate.
By making it own the index maps, instead of holding references to them. This requires moving the free function `find_candidate` into `Candidate::reset_and_find`. It lets the `'alloc` lifetime be removed everywhere that still has it.
1 parent ad5a6e1 commit 9419f5f

File tree

1 file changed

+36
-47
lines changed

1 file changed

+36
-47
lines changed

compiler/rustc_mir_transform/src/dest_prop.rs

+36-47
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
164164

165165
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
166166
let def_id = body.source.def_id();
167-
let mut candidates = FxIndexMap::default();
168-
let mut candidates_reverse = FxIndexMap::default();
167+
let mut candidates = Candidates::default();
169168
let mut write_info = WriteInfo::default();
170169
trace!(func = ?tcx.def_path_str(def_id));
171170

@@ -194,12 +193,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
194193
loop {
195194
// PERF: Can we do something smarter than recalculating the candidates and liveness
196195
// results?
197-
let mut candidates = find_candidates(
198-
body,
199-
&borrowed,
200-
&mut candidates,
201-
&mut candidates_reverse,
202-
);
196+
candidates.reset_and_find(body, &borrowed);
203197
trace!(?candidates);
204198
dest_prop_mir_dump(tcx, body, &points, &live, round_count);
205199

@@ -256,8 +250,8 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
256250
}
257251
}
258252

259-
#[derive(Debug)]
260-
struct Candidates<'alloc> {
253+
#[derive(Debug, Default)]
254+
struct Candidates {
261255
/// The set of candidates we are considering in this optimization.
262256
///
263257
/// We will always merge the key into at most one of its values.
@@ -272,11 +266,12 @@ struct Candidates<'alloc> {
272266
///
273267
/// We will still report that we would like to merge `_1` and `_2` in an attempt to allow us to
274268
/// remove that assignment.
275-
c: &'alloc mut FxIndexMap<Local, Vec<Local>>,
269+
c: FxIndexMap<Local, Vec<Local>>,
270+
276271
/// A reverse index of the `c` set; if the `c` set contains `a => Place { local: b, proj }`,
277272
/// then this contains `b => a`.
278273
// PERF: Possibly these should be `SmallVec`s?
279-
reverse: &'alloc mut FxIndexMap<Local, Vec<Local>>,
274+
reverse: FxIndexMap<Local, Vec<Local>>,
280275
}
281276

282277
//////////////////////////////////////////////////////////
@@ -349,19 +344,40 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
349344
//
350345
// This section enforces bullet point 2
351346

352-
struct FilterInformation<'a, 'alloc, 'tcx> {
347+
struct FilterInformation<'a, 'tcx> {
353348
body: &'a Body<'tcx>,
354349
points: &'a DenseLocationMap,
355350
live: &'a SparseIntervalMatrix<Local, PointIndex>,
356-
candidates: &'a mut Candidates<'alloc>,
351+
candidates: &'a mut Candidates,
357352
write_info: &'a mut WriteInfo,
358353
at: Location,
359354
}
360355

361356
// We first implement some utility functions which we will expose removing candidates according to
362357
// different needs. Throughout the liveness filtering, the `candidates` are only ever accessed
363358
// through these methods, and not directly.
364-
impl<'alloc> Candidates<'alloc> {
359+
impl Candidates {
360+
/// Collects the candidates for merging
361+
///
362+
/// This is responsible for enforcing the first and third bullet point.
363+
fn reset_and_find<'tcx>(&mut self, body: &Body<'tcx>, borrowed: &BitSet<Local>) {
364+
self.c.clear();
365+
self.reverse.clear();
366+
let mut visitor = FindAssignments { body, candidates: &mut self.c, borrowed };
367+
visitor.visit_body(body);
368+
// Deduplicate candidates
369+
for (_, cands) in self.c.iter_mut() {
370+
cands.sort();
371+
cands.dedup();
372+
}
373+
// Generate the reverse map
374+
for (src, cands) in self.c.iter() {
375+
for dest in cands.iter().copied() {
376+
self.reverse.entry(dest).or_default().push(*src);
377+
}
378+
}
379+
}
380+
365381
/// Just `Vec::retain`, but the condition is inverted and we add debugging output
366382
fn vec_filter_candidates(
367383
src: Local,
@@ -436,7 +452,7 @@ enum CandidateFilter {
436452
Remove,
437453
}
438454

439-
impl<'a, 'alloc, 'tcx> FilterInformation<'a, 'alloc, 'tcx> {
455+
impl<'a, 'tcx> FilterInformation<'a, 'tcx> {
440456
/// Filters the set of candidates to remove those that conflict.
441457
///
442458
/// The steps we take are exactly those that are outlined at the top of the file. For each
@@ -455,7 +471,7 @@ impl<'a, 'alloc, 'tcx> FilterInformation<'a, 'alloc, 'tcx> {
455471
/// statement/terminator to be live. We are additionally conservative by treating all written to
456472
/// locals as also being read from.
457473
fn filter_liveness(
458-
candidates: &mut Candidates<'alloc>,
474+
candidates: &mut Candidates,
459475
points: &DenseLocationMap,
460476
live: &SparseIntervalMatrix<Local, PointIndex>,
461477
write_info: &mut WriteInfo,
@@ -725,40 +741,13 @@ fn places_to_candidate_pair<'tcx>(
725741
Some((a, b))
726742
}
727743

728-
/// Collects the candidates for merging
729-
///
730-
/// This is responsible for enforcing the first and third bullet point.
731-
fn find_candidates<'alloc, 'tcx>(
732-
body: &Body<'tcx>,
733-
borrowed: &BitSet<Local>,
734-
candidates: &'alloc mut FxIndexMap<Local, Vec<Local>>,
735-
candidates_reverse: &'alloc mut FxIndexMap<Local, Vec<Local>>,
736-
) -> Candidates<'alloc> {
737-
candidates.clear();
738-
candidates_reverse.clear();
739-
let mut visitor = FindAssignments { body, candidates, borrowed };
740-
visitor.visit_body(body);
741-
// Deduplicate candidates
742-
for (_, cands) in candidates.iter_mut() {
743-
cands.sort();
744-
cands.dedup();
745-
}
746-
// Generate the reverse map
747-
for (src, cands) in candidates.iter() {
748-
for dest in cands.iter().copied() {
749-
candidates_reverse.entry(dest).or_default().push(*src);
750-
}
751-
}
752-
Candidates { c: candidates, reverse: candidates_reverse }
753-
}
754-
755-
struct FindAssignments<'a, 'alloc, 'tcx> {
744+
struct FindAssignments<'a, 'tcx> {
756745
body: &'a Body<'tcx>,
757-
candidates: &'alloc mut FxIndexMap<Local, Vec<Local>>,
746+
candidates: &'a mut FxIndexMap<Local, Vec<Local>>,
758747
borrowed: &'a BitSet<Local>,
759748
}
760749

761-
impl<'tcx> Visitor<'tcx> for FindAssignments<'_, '_, 'tcx> {
750+
impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
762751
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
763752
if let StatementKind::Assign(box (
764753
lhs,

0 commit comments

Comments
 (0)