Skip to content

Commit

Permalink
Auto merge of rust-lang#68665 - eddyb:debuginfo-early-create-var, r=n…
Browse files Browse the repository at this point in the history
…agisa

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 rust-lang#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 rust-lang#48300 (comment)).

r? @nagisa or @oli-obk cc @michaelwoerister @nikomatsakis
  • Loading branch information
bors committed Feb 3, 2020
2 parents c58e09f + e35dfad commit bdd946d
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 94 deletions.
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl BackendTypes for Builder<'_, 'll, 'tcx> {
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;

type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
type DIVariable = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIVariable;
}

impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Funclet = Funclet<'ll>;

type DIScope = &'ll llvm::debuginfo::DIScope;
type DIVariable = &'ll llvm::debuginfo::DIVariable;
}

impl CodegenCx<'ll, 'tcx> {
Expand Down
86 changes: 52 additions & 34 deletions src/librustc_codegen_llvm/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB};

use crate::llvm;
use crate::llvm::debuginfo::{
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType,
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, DIVariable,
};
use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc::ty::subst::{GenericArgKind, SubstsRef};
Expand Down Expand Up @@ -143,33 +143,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
};
}

impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
fn declare_local(
impl DebugInfoBuilderMethods for Builder<'a, 'll, 'tcx> {
// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
fn dbg_var_addr(
&mut self,
dbg_context: &FunctionDebugContext<&'ll DIScope>,
variable_name: ast::Name,
variable_type: Ty<'tcx>,
dbg_var: &'ll DIVariable,
scope_metadata: &'ll DIScope,
variable_alloca: Self::Value,
direct_offset: Size,
indirect_offsets: &[Size],
variable_kind: VariableKind,
span: Span,
) {
assert!(!dbg_context.source_locations_enabled);
let cx = self.cx();

let file = span_start(cx, span).file;
let file_metadata = file_metadata(cx, &file.name, dbg_context.defining_crate);

let loc = span_start(cx, span);
let type_metadata = type_metadata(cx, variable_type, span);

let (argument_index, dwarf_tag) = match variable_kind {
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
LocalVariable => (0, DW_TAG_auto_variable),
};
let align = cx.align_of(variable_type);

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

let name = SmallCStr::new(&variable_name.as_str());
let metadata = unsafe {
llvm::LLVMRustDIBuilderCreateVariable(
DIB(cx),
dwarf_tag,
scope_metadata,
name.as_ptr(),
file_metadata,
loc.line as c_uint,
type_metadata,
cx.sess().opts.optimize != config::OptLevel::No,
DIFlags::FlagZero,
argument_index,
align.bytes() as u32,
)
};
// FIXME(eddyb) maybe this information could be extracted from `var`,
// to avoid having to pass it down in both places?
source_loc::set_debug_location(
self,
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()),
);
unsafe {
let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder);
// FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`.
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
DIB(cx),
variable_alloca,
metadata,
dbg_var,
addr_ops.as_ptr(),
addr_ops.len() as c_uint,
debug_loc,
Expand Down Expand Up @@ -313,7 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// Get the linkage_name, which is just the symbol name
let linkage_name = mangled_name_of_instance(self, instance);

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

let function_name = CString::new(name).unwrap();
let linkage_name = SmallCStr::new(&linkage_name.name.as_str());
Expand Down Expand Up @@ -558,4 +536,44 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn debuginfo_finalize(&self) {
finalize(self)
}

// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
fn create_dbg_var(
&self,
dbg_context: &FunctionDebugContext<&'ll DIScope>,
variable_name: ast::Name,
variable_type: Ty<'tcx>,
scope_metadata: &'ll DIScope,
variable_kind: VariableKind,
span: Span,
) -> &'ll DIVariable {
let loc = span_start(self, span);
let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate);

let type_metadata = type_metadata(self, variable_type, span);

let (argument_index, dwarf_tag) = match variable_kind {
ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
LocalVariable => (0, DW_TAG_auto_variable),
};
let align = self.align_of(variable_type);

let name = SmallCStr::new(&variable_name.as_str());
unsafe {
llvm::LLVMRustDIBuilderCreateVariable(
DIB(self),
dwarf_tag,
scope_metadata,
name.as_ptr(),
file_metadata,
loc.line as c_uint,
type_metadata,
self.sess().opts.optimize != config::OptLevel::No,
DIFlags::FlagZero,
argument_index,
align.bytes() as u32,
)
}
}
}
Loading

0 comments on commit bdd946d

Please sign in to comment.