Introduce UsageMap::user_map.

`UsageMap` contains `used_map`, which maps from an item to the item it
uses. This commit add `user_map`, which is the inverse.

We already compute this inverse, but later on, and it is only held as a
local variable. Its simpler and nicer to put it next to `used_map`.
This commit is contained in:
Nicholas Nethercote 2023-06-01 13:00:06 +10:00
parent de2911f454
commit 5b0c56b333
2 changed files with 14 additions and 21 deletions

View File

@ -213,6 +213,9 @@ pub struct UsageMap<'tcx> {
// are represented as a range, which indexes into `used_items`.
used_map: FxHashMap<MonoItem<'tcx>, Range<usize>>,
// Maps every mono item to the mono items that use it.
user_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>>,
// A mono item that is used by N different other mono items will appear
// here N times. Indexed into by the ranges in `used_map`.
used_items: Vec<MonoItem<'tcx>>,
@ -222,7 +225,11 @@ pub struct UsageMap<'tcx> {
impl<'tcx> UsageMap<'tcx> {
fn new() -> UsageMap<'tcx> {
UsageMap { used_map: FxHashMap::default(), used_items: Vec::new() }
UsageMap {
used_map: FxHashMap::default(),
user_map: FxHashMap::default(),
used_items: Vec::new(),
}
}
fn record_used<'a>(
@ -240,11 +247,16 @@ fn record_used<'a>(
for Spanned { node: used_item, .. } in used_items.into_iter() {
self.used_items.push(*used_item);
self.user_map.entry(*used_item).or_default().push(user_item);
}
assert!(self.used_map.insert(user_item, new_items_range).is_none());
}
pub fn get_user_items(&self, item: MonoItem<'tcx>) -> Option<&[MonoItem<'tcx>]> {
self.user_map.get(&item).map(|items| items.as_slice())
}
/// Internally iterate over all inlined items used by `item`.
pub fn for_each_inlined_used_item<F>(&self, tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>, mut f: F)
where
@ -259,16 +271,6 @@ pub fn for_each_inlined_used_item<F>(&self, tcx: TyCtxt<'tcx>, item: MonoItem<'t
}
}
}
/// Internally iterate over each item and the items used by it.
pub fn for_each_item_and_its_used_items<F>(&self, mut f: F)
where
F: FnMut(MonoItem<'tcx>, &[MonoItem<'tcx>]),
{
for (&item, range) in &self.used_map {
f(item, &self.used_items[range.clone()])
}
}
}
#[instrument(skip(tcx, mode), level = "debug")]

View File

@ -514,15 +514,6 @@ fn internalize_symbols<'tcx>(
return;
}
// Build a map from every monomorphization to all the monomorphizations that
// reference it.
let mut user_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
cx.usage_map.for_each_item_and_its_used_items(|user_item, used_items| {
for used_item in used_items {
user_map.entry(*used_item).or_default().push(user_item);
}
});
// For each internalization candidates in each codegen unit, check if it is
// used from outside its defining codegen unit.
for cgu in codegen_units {
@ -535,7 +526,7 @@ fn internalize_symbols<'tcx>(
}
debug_assert_eq!(mono_item_placements[item], home_cgu);
if let Some(user_items) = user_map.get(item) {
if let Some(user_items) = cx.usage_map.get_user_items(*item) {
if user_items
.iter()
.filter_map(|user_item| {