Skip to content

Commit

Permalink
rustc_mir: track inlined callees in SourceScopeData.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Feb 9, 2020
1 parent 5a343c8 commit 275cb05
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 38 deletions.
14 changes: 9 additions & 5 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub struct Body<'tcx> {

/// A list of source scopes; these are referenced by statements
/// and used for debuginfo. Indexed by a `SourceScope`.
pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,

/// The yield type of the function, if it is a generator.
pub yield_ty: Option<Ty<'tcx>>,
Expand Down Expand Up @@ -179,7 +179,7 @@ pub struct Body<'tcx> {
impl<'tcx> Body<'tcx> {
pub fn new(
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
source_scopes: IndexVec<SourceScope, SourceScopeData>,
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
local_decls: LocalDecls<'tcx>,
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
arg_count: usize,
Expand Down Expand Up @@ -1916,11 +1916,16 @@ rustc_index::newtype_index! {
}
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct SourceScopeData {
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub struct SourceScopeData<'tcx> {
pub span: Span,
pub parent_scope: Option<SourceScope>,

/// Whether this scope is the root of a scope tree of another body,
/// inlined into this body by the MIR inliner.
/// `ty::Instance` is the callee, and the `Span` is the call site.
pub inlined: Option<(ty::Instance<'tcx>, Span)>,

/// Crate-local information for this source scope, that can't (and
/// needn't) be tracked across crates.
pub local_data: ClearCrossCrate<SourceScopeLocalData>,
Expand Down Expand Up @@ -2621,7 +2626,6 @@ CloneTypeFoldableAndLiftImpls! {
FakeReadCause,
RetagKind,
SourceScope,
SourceScopeData,
SourceScopeLocalData,
UserTypeAnnotationIndex,
}
Expand Down
32 changes: 30 additions & 2 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ macro_rules! make_mir_visitor {
}

fn visit_source_scope_data(&mut self,
scope_data: & $($mutability)? SourceScopeData) {
scope_data: & $($mutability)? SourceScopeData<'tcx>) {
self.super_source_scope_data(scope_data);
}

Expand Down Expand Up @@ -329,17 +329,45 @@ macro_rules! make_mir_visitor {
}
}

fn super_source_scope_data(&mut self, scope_data: & $($mutability)? SourceScopeData) {
fn super_source_scope_data(
&mut self,
scope_data: & $($mutability)? SourceScopeData<'tcx>,
) {
let SourceScopeData {
span,
parent_scope,
inlined,
local_data: _,
} = scope_data;

self.visit_span(span);
if let Some(parent_scope) = parent_scope {
self.visit_source_scope(parent_scope);
}
if let Some((callee, callsite_span)) = inlined {
let location = START_BLOCK.start_location();

self.visit_span(callsite_span);

let ty::Instance { def: callee_def, substs: callee_substs } = callee;
match callee_def {
ty::InstanceDef::Item(_def_id) |
ty::InstanceDef::Intrinsic(_def_id) |
ty::InstanceDef::VtableShim(_def_id) |
ty::InstanceDef::ReifyShim(_def_id) |
ty::InstanceDef::Virtual(_def_id, _) |
ty::InstanceDef::ClosureOnceShim { call_once: _def_id } |
ty::InstanceDef::DropGlue(_def_id, None) => {}

ty::InstanceDef::FnPtrShim(_def_id, ty) |
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
ty::InstanceDef::CloneShim(_def_id, ty) => {
// FIXME(eddyb) use a better `TyContext` here.
self.visit_ty(ty, TyContext::Location(location));
}
}
self.visit_substs(callee_substs, location);
}
}

fn super_statement(&mut self,
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_mir/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,12 @@ fn new_body<'tcx>(
Body::new(
basic_blocks,
IndexVec::from_elem_n(
SourceScopeData { span, parent_scope: None, local_data: ClearCrossCrate::Clear },
SourceScopeData {
span,
parent_scope: None,
inlined: None,
local_data: ClearCrossCrate::Clear,
},
1,
),
local_decls,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ struct ConstPropagator<'mir, 'tcx> {
param_env: ParamEnv<'tcx>,
// FIXME(eddyb) avoid cloning these two fields more than once,
// by accessing them through `ecx` instead.
source_scopes: IndexVec<SourceScope, SourceScopeData>,
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
ret: Option<OpTy<'tcx, ()>>,
// Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store
Expand Down
14 changes: 5 additions & 9 deletions src/librustc_mir/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Inliner<'tcx> {
let callee_node_id = self.tcx.hir().as_local_node_id(callsite.callee.def_id());

let callee_body = if let Some(callee_node_id) = callee_node_id {
// Avoid a cycle here by only using `optimized_mir` only if we have
// Avoid a cycle here by only using `instance_mir` only if we have
// a lower node id than the callee. This ensures that the callee will
// not inline us. This trick only works without incremental compilation.
// So don't do it if that is enabled.
Expand Down Expand Up @@ -416,15 +416,11 @@ impl Inliner<'tcx> {
for mut scope in callee_body.source_scopes.iter().cloned() {
if scope.parent_scope.is_none() {
scope.parent_scope = Some(callsite.source_info.scope);
// FIXME(eddyb) is this really needed?
// (also note that it's always overwritten below)
scope.span = callee_body.span;
}

// FIXME(eddyb) this doesn't seem right at all.
// The inlined source scopes should probably be annotated as
// such, but also contain all of the original information.
scope.span = callsite.source_info.span;
// Mark the outermost callee scope as an inlined one.
assert_eq!(scope.inlined, None);
scope.inlined = Some((callsite.callee, callsite.source_info.span));
}

let idx = caller_body.source_scopes.push(scope);
scope_map.push(idx);
Expand Down
19 changes: 17 additions & 2 deletions src/librustc_mir/util/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,23 @@ fn write_scope_tree(
};

for &child in children {
assert_eq!(body.source_scopes[child].parent_scope, Some(parent));
writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?;
let child_data = &body.source_scopes[child];
assert_eq!(child_data.parent_scope, Some(parent));

if let Some((callee, callsite_span)) = child_data.inlined {
let indented_header =
format!("{0:1$}scope {2} (inlined {3}) {{", "", indent, child.index(), callee);
writeln!(
w,
"{0:1$} // at {2}",
indented_header,
ALIGN,
tcx.sess.source_map().span_to_string(callsite_span),
)?;
} else {
writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?;
}

write_scope_tree(tcx, body, scope_tree, w, child, depth + 1)?;
writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir_build/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ struct Builder<'a, 'tcx> {

/// The vector of all scopes that we have created thus far;
/// we track this for debuginfo later.
source_scopes: IndexVec<SourceScope, SourceScopeData>,
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
source_scope: SourceScope,

/// The guard-context: each time we build the guard expression for
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir_build/build/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.source_scopes.push(SourceScopeData {
span,
parent_scope: Some(parent),
inlined: None,
local_data: ClearCrossCrate::Set(scope_local_data),
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-closure-borrows-arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn foo<T: Copy>(_t: T, q: &i32) -> i32 {
// let mut _9: &i32;
// scope 1 {
// debug x => _3;
// scope 2 {
// scope 2 (inlined foo::<T>::{{closure}}#0) {
// debug r => _8;
// debug _s => _9;
// }
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-closure-captures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn foo<T: Copy>(t: T, q: i32) -> (i32, T) {
// let mut _11: i32;
// scope 1 {
// debug x => _3;
// scope 2 {
// scope 2 (inlined foo::<T>::{{closure}}#0) {
// debug _q => _11;
// debug q => (*((*_6).0: &i32));
// debug t => (*((*_6).1: &T));
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn foo<T: Copy>(_t: T, q: i32) -> i32 {
// let mut _9: i32;
// scope 1 {
// debug x => _3;
// scope 2 {
// scope 2 (inlined foo::<T>::{{closure}}#0) {
// debug _t => _8;
// debug _q => _9;
// }
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-into-box-place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn main() {
// scope 1 {
// debug _x => _1;
// }
// scope 2 {
// scope 2 (inlined std::vec::Vec::<u32>::new) {
// }
// bb0: {
// StorageLive(_1);
Expand Down
2 changes: 1 addition & 1 deletion src/test/mir-opt/inline/inline-specialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<T> Foo for Vec<T> {
// scope 1 {
// debug x => _1;
// }
// scope 2 {
// scope 2 (inlined <std::vec::Vec<()> as Foo>::bar) {
// }
// bb0: {
// StorageLive(_1);
Expand Down
24 changes: 12 additions & 12 deletions src/test/mir-opt/simplify_try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ fn main() {
// scope 2 {
// debug err => _6;
// scope 3 {
// scope 7 {
// scope 7 (inlined <i32 as std::convert::From<i32>>::from) {
// debug t => _6;
// }
// scope 8 {
// scope 8 (inlined <std::result::Result<u32, i32> as std::ops::Try>::from_error) {
// debug v => _6;
// let mut _12: i32;
// }
Expand All @@ -42,7 +42,7 @@ fn main() {
// scope 5 {
// }
// }
// scope 6 {
// scope 6 (inlined <std::result::Result<u32, i32> as std::ops::Try>::into_result) {
// debug self => _1;
// }
// bb0: {
Expand Down Expand Up @@ -87,10 +87,10 @@ fn main() {
// scope 2 {
// debug err => _6;
// scope 3 {
// scope 7 {
// scope 7 (inlined <i32 as std::convert::From<i32>>::from) {
// debug t => _6;
// }
// scope 8 {
// scope 8 (inlined <std::result::Result<u32, i32> as std::ops::Try>::from_error) {
// debug v => _6;
// let mut _12: i32;
// }
Expand All @@ -101,7 +101,7 @@ fn main() {
// scope 5 {
// }
// }
// scope 6 {
// scope 6 (inlined <std::result::Result<u32, i32> as std::ops::Try>::into_result) {
// debug self => _1;
// }
// bb0: {
Expand Down Expand Up @@ -146,10 +146,10 @@ fn main() {
// scope 2 {
// debug err => _6;
// scope 3 {
// scope 7 {
// scope 7 (inlined <i32 as std::convert::From<i32>>::from) {
// debug t => _6;
// }
// scope 8 {
// scope 8 (inlined <std::result::Result<u32, i32> as std::ops::Try>::from_error) {
// debug v => _6;
// let mut _12: i32;
// }
Expand All @@ -160,7 +160,7 @@ fn main() {
// scope 5 {
// }
// }
// scope 6 {
// scope 6 (inlined <std::result::Result<u32, i32> as std::ops::Try>::into_result) {
// debug self => _1;
// }
// bb0: {
Expand Down Expand Up @@ -192,10 +192,10 @@ fn main() {
// scope 2 {
// debug err => _3;
// scope 3 {
// scope 7 {
// scope 7 (inlined <i32 as std::convert::From<i32>>::from) {
// debug t => _3;
// }
// scope 8 {
// scope 8 (inlined <std::result::Result<u32, i32> as std::ops::Try>::from_error) {
// debug v => _3;
// }
// }
Expand All @@ -205,7 +205,7 @@ fn main() {
// scope 5 {
// }
// }
// scope 6 {
// scope 6 (inlined <std::result::Result<u32, i32> as std::ops::Try>::into_result) {
// debug self => _1;
// }
// bb0: {
Expand Down

0 comments on commit 275cb05

Please sign in to comment.