Skip to content

Commit 1e3c8f1

Browse files
committed
Auto merge of #116183 - cjgillot:debug-dse-always, r=oli-obk
Always preserve DebugInfo in DeadStoreElimination. This is a version of #106852 that does not check the current crate's debuginfo flag, and always attempts to preserve debuginfo. I haven't figured out how to handle mixing debuginfo levels for std, the one for the test, and the one for the CI target just right to merge #106852, so this can at least fix the debuginfo issue. Fixes #103655
2 parents ab039f7 + b704697 commit 1e3c8f1

File tree

33 files changed

+774
-808
lines changed

33 files changed

+774
-808
lines changed

compiler/rustc_index/src/bit_set.rs

+7-1
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();
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

+1
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

+15-7
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/incremental/hashes/for_loops.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ pub fn change_loop_body() {
2828
}
2929

3030
#[cfg(not(any(cfail1,cfail4)))]
31-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
31+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
3232
#[rustc_clean(cfg="cfail3")]
33-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
33+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
3434
#[rustc_clean(cfg="cfail6")]
3535
pub fn change_loop_body() {
3636
let mut _x = 0;
@@ -180,7 +180,7 @@ pub fn add_loop_label_to_break() {
180180
#[cfg(not(any(cfail1,cfail4)))]
181181
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
182182
#[rustc_clean(cfg="cfail3")]
183-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
183+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
184184
#[rustc_clean(cfg="cfail6")]
185185
pub fn add_loop_label_to_break() {
186186
let mut _x = 0;

tests/incremental/hashes/loop_expressions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ pub fn change_loop_body() {
2828
}
2929

3030
#[cfg(not(any(cfail1,cfail4)))]
31-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
31+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
3232
#[rustc_clean(cfg="cfail3")]
33-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
33+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
3434
#[rustc_clean(cfg="cfail6")]
3535
pub fn change_loop_body() {
3636
let mut _x = 0;

tests/incremental/hashes/while_loops.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ pub fn change_loop_body() {
2828
}
2929

3030
#[cfg(not(any(cfail1,cfail4)))]
31-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
31+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
3232
#[rustc_clean(cfg="cfail3")]
33-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
33+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
3434
#[rustc_clean(cfg="cfail6")]
3535
pub fn change_loop_body() {
3636
let mut _x = 0;
@@ -53,9 +53,9 @@ pub fn change_loop_condition() {
5353
}
5454

5555
#[cfg(not(any(cfail1,cfail4)))]
56-
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
56+
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
5757
#[rustc_clean(cfg="cfail3")]
58-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
58+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
5959
#[rustc_clean(cfg="cfail6")]
6060
pub fn change_loop_condition() {
6161
let mut _x = 0;
@@ -211,7 +211,7 @@ pub fn change_continue_label() {
211211
#[cfg(not(any(cfail1,cfail4)))]
212212
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
213213
#[rustc_clean(cfg="cfail3")]
214-
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
214+
#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
215215
#[rustc_clean(cfg="cfail6")]
216216
pub fn change_continue_label() {
217217
let mut _x = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
- // MIR for `cycle` before DeadStoreElimination
2+
+ // MIR for `cycle` after DeadStoreElimination
3+
4+
fn cycle(_1: i32, _2: i32, _3: i32) -> () {
5+
let mut _0: ();
6+
let mut _4: bool;
7+
- let mut _5: i32;
8+
9+
bb0: {
10+
_4 = cond() -> [return: bb1, unwind continue];
11+
}
12+
13+
bb1: {
14+
switchInt(_4) -> [1: bb2, otherwise: bb3];
15+
}
16+
17+
bb2: {
18+
- _5 = _3;
19+
- _3 = _2;
20+
- _2 = _1;
21+
- _1 = _5;
22+
_4 = cond() -> [return: bb1, unwind continue];
23+
}
24+
25+
bb3: {
26+
return;
27+
}
28+
}
29+

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

-73
This file was deleted.

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

-73
This file was deleted.

0 commit comments

Comments
 (0)