Skip to content

Commit a6441a6

Browse files
committed
Perform GVN into debuginfo.
1 parent aa05458 commit a6441a6

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

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);
@@ -1221,6 +1224,51 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
12211224
self.tcx
12221225
}
12231226

1227+
fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) {
1228+
let mut replace_dereffed = |place: &mut Place<'tcx>| -> Option<!> {
1229+
let last_deref = place.projection.iter().rposition(|e| e == PlaceElem::Deref)?;
1230+
1231+
// Another place that holds the same value.
1232+
let mut place_ref = place.as_ref();
1233+
let mut value = self.locals[place.local]?;
1234+
1235+
for (index, &proj) in place.projection[..last_deref].iter().enumerate() {
1236+
if let Some(candidates) = self.rev_locals.get(value)
1237+
&& let Some(&local) = candidates.first()
1238+
{
1239+
place_ref = PlaceRef { local, projection: &place.projection[index..] };
1240+
}
1241+
1242+
let place_upto =
1243+
PlaceRef { local: place.local, projection: &place.projection[..index] };
1244+
if let Some(projected) = self.project(place_upto, value, proj) {
1245+
value = projected;
1246+
} else {
1247+
if place_ref.projection.len() < place.projection.len() {
1248+
*place = place_ref.project_deeper(&[], self.tcx);
1249+
}
1250+
return None;
1251+
}
1252+
}
1253+
1254+
if let Some(candidates) = self.rev_locals.get(value)
1255+
&& let Some(&local) = candidates.first()
1256+
{
1257+
let place_ref = PlaceRef { local, projection: &place.projection[last_deref..] };
1258+
*place = place_ref.project_deeper(&[], self.tcx);
1259+
}
1260+
1261+
return None;
1262+
};
1263+
1264+
match &mut var_debug_info.value {
1265+
VarDebugInfoContents::Const(_) => {}
1266+
VarDebugInfoContents::Place(place) => {
1267+
replace_dereffed(place);
1268+
}
1269+
}
1270+
}
1271+
12241272
fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, location: Location) {
12251273
self.simplify_place_projection(place, location);
12261274
}

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)