Skip to content

Commit b2e81b0

Browse files
committed
Replace locals in debuginfo records during ref_prop
1 parent 9462e73 commit b2e81b0

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,10 @@ macro_rules! super_body {
10981098
}
10991099
}
11001100

1101+
for var_debug_info in &$($mutability)? $body.var_debug_info {
1102+
$self.visit_var_debug_info(var_debug_info);
1103+
}
1104+
11011105
for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) {
11021106
$self.visit_basic_block_data(bb, data);
11031107
}
@@ -1127,10 +1131,6 @@ macro_rules! super_body {
11271131
);
11281132
}
11291133

1130-
for var_debug_info in &$($mutability)? $body.var_debug_info {
1131-
$self.visit_var_debug_info(var_debug_info);
1132-
}
1133-
11341134
$self.visit_span($(& $mutability)? $body.span);
11351135

11361136
if let Some(required_consts) = &$($mutability)? $body.required_consts {

compiler/rustc_mir_transform/src/ref_prop.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ fn compute_replacement<'tcx>(
302302
return Replacer {
303303
tcx,
304304
targets: finder.targets,
305+
remap_var_debug_infos: IndexVec::from_elem(None, body.local_decls()),
305306
storage_to_remove,
306307
allowed_replacements,
307308
any_replacement: false,
@@ -381,6 +382,7 @@ fn fully_replaceable_locals(ssa: &SsaLocals) -> DenseBitSet<Local> {
381382
struct Replacer<'tcx> {
382383
tcx: TyCtxt<'tcx>,
383384
targets: IndexVec<Local, Value<'tcx>>,
385+
remap_var_debug_infos: IndexVec<Local, Option<Local>>,
384386
storage_to_remove: DenseBitSet<Local>,
385387
allowed_replacements: FxHashSet<(Local, Location)>,
386388
any_replacement: bool,
@@ -392,21 +394,45 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
392394
}
393395

394396
fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) {
395-
// If the debuginfo is a pointer to another place
396-
// and it's a reborrow: see through it
397-
while let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
397+
if let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
398398
&& place.projection.is_empty()
399-
&& let Value::Pointer(target, _) = self.targets[place.local]
400-
&& let &[PlaceElem::Deref] = &target.projection[..]
401399
{
402-
*place = Place::from(target.local);
403-
self.any_replacement = true;
400+
let mut new_local = place.local;
401+
402+
// If the debuginfo is a pointer to another place
403+
// and it's a reborrow: see through it
404+
while let Value::Pointer(target, _) = self.targets[new_local]
405+
&& let &[PlaceElem::Deref] = &target.projection[..]
406+
{
407+
new_local = target.local;
408+
}
409+
if place.local != new_local {
410+
self.remap_var_debug_infos[place.local] = Some(new_local);
411+
place.local = new_local;
412+
413+
self.any_replacement = true;
414+
}
404415
}
405416

406417
// Simplify eventual projections left inside `debuginfo`.
407418
self.super_var_debug_info(debuginfo);
408419
}
409420

421+
fn visit_statement_debuginfo(
422+
&mut self,
423+
stmt_debuginfo: &mut StmtDebugInfo<'tcx>,
424+
location: Location,
425+
) {
426+
let local = match stmt_debuginfo {
427+
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => local,
428+
};
429+
if let Some(target) = self.remap_var_debug_infos[*local] {
430+
*local = target;
431+
self.any_replacement = true;
432+
}
433+
self.super_statement_debuginfo(stmt_debuginfo, location);
434+
}
435+
410436
fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
411437
loop {
412438
let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() else { return };
@@ -437,8 +463,9 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
437463
{
438464
stmt.make_nop(true);
439465
}
440-
// Do not remove assignments as they may still be useful for debuginfo.
441-
_ => self.super_statement(stmt, loc),
466+
_ => {}
442467
}
468+
// Do not remove assignments as they may still be useful for debuginfo.
469+
self.super_statement(stmt, loc);
443470
}
444471
}

tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
- StorageDead(_2);
2626
- StorageDead(_3);
2727
- StorageDead(_1);
28-
+ // DBG: _1 = &(*_5);
28+
+ // DBG: _5 = &(*_5);
2929
_0 = const ();
3030
return;
3131
}

tests/mir-opt/debuginfo/ref_prop.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// skip-filecheck
21
//@ test-mir-pass: ReferencePropagation
32
//@ compile-flags: -g -Zub_checks=false -Zinline-mir -Zmir-enable-passes=+DeadStoreElimination-initial
43

@@ -9,6 +8,11 @@ use std::intrinsics::mir::*;
98

109
// EMIT_MIR ref_prop.remap_debuginfo_locals.ReferencePropagation.diff
1110
pub fn remap_debuginfo_locals() {
11+
// CHECK-LABEL: fn remap_debuginfo_locals()
12+
// CHECK: debug a => [[a:_.*]];
13+
// CHECK: bb0:
14+
// CHECK-NEXT: [[a]] = const
15+
// CHECK-NEXT: DBG: [[a]] = &(*[[a]]);
1216
foo(&0);
1317
}
1418

tests/crashes/147485.rs renamed to tests/ui/debuginfo/ref_prop_debuginfo-147485.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
//@ known-bug: #147485
1+
//@ build-pass
22
//@ compile-flags: -g -O
33

4+
// Regression test for #147485.
5+
46
#![crate_type = "lib"]
57

68
pub fn f(x: *const usize) -> &'static usize {

0 commit comments

Comments
 (0)