diff options
| author | dianqk <dianqk@dianqk.net> | 2025-09-21 20:58:34 +0800 |
|---|---|---|
| committer | dianqk <dianqk@dianqk.net> | 2025-10-03 08:08:22 +0800 |
| commit | c2a03cefd8899941032940df0c6be3b364de0ed0 (patch) | |
| tree | f157a032ba7e1901fc80486f0b967024858a0230 /compiler/rustc_codegen_ssa/src | |
| parent | 8da04285cf6fe61587e16155a8b224dba64bf0be (diff) | |
| download | rust-c2a03cefd8899941032940df0c6be3b364de0ed0.tar.gz rust-c2a03cefd8899941032940df0c6be3b364de0ed0.zip | |
debuginfo: Use `LocalRef` to simplify reference debuginfos
If the `LocalRef` is `LocalRef::Place`, we can refer to it directly, because the local of place is an indirect pointer. Such a statement is `_1 = &(_2.1)`. If the `LocalRef` is `LocalRef::Operand`, the `OperandRef` should provide the pointer of the reference. Such a statement is `_1 = &((*_2).1)`. But there is a special case that hasn't been handled, scalar pairs like `(&[i32; 16], i32)`.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/statement.rs | 61 |
2 files changed, 23 insertions, 47 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 38bb6f24b1c..0c9acf087f9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -259,8 +259,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &self, bx: &mut Bx, local: mir::Local, - base: PlaceValue<Bx::Value>, - layout: TyAndLayout<'tcx>, + base: PlaceRef<'tcx, Bx::Value>, projection: &[mir::PlaceElem<'tcx>], ) { let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full; @@ -274,7 +273,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } = - calculate_debuginfo_offset(bx, projection, layout); + calculate_debuginfo_offset(bx, projection, base.layout); for var in vars.iter() { let Some(dbg_var) = var.dbg_var else { continue; @@ -285,7 +284,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.dbg_var_value( dbg_var, dbg_loc, - base.llval, + base.val.llval, direct_offset, &indirect_offsets, &var.fragment, @@ -298,7 +297,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.cx().layout_of(ty); let to_backend_ty = bx.cx().immediate_backend_type(layout); let place_ref = PlaceRef::new_sized(bx.cx().const_poison(to_backend_ty), layout); - self.debug_new_val_to_local(bx, local, place_ref.val, layout, &[]); + self.debug_new_val_to_local(bx, local, place_ref, &[]); } /// Apply debuginfo and/or name, after creating the `alloca` for a local, diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 80f4f0fcda1..88590b6271b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -1,11 +1,8 @@ -use rustc_middle::mir::{self, NonDivergingIntrinsic, RETURN_PLACE, StmtDebugInfo}; -use rustc_middle::{bug, span_bug}; -use rustc_target::callconv::PassMode; +use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo}; +use rustc_middle::span_bug; use tracing::instrument; use super::{FunctionCx, LocalRef}; -use crate::common::TypeKind; -use crate::mir::place::PlaceRef; use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { @@ -110,48 +107,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match debuginfo { StmtDebugInfo::AssignRef(dest, place) => { let local_ref = match self.locals[place.local] { - LocalRef::Place(place_ref) | LocalRef::UnsizedPlace(place_ref) => { - Some(place_ref) + // For an rvalue like `&(_1.1)`, when `BackendRepr` is `BackendRepr::Memory`, we allocate a block of memory to this place. + // The place is an indirect pointer, we can refer to it directly. + LocalRef::Place(place_ref) => Some((place_ref, place.projection.as_slice())), + // For an rvalue like `&((*_1).1)`, we are calculating the address of `_1.1`. + // The deref projection is no-op here. + LocalRef::Operand(operand_ref) if place.is_indirect_first_projection() => { + Some((operand_ref.deref(bx.cx()), &place.projection[1..])) } - LocalRef::Operand(operand_ref) => operand_ref - .val - .try_pointer_parts() - .map(|(pointer, _)| PlaceRef::new_sized(pointer, operand_ref.layout)), - LocalRef::PendingOperand => None, + // For an rvalue like `&1`, when `BackendRepr` is `BackendRepr::Scalar`, + // we cannot get the address. + // N.B. `non_ssa_locals` returns that this is an SSA local. + LocalRef::Operand(_) => None, + LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => None, } - .filter(|place_ref| { - // For the reference of an argument (e.x. `&_1`), it's only valid if the pass mode is indirect, and its reference is - // llval. - let local_ref_pass_mode = place.as_local().and_then(|local| { - if local == RETURN_PLACE { - None - } else { - self.fn_abi.args.get(local.as_usize() - 1).map(|arg| &arg.mode) - } - }); - matches!(local_ref_pass_mode, Some(&PassMode::Indirect {..}) | None) && + .filter(|(_, projection)| { // Drop unsupported projections. - place.projection.iter().all(|p| p.can_use_in_debuginfo()) && - // Only pointers can be calculated addresses. - bx.type_kind(bx.val_ty(place_ref.val.llval)) == TypeKind::Pointer + projection.iter().all(|p| p.can_use_in_debuginfo()) }); - if let Some(local_ref) = local_ref { - let (base_layout, projection) = if place.is_indirect_first_projection() { - // For `_n = &((*_1).0: i32);`, we are calculating the address of `_1.0`, so - // we should drop the deref projection. - let projected_ty = local_ref - .layout - .ty - .builtin_deref(true) - .unwrap_or_else(|| bug!("deref of non-pointer {:?}", local_ref)); - let layout = bx.cx().layout_of(projected_ty); - (layout, &place.projection[1..]) - } else { - (local_ref.layout, place.projection.as_slice()) - }; - self.debug_new_val_to_local(bx, *dest, local_ref.val, base_layout, projection); + if let Some((base, projection)) = local_ref { + self.debug_new_val_to_local(bx, *dest, base, projection); } else { - // If the address cannot be computed, use poison to indicate that the value has been optimized out. + // If the address cannot be calculated, use poison to indicate that the value has been optimized out. self.debug_poison_to_local(bx, *dest); } } |
