Skip to content

Commit bdd946d

Browse files
committed
Auto merge of #68665 - eddyb:debuginfo-early-create-var, r=nagisa
codegen: create DIVariables ahead of using them with llvm.dbg.declare. Instead of having `rustc_codegen_llvm` bundle creation of a `DIVariable` and `llvm.dbg.declare` into a single operation, they are now two separate methods, and the `DIVariable` is created earlier, specifically when `mir::VarDebugInfo`s are being partitioned into locals. While this isn't currently needed, it's a prerequisite for #48300, which adds fragmented debuginfo, where one `mir::VarDebugInfo` has multiple parts of itself mapped to different `mir::Place`s. For debuggers to see one composite variable instead of several ones with the same name, we need to create a single `DIVariable` and share it between multiple `llvm.dbg.declare` calls, which are likely pointing to different MIR locals. That makes the `per_local_var_debug_info` partitioning a good spot to do this in, as we can create *exactly* one `DIVariable` per `mir::VarDebugInfo`, and refer to it as many things as needed. I'm opening this PR separately because I want to test its perf impact in isolation (see #48300 (comment)). r? @nagisa or @oli-obk cc @michaelwoerister @nikomatsakis
2 parents c58e09f + e35dfad commit bdd946d

File tree

9 files changed

+209
-94
lines changed

9 files changed

+209
-94
lines changed

src/librustc_codegen_llvm/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> {
5757
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
5858

5959
type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
60+
type DIVariable = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIVariable;
6061
}
6162

6263
impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {

src/librustc_codegen_llvm/common.rs

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> {
9191
type Funclet = Funclet<'ll>;
9292

9393
type DIScope = &'ll llvm::debuginfo::DIScope;
94+
type DIVariable = &'ll llvm::debuginfo::DIVariable;
9495
}
9596

9697
impl CodegenCx<'ll, 'tcx> {

src/librustc_codegen_llvm/debuginfo/mod.rs

+52-34
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB};
1111

1212
use crate::llvm;
1313
use crate::llvm::debuginfo::{
14-
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType,
14+
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIVariable,
1515
};
1616
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1717
use rustc::ty::subst::{GenericArgKind, SubstsRef};
@@ -143,33 +143,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
143143
};
144144
}
145145

146-
impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
147-
fn declare_local(
146+
impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
147+
// FIXME(eddyb) find a common convention for all of the debuginfo-related
148+
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
149+
fn dbg_var_addr(
148150
&mut self,
149151
dbg_context: &FunctionDebugContext<&'ll DIScope>,
150-
variable_name: ast::Name,
151-
variable_type: Ty<'tcx>,
152+
dbg_var: &'ll DIVariable,
152153
scope_metadata: &'ll DIScope,
153154
variable_alloca: Self::Value,
154155
direct_offset: Size,
155156
indirect_offsets: &[Size],
156-
variable_kind: VariableKind,
157157
span: Span,
158158
) {
159159
assert!(!dbg_context.source_locations_enabled);
160160
let cx = self.cx();
161161

162-
let file = span_start(cx, span).file;
163-
let file_metadata = file_metadata(cx, &file.name, dbg_context.defining_crate);
164-
165162
let loc = span_start(cx, span);
166-
let type_metadata = type_metadata(cx, variable_type, span);
167-
168-
let (argument_index, dwarf_tag) = match variable_kind {
169-
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
170-
LocalVariable => (0, DW_TAG_auto_variable),
171-
};
172-
let align = cx.align_of(variable_type);
173163

174164
// Convert the direct and indirect offsets to address ops.
175165
let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() };
@@ -188,32 +178,19 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
188178
}
189179
}
190180

191-
let name = SmallCStr::new(&variable_name.as_str());
192-
let metadata = unsafe {
193-
llvm::LLVMRustDIBuilderCreateVariable(
194-
DIB(cx),
195-
dwarf_tag,
196-
scope_metadata,
197-
name.as_ptr(),
198-
file_metadata,
199-
loc.line as c_uint,
200-
type_metadata,
201-
cx.sess().opts.optimize != config::OptLevel::No,
202-
DIFlags::FlagZero,
203-
argument_index,
204-
align.bytes() as u32,
205-
)
206-
};
181+
// FIXME(eddyb) maybe this information could be extracted from `var`,
182+
// to avoid having to pass it down in both places?
207183
source_loc::set_debug_location(
208184
self,
209185
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()),
210186
);
211187
unsafe {
212188
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
189+
// FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`.
213190
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
214191
DIB(cx),
215192
variable_alloca,
216-
metadata,
193+
dbg_var,
217194
addr_ops.as_ptr(),
218195
addr_ops.len() as c_uint,
219196
debug_loc,
@@ -313,7 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
313290
// Get the linkage_name, which is just the symbol name
314291
let linkage_name = mangled_name_of_instance(self, instance);
315292

316-
let scope_line = span_start(self, span).line;
293+
// FIXME(eddyb) does this need to be separate from `loc.line` for some reason?
294+
let scope_line = loc.line;
317295

318296
let function_name = CString::new(name).unwrap();
319297
let linkage_name = SmallCStr::new(&linkage_name.name.as_str());
@@ -558,4 +536,44 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
558536
fn debuginfo_finalize(&self) {
559537
finalize(self)
560538
}
539+
540+
// FIXME(eddyb) find a common convention for all of the debuginfo-related
541+
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
542+
fn create_dbg_var(
543+
&self,
544+
dbg_context: &FunctionDebugContext<&'ll DIScope>,
545+
variable_name: ast::Name,
546+
variable_type: Ty<'tcx>,
547+
scope_metadata: &'ll DIScope,
548+
variable_kind: VariableKind,
549+
span: Span,
550+
) -> &'ll DIVariable {
551+
let loc = span_start(self, span);
552+
let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate);
553+
554+
let type_metadata = type_metadata(self, variable_type, span);
555+
556+
let (argument_index, dwarf_tag) = match variable_kind {
557+
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
558+
LocalVariable => (0, DW_TAG_auto_variable),
559+
};
560+
let align = self.align_of(variable_type);
561+
562+
let name = SmallCStr::new(&variable_name.as_str());
563+
unsafe {
564+
llvm::LLVMRustDIBuilderCreateVariable(
565+
DIB(self),
566+
dwarf_tag,
567+
scope_metadata,
568+
name.as_ptr(),
569+
file_metadata,
570+
loc.line as c_uint,
571+
type_metadata,
572+
self.sess().opts.optimize != config::OptLevel::No,
573+
DIFlags::FlagZero,
574+
argument_index,
575+
align.bytes() as u32,
576+
)
577+
}
578+
}
561579
}

0 commit comments

Comments
 (0)