diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index bd57c8f0f32fe..2cc1fbfa6316c 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -153,6 +153,9 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { state.next_opaque = None; let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec(); + for dbg in body.var_debug_info.iter_mut() { + state.visit_var_debug_info(dbg); + } for bb in reverse_postorder { let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb]; state.visit_basic_block_data(bb, data); @@ -1238,6 +1241,51 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> { self.tcx } + fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) { + let mut replace_dereffed = |place: &mut Place<'tcx>| -> Option { + let last_deref = place.projection.iter().rposition(|e| e == PlaceElem::Deref)?; + + // Another place that holds the same value. + let mut place_ref = place.as_ref(); + let mut value = self.locals[place.local]?; + + for (index, &proj) in place.projection[..last_deref].iter().enumerate() { + if let Some(candidates) = self.rev_locals.get(value) + && let Some(&local) = candidates.first() + { + place_ref = PlaceRef { local, projection: &place.projection[index..] }; + } + + let place_upto = + PlaceRef { local: place.local, projection: &place.projection[..index] }; + if let Some(projected) = self.project(place_upto, value, proj) { + value = projected; + } else { + if place_ref.projection.len() < place.projection.len() { + *place = place_ref.project_deeper(&[], self.tcx); + } + return None; + } + } + + if let Some(candidates) = self.rev_locals.get(value) + && let Some(&local) = candidates.first() + { + let place_ref = PlaceRef { local, projection: &place.projection[last_deref..] }; + *place = place_ref.project_deeper(&[], self.tcx); + } + + return None; + }; + + match &mut var_debug_info.value { + VarDebugInfoContents::Const(_) => {} + VarDebugInfoContents::Place(place) => { + replace_dereffed(place); + } + } + } + fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, location: Location) { self.simplify_place_projection(place, location); } diff --git a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index 10b81e59b5f4b..a105e08c95260 100644 --- a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -15,8 +15,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) { debug x => _3; scope 2 (inlined foo::::{closure#0}) { debug _q => _9; - debug q => (*((*_6).0: &i32)); - debug t => (*((*_6).1: &T)); + debug q => (*_10); + debug t => (*_12); let mut _10: &i32; let mut _11: i32; let mut _12: &T;