Skip to content

Commit

Permalink
Functions inlined into reachable functions are reachable
Browse files Browse the repository at this point in the history
Consider functions to be reachable for code coverage purposes, either
when they reach the code generation directly, or indirectly as inlined
part of another function.
  • Loading branch information
tmiasko committed Mar 15, 2021
1 parent 1796cc0 commit 5a9538a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Expand Up @@ -284,7 +284,7 @@ fn add_unreachable_coverage<'tcx>(
let all_def_ids: DefIdSet =
tcx.mir_keys(LOCAL_CRATE).iter().map(|local_def_id| local_def_id.to_def_id()).collect();

let (codegenned_def_ids, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
let codegenned_def_ids = tcx.codegened_and_inlined_items(LOCAL_CRATE);

let mut unreachable_def_ids_by_file: FxHashMap<Symbol, Vec<DefId>> = FxHashMap::default();
for &non_codegenned_def_id in all_def_ids.difference(codegenned_def_ids) {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Expand Up @@ -1397,6 +1397,14 @@ rustc_queries! {
query is_codegened_item(def_id: DefId) -> bool {
desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) }
}

/// All items participating in code generation together with items inlined into them.
query codegened_and_inlined_items(_: CrateNum)
-> &'tcx DefIdSet {
eval_always
desc { "codegened_and_inlined_items" }
}

query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
desc { "codegen_unit" }
}
Expand Down
25 changes: 25 additions & 0 deletions compiler/rustc_mir/src/monomorphize/partitioning/mod.rs
Expand Up @@ -424,8 +424,33 @@ fn collect_and_partition_mono_items<'tcx>(
(tcx.arena.alloc(mono_items), codegen_units)
}

fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx DefIdSet {
let (items, cgus) = tcx.collect_and_partition_mono_items(cnum);
let mut visited = DefIdSet::default();
let mut result = items.clone();

for cgu in cgus {
for (item, _) in cgu.items() {
if let MonoItem::Fn(ref instance) = item {
let did = instance.def_id();
if !visited.insert(did) {
continue;
}
for scope in &tcx.instance_mir(instance.def).source_scopes {
if let Some((ref inlined, _)) = scope.inlined {
result.insert(inlined.def_id());
}
}
}
}
}

tcx.arena.alloc(result)
}

pub fn provide(providers: &mut Providers) {
providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
providers.codegened_and_inlined_items = codegened_and_inlined_items;

providers.is_codegened_item = |tcx, def_id| {
let (all_mono_items, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
Expand Down

0 comments on commit 5a9538a

Please sign in to comment.