mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
coverage: Change query codegened_and_inlined_items
to a plain function
This query has a name that sounds general-purpose, but in fact it has coverage-specific semantics, and (fortunately) is only used by coverage code. Because it is only ever called once (from one designated CGU), it doesn't need to be a query, and we can change it to a regular function instead.
This commit is contained in:
parent
cdeeffde64
commit
6f1ca8d9eb
@ -13,6 +13,7 @@ use rustc_middle::bug;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::coverage::CodeRegion;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::def_id::DefIdSet;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
/// Generates and exports the Coverage Map.
|
||||
@ -313,8 +314,7 @@ fn save_function_record(
|
||||
/// `-Clink-dead-code` will not generate code for unused generic functions.)
|
||||
///
|
||||
/// We can find the unused functions (including generic functions) by the set difference of all MIR
|
||||
/// `DefId`s (`tcx` query `mir_keys`) minus the codegenned `DefId`s (`tcx` query
|
||||
/// `codegened_and_inlined_items`).
|
||||
/// `DefId`s (`tcx` query `mir_keys`) minus the codegenned `DefId`s (`codegenned_and_inlined_items`).
|
||||
///
|
||||
/// These unused functions don't need to be codegenned, but we do need to add them to the function
|
||||
/// coverage map (in a single designated CGU) so that we still emit coverage mappings for them.
|
||||
@ -350,7 +350,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let codegenned_def_ids = tcx.codegened_and_inlined_items(());
|
||||
let codegenned_def_ids = codegenned_and_inlined_items(tcx);
|
||||
|
||||
// For each `DefId` that should have coverage instrumentation but wasn't
|
||||
// codegenned, add it to the function coverage map as an unused function.
|
||||
@ -368,6 +368,37 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// All items participating in code generation together with (instrumented)
|
||||
/// items inlined into them.
|
||||
fn codegenned_and_inlined_items(tcx: TyCtxt<'_>) -> DefIdSet {
|
||||
let (items, cgus) = tcx.collect_and_partition_mono_items(());
|
||||
let mut visited = DefIdSet::default();
|
||||
let mut result = items.clone();
|
||||
|
||||
for cgu in cgus {
|
||||
for item in cgu.items().keys() {
|
||||
if let mir::mono::MonoItem::Fn(ref instance) = item {
|
||||
let did = instance.def_id();
|
||||
if !visited.insert(did) {
|
||||
continue;
|
||||
}
|
||||
let body = tcx.instance_mir(instance.def);
|
||||
for block in body.basic_blocks.iter() {
|
||||
for statement in &block.statements {
|
||||
let mir::StatementKind::Coverage(_) = statement.kind else { continue };
|
||||
let scope = statement.source_info.scope;
|
||||
if let Some(inlined) = scope.inlined_instance(&body.source_scopes) {
|
||||
result.insert(inlined.def_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn declare_unused_fn<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::Instance<'tcx> {
|
||||
ty::Instance::new(
|
||||
def_id,
|
||||
|
@ -1882,12 +1882,6 @@ rustc_queries! {
|
||||
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(_: ()) -> &'tcx DefIdSet {
|
||||
eval_always
|
||||
desc { "collecting codegened and inlined items" }
|
||||
}
|
||||
|
||||
query codegen_unit(sym: Symbol) -> &'tcx CodegenUnit<'tcx> {
|
||||
desc { "getting codegen unit `{sym}`" }
|
||||
}
|
||||
|
@ -105,7 +105,6 @@ use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::DefPathDataName;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::mono::{
|
||||
CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, MonoItem, MonoItemData,
|
||||
Visibility,
|
||||
@ -1279,38 +1278,8 @@ fn dump_mono_items_stats<'tcx>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn codegened_and_inlined_items(tcx: TyCtxt<'_>, (): ()) -> &DefIdSet {
|
||||
let (items, cgus) = tcx.collect_and_partition_mono_items(());
|
||||
let mut visited = DefIdSet::default();
|
||||
let mut result = items.clone();
|
||||
|
||||
for cgu in cgus {
|
||||
for item in cgu.items().keys() {
|
||||
if let MonoItem::Fn(ref instance) = item {
|
||||
let did = instance.def_id();
|
||||
if !visited.insert(did) {
|
||||
continue;
|
||||
}
|
||||
let body = tcx.instance_mir(instance.def);
|
||||
for block in body.basic_blocks.iter() {
|
||||
for statement in &block.statements {
|
||||
let mir::StatementKind::Coverage(_) = statement.kind else { continue };
|
||||
let scope = statement.source_info.scope;
|
||||
if let Some(inlined) = scope.inlined_instance(&body.source_scopes) {
|
||||
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(());
|
||||
|
Loading…
Reference in New Issue
Block a user