diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index d4f736d2a50f6..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); @@ -893,6 +896,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } + let fields: Option> = fields + .iter_mut() + .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque())) + .collect(); + let fields = fields?; + let (ty, variant_index) = match *kind { AggregateKind::Array(..) => { assert!(!fields.is_empty()); @@ -912,12 +921,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { AggregateKind::Adt(_, _, _, _, Some(_)) => return None, }; - let fields: Option> = fields - .iter_mut() - .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque())) - .collect(); - let fields = fields?; - if let AggregateTy::Array = ty && fields.len() > 4 { @@ -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/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff index febb6bfb0a43f..2ac9769a0e773 100644 --- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff +++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff @@ -10,8 +10,9 @@ StorageLive(_1); StorageLive(_2); - _2 = (); +- _1 = Union32 { value: move _2 }; + _2 = const (); - _1 = Union32 { value: move _2 }; ++ _1 = Union32 { value: const () }; StorageDead(_2); _0 = move _1 as u32 (Transmute); StorageDead(_1); diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff index febb6bfb0a43f..2ac9769a0e773 100644 --- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff +++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff @@ -10,8 +10,9 @@ StorageLive(_1); StorageLive(_2); - _2 = (); +- _1 = Union32 { value: move _2 }; + _2 = const (); - _1 = Union32 { value: move _2 }; ++ _1 = Union32 { value: const () }; StorageDead(_2); _0 = move _1 as u32 (Transmute); StorageDead(_1); diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff index 570ec129f06e2..ea8abfbe51a19 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff @@ -5,11 +5,10 @@ let mut _0: (); let _1: main::Un; let mut _2: u32; - let mut _3: u32; scope 1 { debug un => _1; scope 3 (inlined std::mem::drop::) { - debug _x => _3; + debug _x => _2; } } scope 2 (inlined val) { @@ -17,13 +16,10 @@ bb0: { StorageLive(_1); - StorageLive(_2); - _2 = const 1_u32; _1 = Un { us: const 1_u32 }; + StorageLive(_2); + _2 = (_1.0: u32); StorageDead(_2); - StorageLive(_3); - _3 = (_1.0: u32); - StorageDead(_3); StorageDead(_1); return; } diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff index 570ec129f06e2..ea8abfbe51a19 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff @@ -5,11 +5,10 @@ let mut _0: (); let _1: main::Un; let mut _2: u32; - let mut _3: u32; scope 1 { debug un => _1; scope 3 (inlined std::mem::drop::) { - debug _x => _3; + debug _x => _2; } } scope 2 (inlined val) { @@ -17,13 +16,10 @@ bb0: { StorageLive(_1); - StorageLive(_2); - _2 = const 1_u32; _1 = Un { us: const 1_u32 }; + StorageLive(_2); + _2 = (_1.0: u32); StorageDead(_2); - StorageLive(_3); - _3 = (_1.0: u32); - StorageDead(_3); StorageDead(_1); return; } 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;