[code coverage] Fix missing dead code in modules that are never called

The issue here is that the logic used to determine which CGU to put the
dead function stubs in doesn't handle cases where a module is never
assigned to a CGU.

The partitioning logic also caused issues in #85461 where inline
functions were duplicated into multiple CGUs resulting in duplicate
symbols.

This commit fixes the issue by removing the complex logic used to assign
dead code stubs to CGUs and replaces it with a much simplier model: we
pick one CGU to hold all the dead code stubs. We pick a CGU which has
exported items which increases the likelihood the linker won't throw
away our dead functions and we pick the smallest to minimize the impact
on compilation times for crates with very large CGUs.

Fixes #86177
Fixes #85718
Fixes #79622
This commit is contained in:
Wesley Wiser 2021-12-20 16:36:56 -05:00
parent 341d65d975
commit ef57f249a2
8 changed files with 76 additions and 121 deletions

View file

@ -9,7 +9,6 @@ use rustc_span::def_id::DefId;
/// A `query` provider for retrieving coverage information injected into MIR.
pub(crate) fn provide(providers: &mut Providers) {
providers.coverageinfo = |tcx, def_id| coverageinfo(tcx, def_id);
providers.covered_file_name = |tcx, def_id| covered_file_name(tcx, def_id);
providers.covered_code_regions = |tcx, def_id| covered_code_regions(tcx, def_id);
}
@ -137,25 +136,6 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) ->
coverage_visitor.info
}
fn covered_file_name(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
if tcx.is_mir_available(def_id) {
let body = mir_body(tcx, def_id);
for bb_data in body.basic_blocks().iter() {
for statement in bb_data.statements.iter() {
if let StatementKind::Coverage(box ref coverage) = statement.kind {
if let Some(code_region) = coverage.code_region.as_ref() {
if is_inlined(body, statement) {
continue;
}
return Some(code_region.file_name);
}
}
}
}
}
return None;
}
fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
let body = mir_body(tcx, def_id);
body.basic_blocks()