rustc_mir: track inlined callees in SourceScopeData.
This commit is contained in:
parent
708fc0b692
commit
6bc5eafbce
41 changed files with 124 additions and 74 deletions
|
@ -212,7 +212,12 @@ fn new_body<'tcx>(
|
|||
source,
|
||||
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,
|
||||
|
|
|
@ -313,7 +313,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>>,
|
||||
// Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store
|
||||
// the last known `SourceInfo` here and just keep revisiting it.
|
||||
|
|
|
@ -112,7 +112,7 @@ impl Inliner<'tcx> {
|
|||
|
||||
let callee_body = if let Some(callee_def_id) = callsite.callee.def_id().as_local() {
|
||||
let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_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 `HirId` 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. Also avoid inlining into generators,
|
||||
|
@ -442,15 +442,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);
|
||||
|
|
|
@ -548,8 +548,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())?;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue