1
Fork 0

rustc_mir: track inlined callees in SourceScopeData.

This commit is contained in:
Eduard-Mihai Burtescu 2020-02-08 21:31:09 +02:00
parent 708fc0b692
commit 6bc5eafbce
41 changed files with 124 additions and 74 deletions

View file

@ -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,

View file

@ -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.

View file

@ -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);

View file

@ -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())?;
}