1
Fork 0

rustc_codegen_llvm: move DISubprogram creation to a dbg_scope_fn method.

This commit is contained in:
Eduard-Mihai Burtescu 2020-02-10 22:30:51 +02:00
parent 9d57c417fc
commit fa2b381ec8
6 changed files with 52 additions and 36 deletions

View file

@ -80,6 +80,7 @@ impl Funclet<'ll> {
impl BackendTypes for CodegenCx<'ll, 'tcx> { impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Value = &'ll Value; type Value = &'ll Value;
// FIXME(eddyb) replace this with a `Function` "subclass" of `Value`.
type Function = &'ll Value; type Function = &'ll Value;
type BasicBlock = &'ll BasicBlock; type BasicBlock = &'ll BasicBlock;

View file

@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::*;
use crate::common::CodegenCx; use crate::common::CodegenCx;
use crate::llvm; use crate::llvm;
use crate::llvm::debuginfo::{DIScope, DISubprogram}; use crate::llvm::debuginfo::DIScope;
use rustc_middle::mir::{Body, SourceScope}; use rustc_middle::mir::{Body, SourceScope};
use rustc_session::config::DebugInfo; use rustc_session::config::DebugInfo;
@ -16,7 +16,7 @@ use rustc_index::vec::Idx;
pub fn compute_mir_scopes( pub fn compute_mir_scopes(
cx: &CodegenCx<'ll, '_>, cx: &CodegenCx<'ll, '_>,
mir: &Body<'_>, mir: &Body<'_>,
fn_metadata: &'ll DISubprogram, fn_dbg_scope: &'ll DIScope,
debug_context: &mut FunctionDebugContext<&'ll DIScope>, debug_context: &mut FunctionDebugContext<&'ll DIScope>,
) { ) {
// Find all the scopes with variables defined in them. // Find all the scopes with variables defined in them.
@ -37,16 +37,16 @@ pub fn compute_mir_scopes(
// Instantiate all scopes. // Instantiate all scopes.
for idx in 0..mir.source_scopes.len() { for idx in 0..mir.source_scopes.len() {
let scope = SourceScope::new(idx); let scope = SourceScope::new(idx);
make_mir_scope(cx, &mir, fn_metadata, &has_variables, debug_context, scope); make_mir_scope(cx, &mir, fn_dbg_scope, &has_variables, debug_context, scope);
} }
} }
fn make_mir_scope( fn make_mir_scope(
cx: &CodegenCx<'ll, '_>, cx: &CodegenCx<'ll, '_>,
mir: &Body<'_>, mir: &Body<'_>,
fn_metadata: &'ll DISubprogram, fn_dbg_scope: &'ll DIScope,
has_variables: &BitSet<SourceScope>, has_variables: &BitSet<SourceScope>,
debug_context: &mut FunctionDebugContext<&'ll DISubprogram>, debug_context: &mut FunctionDebugContext<&'ll DIScope>,
scope: SourceScope, scope: SourceScope,
) { ) {
if debug_context.scopes[scope].is_valid() { if debug_context.scopes[scope].is_valid() {
@ -55,13 +55,13 @@ fn make_mir_scope(
let scope_data = &mir.source_scopes[scope]; let scope_data = &mir.source_scopes[scope];
let parent_scope = if let Some(parent) = scope_data.parent_scope { let parent_scope = if let Some(parent) = scope_data.parent_scope {
make_mir_scope(cx, mir, fn_metadata, has_variables, debug_context, parent); make_mir_scope(cx, mir, fn_dbg_scope, has_variables, debug_context, parent);
debug_context.scopes[parent] debug_context.scopes[parent]
} else { } else {
// The root is the function itself. // The root is the function itself.
let loc = cx.lookup_debug_loc(mir.span.lo()); let loc = cx.lookup_debug_loc(mir.span.lo());
debug_context.scopes[scope] = DebugScope { debug_context.scopes[scope] = DebugScope {
scope_metadata: Some(fn_metadata), scope_metadata: Some(fn_dbg_scope),
file_start_pos: loc.file.start_pos, file_start_pos: loc.file.start_pos,
file_end_pos: loc.file.end_pos, file_end_pos: loc.file.end_pos,
}; };

View file

@ -235,16 +235,36 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
return None; return None;
} }
let span = mir.span; // Initialize fn debug context (including scopes).
// FIXME(eddyb) figure out a way to not need `Option` for `scope_metadata`.
let empty_scope = DebugScope {
scope_metadata: None,
file_start_pos: BytePos(0),
file_end_pos: BytePos(0),
};
let mut fn_debug_context =
FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes) };
// This can be the case for functions inlined from another crate // Fill in all the scopes, with the information from the MIR body.
if span.is_dummy() { compute_mir_scopes(
// FIXME(simulacrum): Probably can't happen; remove. self,
return None; mir,
} self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
&mut fn_debug_context,
);
Some(fn_debug_context)
}
fn dbg_scope_fn(
&self,
instance: Instance<'tcx>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
maybe_definition_llfn: Option<&'ll Value>,
) -> &'ll DIScope {
let def_id = instance.def_id(); let def_id = instance.def_id();
let containing_scope = get_containing_scope(self, instance); let containing_scope = get_containing_scope(self, instance);
let span = self.tcx.def_span(def_id);
let loc = self.lookup_debug_loc(span.lo()); let loc = self.lookup_debug_loc(span.lo());
let file_metadata = file_metadata(self, &loc.file); let file_metadata = file_metadata(self, &loc.file);
@ -291,8 +311,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
} }
} }
let fn_metadata = unsafe { unsafe {
llvm::LLVMRustDIBuilderCreateFunction( return llvm::LLVMRustDIBuilderCreateFunction(
DIB(self), DIB(self),
containing_scope, containing_scope,
name.as_ptr().cast(), name.as_ptr().cast(),
@ -305,26 +325,11 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
scope_line.unwrap_or(UNKNOWN_LINE_NUMBER), scope_line.unwrap_or(UNKNOWN_LINE_NUMBER),
flags, flags,
spflags, spflags,
llfn, maybe_definition_llfn,
template_parameters, template_parameters,
None, None,
) );
}; }
// Initialize fn debug context (including scopes).
// FIXME(eddyb) figure out a way to not need `Option` for `scope_metadata`.
let null_scope = DebugScope {
scope_metadata: None,
file_start_pos: BytePos(0),
file_end_pos: BytePos(0),
};
let mut fn_debug_context =
FunctionDebugContext { scopes: IndexVec::from_elem(null_scope, &mir.source_scopes) };
// Fill in all the scopes, with the information from the MIR body.
compute_mir_scopes(self, mir, fn_metadata, &mut fn_debug_context);
return Some(fn_debug_context);
fn get_function_signature<'ll, 'tcx>( fn get_function_signature<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,

View file

@ -1854,7 +1854,7 @@ extern "C" {
ScopeLine: c_uint, ScopeLine: c_uint,
Flags: DIFlags, Flags: DIFlags,
SPFlags: DISPFlags, SPFlags: DISPFlags,
Fn: &'a Value, MaybeFn: Option<&'a Value>,
TParam: &'a DIArray, TParam: &'a DIArray,
Decl: Option<&'a DIDescriptor>, Decl: Option<&'a DIDescriptor>,
) -> &'a DISubprogram; ) -> &'a DISubprogram;

View file

@ -21,6 +21,15 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes {
mir: &mir::Body<'_>, mir: &mir::Body<'_>,
) -> Option<FunctionDebugContext<Self::DIScope>>; ) -> Option<FunctionDebugContext<Self::DIScope>>;
// FIXME(eddyb) find a common convention for all of the debuginfo-related
// names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.).
fn dbg_scope_fn(
&self,
instance: Instance<'tcx>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
maybe_definition_llfn: Option<Self::Function>,
) -> Self::DIScope;
fn extend_scope_to_file( fn extend_scope_to_file(
&self, &self,
scope_metadata: Self::DIScope, scope_metadata: Self::DIScope,

View file

@ -733,7 +733,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
const char *LinkageName, size_t LinkageNameLen, const char *LinkageName, size_t LinkageNameLen,
LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef File, unsigned LineNo,
LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags, LLVMMetadataRef Ty, unsigned ScopeLine, LLVMRustDIFlags Flags,
LLVMRustDISPFlags SPFlags, LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam,
LLVMMetadataRef Decl) { LLVMMetadataRef Decl) {
DITemplateParameterArray TParams = DITemplateParameterArray TParams =
DITemplateParameterArray(unwrap<MDTuple>(TParam)); DITemplateParameterArray(unwrap<MDTuple>(TParam));
@ -750,7 +750,8 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIFile>(File), LineNo,
unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags, unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags,
llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl)); llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl));
unwrap<Function>(Fn)->setSubprogram(Sub); if (MaybeFn)
unwrap<Function>(MaybeFn)->setSubprogram(Sub);
return wrap(Sub); return wrap(Sub);
} }