Skip to content

Commit 0d8e905

Browse files
committed
codegen: emit the debugging information for the dead code
1 parent 72f688f commit 0d8e905

14 files changed

+167
-55
lines changed

compiler/rustc_codegen_gcc/src/debuginfo.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
2626
&mut self,
2727
_dbg_var: Self::DIVariable,
2828
_dbg_loc: Self::DILocation,
29-
_variable_alloca: Self::Value,
29+
_is_declared: bool,
30+
_val: Self::Value,
3031
_direct_offset: Size,
3132
_indirect_offsets: &[Size],
3233
_fragment: Option<Range<Size>>,

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+26-12
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
154154
&mut self,
155155
dbg_var: &'ll DIVariable,
156156
dbg_loc: &'ll DILocation,
157-
variable_alloca: Self::Value,
157+
is_declared: bool,
158+
val: Self::Value,
158159
direct_offset: Size,
159160
indirect_offsets: &[Size],
160161
fragment: Option<Range<Size>>,
@@ -183,17 +184,30 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
183184
addr_ops.push((fragment.end - fragment.start).bits() as u64);
184185
}
185186

186-
unsafe {
187-
// FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`.
188-
llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
189-
DIB(self.cx()),
190-
variable_alloca,
191-
dbg_var,
192-
addr_ops.as_ptr(),
193-
addr_ops.len() as c_uint,
194-
dbg_loc,
195-
self.llbb(),
196-
);
187+
if is_declared {
188+
unsafe {
189+
llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
190+
DIB(self.cx()),
191+
val,
192+
dbg_var,
193+
addr_ops.as_ptr(),
194+
addr_ops.len() as c_uint,
195+
dbg_loc,
196+
self.llbb(),
197+
);
198+
}
199+
} else {
200+
unsafe {
201+
llvm::LLVMRustDIBuilderInsertDbgValueAtEnd(
202+
DIB(self.cx()),
203+
val,
204+
dbg_var,
205+
addr_ops.as_ptr(),
206+
addr_ops.len() as c_uint,
207+
dbg_loc,
208+
self.llbb(),
209+
);
210+
}
197211
}
198212
}
199213

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2301,6 +2301,16 @@ unsafe extern "C" {
23012301
InsertAtEnd: &'a BasicBlock,
23022302
);
23032303

2304+
pub(crate) fn LLVMRustDIBuilderInsertDbgValueAtEnd<'a>(
2305+
Builder: &DIBuilder<'a>,
2306+
Val: &'a Value,
2307+
VarInfo: &'a DIVariable,
2308+
AddrOps: *const u64,
2309+
AddrOpsCount: c_uint,
2310+
DL: &'a DILocation,
2311+
InsertAtEnd: &'a BasicBlock,
2312+
);
2313+
23042314
pub(crate) fn LLVMRustDIBuilderCreateEnumerator<'a>(
23052315
Builder: &DIBuilder<'a>,
23062316
Name: *const c_char,

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+49-2
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,52 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
378378
}
379379
}
380380

381+
pub(crate) fn debug_new_value_to_local(
382+
&self,
383+
bx: &mut Bx,
384+
local: mir::Local,
385+
base: PlaceValue<Bx::Value>,
386+
layout: TyAndLayout<'tcx>,
387+
projection: &[mir::PlaceElem<'tcx>],
388+
) {
389+
let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;
390+
if !full_debug_info {
391+
return;
392+
}
393+
394+
let vars = match &self.per_local_var_debug_info {
395+
Some(per_local) => &per_local[local],
396+
None => return,
397+
};
398+
399+
for var in vars.iter().cloned() {
400+
self.debug_new_value_to_local_as_var(bx, base, layout, projection, var);
401+
}
402+
}
403+
404+
fn debug_new_value_to_local_as_var(
405+
&self,
406+
bx: &mut Bx,
407+
base: PlaceValue<Bx::Value>,
408+
layout: TyAndLayout<'tcx>,
409+
projection: &[mir::PlaceElem<'tcx>],
410+
var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
411+
) {
412+
let Some(dbg_var) = var.dbg_var else { return };
413+
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
414+
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
415+
calculate_debuginfo_offset(bx, projection, layout);
416+
bx.dbg_var_addr(
417+
dbg_var,
418+
dbg_loc,
419+
false,
420+
base.llval,
421+
direct_offset,
422+
&indirect_offsets,
423+
var.fragment,
424+
);
425+
}
426+
381427
fn debug_introduce_local_as_var(
382428
&self,
383429
bx: &mut Bx,
@@ -387,7 +433,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
387433
) {
388434
let Some(dbg_var) = var.dbg_var else { return };
389435
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
390-
391436
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
392437
calculate_debuginfo_offset(bx, var.projection, base.layout);
393438

@@ -422,6 +467,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
422467
bx.dbg_var_addr(
423468
dbg_var,
424469
dbg_loc,
470+
true,
425471
alloca.val.llval,
426472
Size::ZERO,
427473
&[Size::ZERO],
@@ -431,6 +477,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
431477
bx.dbg_var_addr(
432478
dbg_var,
433479
dbg_loc,
480+
true,
434481
base.val.llval,
435482
direct_offset,
436483
&indirect_offsets,
@@ -456,7 +503,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
456503
let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx);
457504
bx.clear_dbg_loc();
458505

459-
bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], fragment);
506+
bx.dbg_var_addr(dbg_var, dbg_loc, true, base.val.llval, Size::ZERO, &[], fragment);
460507
}
461508
}
462509
}

compiler/rustc_codegen_ssa/src/mir/statement.rs

+66-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
use std::ops::Deref;
2+
13
use rustc_middle::mir::{self, NonDivergingIntrinsic};
2-
use rustc_middle::span_bug;
4+
use rustc_middle::ty::layout::HasTyCtxt;
5+
use rustc_middle::ty::{Ty, TyCtxt};
6+
use rustc_middle::{bug, span_bug};
37
use tracing::instrument;
48

59
use super::{FunctionCx, LocalRef};
10+
use crate::mir::operand::{OperandRef, OperandValue};
11+
use crate::mir::place::PlaceRef;
612
use crate::traits::*;
713

814
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
@@ -94,8 +100,65 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
94100
| mir::StatementKind::PlaceMention(..)
95101
| mir::StatementKind::BackwardIncompatibleDropHint { .. } => {}
96102
mir::StatementKind::Nop(ref stmt) => {
97-
if stmt.is_some() {
98-
todo!("add debugging information")
103+
if let Some(box stmt_kind) = stmt {
104+
match stmt_kind {
105+
mir::StatementKind::Assign(box (dest, rvalue)) => {
106+
if let Some(index) = dest.as_local()
107+
&& let mir::Rvalue::Ref(_, _, place) = *rvalue
108+
{
109+
let place_ref = match self.locals[place.local] {
110+
LocalRef::Place(place_ref)
111+
| LocalRef::UnsizedPlace(place_ref) => Some(place_ref),
112+
LocalRef::Operand(operand_ref) => match operand_ref.val {
113+
OperandValue::Ref(_place_value) => {
114+
todo!("OperandValue::Ref")
115+
}
116+
OperandValue::Immediate(v) => {
117+
Some(PlaceRef::new_sized(v, operand_ref.layout))
118+
}
119+
OperandValue::Pair(_, _) => None,
120+
OperandValue::ZeroSized => None,
121+
},
122+
LocalRef::PendingOperand => None,
123+
};
124+
let (val, layout, projection) =
125+
match (place_ref, place.is_indirect_first_projection()) {
126+
(Some(place_ref), false) => (
127+
place_ref.val,
128+
place_ref.layout,
129+
place.projection.as_slice(),
130+
),
131+
(Some(place_ref), true) => {
132+
let projected_ty = place_ref
133+
.layout
134+
.ty
135+
.builtin_deref(true)
136+
.unwrap_or_else(|| {
137+
bug!("deref of non-pointer {:?}", place_ref)
138+
});
139+
let layout = bx.cx().layout_of(projected_ty);
140+
(place_ref.val, layout, &place.projection[1..])
141+
}
142+
_ => {
143+
let ty =
144+
self.monomorphize(self.mir.local_decls[index].ty);
145+
let layout = bx.cx().layout_of(ty);
146+
let to_backend_ty =
147+
bx.cx().immediate_backend_type(layout);
148+
let place_ref = PlaceRef::new_sized(
149+
bx.cx().const_poison(to_backend_ty),
150+
layout,
151+
);
152+
(place_ref.val, layout, [].as_slice())
153+
}
154+
};
155+
self.debug_new_value_to_local(bx, index, val, layout, projection);
156+
} else {
157+
todo!("add debugging information")
158+
}
159+
}
160+
_ => {}
161+
}
99162
}
100163
}
101164
}

compiler/rustc_codegen_ssa/src/traits/debuginfo.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
7171
&mut self,
7272
dbg_var: Self::DIVariable,
7373
dbg_loc: Self::DILocation,
74-
variable_alloca: Self::Value,
74+
is_declared: bool,
75+
val: Self::Value,
7576
direct_offset: Size,
7677
// NB: each offset implies a deref (i.e. they're steps in a pointer chain).
7778
indirect_offsets: &[Size],

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,18 @@ LLVMRustDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef V,
12471247
DebugLoc(cast<MDNode>(unwrap(DL))), unwrap(InsertAtEnd));
12481248
}
12491249

1250+
extern "C" void
1251+
LLVMRustDIBuilderInsertDbgValueAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef V,
1252+
LLVMMetadataRef VarInfo, uint64_t *AddrOps,
1253+
unsigned AddrOpsCount, LLVMMetadataRef DL,
1254+
LLVMBasicBlockRef InsertAtEnd) {
1255+
unwrap(Builder)->insertDbgValueIntrinsic(
1256+
unwrap(V), unwrap<DILocalVariable>(VarInfo),
1257+
unwrap(Builder)->createExpression(
1258+
llvm::ArrayRef<uint64_t>(AddrOps, AddrOpsCount)),
1259+
DebugLoc(cast<MDNode>(unwrap(DL))), unwrap(InsertAtEnd));
1260+
}
1261+
12501262
extern "C" LLVMMetadataRef
12511263
LLVMRustDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name,
12521264
size_t NameLen, const uint64_t Value[2],

tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff

-6
Original file line numberDiff line numberDiff line change
@@ -221,23 +221,18 @@
221221
+ _22 = &mut (*_23);
222222
+ StorageDead(_24);
223223
+ StorageLive(_45);
224-
+ StorageLive(_46);
225224
+ StorageLive(_50);
226225
+ StorageLive(_42);
227226
+ StorageLive(_43);
228-
+ StorageLive(_44);
229227
+ Nop(Assign((_46, &mut _19)));
230-
+ StorageLive(_47);
231228
+ Nop(Assign((_47, &mut (_19.0: &mut std::future::Ready<()>))));
232229
+ _45 = copy (_19.0: &mut std::future::Ready<()>);
233-
+ StorageDead(_47);
234230
+ Nop(Assign((_44, &mut ((*_45).0: std::option::Option<()>))));
235231
+ StorageLive(_48);
236232
+ _48 = Option::<()>::None;
237233
+ _43 = copy ((*_45).0: std::option::Option<()>);
238234
+ ((*_45).0: std::option::Option<()>) = copy _48;
239235
+ StorageDead(_48);
240-
+ StorageDead(_44);
241236
+ StorageLive(_49);
242237
+ _49 = discriminant(_43);
243238
+ switchInt(move _49) -> [0: bb11, 1: bb12, otherwise: bb5];
@@ -313,7 +308,6 @@
313308
+ _18 = Poll::<()>::Ready(move _42);
314309
+ StorageDead(_42);
315310
+ StorageDead(_50);
316-
+ StorageDead(_46);
317311
+ StorageDead(_45);
318312
+ StorageDead(_22);
319313
+ StorageDead(_19);

tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff

-6
Original file line numberDiff line numberDiff line change
@@ -238,23 +238,18 @@
238238
+ _22 = &mut (*_23);
239239
+ StorageDead(_24);
240240
+ StorageLive(_47);
241-
+ StorageLive(_48);
242241
+ StorageLive(_52);
243242
+ StorageLive(_44);
244243
+ StorageLive(_45);
245-
+ StorageLive(_46);
246244
+ Nop(Assign((_48, &mut _19)));
247-
+ StorageLive(_49);
248245
+ Nop(Assign((_49, &mut (_19.0: &mut std::future::Ready<()>))));
249246
+ _47 = copy (_19.0: &mut std::future::Ready<()>);
250-
+ StorageDead(_49);
251247
+ Nop(Assign((_46, &mut ((*_47).0: std::option::Option<()>))));
252248
+ StorageLive(_50);
253249
+ _50 = Option::<()>::None;
254250
+ _45 = copy ((*_47).0: std::option::Option<()>);
255251
+ ((*_47).0: std::option::Option<()>) = copy _50;
256252
+ StorageDead(_50);
257-
+ StorageDead(_46);
258253
+ StorageLive(_51);
259254
+ _51 = discriminant(_45);
260255
+ switchInt(move _51) -> [0: bb16, 1: bb17, otherwise: bb7];
@@ -354,7 +349,6 @@
354349
+ _18 = Poll::<()>::Ready(move _44);
355350
+ StorageDead(_44);
356351
+ StorageDead(_52);
357-
+ StorageDead(_48);
358352
+ StorageDead(_47);
359353
+ StorageDead(_22);
360354
+ StorageDead(_19);

tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff

-6
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,9 @@
3737
}
3838

3939
bb2: {
40-
StorageLive(_7);
4140
Nop(Assign((_7, &(*_2)[0 of 3])));
42-
StorageLive(_8);
4341
Nop(Assign((_8, &(*_2)[1 of 3])));
44-
StorageLive(_9);
4542
Nop(Assign((_9, &(*_2)[2 of 3])));
46-
StorageDead(_9);
47-
StorageDead(_8);
48-
StorageDead(_7);
4943
StorageDead(_4);
5044
return;
5145
}

tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff

-6
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,9 @@
3737
}
3838

3939
bb2: {
40-
StorageLive(_7);
4140
Nop(Assign((_7, &(*_2)[0 of 3])));
42-
StorageLive(_8);
4341
Nop(Assign((_8, &(*_2)[1 of 3])));
44-
StorageLive(_9);
4542
Nop(Assign((_9, &(*_2)[2 of 3])));
46-
StorageDead(_9);
47-
StorageDead(_8);
48-
StorageDead(_7);
4943
StorageDead(_4);
5044
return;
5145
}

tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir

-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ fn clone_as_copy(_1: &NestCopy) -> NestCopy {
1212
}
1313

1414
bb0: {
15-
StorageLive(_2);
1615
Nop(Assign((_2, &((*_1).1: AllCopy))));
1716
_0 = copy (*_1);
18-
StorageDead(_2);
1917
return;
2018
}
2119
}

0 commit comments

Comments
 (0)