Skip to content

Commit d272ab3

Browse files
committed
Perform GVN into debuginfo.
1 parent 69d51fc commit d272ab3

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

Diff for: compiler/rustc_mir_transform/src/gvn.rs

+48
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
153153
state.next_opaque = None;
154154

155155
let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec();
156+
for dbg in body.var_debug_info.iter_mut() {
157+
state.visit_var_debug_info(dbg);
158+
}
156159
for bb in reverse_postorder {
157160
let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb];
158161
state.visit_basic_block_data(bb, data);
@@ -1238,6 +1241,51 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
12381241
self.tcx
12391242
}
12401243

1244+
fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) {
1245+
let mut replace_dereffed = |place: &mut Place<'tcx>| -> Option<!> {
1246+
let last_deref = place.projection.iter().rposition(|e| e == PlaceElem::Deref)?;
1247+
1248+
// Another place that holds the same value.
1249+
let mut place_ref = place.as_ref();
1250+
let mut value = self.locals[place.local]?;
1251+
1252+
for (index, &proj) in place.projection[..last_deref].iter().enumerate() {
1253+
if let Some(candidates) = self.rev_locals.get(value)
1254+
&& let Some(&local) = candidates.first()
1255+
{
1256+
place_ref = PlaceRef { local, projection: &place.projection[index..] };
1257+
}
1258+
1259+
let place_upto =
1260+
PlaceRef { local: place.local, projection: &place.projection[..index] };
1261+
if let Some(projected) = self.project(place_upto, value, proj) {
1262+
value = projected;
1263+
} else {
1264+
if place_ref.projection.len() < place.projection.len() {
1265+
*place = place_ref.project_deeper(&[], self.tcx);
1266+
}
1267+
return None;
1268+
}
1269+
}
1270+
1271+
if let Some(candidates) = self.rev_locals.get(value)
1272+
&& let Some(&local) = candidates.first()
1273+
{
1274+
let place_ref = PlaceRef { local, projection: &place.projection[last_deref..] };
1275+
*place = place_ref.project_deeper(&[], self.tcx);
1276+
}
1277+
1278+
return None;
1279+
};
1280+
1281+
match &mut var_debug_info.value {
1282+
VarDebugInfoContents::Const(_) => {}
1283+
VarDebugInfoContents::Place(place) => {
1284+
replace_dereffed(place);
1285+
}
1286+
}
1287+
}
1288+
12411289
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, location: Location) {
12421290
self.simplify_place_projection(place, location);
12431291
}

Diff for: tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
1515
debug x => _3;
1616
scope 2 (inlined foo::<T>::{closure#0}) {
1717
debug _q => _9;
18-
debug q => (*((*_6).0: &i32));
19-
debug t => (*((*_6).1: &T));
18+
debug q => (*_10);
19+
debug t => (*_12);
2020
let mut _10: &i32;
2121
let mut _11: i32;
2222
let mut _12: &T;

0 commit comments

Comments
 (0)