Skip to content

Commit 3295955

Browse files
committed
Preserve DebugInfo in DeadStoreElimination.
1 parent 551c718 commit 3295955

File tree

29 files changed

+737
-742
lines changed

29 files changed

+737
-742
lines changed

compiler/rustc_index/src/bit_set.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ impl<T: Idx> From<GrowableBitSet<T>> for BitSet<T> {
365365
/// All operations that involve an element will panic if the element is equal
366366
/// to or greater than the domain size. All operations that involve two bitsets
367367
/// will panic if the bitsets have differing domain sizes.
368-
#[derive(Debug, PartialEq, Eq)]
368+
#[derive(PartialEq, Eq)]
369369
pub struct ChunkedBitSet<T> {
370370
domain_size: usize,
371371

@@ -1074,6 +1074,12 @@ impl<T: Idx> fmt::Debug for BitSet<T> {
10741074
}
10751075
}
10761076

1077+
impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
1078+
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
1079+
w.debug_list().entries(self.iter()).finish()
1080+
}
1081+
}
1082+
10771083
impl<T: Idx> ToString for BitSet<T> {
10781084
fn to_string(&self) -> String {
10791085
let mut result = String::new();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use rustc_index::bit_set::BitSet;
2+
use rustc_middle::mir::visit::*;
3+
use rustc_middle::mir::*;
4+
5+
/// Return the set of locals that appear in debuginfo.
6+
pub fn debuginfo_locals(body: &Body<'_>) -> BitSet<Local> {
7+
let mut visitor = DebuginfoLocals(BitSet::new_empty(body.local_decls.len()));
8+
for debuginfo in body.var_debug_info.iter() {
9+
visitor.visit_var_debug_info(debuginfo);
10+
}
11+
visitor.0
12+
}
13+
14+
struct DebuginfoLocals(BitSet<Local>);
15+
16+
impl Visitor<'_> for DebuginfoLocals {
17+
fn visit_local(&mut self, local: Local, _: PlaceContext, _: Location) {
18+
self.0.insert(local);
19+
}
20+
}

compiler/rustc_mir_dataflow/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub use self::framework::{
3535

3636
use self::move_paths::MoveData;
3737

38+
pub mod debuginfo;
3839
pub mod drop_flag_effects;
3940
pub mod elaborate_drops;
4041
mod errors;

compiler/rustc_mir_transform/src/dead_store_elimination.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
//!
1414
1515
use crate::util::is_within_packed;
16-
use rustc_index::bit_set::BitSet;
1716
use rustc_middle::mir::visit::Visitor;
1817
use rustc_middle::mir::*;
1918
use rustc_middle::ty::TyCtxt;
19+
use rustc_mir_dataflow::debuginfo::debuginfo_locals;
2020
use rustc_mir_dataflow::impls::{
2121
borrowed_locals, LivenessTransferFunction, MaybeTransitiveLiveLocals,
2222
};
@@ -26,8 +26,15 @@ use rustc_mir_dataflow::Analysis;
2626
///
2727
/// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It
2828
/// can be generated via the [`borrowed_locals`] function.
29-
pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitSet<Local>) {
30-
let mut live = MaybeTransitiveLiveLocals::new(borrowed)
29+
pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
30+
let borrowed_locals = borrowed_locals(body);
31+
32+
// If the user requests complete debuginfo, mark the locals that appear in it as live, so
33+
// we don't remove assignements to them.
34+
let mut always_live = debuginfo_locals(body);
35+
always_live.union(&borrowed_locals);
36+
37+
let mut live = MaybeTransitiveLiveLocals::new(&always_live)
3138
.into_engine(tcx, body)
3239
.iterate_to_fixpoint()
3340
.into_results_cursor(body);
@@ -48,7 +55,9 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
4855
for (index, arg) in args.iter().enumerate().rev() {
4956
if let Operand::Copy(place) = *arg
5057
&& !place.is_indirect()
51-
&& !borrowed.contains(place.local)
58+
// Do not skip the transformation if the local is in debuginfo, as we do
59+
// not really lose any information for this purpose.
60+
&& !borrowed_locals.contains(place.local)
5261
&& !state.contains(place.local)
5362
// If `place` is a projection of a disaligned field in a packed ADT,
5463
// the move may be codegened as a pointer to that field.
@@ -75,7 +84,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
7584
StatementKind::Assign(box (place, _))
7685
| StatementKind::SetDiscriminant { place: box place, .. }
7786
| StatementKind::Deinit(box place) => {
78-
if !place.is_indirect() && !borrowed.contains(place.local) {
87+
if !place.is_indirect() && !always_live.contains(place.local) {
7988
live.seek_before_primary_effect(loc);
8089
if !live.get().contains(place.local) {
8190
patch.push(loc);
@@ -126,7 +135,6 @@ impl<'tcx> MirPass<'tcx> for DeadStoreElimination {
126135
}
127136

128137
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
129-
let borrowed = borrowed_locals(body);
130-
eliminate(tcx, body, &borrowed);
138+
eliminate(tcx, body);
131139
}
132140
}

tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-abort.diff

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,27 @@
22
+ // MIR for `cycle` after DeadStoreElimination
33

44
fn cycle(_1: i32, _2: i32, _3: i32) -> () {
5-
debug x => _1;
6-
debug y => _2;
7-
debug z => _3;
85
let mut _0: ();
9-
- let mut _4: ();
10-
- let mut _5: bool;
11-
- let _6: i32;
12-
- let mut _7: i32;
13-
- let mut _8: i32;
14-
- let mut _9: i32;
15-
- let mut _10: !;
16-
- let _11: ();
17-
- let mut _12: !;
18-
+ let mut _4: bool;
19-
+ let _5: i32;
20-
scope 1 {
21-
- debug temp => _6;
22-
+ debug temp => _5;
23-
}
6+
let mut _4: bool;
7+
- let mut _5: i32;
248

259
bb0: {
26-
goto -> bb1;
10+
_4 = cond() -> [return: bb1, unwind continue];
2711
}
2812

2913
bb1: {
30-
- StorageLive(_5);
31-
- _5 = cond() -> [return: bb2, unwind unreachable];
32-
+ StorageLive(_4);
33-
+ _4 = cond() -> [return: bb2, unwind unreachable];
14+
switchInt(_4) -> [1: bb2, otherwise: bb3];
3415
}
3516

3617
bb2: {
37-
- switchInt(move _5) -> [0: bb4, otherwise: bb3];
38-
+ switchInt(move _4) -> [0: bb4, otherwise: bb3];
18+
- _5 = _3;
19+
- _3 = _2;
20+
- _2 = _1;
21+
- _1 = _5;
22+
_4 = cond() -> [return: bb1, unwind continue];
3923
}
4024

4125
bb3: {
42-
- StorageLive(_6);
43-
- _6 = _3;
44-
- StorageLive(_7);
45-
- _7 = _2;
46-
- _3 = move _7;
47-
- StorageDead(_7);
48-
- StorageLive(_8);
49-
- _8 = _1;
50-
- _2 = move _8;
51-
- StorageDead(_8);
52-
- StorageLive(_9);
53-
- _9 = _6;
54-
- _1 = move _9;
55-
- StorageDead(_9);
56-
- _4 = const ();
57-
- StorageDead(_6);
58-
+ StorageLive(_5);
59-
StorageDead(_5);
60-
+ StorageDead(_4);
61-
goto -> bb1;
62-
}
63-
64-
bb4: {
65-
- StorageLive(_11);
66-
_0 = const ();
67-
- StorageDead(_11);
68-
- StorageDead(_5);
69-
+ StorageDead(_4);
7026
return;
7127
}
7228
}

tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.panic-unwind.diff

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,27 @@
22
+ // MIR for `cycle` after DeadStoreElimination
33

44
fn cycle(_1: i32, _2: i32, _3: i32) -> () {
5-
debug x => _1;
6-
debug y => _2;
7-
debug z => _3;
85
let mut _0: ();
9-
- let mut _4: ();
10-
- let mut _5: bool;
11-
- let _6: i32;
12-
- let mut _7: i32;
13-
- let mut _8: i32;
14-
- let mut _9: i32;
15-
- let mut _10: !;
16-
- let _11: ();
17-
- let mut _12: !;
18-
+ let mut _4: bool;
19-
+ let _5: i32;
20-
scope 1 {
21-
- debug temp => _6;
22-
+ debug temp => _5;
23-
}
6+
let mut _4: bool;
7+
- let mut _5: i32;
248

259
bb0: {
26-
goto -> bb1;
10+
_4 = cond() -> [return: bb1, unwind continue];
2711
}
2812

2913
bb1: {
30-
- StorageLive(_5);
31-
- _5 = cond() -> [return: bb2, unwind continue];
32-
+ StorageLive(_4);
33-
+ _4 = cond() -> [return: bb2, unwind continue];
14+
switchInt(_4) -> [1: bb2, otherwise: bb3];
3415
}
3516

3617
bb2: {
37-
- switchInt(move _5) -> [0: bb4, otherwise: bb3];
38-
+ switchInt(move _4) -> [0: bb4, otherwise: bb3];
18+
- _5 = _3;
19+
- _3 = _2;
20+
- _2 = _1;
21+
- _1 = _5;
22+
_4 = cond() -> [return: bb1, unwind continue];
3923
}
4024

4125
bb3: {
42-
- StorageLive(_6);
43-
- _6 = _3;
44-
- StorageLive(_7);
45-
- _7 = _2;
46-
- _3 = move _7;
47-
- StorageDead(_7);
48-
- StorageLive(_8);
49-
- _8 = _1;
50-
- _2 = move _8;
51-
- StorageDead(_8);
52-
- StorageLive(_9);
53-
- _9 = _6;
54-
- _1 = move _9;
55-
- StorageDead(_9);
56-
- _4 = const ();
57-
- StorageDead(_6);
58-
+ StorageLive(_5);
59-
StorageDead(_5);
60-
+ StorageDead(_4);
61-
goto -> bb1;
62-
}
63-
64-
bb4: {
65-
- StorageLive(_11);
66-
_0 = const ();
67-
- StorageDead(_11);
68-
- StorageDead(_5);
69-
+ StorageDead(_4);
7026
return;
7127
}
7228
}

tests/mir-opt/dead-store-elimination/cycle.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,40 @@
1+
// This example is interesting because the non-transitive version of `MaybeLiveLocals` would
2+
// report that *all* of these stores are live.
3+
//
14
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
25
// unit-test: DeadStoreElimination
36

7+
#![feature(core_intrinsics, custom_mir)]
8+
use std::intrinsics::mir::*;
9+
410
#[inline(never)]
511
fn cond() -> bool {
612
false
713
}
814

915
// EMIT_MIR cycle.cycle.DeadStoreElimination.diff
16+
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
1017
fn cycle(mut x: i32, mut y: i32, mut z: i32) {
11-
// This example is interesting because the non-transitive version of `MaybeLiveLocals` would
12-
// report that *all* of these stores are live.
13-
while cond() {
14-
let temp = z;
15-
z = y;
16-
y = x;
17-
x = temp;
18-
}
18+
// We use custom MIR to avoid generating debuginfo, that would force to preserve writes.
19+
mir!(
20+
let condition: bool;
21+
{
22+
Call(condition = cond(), bb1)
23+
}
24+
bb1 = {
25+
match condition { true => bb2, _ => ret }
26+
}
27+
bb2 = {
28+
let temp = z;
29+
z = y;
30+
y = x;
31+
x = temp;
32+
Call(condition = cond(), bb1)
33+
}
34+
ret = {
35+
Return()
36+
}
37+
)
1938
}
2039

2140
fn main() {

tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-abort.mir

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ fn f(_1: usize) -> usize {
77
let mut _3: usize;
88
let mut _4: usize;
99
scope 1 {
10-
debug b => _1;
10+
debug b => _3;
1111
}
1212

1313
bb0: {
1414
nop;
15+
_3 = _1;
16+
_1 = const 5_usize;
1517
nop;
1618
nop;
17-
nop;
18-
nop;
19+
_1 = move _3;
1920
nop;
2021
nop;
2122
nop;

tests/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.panic-unwind.mir

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ fn f(_1: usize) -> usize {
77
let mut _3: usize;
88
let mut _4: usize;
99
scope 1 {
10-
debug b => _1;
10+
debug b => _3;
1111
}
1212

1313
bb0: {
1414
nop;
15+
_3 = _1;
16+
_1 = const 5_usize;
1517
nop;
1618
nop;
17-
nop;
18-
nop;
19+
_1 = move _3;
1920
nop;
2021
nop;
2122
nop;

tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
}
2323

2424
bb1: {
25+
_1 = Un { us: move _2 };
2526
StorageDead(_2);
2627
StorageLive(_3);
28+
_3 = (_1.0: u32);
2729
StorageDead(_3);
2830
StorageDead(_1);
2931
return;

tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
}
2323

2424
bb1: {
25+
_1 = Un { us: move _2 };
2526
StorageDead(_2);
2627
StorageLive(_3);
28+
_3 = (_1.0: u32);
2729
StorageDead(_3);
2830
StorageDead(_1);
2931
return;

tests/mir-opt/issue_101973.inner.ConstProp.panic-abort.diff

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
StorageLive(_2);
3434
StorageLive(_3);
3535
StorageLive(_4);
36+
_4 = const 0_u32;
3637
StorageLive(_15);
3738
StorageLive(_14);
3839
_14 = Shr(_1, const 0_i32);

tests/mir-opt/issue_101973.inner.ConstProp.panic-unwind.diff

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
StorageLive(_2);
3434
StorageLive(_3);
3535
StorageLive(_4);
36+
_4 = const 0_u32;
3637
StorageLive(_15);
3738
StorageLive(_14);
3839
_14 = Shr(_1, const 0_i32);

0 commit comments

Comments
 (0)