Skip to content

Commit 0689077

Browse files
committed
Deduplicate inlined function debug info, but create a new lexical scope to child subsequent scopes and variables from colliding
1 parent 83995f3 commit 0689077

File tree

7 files changed

+61
-22
lines changed

7 files changed

+61
-22
lines changed

compiler/rustc_codegen_gcc/src/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
5555
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
5656
_llfn: RValue<'gcc>,
5757
_mir: &mir::Body<'tcx>,
58-
) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>> {
58+
) -> Option<FunctionDebugContext<'tcx, Self::DIScope, Self::DILocation>> {
5959
// TODO(antoyo)
6060
None
6161
}

compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub fn compute_mir_scopes<'ll, 'tcx>(
2020
cx: &CodegenCx<'ll, 'tcx>,
2121
instance: Instance<'tcx>,
2222
mir: &Body<'tcx>,
23-
debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
23+
debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
2424
) {
2525
// Find all scopes with variables defined in them.
2626
let variables = if cx.sess().opts.debuginfo == DebugInfo::Full {
@@ -51,7 +51,7 @@ fn make_mir_scope<'ll, 'tcx>(
5151
instance: Instance<'tcx>,
5252
mir: &Body<'tcx>,
5353
variables: &Option<BitSet<SourceScope>>,
54-
debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>,
54+
debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
5555
instantiated: &mut BitSet<SourceScope>,
5656
scope: SourceScope,
5757
) {
@@ -86,7 +86,7 @@ fn make_mir_scope<'ll, 'tcx>(
8686
let loc = cx.lookup_debug_loc(scope_data.span.lo());
8787
let file_metadata = file_metadata(cx, &loc.file);
8888

89-
let dbg_scope = match scope_data.inlined {
89+
let parent_dbg_scope = match scope_data.inlined {
9090
Some((callee, _)) => {
9191
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
9292
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
@@ -95,18 +95,22 @@ fn make_mir_scope<'ll, 'tcx>(
9595
ty::ParamEnv::reveal_all(),
9696
ty::EarlyBinder::bind(callee),
9797
);
98-
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
99-
cx.dbg_scope_fn(callee, callee_fn_abi, None)
98+
debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| {
99+
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
100+
cx.dbg_scope_fn(callee, callee_fn_abi, None)
101+
})
100102
}
101-
None => unsafe {
102-
llvm::LLVMRustDIBuilderCreateLexicalBlock(
103-
DIB(cx),
104-
parent_scope.dbg_scope,
105-
file_metadata,
106-
loc.line,
107-
loc.col,
108-
)
109-
},
103+
None => parent_scope.dbg_scope,
104+
};
105+
106+
let dbg_scope = unsafe {
107+
llvm::LLVMRustDIBuilderCreateLexicalBlock(
108+
DIB(cx),
109+
parent_dbg_scope,
110+
file_metadata,
111+
loc.line,
112+
loc.col,
113+
)
110114
};
111115

112116
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
292292
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
293293
llfn: &'ll Value,
294294
mir: &mir::Body<'tcx>,
295-
) -> Option<FunctionDebugContext<&'ll DIScope, &'ll DILocation>> {
295+
) -> Option<FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>> {
296296
if self.sess().opts.debuginfo == DebugInfo::None {
297297
return None;
298298
}
@@ -304,8 +304,10 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
304304
file_start_pos: BytePos(0),
305305
file_end_pos: BytePos(0),
306306
};
307-
let mut fn_debug_context =
308-
FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes) };
307+
let mut fn_debug_context = FunctionDebugContext {
308+
scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes),
309+
inlined_function_scopes: Default::default(),
310+
};
309311

310312
// Fill in all the scopes, with the information from the MIR body.
311313
compute_mir_scopes(self, instance, mir, &mut fn_debug_context);

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use crate::traits::*;
2+
use rustc_data_structures::fx::FxHashMap;
23
use rustc_index::IndexVec;
34
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
45
use rustc_middle::mir;
56
use rustc_middle::ty;
67
use rustc_middle::ty::layout::TyAndLayout;
78
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
9+
use rustc_middle::ty::Instance;
810
use rustc_middle::ty::Ty;
911
use rustc_session::config::DebugInfo;
1012
use rustc_span::symbol::{kw, Symbol};
@@ -17,10 +19,13 @@ use super::{FunctionCx, LocalRef};
1719

1820
use std::ops::Range;
1921

20-
pub struct FunctionDebugContext<S, L> {
22+
pub struct FunctionDebugContext<'tcx, S, L> {
23+
/// Maps from source code to the corresponding debug info scope.
2124
pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
22-
}
2325

26+
/// Maps from an inlined function to its debug info declaration.
27+
pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
28+
}
2429
#[derive(Copy, Clone)]
2530
pub enum VariableKind {
2631
ArgumentVariable(usize /*index*/),

compiler/rustc_codegen_ssa/src/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
4646

4747
mir: &'tcx mir::Body<'tcx>,
4848

49-
debug_context: Option<FunctionDebugContext<Bx::DIScope, Bx::DILocation>>,
49+
debug_context: Option<FunctionDebugContext<'tcx, Bx::DIScope, Bx::DILocation>>,
5050

5151
llfn: Bx::Function,
5252

compiler/rustc_codegen_ssa/src/traits/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
2626
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
2727
llfn: Self::Function,
2828
mir: &mir::Body<'tcx>,
29-
) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>>;
29+
) -> Option<FunctionDebugContext<'tcx, Self::DIScope, Self::DILocation>>;
3030

3131
// FIXME(eddyb) find a common convention for all of the debuginfo-related
3232
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// compile-flags: -g -O
2+
3+
// Check that each inline call site for the same function uses the same "sub-program" so that LLVM
4+
// can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail
5+
// calls to panic.
6+
7+
// CHECK: tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E
8+
// CHECK-SAME: !dbg ![[#first_dbg:]]
9+
// CHECK: tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E
10+
// CHECK-SAME: !dbg ![[#second_dbg:]]
11+
12+
// CHECK-DAG: ![[#func_dbg:]] = distinct !DISubprogram(name: "unwrap<i32>"
13+
// CHECK-DAG: ![[#first_scope:]] = distinct !DILexicalBlock(scope: ![[#func_dbg]],
14+
// CHECK: ![[#second_scope:]] = distinct !DILexicalBlock(scope: ![[#func_dbg]],
15+
// CHECK: ![[#first_dbg]] = !DILocation(line: [[#]]
16+
// CHECK-SAME: scope: ![[#first_scope]], inlinedAt: ![[#]])
17+
// CHECK: ![[#second_dbg]] = !DILocation(line: [[#]]
18+
// CHECK-SAME: scope: ![[#second_scope]], inlinedAt: ![[#]])
19+
20+
#![crate_type = "lib"]
21+
22+
#[no_mangle]
23+
extern "C" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 {
24+
let x1 = x.unwrap();
25+
let y1 = y.unwrap();
26+
27+
x1 + y1
28+
}

0 commit comments

Comments
 (0)