Skip to content

Commit d55b9f4

Browse files
committed
Only rebuild storage for locals that previously had storage statements
1 parent cef0462 commit d55b9f4

1 file changed

Lines changed: 27 additions & 10 deletions

File tree

compiler/rustc_mir_transform/src/move_elimination.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ impl<'tcx> crate::MirPass<'tcx> for MoveElimination {
5353
&liveness_matrix,
5454
);
5555

56-
apply_mappings(tcx, body, &remapped_locals);
56+
let storage_to_rebuild = apply_mappings(tcx, body, &remapped_locals);
5757

58-
if false && tcx.sess.emit_lifetime_markers() {
59-
reconstruct_storage(body, &points, &liveness_matrix);
58+
if tcx.sess.emit_lifetime_markers() {
59+
reconstruct_storage(body, &points, &liveness_matrix, &storage_to_rebuild);
6060
}
6161

6262
apply_alias_fixup(tcx, body);
@@ -384,27 +384,31 @@ impl<'tcx> Visitor<'tcx> for PlaceUnification<'_, 'tcx> {
384384
////////////////////////////////////////////////////////////////////////////////
385385
// Apply place mappings to the MIR body.
386386

387+
/// Returns the set of locals whose storage needs to be rebuilt.
387388
fn apply_mappings<'tcx>(
388389
tcx: TyCtxt<'tcx>,
389390
body: &mut Body<'tcx>,
390391
remapped_locals: &IndexVec<Local, Option<Place<'tcx>>>,
391-
) {
392-
let mut mapped_locals = DenseBitSet::new_empty(body.local_decls.len());
392+
) -> DenseBitSet<Local> {
393+
let mut unified_locals = DenseBitSet::new_empty(body.local_decls.len());
393394
for (src, dst) in remapped_locals.iter_enumerated() {
394395
if let Some(dst_place) = dst {
395-
mapped_locals.insert(src);
396-
mapped_locals.insert(dst_place.local);
396+
unified_locals.insert(src);
397+
unified_locals.insert(dst_place.local);
397398
}
398399
}
399400

400-
let mut rewriter = PlaceUpdater { tcx, remapped_locals, mapped_locals };
401+
let storage_to_rebuild = DenseBitSet::new_empty(body.local_decls.len());
402+
let mut rewriter = PlaceUpdater { tcx, remapped_locals, unified_locals, storage_to_rebuild };
401403
rewriter.visit_body_preserves_cfg(body);
404+
rewriter.storage_to_rebuild
402405
}
403406

404407
struct PlaceUpdater<'a, 'tcx> {
405408
tcx: TyCtxt<'tcx>,
406409
remapped_locals: &'a IndexVec<Local, Option<Place<'tcx>>>,
407-
mapped_locals: DenseBitSet<Local>,
410+
unified_locals: DenseBitSet<Local>,
411+
storage_to_rebuild: DenseBitSet<Local>,
408412
}
409413

410414
impl<'tcx> MutVisitor<'tcx> for PlaceUpdater<'_, 'tcx> {
@@ -434,8 +438,16 @@ impl<'tcx> MutVisitor<'tcx> for PlaceUpdater<'_, 'tcx> {
434438
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
435439
match statement.kind {
436440
StatementKind::StorageDead(local) | StatementKind::StorageLive(local)
437-
if self.mapped_locals.contains(local) =>
441+
if self.unified_locals.contains(local) =>
438442
{
443+
// Only rebuild storage for locals that previously had storage
444+
// statements.
445+
let mapped_local = match self.remapped_locals[local] {
446+
Some(place) => place.local,
447+
None => local,
448+
};
449+
self.storage_to_rebuild.insert(mapped_local);
450+
439451
statement.make_nop(true);
440452
return;
441453
}
@@ -481,11 +493,16 @@ fn reconstruct_storage<'tcx>(
481493
body: &mut Body<'tcx>,
482494
points: &DenseLocationMap,
483495
liveness_matrix: &SparseIntervalMatrix<Local, SplitPointIndex>,
496+
storage_to_rebuild: &DenseBitSet<Local>,
484497
) {
485498
let mut patcher = MirPatch::new(body);
486499
let mut split_edges: FxHashMap<(BasicBlock, BasicBlock), BasicBlock> = Default::default();
487500

488501
for local in body.local_decls.indices() {
502+
if !storage_to_rebuild.contains(local) {
503+
continue;
504+
}
505+
489506
// Arguments and return values don't use storage statements.
490507
match body.local_kind(local) {
491508
LocalKind::Arg | LocalKind::ReturnPointer => continue,

0 commit comments

Comments
 (0)