Skip to content

Commit 24bfdc9

Browse files
committed
Fix debuginfo so that it points to the correct local
1 parent 9248d90 commit 24bfdc9

File tree

7 files changed

+126
-111
lines changed

7 files changed

+126
-111
lines changed

src/librustc_middle/mir/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ impl<'tcx> Body<'tcx> {
256256
(&mut self.basic_blocks, &mut self.local_decls)
257257
}
258258

259+
#[inline]
260+
pub fn basic_blocks_local_decls_mut_and_var_debug_info(
261+
&mut self,
262+
) -> (
263+
&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
264+
&mut LocalDecls<'tcx>,
265+
&mut Vec<VarDebugInfo<'tcx>>,
266+
) {
267+
self.predecessor_cache.invalidate();
268+
(&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info)
269+
}
270+
259271
/// Returns `true` if a cycle exists in the control-flow graph that is reachable from the
260272
/// `START_BLOCK`.
261273
pub fn is_cfg_cyclic(&self) -> bool {

src/librustc_mir/transform/simplify_try.rs

+59-10
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
1212
use crate::transform::{simplify, MirPass, MirSource};
1313
use itertools::Itertools as _;
14-
use rustc_index::vec::IndexVec;
15-
use rustc_middle::mir::visit::{PlaceContext, Visitor};
14+
use rustc_index::{bit_set::BitSet, vec::IndexVec};
15+
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
1616
use rustc_middle::mir::*;
17-
use rustc_middle::ty::{Ty, TyCtxt};
17+
use rustc_middle::ty::{List, Ty, TyCtxt};
1818
use rustc_target::abi::VariantIdx;
1919
use std::iter::{Enumerate, Peekable};
2020
use std::slice::Iter;
@@ -74,10 +74,19 @@ struct ArmIdentityInfo<'tcx> {
7474

7575
/// The statements that should be removed (turned into nops)
7676
stmts_to_remove: Vec<usize>,
77+
78+
/// Indices of debug variables that need to be adjusted to point to
79+
// `{local_0}.{dbg_projection}`.
80+
dbg_info_to_adjust: Vec<usize>,
81+
82+
/// The projection used to rewrite debug info.
83+
dbg_projection: &'tcx List<PlaceElem<'tcx>>,
7784
}
7885

7986
fn get_arm_identity_info<'a, 'tcx>(
8087
stmts: &'a [Statement<'tcx>],
88+
locals_count: usize,
89+
debug_info: &'a [VarDebugInfo<'tcx>],
8190
) -> Option<ArmIdentityInfo<'tcx>> {
8291
// This can't possibly match unless there are at least 3 statements in the block
8392
// so fail fast on tiny blocks.
@@ -190,7 +199,7 @@ fn get_arm_identity_info<'a, 'tcx>(
190199
try_eat_storage_stmts(&mut stmt_iter, &mut storage_live_stmts, &mut storage_dead_stmts);
191200

192201
let (get_variant_field_stmt, stmt) = stmt_iter.next()?;
193-
let (local_tmp_s0, local_1, vf_s0) = match_get_variant_field(stmt)?;
202+
let (local_tmp_s0, local_1, vf_s0, dbg_projection) = match_get_variant_field(stmt)?;
194203

195204
try_eat_storage_stmts(&mut stmt_iter, &mut storage_live_stmts, &mut storage_dead_stmts);
196205

@@ -231,6 +240,19 @@ fn get_arm_identity_info<'a, 'tcx>(
231240
let stmt_to_overwrite =
232241
nop_stmts.iter().find(|stmt_idx| live_idx < **stmt_idx && **stmt_idx < dead_idx);
233242

243+
let mut tmp_assigned_vars = BitSet::new_empty(locals_count);
244+
for (l, r) in &tmp_assigns {
245+
tmp_assigned_vars.insert(*l);
246+
tmp_assigned_vars.insert(*r);
247+
}
248+
249+
let mut dbg_info_to_adjust = Vec::new();
250+
for (i, var_info) in debug_info.iter().enumerate() {
251+
if tmp_assigned_vars.contains(var_info.place.local) {
252+
dbg_info_to_adjust.push(i);
253+
}
254+
}
255+
234256
Some(ArmIdentityInfo {
235257
local_temp_0: local_tmp_s0,
236258
local_1,
@@ -246,13 +268,16 @@ fn get_arm_identity_info<'a, 'tcx>(
246268
source_info: discr_stmt_source_info,
247269
storage_stmts,
248270
stmts_to_remove: nop_stmts,
271+
dbg_info_to_adjust,
272+
dbg_projection,
249273
})
250274
}
251275

252276
fn optimization_applies<'tcx>(
253277
opt_info: &ArmIdentityInfo<'tcx>,
254278
local_decls: &IndexVec<Local, LocalDecl<'tcx>>,
255279
local_uses: &IndexVec<Local, usize>,
280+
var_debug_info: &[VarDebugInfo<'tcx>],
256281
) -> bool {
257282
trace!("testing if optimization applies...");
258283

@@ -309,6 +334,15 @@ fn optimization_applies<'tcx>(
309334
}
310335
}
311336

337+
// Check that debug info only points to full Locals and not projections.
338+
for dbg_idx in &opt_info.dbg_info_to_adjust {
339+
let dbg_info = &var_debug_info[*dbg_idx];
340+
if !dbg_info.place.projection.is_empty() {
341+
trace!("NO: debug info for {:?} had a projection {:?}", dbg_info.name, dbg_info.place);
342+
return false;
343+
}
344+
}
345+
312346
if source_local != opt_info.local_temp_0 {
313347
trace!(
314348
"NO: start of assignment chain does not match enum variant temp: {:?} != {:?}",
@@ -337,11 +371,14 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
337371

338372
trace!("running SimplifyArmIdentity on {:?}", source);
339373
let local_uses = LocalUseCounter::get_local_uses(body);
340-
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
374+
let (basic_blocks, local_decls, debug_info) =
375+
body.basic_blocks_local_decls_mut_and_var_debug_info();
341376
for bb in basic_blocks {
342-
if let Some(opt_info) = get_arm_identity_info(&bb.statements) {
377+
if let Some(opt_info) =
378+
get_arm_identity_info(&bb.statements, local_decls.len(), debug_info)
379+
{
343380
trace!("got opt_info = {:#?}", opt_info);
344-
if !optimization_applies(&opt_info, local_decls, &local_uses) {
381+
if !optimization_applies(&opt_info, local_decls, &local_uses, &debug_info) {
345382
debug!("optimization skipped for {:?}", source);
346383
continue;
347384
}
@@ -377,6 +414,14 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
377414

378415
bb.statements.retain(|stmt| stmt.kind != StatementKind::Nop);
379416

417+
// Fix the debug info to point to the right local
418+
for dbg_index in opt_info.dbg_info_to_adjust {
419+
let dbg_info = &mut debug_info[dbg_index];
420+
assert!(dbg_info.place.projection.is_empty());
421+
dbg_info.place.local = opt_info.local_0;
422+
dbg_info.place.projection = opt_info.dbg_projection;
423+
}
424+
380425
trace!("block is now {:?}", bb.statements);
381426
}
382427
}
@@ -397,7 +442,9 @@ impl LocalUseCounter {
397442

398443
impl<'tcx> Visitor<'tcx> for LocalUseCounter {
399444
fn visit_local(&mut self, local: &Local, context: PlaceContext, _location: Location) {
400-
if context.is_storage_marker() {
445+
if context.is_storage_marker()
446+
|| context == PlaceContext::NonUse(NonUseContext::VarDebugInfo)
447+
{
401448
return;
402449
}
403450

@@ -409,13 +456,15 @@ impl<'tcx> Visitor<'tcx> for LocalUseCounter {
409456
/// ```rust
410457
/// _LOCAL_INTO = ((_LOCAL_FROM as Variant).FIELD: TY);
411458
/// ```
412-
fn match_get_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local, VarField<'tcx>)> {
459+
fn match_get_variant_field<'tcx>(
460+
stmt: &Statement<'tcx>,
461+
) -> Option<(Local, Local, VarField<'tcx>, &'tcx List<PlaceElem<'tcx>>)> {
413462
match &stmt.kind {
414463
StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from {
415464
Rvalue::Use(Operand::Copy(pf) | Operand::Move(pf)) => {
416465
let local_into = place_into.as_local()?;
417466
let (local_from, vf) = match_variant_field_place(*pf)?;
418-
Some((local_into, local_from, vf))
467+
Some((local_into, local_from, vf, pf.projection))
419468
}
420469
_ => None,
421470
},

src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
66
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
77
let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
8-
let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
8+
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
99
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
1010
- let mut _5: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
1111
- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
1212
scope 1 {
13-
debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
13+
debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
1414
}
1515

1616
bb0: {
@@ -19,9 +19,7 @@
1919
}
2020

2121
bb1: {
22-
_3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
23-
((_0 as Some).0: std::boxed::Box<()>) = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
24-
discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
22+
_0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
2523
goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
2624
}
2725

src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/64bit/rustc.map.SimplifyLocals.diff

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
66
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
77
let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
8-
let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
8+
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
99
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
1010
- let mut _5: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
1111
- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
1212
scope 1 {
13-
debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
13+
debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
1414
}
1515

1616
bb0: {
@@ -19,9 +19,7 @@
1919
}
2020

2121
bb1: {
22-
_3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
23-
((_0 as Some).0: std::boxed::Box<()>) = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
24-
discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
22+
_0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
2523
goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
2624
}
2725

src/test/mir-opt/simplify_try/rustc.try_identity.SimplifyArmIdentity.diff

+35-28
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,27 @@
1515
let _10: u32; // in scope 0 at $DIR/simplify_try.rs:6:13: 6:15
1616
let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:7:8: 7:9
1717
scope 1 {
18-
debug y => _2; // in scope 1 at $DIR/simplify_try.rs:6:9: 6:10
18+
- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:6:9: 6:10
19+
+ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:6:9: 6:10
1920
}
2021
scope 2 {
21-
debug err => _6; // in scope 2 at $DIR/simplify_try.rs:6:14: 6:15
22+
- debug err => _6; // in scope 2 at $DIR/simplify_try.rs:6:14: 6:15
23+
+ debug err => ((_0 as Err).0: i32); // in scope 2 at $DIR/simplify_try.rs:6:14: 6:15
2224
scope 3 {
2325
scope 7 {
24-
debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
26+
- debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
27+
+ debug t => ((_0 as Err).0: i32); // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
2528
}
2629
scope 8 {
27-
debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
30+
- debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
31+
+ debug v => ((_0 as Err).0: i32); // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
2832
let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:6:14: 6:15
2933
}
3034
}
3135
}
3236
scope 4 {
33-
debug val => _10; // in scope 4 at $DIR/simplify_try.rs:6:13: 6:15
37+
- debug val => _10; // in scope 4 at $DIR/simplify_try.rs:6:13: 6:15
38+
+ debug val => ((_0 as Ok).0: u32); // in scope 4 at $DIR/simplify_try.rs:6:13: 6:15
3439
scope 5 {
3540
}
3641
}
@@ -50,35 +55,37 @@
5055
}
5156

5257
bb1: {
53-
StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:6:13: 6:15
54-
_10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:6:13: 6:15
55-
_2 = _10; // scope 5 at $DIR/simplify_try.rs:6:13: 6:15
56-
StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
58+
- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:6:13: 6:15
59+
- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:6:13: 6:15
60+
- _2 = _10; // scope 5 at $DIR/simplify_try.rs:6:13: 6:15
61+
- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
62+
+ _0 = move _3; // scope 1 at $DIR/simplify_try.rs:7:5: 7:10
5763
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:6:15: 6:16
58-
StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:7:8: 7:9
59-
_11 = _2; // scope 1 at $DIR/simplify_try.rs:7:8: 7:9
60-
((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:7:5: 7:10
61-
discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:7:5: 7:10
62-
StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:7:9: 7:10
64+
- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:7:8: 7:9
65+
- _11 = _2; // scope 1 at $DIR/simplify_try.rs:7:8: 7:9
66+
- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:7:5: 7:10
67+
- discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:7:5: 7:10
68+
- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:7:9: 7:10
6369
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:8:1: 8:2
6470
goto -> bb3; // scope 0 at $DIR/simplify_try.rs:8:2: 8:2
6571
}
6672

6773
bb2: {
68-
StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
69-
_6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
70-
StorageLive(_8); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
71-
StorageLive(_9); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
72-
_9 = _6; // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
73-
_8 = move _9; // scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
74-
StorageDead(_9); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
75-
StorageLive(_12); // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
76-
_12 = move _8; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
77-
((_0 as Err).0: i32) = move _12; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
78-
discriminant(_0) = 1; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
79-
StorageDead(_12); // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
80-
StorageDead(_8); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
81-
StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
74+
- StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
75+
- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
76+
- StorageLive(_8); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
77+
- StorageLive(_9); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
78+
- _9 = _6; // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
79+
- _8 = move _9; // scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
80+
- StorageDead(_9); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
81+
- StorageLive(_12); // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
82+
- _12 = move _8; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
83+
- ((_0 as Err).0: i32) = move _12; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
84+
- discriminant(_0) = 1; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
85+
- StorageDead(_12); // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
86+
- StorageDead(_8); // scope 3 at $DIR/simplify_try.rs:6:14: 6:15
87+
- StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:6:14: 6:15
88+
+ _0 = move _3; // scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
8289
StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:6:15: 6:16
8390
StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:8:1: 8:2
8491
goto -> bb3; // scope 0 at $DIR/simplify_try.rs:6:14: 6:15

0 commit comments

Comments
 (0)