Split loop in place_inlined_mono_item.

This loop is doing two different things. For inlined items, it's adding
them to the CGU. For all items, it's recording them in
`mono_item_placements`.

This commit splits it into two separate loops. This avoids putting root
mono items into `reachable`, and removes the low-value check that
`roots` doesn't contain inlined mono items.
This commit is contained in:
Nicholas Nethercote 2023-06-07 09:24:37 +10:00
parent fe3b646565
commit 8dbb3475b9

View File

@ -416,37 +416,35 @@ enum MonoItemPlacement {
fn place_inlined_mono_items<'tcx>( fn place_inlined_mono_items<'tcx>(
cx: &PartitioningCx<'_, 'tcx>, cx: &PartitioningCx<'_, 'tcx>,
codegen_units: &mut [CodegenUnit<'tcx>], codegen_units: &mut [CodegenUnit<'tcx>],
roots: FxHashSet<MonoItem<'tcx>>, _roots: FxHashSet<MonoItem<'tcx>>,
) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> { ) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
let mut mono_item_placements = FxHashMap::default();
let single_codegen_unit = codegen_units.len() == 1;
for cgu in codegen_units.iter_mut() { for cgu in codegen_units.iter_mut() {
// Collect all items that need to be available in this codegen unit. // Collect all inlined items that need to be available in this codegen unit.
let mut reachable = FxHashSet::default(); let mut reachable_inlined_items = FxHashSet::default();
for root in cgu.items().keys() { for root in cgu.items().keys() {
// Insert the root item itself, plus all inlined items that are // Get all inlined items that are reachable from it without going
// reachable from it without going via another root item. // via another root item.
reachable.insert(*root); get_reachable_inlined_items(cx.tcx, *root, cx.usage_map, &mut reachable_inlined_items);
get_reachable_inlined_items(cx.tcx, *root, cx.usage_map, &mut reachable);
} }
// Add all monomorphizations that are not already there. // Add all monomorphizations that are not already there.
for mono_item in reachable { for inlined_item in reachable_inlined_items {
if !cgu.items().contains_key(&mono_item) { assert!(!cgu.items().contains_key(&inlined_item));
if roots.contains(&mono_item) {
bug!("GloballyShared mono-item inlined into other CGU: {:?}", mono_item);
}
// This is a CGU-private copy. // This is a CGU-private copy.
cgu.items_mut().insert(mono_item, (Linkage::Internal, Visibility::Default)); cgu.items_mut().insert(inlined_item, (Linkage::Internal, Visibility::Default));
} }
}
let mut mono_item_placements = FxHashMap::default();
let single_codegen_unit = codegen_units.len() == 1;
for cgu in codegen_units.iter_mut() {
for item in cgu.items().keys() {
if !single_codegen_unit { if !single_codegen_unit {
// If there is more than one codegen unit, we need to keep track // If there is more than one codegen unit, we need to keep track
// in which codegen units each monomorphization is placed. // in which codegen units each monomorphization is placed.
match mono_item_placements.entry(mono_item) { match mono_item_placements.entry(*item) {
Entry::Occupied(e) => { Entry::Occupied(e) => {
let placement = e.into_mut(); let placement = e.into_mut();
debug_assert!(match *placement { debug_assert!(match *placement {