Replace locals in debuginfo records during ref_prop
This commit is contained in:
parent
9462e7301f
commit
b2e81b00e5
5 changed files with 49 additions and 16 deletions
|
|
@ -1098,6 +1098,10 @@ macro_rules! super_body {
|
|||
}
|
||||
}
|
||||
|
||||
for var_debug_info in &$($mutability)? $body.var_debug_info {
|
||||
$self.visit_var_debug_info(var_debug_info);
|
||||
}
|
||||
|
||||
for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) {
|
||||
$self.visit_basic_block_data(bb, data);
|
||||
}
|
||||
|
|
@ -1127,10 +1131,6 @@ macro_rules! super_body {
|
|||
);
|
||||
}
|
||||
|
||||
for var_debug_info in &$($mutability)? $body.var_debug_info {
|
||||
$self.visit_var_debug_info(var_debug_info);
|
||||
}
|
||||
|
||||
$self.visit_span($(& $mutability)? $body.span);
|
||||
|
||||
if let Some(required_consts) = &$($mutability)? $body.required_consts {
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ fn compute_replacement<'tcx>(
|
|||
return Replacer {
|
||||
tcx,
|
||||
targets: finder.targets,
|
||||
remap_var_debug_infos: IndexVec::from_elem(None, body.local_decls()),
|
||||
storage_to_remove,
|
||||
allowed_replacements,
|
||||
any_replacement: false,
|
||||
|
|
@ -381,6 +382,7 @@ fn fully_replaceable_locals(ssa: &SsaLocals) -> DenseBitSet<Local> {
|
|||
struct Replacer<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
targets: IndexVec<Local, Value<'tcx>>,
|
||||
remap_var_debug_infos: IndexVec<Local, Option<Local>>,
|
||||
storage_to_remove: DenseBitSet<Local>,
|
||||
allowed_replacements: FxHashSet<(Local, Location)>,
|
||||
any_replacement: bool,
|
||||
|
|
@ -392,21 +394,45 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) {
|
||||
// If the debuginfo is a pointer to another place
|
||||
// and it's a reborrow: see through it
|
||||
while let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
|
||||
if let VarDebugInfoContents::Place(ref mut place) = debuginfo.value
|
||||
&& place.projection.is_empty()
|
||||
&& let Value::Pointer(target, _) = self.targets[place.local]
|
||||
&& let &[PlaceElem::Deref] = &target.projection[..]
|
||||
{
|
||||
*place = Place::from(target.local);
|
||||
self.any_replacement = true;
|
||||
let mut new_local = place.local;
|
||||
|
||||
// If the debuginfo is a pointer to another place
|
||||
// and it's a reborrow: see through it
|
||||
while let Value::Pointer(target, _) = self.targets[new_local]
|
||||
&& let &[PlaceElem::Deref] = &target.projection[..]
|
||||
{
|
||||
new_local = target.local;
|
||||
}
|
||||
if place.local != new_local {
|
||||
self.remap_var_debug_infos[place.local] = Some(new_local);
|
||||
place.local = new_local;
|
||||
|
||||
self.any_replacement = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Simplify eventual projections left inside `debuginfo`.
|
||||
self.super_var_debug_info(debuginfo);
|
||||
}
|
||||
|
||||
fn visit_statement_debuginfo(
|
||||
&mut self,
|
||||
stmt_debuginfo: &mut StmtDebugInfo<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
let local = match stmt_debuginfo {
|
||||
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => local,
|
||||
};
|
||||
if let Some(target) = self.remap_var_debug_infos[*local] {
|
||||
*local = target;
|
||||
self.any_replacement = true;
|
||||
}
|
||||
self.super_statement_debuginfo(stmt_debuginfo, location);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
|
||||
loop {
|
||||
let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() else { return };
|
||||
|
|
@ -437,8 +463,9 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
|||
{
|
||||
stmt.make_nop(true);
|
||||
}
|
||||
// Do not remove assignments as they may still be useful for debuginfo.
|
||||
_ => self.super_statement(stmt, loc),
|
||||
_ => {}
|
||||
}
|
||||
// Do not remove assignments as they may still be useful for debuginfo.
|
||||
self.super_statement(stmt, loc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
- StorageDead(_2);
|
||||
- StorageDead(_3);
|
||||
- StorageDead(_1);
|
||||
+ // DBG: _1 = &(*_5);
|
||||
+ // DBG: _5 = &(*_5);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// skip-filecheck
|
||||
//@ test-mir-pass: ReferencePropagation
|
||||
//@ compile-flags: -g -Zub_checks=false -Zinline-mir -Zmir-enable-passes=+DeadStoreElimination-initial
|
||||
|
||||
|
|
@ -9,6 +8,11 @@ use std::intrinsics::mir::*;
|
|||
|
||||
// EMIT_MIR ref_prop.remap_debuginfo_locals.ReferencePropagation.diff
|
||||
pub fn remap_debuginfo_locals() {
|
||||
// CHECK-LABEL: fn remap_debuginfo_locals()
|
||||
// CHECK: debug a => [[a:_.*]];
|
||||
// CHECK: bb0:
|
||||
// CHECK-NEXT: [[a]] = const
|
||||
// CHECK-NEXT: DBG: [[a]] = &(*[[a]]);
|
||||
foo(&0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//@ known-bug: #147485
|
||||
//@ build-pass
|
||||
//@ compile-flags: -g -O
|
||||
|
||||
// Regression test for #147485.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn f(x: *const usize) -> &'static usize {
|
||||
Loading…
Add table
Add a link
Reference in a new issue