Move dead CGU marking code out of partition.

The other major steps in `partition` have their own function, so it's
nice for this one to be likewise.
This commit is contained in:
Nicholas Nethercote 2023-06-15 09:37:36 +10:00
parent 0b475c705f
commit 9d7295f0be

View File

@ -197,34 +197,8 @@ fn partition<'tcx, I>(
let instrument_dead_code =
tcx.sess.instrument_coverage() && !tcx.sess.instrument_coverage_except_unused_functions();
if instrument_dead_code {
assert!(
codegen_units.len() > 0,
"There must be at least one CGU that code coverage data can be generated in."
);
// Find the smallest CGU that has exported symbols and put the dead
// function stubs in that CGU. We look for exported symbols to increase
// the likelihood the linker won't throw away the dead functions.
// FIXME(#92165): In order to truly resolve this, we need to make sure
// the object file (CGU) containing the dead function stubs is included
// in the final binary. This will probably require forcing these
// function symbols to be included via `-u` or `/include` linker args.
let mut cgus: Vec<_> = codegen_units.iter_mut().collect();
cgus.sort_by_key(|cgu| cgu.size_estimate());
let dead_code_cgu =
if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
}) {
cgu
} else {
// If there are no CGUs that have externally linked items,
// then we just pick the first CGU as a fallback.
&mut codegen_units[0]
};
dead_code_cgu.make_code_coverage_dead_code_cgu();
mark_code_coverage_dead_code_cgu(&mut codegen_units);
}
// Ensure CGUs are sorted by name, so that we get deterministic results.
@ -545,6 +519,33 @@ enum MonoItemPlacement {
}
}
fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>]) {
assert!(!codegen_units.is_empty());
// Find the smallest CGU that has exported symbols and put the dead
// function stubs in that CGU. We look for exported symbols to increase
// the likelihood the linker won't throw away the dead functions.
// FIXME(#92165): In order to truly resolve this, we need to make sure
// the object file (CGU) containing the dead function stubs is included
// in the final binary. This will probably require forcing these
// function symbols to be included via `-u` or `/include` linker args.
let mut cgus: Vec<&mut CodegenUnit<'tcx>> = codegen_units.iter_mut().collect();
cgus.sort_by_key(|cgu| cgu.size_estimate());
let dead_code_cgu = if let Some(cgu) = cgus
.into_iter()
.rev()
.find(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
{
cgu
} else {
// If there are no CGUs that have externally linked items,
// then we just pick the first CGU as a fallback.
&mut codegen_units[0]
};
dead_code_cgu.make_code_coverage_dead_code_cgu();
}
fn characteristic_def_id_of_mono_item<'tcx>(
tcx: TyCtxt<'tcx>,
mono_item: MonoItem<'tcx>,