Skip to content

Commit 9237612

Browse files
committed
Perform GVN into debuginfo.
1 parent 236aa05 commit 9237612

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
154154
state.next_opaque = None;
155155

156156
let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec();
157+
for dbg in body.var_debug_info.iter_mut() {
158+
state.visit_var_debug_info(dbg);
159+
}
157160
for bb in reverse_postorder {
158161
let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb];
159162
state.visit_basic_block_data(bb, data);
@@ -1161,6 +1164,51 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
11611164
self.tcx
11621165
}
11631166

1167+
fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) {
1168+
let mut replace_dereffed = |place: &mut Place<'tcx>| -> Option<!> {
1169+
let last_deref = place.projection.iter().rposition(|e| e == PlaceElem::Deref)?;
1170+
1171+
// Another place that holds the same value.
1172+
let mut place_ref = place.as_ref();
1173+
let mut value = self.locals[place.local]?;
1174+
1175+
for (index, &proj) in place.projection[..last_deref].iter().enumerate() {
1176+
if let Some(candidates) = self.rev_locals.get(value)
1177+
&& let Some(&local) = candidates.first()
1178+
{
1179+
place_ref = PlaceRef { local, projection: &place.projection[index..] };
1180+
}
1181+
1182+
let place_upto =
1183+
PlaceRef { local: place.local, projection: &place.projection[..index] };
1184+
if let Some(projected) = self.project(place_upto, value, proj) {
1185+
value = projected;
1186+
} else {
1187+
if place_ref.projection.len() < place.projection.len() {
1188+
*place = place_ref.project_deeper(&[], self.tcx);
1189+
}
1190+
return None;
1191+
}
1192+
}
1193+
1194+
if let Some(candidates) = self.rev_locals.get(value)
1195+
&& let Some(&local) = candidates.first()
1196+
{
1197+
let place_ref = PlaceRef { local, projection: &place.projection[last_deref..] };
1198+
*place = place_ref.project_deeper(&[], self.tcx);
1199+
}
1200+
1201+
return None;
1202+
};
1203+
1204+
match &mut var_debug_info.value {
1205+
VarDebugInfoContents::Const(_) => {}
1206+
VarDebugInfoContents::Place(place) => {
1207+
replace_dereffed(place);
1208+
}
1209+
}
1210+
}
1211+
11641212
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, location: Location) {
11651213
self.simplify_place_projection(place, location);
11661214
}

tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir

Lines changed: 2 additions & 2 deletions
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)