Skip to content

Commit 6d2c2e5

Browse files
committed
mir-opt: Eliminate statements need debuginfo when mir-opt-level >= 2
`-Copt-level=0` (`-Zmir-opt-level=1`) is preferred for debugging.
1 parent b5cd399 commit 6d2c2e5

File tree

54 files changed

+380
-382
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

+380
-382
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,13 @@ impl<'tcx> BasicBlockData<'tcx> {
14331433
pub fn strip_nops(&mut self) {
14341434
self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
14351435
}
1436+
1437+
pub fn drop_debuginfo(&mut self) {
1438+
self.after_last_stmt_debuginfos = Vec::new();
1439+
for stmt in self.statements.iter_mut() {
1440+
stmt.debuginfos = Vec::new();
1441+
}
1442+
}
14361443
}
14371444

14381445
///////////////////////////////////////////////////////////////////////////

compiler/rustc_mir_transform/src/copy_prop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'tcx> crate::MirPass<'tcx> for CopyProp {
5252
Replacer { tcx, copy_classes: ssa.copy_classes(), fully_moved, storage_to_remove }
5353
.visit_body_preserves_cfg(body);
5454

55-
crate::simplify::remove_unused_definitions(body);
55+
crate::simplify::remove_unused_definitions(body, tcx.sess.mir_opt_level());
5656
}
5757

5858
fn is_required(&self) -> bool {

compiler/rustc_mir_transform/src/dead_store_elimination.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ use rustc_mir_dataflow::impls::{
2222
LivenessTransferFunction, MaybeTransitiveLiveLocals, borrowed_locals,
2323
};
2424

25+
use crate::simplify::remove_unused_definitions;
2526
use crate::util::is_within_packed;
2627

2728
/// Performs the optimization on the body
2829
///
2930
/// The `borrowed` set must be a `DenseBitSet` of all the locals that are ever borrowed in this
3031
/// body. It can be generated via the [`borrowed_locals`] function.
31-
fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
32+
fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
3233
let borrowed_locals = borrowed_locals(body);
3334

3435
// If the user requests complete debuginfo, mark the locals that appear in it as live, so
@@ -89,8 +90,9 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
8990
}
9091

9192
if patch.is_empty() && call_operands_to_move.is_empty() {
92-
return;
93+
return false;
9394
}
95+
let eliminated = !patch.is_empty();
9496

9597
let bbs = body.basic_blocks.as_mut_preserves_cfg();
9698
for (Location { block, statement_index }, drop_debuginfo) in patch {
@@ -104,6 +106,8 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
104106
let Operand::Copy(place) = *arg else { bug!() };
105107
*arg = Operand::Move(place);
106108
}
109+
110+
eliminated
107111
}
108112

109113
pub(super) enum DeadStoreElimination {
@@ -124,7 +128,10 @@ impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
124128
}
125129

126130
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
127-
eliminate(tcx, body);
131+
if eliminate(tcx, body) {
132+
// Remove unnecessary StorageLive and StorageDead annotations.
133+
remove_unused_definitions(body, tcx.sess.mir_opt_level());
134+
}
128135
}
129136

130137
fn is_required(&self) -> bool {

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,10 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
995995
// people working on rust can build with or without debuginfo while
996996
// still getting consistent results from the mir-opt tests.
997997
caller_body.var_debug_info.append(&mut callee_body.var_debug_info);
998+
} else {
999+
for bb in callee_body.basic_blocks_mut() {
1000+
bb.drop_debuginfo();
1001+
}
9981002
}
9991003
caller_body.basic_blocks_mut().append(callee_body.basic_blocks_mut());
10001004

compiler/rustc_mir_transform/src/ref_prop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
9999
replacer.visit_body_preserves_cfg(body);
100100

101101
if replacer.any_replacement {
102-
crate::simplify::remove_unused_definitions(body);
102+
crate::simplify::remove_unused_definitions(body, tcx.sess.mir_opt_level());
103103
}
104104

105105
replacer.any_replacement

compiler/rustc_mir_transform/src/simplify.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
416416
trace!("running SimplifyLocals on {:?}", body.source);
417417

418418
// First, we're going to get a count of *actual* uses for every `Local`.
419-
let mut used_locals = UsedLocals::new(body);
419+
let mut used_locals = UsedLocals::new(body, tcx.sess.mir_opt_level());
420420

421421
// Next, we're going to remove any `Local` with zero actual uses. When we remove those
422422
// `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals`
@@ -444,9 +444,9 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
444444
}
445445
}
446446

447-
pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) {
447+
pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>, mir_opt_level: usize) {
448448
// First, we're going to get a count of *actual* uses for every `Local`.
449-
let mut used_locals = UsedLocals::new(body);
449+
let mut used_locals = UsedLocals::new(body, mir_opt_level);
450450

451451
// Next, we're going to remove any `Local` with zero actual uses. When we remove those
452452
// `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals`
@@ -466,7 +466,7 @@ fn make_local_map<V>(
466466

467467
for alive_index in local_decls.indices() {
468468
// `is_used` treats the `RETURN_PLACE` and arguments as used.
469-
if !used_locals.is_used(alive_index) {
469+
if !used_locals.is_used(alive_index, true) {
470470
continue;
471471
}
472472

@@ -486,34 +486,37 @@ struct UsedLocals {
486486
arg_count: u32,
487487
use_count: IndexVec<Local, u32>,
488488
debuginfo_use: IndexVec<Local, bool>,
489+
mir_opt_level: usize,
489490
}
490491

491492
impl UsedLocals {
492493
/// Determines which locals are used & unused in the given body.
493-
fn new(body: &Body<'_>) -> Self {
494+
fn new(body: &Body<'_>, mir_opt_level: usize) -> Self {
494495
let mut this = Self {
495496
increment: true,
496497
arg_count: body.arg_count.try_into().unwrap(),
497498
use_count: IndexVec::from_elem(0, &body.local_decls),
498499
debuginfo_use: IndexVec::from_elem(false, &body.local_decls),
500+
mir_opt_level,
499501
};
502+
for var_debug_info in &body.var_debug_info {
503+
this.visit_var_debug_info(var_debug_info);
504+
}
500505
this.visit_body(body);
501506
this
502507
}
503508

504509
/// Checks if local is used.
505510
///
506511
/// Return place and arguments are always considered used.
507-
fn is_used(&self, local: Local) -> bool {
512+
fn is_used(&self, local: Local, debuginfo_is_used: bool) -> bool {
508513
trace!(
509514
"is_used({:?}): use_count: {:?}, debuginfo_use: {}",
510515
local, self.use_count[local], self.debuginfo_use[local]
511516
);
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+
local.as_u32() <= self.arg_count
518+
|| self.use_count[local] != 0
519+
|| (debuginfo_is_used && self.debuginfo_use[local])
517520
}
518521

519522
fn is_debuginfo_used(&self, local: Local) -> bool {
@@ -573,7 +576,17 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
573576
}
574577

575578
StatementKind::Assign(box (ref place, ref rvalue)) => {
576-
if rvalue.is_safe_to_remove() {
579+
if rvalue.is_safe_to_remove()
580+
&& (!self.is_debuginfo_used(place.local)
581+
|| (
582+
// Transform statements to debug information only when user requests more aggressive optimization.
583+
// This may degrade the debugging experience.
584+
self.mir_opt_level > 1
585+
// FIXME: We are not sure how we should represent this debugging information for some statements,
586+
// keep it for now.
587+
&& statement.kind.as_debuginfo().is_some()
588+
))
589+
{
577590
self.visit_statement_debuginfos(&statement.debuginfos, location);
578591
self.visit_lhs(place, location);
579592
self.visit_rvalue(rvalue, location);
@@ -620,22 +633,19 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod
620633
// Remove unnecessary StorageLive and StorageDead annotations.
621634
for statement in data.statements.iter_mut() {
622635
let (keep_statement, drop_debuginfo) = match &statement.kind {
623-
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => (
624-
!used_locals.is_used(*local) || used_locals.is_only_debuginfo_used(*local),
625-
true,
626-
),
636+
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
637+
(used_locals.is_used(*local, false), true)
638+
}
627639
StatementKind::Assign(box (place, _))
628640
| StatementKind::SetDiscriminant { box place, .. }
629641
| StatementKind::BackwardIncompatibleDropHint { box place, .. }
630642
| StatementKind::Deinit(box place) => (
631-
!used_locals.is_used(place.local)
632-
|| (used_locals.is_only_debuginfo_used(place.local)
633-
&& statement.kind.as_debuginfo().is_some()),
643+
used_locals.is_used(place.local, statement.kind.as_debuginfo().is_none()),
634644
!used_locals.is_debuginfo_used(place.local),
635645
),
636646
_ => continue,
637647
};
638-
if !keep_statement {
648+
if keep_statement {
639649
continue;
640650
}
641651
trace!("removing statement {:?}", statement);

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
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: _4 = &(*_2)
35-
+ // DBG: _3 = &(*_4)
3634
StorageLive(_6);
3735
- StorageLive(_7);
3836
- _7 = copy _5;
@@ -45,7 +43,7 @@
4543
StorageDead(_6);
4644
_0 = const ();
4745
- StorageDead(_5);
48-
- StorageDead(_3);
46+
StorageDead(_3);
4947
- StorageDead(_2);
5048
return;
5149
}

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
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: _4 = &(*_2)
35-
+ // DBG: _3 = &(*_4)
3634
StorageLive(_6);
3735
- StorageLive(_7);
3836
- _7 = copy _5;
@@ -45,7 +43,7 @@
4543
StorageDead(_6);
4644
_0 = const ();
4745
- StorageDead(_5);
48-
- StorageDead(_3);
46+
StorageDead(_3);
4947
- StorageDead(_2);
5048
return;
5149
}

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
}

0 commit comments

Comments
 (0)