Skip to content

Commit 335cb25

Browse files
committed
mir-opt: Eliminate trivial unnecessary storage annotations
1 parent bef9ddf commit 335cb25

File tree

54 files changed

+434
-528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+434
-528
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,10 @@ impl<'tcx> BasicBlockData<'tcx> {
14261426
});
14271427
self.after_last_stmt_debuginfos.extend_from_slice(&debuginfos);
14281428
}
1429+
1430+
pub fn strip_nops(&mut self) {
1431+
self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
1432+
}
14291433
}
14301434

14311435
///////////////////////////////////////////////////////////////////////////

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,10 @@ impl<'tcx> Statement<'tcx> {
2626
}
2727
let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop);
2828
if !drop_debuginfo {
29-
match replaced_stmt {
30-
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place)))
31-
if let Some(local) = place.as_local() =>
32-
{
33-
self.debuginfos.push(StmtDebugInfo::AssignRef(local, ref_place));
34-
}
35-
_ => {
36-
bug!("debuginfo is not yet supported.")
37-
}
38-
}
29+
let Some(debuginfo) = replaced_stmt.as_debuginfo() else {
30+
bug!("debuginfo is not yet supported.")
31+
};
32+
self.debuginfos.push(debuginfo);
3933
}
4034
}
4135

@@ -78,6 +72,17 @@ impl<'tcx> StatementKind<'tcx> {
7872
_ => None,
7973
}
8074
}
75+
76+
pub fn as_debuginfo(&self) -> Option<StmtDebugInfo<'tcx>> {
77+
match self {
78+
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place)))
79+
if let Some(local) = place.as_local() =>
80+
{
81+
Some(StmtDebugInfo::AssignRef(local, *ref_place))
82+
}
83+
_ => None,
84+
}
85+
}
8186
}
8287

8388
///////////////////////////////////////////////////////////////////////////

compiler/rustc_mir_transform/src/simplify.rs

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
310310

311311
fn strip_nops(&mut self) {
312312
for blk in self.basic_blocks.iter_mut() {
313-
blk.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
313+
blk.strip_nops();
314314
}
315315
}
316316
}
@@ -485,6 +485,7 @@ struct UsedLocals {
485485
increment: bool,
486486
arg_count: u32,
487487
use_count: IndexVec<Local, u32>,
488+
debuginfo_use: IndexVec<Local, bool>,
488489
}
489490

490491
impl UsedLocals {
@@ -494,6 +495,7 @@ impl UsedLocals {
494495
increment: true,
495496
arg_count: body.arg_count.try_into().unwrap(),
496497
use_count: IndexVec::from_elem(0, &body.local_decls),
498+
debuginfo_use: IndexVec::from_elem(false, &body.local_decls),
497499
};
498500
this.visit_body(body);
499501
this
@@ -503,8 +505,19 @@ impl UsedLocals {
503505
///
504506
/// Return place and arguments are always considered used.
505507
fn is_used(&self, local: Local) -> bool {
506-
trace!("is_used({:?}): use_count: {:?}", local, self.use_count[local]);
507-
local.as_u32() <= self.arg_count || self.use_count[local] != 0
508+
trace!(
509+
"is_used({:?}): use_count: {:?}, debuginfo_use: {}",
510+
local, self.use_count[local], self.debuginfo_use[local]
511+
);
512+
local.as_u32() <= self.arg_count || self.use_count[local] != 0 || self.debuginfo_use[local]
513+
}
514+
515+
fn is_only_debuginfo_used(&self, local: Local) -> bool {
516+
local.as_u32() > self.arg_count && self.use_count[local] == 0 && self.debuginfo_use[local]
517+
}
518+
519+
fn is_debuginfo_used(&self, local: Local) -> bool {
520+
self.debuginfo_use[local]
508521
}
509522

510523
/// Updates the use counts to reflect the removal of given statement.
@@ -516,6 +529,12 @@ impl UsedLocals {
516529
self.visit_statement(statement, location);
517530
}
518531

532+
fn statement_debuginfo_updated(&mut self, statement: &Statement<'_>) {
533+
// The location of the statement is irrelevant.
534+
let location = Location::START;
535+
self.visit_statement_debuginfos(&statement.debuginfos, location);
536+
}
537+
519538
/// Visits a left-hand side of an assignment.
520539
fn visit_lhs(&mut self, place: &Place<'_>, location: Location) {
521540
if place.is_indirect() {
@@ -573,12 +592,15 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
573592
}
574593

575594
fn visit_local(&mut self, local: Local, ctx: PlaceContext, _location: Location) {
595+
if ctx == PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
596+
self.debuginfo_use[local] = true;
597+
return;
598+
}
576599
if self.increment {
577600
self.use_count[local] += 1;
578-
} else if ctx != PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
579-
assert_ne!(self.use_count[local], 0);
601+
} else {
580602
self.use_count[local] -= 1;
581-
}
603+
};
582604
}
583605
}
584606

@@ -595,30 +617,40 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod
595617

596618
for data in body.basic_blocks.as_mut_preserves_cfg() {
597619
// Remove unnecessary StorageLive and StorageDead annotations.
598-
data.retain_statements(|statement| {
599-
let keep = match &statement.kind {
620+
for statement in data.statements.iter_mut() {
621+
let drop_debuginfo = match &statement.kind {
600622
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
601-
used_locals.is_used(*local)
623+
if used_locals.is_used(*local)
624+
&& !used_locals.is_only_debuginfo_used(*local)
625+
{
626+
continue;
627+
}
628+
true
602629
}
603-
StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local),
604-
605-
StatementKind::SetDiscriminant { place, .. }
606-
| StatementKind::BackwardIncompatibleDropHint { place, reason: _ }
607-
| StatementKind::Deinit(place) => used_locals.is_used(place.local),
608-
StatementKind::Nop => false,
609-
_ => true,
630+
StatementKind::Assign(box (place, _))
631+
| StatementKind::SetDiscriminant { box place, .. }
632+
| StatementKind::BackwardIncompatibleDropHint { box place, .. }
633+
| StatementKind::Deinit(box place) => {
634+
if used_locals.is_used(place.local)
635+
&& !(used_locals.is_only_debuginfo_used(place.local)
636+
&& statement.kind.as_debuginfo().is_some())
637+
{
638+
continue;
639+
}
640+
!used_locals.is_debuginfo_used(place.local)
641+
}
642+
_ => continue,
610643
};
611-
612-
if !keep {
613-
trace!("removing statement {:?}", statement);
614-
modified = true;
615-
used_locals.statement_removed(statement);
616-
}
617-
618-
keep
619-
});
644+
trace!("removing statement {:?}", statement);
645+
modified = true;
646+
used_locals.statement_removed(statement);
647+
statement.make_nop(drop_debuginfo);
648+
used_locals.statement_debuginfo_updated(statement);
649+
}
650+
data.strip_nops();
620651
}
621652
}
653+
// cleanup unused local
622654
}
623655

624656
struct LocalUpdater<'tcx> {

tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@
2424
bb0: {
2525
- StorageLive(_2);
2626
_2 = &raw mut _1;
27-
StorageLive(_3);
28-
StorageLive(_4);
29-
_4 = &mut (*_2);
30-
_3 = &mut (*_4);
31-
StorageDead(_4);
27+
- StorageLive(_3);
28+
- StorageLive(_4);
29+
- _4 = &mut (*_2);
30+
- _3 = &mut (*_4);
31+
- StorageDead(_4);
3232
- StorageLive(_5);
3333
- _5 = copy _2;
34+
+ // DBG: AssignRef(_4, (*_2))
35+
+ // DBG: AssignRef(_3, (*_4))
3436
StorageLive(_6);
3537
- StorageLive(_7);
3638
- _7 = copy _5;
@@ -43,7 +45,7 @@
4345
StorageDead(_6);
4446
_0 = const ();
4547
- StorageDead(_5);
46-
StorageDead(_3);
48+
- StorageDead(_3);
4749
- StorageDead(_2);
4850
return;
4951
}

tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@
2424
bb0: {
2525
- StorageLive(_2);
2626
_2 = &raw mut _1;
27-
StorageLive(_3);
28-
StorageLive(_4);
29-
_4 = &mut (*_2);
30-
_3 = &mut (*_4);
31-
StorageDead(_4);
27+
- StorageLive(_3);
28+
- StorageLive(_4);
29+
- _4 = &mut (*_2);
30+
- _3 = &mut (*_4);
31+
- StorageDead(_4);
3232
- StorageLive(_5);
3333
- _5 = copy _2;
34+
+ // DBG: AssignRef(_4, (*_2))
35+
+ // DBG: AssignRef(_3, (*_4))
3436
StorageLive(_6);
3537
- StorageLive(_7);
3638
- _7 = copy _5;
@@ -43,7 +45,7 @@
4345
StorageDead(_6);
4446
_0 = const ();
4547
- StorageDead(_5);
46-
StorageDead(_3);
48+
- StorageDead(_3);
4749
- StorageDead(_2);
4850
return;
4951
}

tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
bb0: {
2424
- StorageLive(_2);
2525
_2 = &raw mut _1;
26-
StorageLive(_3);
26+
- StorageLive(_3);
2727
_3 = &raw mut (*_2);
2828
- StorageLive(_4);
2929
- _4 = copy _2;
@@ -39,7 +39,7 @@
3939
StorageDead(_5);
4040
_0 = const ();
4141
- StorageDead(_4);
42-
StorageDead(_3);
42+
- StorageDead(_3);
4343
- StorageDead(_2);
4444
return;
4545
}

tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
bb0: {
2424
- StorageLive(_2);
2525
_2 = &raw mut _1;
26-
StorageLive(_3);
26+
- StorageLive(_3);
2727
_3 = &raw mut (*_2);
2828
- StorageLive(_4);
2929
- _4 = copy _2;
@@ -39,7 +39,7 @@
3939
StorageDead(_5);
4040
_0 = const ();
4141
- StorageDead(_4);
42-
StorageDead(_3);
42+
- StorageDead(_3);
4343
- StorageDead(_2);
4444
return;
4545
}

tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-abort.diff

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
bb0: {
2424
- StorageLive(_2);
2525
_2 = &mut _1;
26-
StorageLive(_3);
27-
_3 = &mut (*_2);
26+
- StorageLive(_3);
27+
- _3 = &mut (*_2);
2828
- StorageLive(_4);
2929
- _4 = move _2;
30+
+ // DBG: AssignRef(_3, (*_2))
3031
StorageLive(_5);
3132
- StorageLive(_6);
3233
- _6 = move _4;
@@ -39,7 +40,7 @@
3940
StorageDead(_5);
4041
_0 = const ();
4142
- StorageDead(_4);
42-
StorageDead(_3);
43+
- StorageDead(_3);
4344
- StorageDead(_2);
4445
return;
4546
}

tests/mir-opt/copy-prop/reborrow.remut.CopyProp.panic-unwind.diff

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
bb0: {
2424
- StorageLive(_2);
2525
_2 = &mut _1;
26-
StorageLive(_3);
27-
_3 = &mut (*_2);
26+
- StorageLive(_3);
27+
- _3 = &mut (*_2);
2828
- StorageLive(_4);
2929
- _4 = move _2;
30+
+ // DBG: AssignRef(_3, (*_2))
3031
StorageLive(_5);
3132
- StorageLive(_6);
3233
- _6 = move _4;
@@ -39,7 +40,7 @@
3940
StorageDead(_5);
4041
_0 = const ();
4142
- StorageDead(_4);
42-
StorageDead(_3);
43+
- StorageDead(_3);
4344
- StorageDead(_2);
4445
return;
4546
}

tests/mir-opt/copy-prop/reborrow.reraw.CopyProp.panic-abort.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
bb0: {
2424
- StorageLive(_2);
2525
_2 = &mut _1;
26-
StorageLive(_3);
26+
- StorageLive(_3);
2727
_3 = &raw mut (*_2);
2828
- StorageLive(_4);
2929
- _4 = move _2;
@@ -39,7 +39,7 @@
3939
StorageDead(_5);
4040
_0 = const ();
4141
- StorageDead(_4);
42-
StorageDead(_3);
42+
- StorageDead(_3);
4343
- StorageDead(_2);
4444
return;
4545
}

0 commit comments

Comments
 (0)