Skip to content

Commit

Permalink
Fix variable debuginfo being optimized away at mir-opt-level=2
Browse files Browse the repository at this point in the history
The `DeadStoreElmination` pass was removing the uses of these locals
because the are never used in the MIR body except for debuginfo. I've
updated the pass to consider locals referenced by debuginfo as always
alive unless a higher MIR opt level is requested by the user.
  • Loading branch information
wesleywiser committed Oct 27, 2022
1 parent bebe274 commit daf2968
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 24 deletions.
28 changes: 22 additions & 6 deletions compiler/rustc_mir_transform/src/dead_store_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ use rustc_mir_dataflow::Analysis;

/// Performs the optimization on the body
///
/// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It
/// The `always_live` set must be a `BitSet` of all the locals that are considered always alive and
/// never eliminated. This should be, at least, the set of locals which are ever borrowed in this
/// body. It may include other locals as well if necessary. The minimum set of always alive locals
/// can be generated via the [`borrowed_locals`] function.
pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitSet<Local>) {
let mut live = MaybeTransitiveLiveLocals::new(borrowed)
pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, always_live: &BitSet<Local>) {
let mut live = MaybeTransitiveLiveLocals::new(always_live)
.into_engine(tcx, body)
.iterate_to_fixpoint()
.into_results_cursor(body);
Expand All @@ -41,7 +43,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
StatementKind::Assign(box (place, _))
| StatementKind::SetDiscriminant { place: box place, .. }
| StatementKind::Deinit(box place) => {
if !place.is_indirect() && !borrowed.contains(place.local) {
if !place.is_indirect() && !always_live.contains(place.local) {
live.seek_before_primary_effect(loc);
if !live.get().contains(place.local) {
patch.push(loc);
Expand Down Expand Up @@ -80,7 +82,21 @@ impl<'tcx> MirPass<'tcx> for DeadStoreElimination {
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let borrowed = borrowed_locals(body);
eliminate(tcx, body, &borrowed);
let mut always_live = borrowed_locals(body);

// Include any locals which are used by debuginfo unless we're at a high enough MIR opt
// level that degrading debuginfo is acceptable.
if tcx.sess.mir_opt_level() < 3 {
for x in &body.var_debug_info {
match x.value {
VarDebugInfoContents::Place(p) => {
always_live.insert(p.local);
}
VarDebugInfoContents::Const(..) => {}
}
}
}

eliminate(tcx, body, &always_live);
}
}
28 changes: 28 additions & 0 deletions src/test/codegen/debuginfo-constant-locals.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// compile-flags: -g -O

// Check that simple constant values are preserved in debuginfo across both MIR opts and LLVM opts

#![crate_type = "lib"]

#[no_mangle]
pub fn check_it() {
let a = 1;
let b = 42;

foo(a + b);
}

#[inline(never)]
fn foo(x: i32) {
std::process::exit(x);
}

// CHECK-LABEL: @check_it
// CHECK: call void @llvm.dbg.value(metadata i32 1, metadata ![[a_metadata:[0-9]+]], metadata !DIExpression())
// CHECK: call void @llvm.dbg.value(metadata i32 42, metadata ![[b_metadata:[0-9]+]], metadata !DIExpression())

// CHECK: ![[a_metadata]] = !DILocalVariable(name: "a"
// CHECK-SAME: line: 9

// CHECK: ![[b_metadata]] = !DILocalVariable(name: "b"
// CHECK-SAME: line: 10
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@

bb0: {
StorageLive(_1); // scope 0 at $DIR/constant-local-debuginfo.rs:+1:9: +1:10
- _1 = const 1_i32; // scope 0 at $DIR/constant-local-debuginfo.rs:+1:13: +1:14
+ nop; // scope 0 at $DIR/constant-local-debuginfo.rs:+1:13: +1:14
_1 = const 1_i32; // scope 0 at $DIR/constant-local-debuginfo.rs:+1:13: +1:14
StorageLive(_2); // scope 1 at $DIR/constant-local-debuginfo.rs:+2:9: +2:10
- _2 = const 4_i32; // scope 1 at $DIR/constant-local-debuginfo.rs:+2:13: +2:14
+ nop; // scope 1 at $DIR/constant-local-debuginfo.rs:+2:13: +2:14
_2 = const 4_i32; // scope 1 at $DIR/constant-local-debuginfo.rs:+2:13: +2:14
StorageLive(_3); // scope 2 at $DIR/constant-local-debuginfo.rs:+4:5: +4:15
StorageLive(_4); // scope 2 at $DIR/constant-local-debuginfo.rs:+4:9: +4:14
StorageLive(_5); // scope 2 at $DIR/constant-local-debuginfo.rs:+4:9: +4:10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,18 @@

bb3: {
StorageLive(_6); // scope 0 at $DIR/cycle.rs:+4:13: +4:17
- _6 = _3; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
+ nop; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
_6 = _3; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
StorageLive(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
- _7 = _2; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
- _3 = move _7; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
+ nop; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
+ nop; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
_7 = _2; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
_3 = move _7; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
StorageDead(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
StorageLive(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
- _8 = _1; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
- _2 = move _8; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
+ nop; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
+ nop; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
_8 = _1; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
_2 = move _8; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
StorageDead(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
StorageLive(_9); // scope 1 at $DIR/cycle.rs:+7:13: +7:17
- _9 = _6; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
- _1 = move _9; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
+ nop; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
+ nop; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
_9 = _6; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
_1 = move _9; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17
- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6
+ nop; // scope 0 at $DIR/cycle.rs:+3:18: +8:6
Expand Down

0 comments on commit daf2968

Please sign in to comment.