Skip to content

Commit c2a03ce

Browse files
committed
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)`.
1 parent 8da0428 commit c2a03ce

File tree

3 files changed

+318
-157
lines changed

3 files changed

+318
-157
lines changed

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
259259
&self,
260260
bx: &mut Bx,
261261
local: mir::Local,
262-
base: PlaceValue<Bx::Value>,
263-
layout: TyAndLayout<'tcx>,
262+
base: PlaceRef<'tcx, Bx::Value>,
264263
projection: &[mir::PlaceElem<'tcx>],
265264
) {
266265
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> {
274273
};
275274

276275
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
277-
calculate_debuginfo_offset(bx, projection, layout);
276+
calculate_debuginfo_offset(bx, projection, base.layout);
278277
for var in vars.iter() {
279278
let Some(dbg_var) = var.dbg_var else {
280279
continue;
@@ -285,7 +284,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
285284
bx.dbg_var_value(
286285
dbg_var,
287286
dbg_loc,
288-
base.llval,
287+
base.val.llval,
289288
direct_offset,
290289
&indirect_offsets,
291290
&var.fragment,
@@ -298,7 +297,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
298297
let layout = bx.cx().layout_of(ty);
299298
let to_backend_ty = bx.cx().immediate_backend_type(layout);
300299
let place_ref = PlaceRef::new_sized(bx.cx().const_poison(to_backend_ty), layout);
301-
self.debug_new_val_to_local(bx, local, place_ref.val, layout, &[]);
300+
self.debug_new_val_to_local(bx, local, place_ref, &[]);
302301
}
303302

304303
/// Apply debuginfo and/or name, after creating the `alloca` for a local,

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
use rustc_middle::mir::{self, NonDivergingIntrinsic, RETURN_PLACE, StmtDebugInfo};
2-
use rustc_middle::{bug, span_bug};
3-
use rustc_target::callconv::PassMode;
1+
use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo};
2+
use rustc_middle::span_bug;
43
use tracing::instrument;
54

65
use super::{FunctionCx, LocalRef};
7-
use crate::common::TypeKind;
8-
use crate::mir::place::PlaceRef;
96
use crate::traits::*;
107

118
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> {
110107
match debuginfo {
111108
StmtDebugInfo::AssignRef(dest, place) => {
112109
let local_ref = match self.locals[place.local] {
113-
LocalRef::Place(place_ref) | LocalRef::UnsizedPlace(place_ref) => {
114-
Some(place_ref)
110+
// For an rvalue like `&(_1.1)`, when `BackendRepr` is `BackendRepr::Memory`, we allocate a block of memory to this place.
111+
// The place is an indirect pointer, we can refer to it directly.
112+
LocalRef::Place(place_ref) => Some((place_ref, place.projection.as_slice())),
113+
// For an rvalue like `&((*_1).1)`, we are calculating the address of `_1.1`.
114+
// The deref projection is no-op here.
115+
LocalRef::Operand(operand_ref) if place.is_indirect_first_projection() => {
116+
Some((operand_ref.deref(bx.cx()), &place.projection[1..]))
115117
}
116-
LocalRef::Operand(operand_ref) => operand_ref
117-
.val
118-
.try_pointer_parts()
119-
.map(|(pointer, _)| PlaceRef::new_sized(pointer, operand_ref.layout)),
120-
LocalRef::PendingOperand => None,
118+
// For an rvalue like `&1`, when `BackendRepr` is `BackendRepr::Scalar`,
119+
// we cannot get the address.
120+
// N.B. `non_ssa_locals` returns that this is an SSA local.
121+
LocalRef::Operand(_) => None,
122+
LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => None,
121123
}
122-
.filter(|place_ref| {
123-
// For the reference of an argument (e.x. `&_1`), it's only valid if the pass mode is indirect, and its reference is
124-
// llval.
125-
let local_ref_pass_mode = place.as_local().and_then(|local| {
126-
if local == RETURN_PLACE {
127-
None
128-
} else {
129-
self.fn_abi.args.get(local.as_usize() - 1).map(|arg| &arg.mode)
130-
}
131-
});
132-
matches!(local_ref_pass_mode, Some(&PassMode::Indirect {..}) | None) &&
124+
.filter(|(_, projection)| {
133125
// Drop unsupported projections.
134-
place.projection.iter().all(|p| p.can_use_in_debuginfo()) &&
135-
// Only pointers can be calculated addresses.
136-
bx.type_kind(bx.val_ty(place_ref.val.llval)) == TypeKind::Pointer
126+
projection.iter().all(|p| p.can_use_in_debuginfo())
137127
});
138-
if let Some(local_ref) = local_ref {
139-
let (base_layout, projection) = if place.is_indirect_first_projection() {
140-
// For `_n = &((*_1).0: i32);`, we are calculating the address of `_1.0`, so
141-
// we should drop the deref projection.
142-
let projected_ty = local_ref
143-
.layout
144-
.ty
145-
.builtin_deref(true)
146-
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", local_ref));
147-
let layout = bx.cx().layout_of(projected_ty);
148-
(layout, &place.projection[1..])
149-
} else {
150-
(local_ref.layout, place.projection.as_slice())
151-
};
152-
self.debug_new_val_to_local(bx, *dest, local_ref.val, base_layout, projection);
128+
if let Some((base, projection)) = local_ref {
129+
self.debug_new_val_to_local(bx, *dest, base, projection);
153130
} else {
154-
// If the address cannot be computed, use poison to indicate that the value has been optimized out.
131+
// If the address cannot be calculated, use poison to indicate that the value has been optimized out.
155132
self.debug_poison_to_local(bx, *dest);
156133
}
157134
}

0 commit comments

Comments
 (0)