Overhaul CGU formation terminology.
Currently, the code uses multiple words to describe when a mono item `f` uses a mono item `g`, all of which have problems. - `f` references `g`: confusing because there are multiple kinds of use, e.g. "`f` calls `g`" is one, but "`f` takes a (`&T`-style) reference of `g`" is another, and that's two subtly different meanings of "reference" in play. - `f` accesses `g`: meh, "accesses" makes me think of data, and this is code. - `g` is a neighbor (or neighbour) of `f`: is verbose, and doesn't capture the directionality. This commit changes the code to use "`f` uses `g`" everywhere. I think it's better than the current terminology, and the consistency is important. Also, `InliningMap` is renamed `UsageMap` because (a) it was always mostly about usage, and (b) the inlining information it did record was removed in a recent commit.
This commit is contained in:
parent
f85ab544df
commit
de2911f454
2 changed files with 115 additions and 120 deletions
|
@ -115,14 +115,14 @@ use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt};
|
|||
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
use crate::collector::InliningMap;
|
||||
use crate::collector::UsageMap;
|
||||
use crate::collector::{self, MonoItemCollectionMode};
|
||||
use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode};
|
||||
|
||||
struct PartitioningCx<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
target_cgu_count: usize,
|
||||
inlining_map: &'a InliningMap<'tcx>,
|
||||
usage_map: &'a UsageMap<'tcx>,
|
||||
}
|
||||
|
||||
struct PlacedRootMonoItems<'tcx> {
|
||||
|
@ -138,14 +138,14 @@ fn partition<'tcx, I>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
mono_items: &mut I,
|
||||
max_cgu_count: usize,
|
||||
inlining_map: &InliningMap<'tcx>,
|
||||
usage_map: &UsageMap<'tcx>,
|
||||
) -> Vec<CodegenUnit<'tcx>>
|
||||
where
|
||||
I: Iterator<Item = MonoItem<'tcx>>,
|
||||
{
|
||||
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning");
|
||||
|
||||
let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map };
|
||||
let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, usage_map };
|
||||
|
||||
// In the first step, we place all regular monomorphizations into their
|
||||
// respective 'home' codegen unit. Regular monomorphizations are all
|
||||
|
@ -405,7 +405,7 @@ fn merge_codegen_units<'tcx>(
|
|||
}
|
||||
|
||||
/// For symbol internalization, we need to know whether a symbol/mono-item is
|
||||
/// accessed from outside the codegen unit it is defined in. This type is used
|
||||
/// used from outside the codegen unit it is defined in. This type is used
|
||||
/// to keep track of that.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
enum MonoItemPlacement {
|
||||
|
@ -426,7 +426,7 @@ fn place_inlined_mono_items<'tcx>(
|
|||
// Collect all items that need to be available in this codegen unit.
|
||||
let mut reachable = FxHashSet::default();
|
||||
for root in old_codegen_unit.items().keys() {
|
||||
follow_inlining(cx.tcx, *root, cx.inlining_map, &mut reachable);
|
||||
follow_inlining(cx.tcx, *root, cx.usage_map, &mut reachable);
|
||||
}
|
||||
|
||||
let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
|
||||
|
@ -481,16 +481,16 @@ fn place_inlined_mono_items<'tcx>(
|
|||
|
||||
fn follow_inlining<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mono_item: MonoItem<'tcx>,
|
||||
inlining_map: &InliningMap<'tcx>,
|
||||
item: MonoItem<'tcx>,
|
||||
usage_map: &UsageMap<'tcx>,
|
||||
visited: &mut FxHashSet<MonoItem<'tcx>>,
|
||||
) {
|
||||
if !visited.insert(mono_item) {
|
||||
if !visited.insert(item) {
|
||||
return;
|
||||
}
|
||||
|
||||
inlining_map.with_inlining_candidates(tcx, mono_item, |target| {
|
||||
follow_inlining(tcx, target, inlining_map, visited);
|
||||
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
|
||||
follow_inlining(tcx, inlined_item, usage_map, visited);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ fn internalize_symbols<'tcx>(
|
|||
if codegen_units.len() == 1 {
|
||||
// Fast path for when there is only one codegen unit. In this case we
|
||||
// can internalize all candidates, since there is nowhere else they
|
||||
// could be accessed from.
|
||||
// could be used from.
|
||||
for cgu in codegen_units {
|
||||
for candidate in &internalization_candidates {
|
||||
cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default));
|
||||
|
@ -516,43 +516,43 @@ fn internalize_symbols<'tcx>(
|
|||
|
||||
// Build a map from every monomorphization to all the monomorphizations that
|
||||
// reference it.
|
||||
let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
|
||||
cx.inlining_map.iter_accesses(|accessor, accessees| {
|
||||
for accessee in accessees {
|
||||
accessor_map.entry(*accessee).or_default().push(accessor);
|
||||
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
|
||||
// accessed from outside its defining codegen unit.
|
||||
// used from outside its defining codegen unit.
|
||||
for cgu in codegen_units {
|
||||
let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
|
||||
|
||||
for (accessee, linkage_and_visibility) in cgu.items_mut() {
|
||||
if !internalization_candidates.contains(accessee) {
|
||||
for (item, linkage_and_visibility) in cgu.items_mut() {
|
||||
if !internalization_candidates.contains(item) {
|
||||
// This item is no candidate for internalizing, so skip it.
|
||||
continue;
|
||||
}
|
||||
debug_assert_eq!(mono_item_placements[accessee], home_cgu);
|
||||
debug_assert_eq!(mono_item_placements[item], home_cgu);
|
||||
|
||||
if let Some(accessors) = accessor_map.get(accessee) {
|
||||
if accessors
|
||||
if let Some(user_items) = user_map.get(item) {
|
||||
if user_items
|
||||
.iter()
|
||||
.filter_map(|accessor| {
|
||||
// Some accessors might not have been
|
||||
.filter_map(|user_item| {
|
||||
// Some user mono items might not have been
|
||||
// instantiated. We can safely ignore those.
|
||||
mono_item_placements.get(accessor)
|
||||
mono_item_placements.get(user_item)
|
||||
})
|
||||
.any(|placement| *placement != home_cgu)
|
||||
{
|
||||
// Found an accessor from another CGU, so skip to the next
|
||||
// item without marking this one as internal.
|
||||
// Found a user from another CGU, so skip to the next item
|
||||
// without marking this one as internal.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, we did not find any accesses from other CGUs,
|
||||
// so it's fine to make this monomorphization internal.
|
||||
// If we got here, we did not find any uses from other CGUs, so
|
||||
// it's fine to make this monomorphization internal.
|
||||
*linkage_and_visibility = (Linkage::Internal, Visibility::Default);
|
||||
}
|
||||
}
|
||||
|
@ -788,7 +788,7 @@ fn mono_item_visibility<'tcx>(
|
|||
} else {
|
||||
// If this isn't a generic function then we mark this a `Default` if
|
||||
// this is a reachable item, meaning that it's a symbol other crates may
|
||||
// access when they link to us.
|
||||
// use when they link to us.
|
||||
if tcx.is_reachable_non_generic(def_id.to_def_id()) {
|
||||
*can_be_internalized = false;
|
||||
debug_assert!(!is_generic);
|
||||
|
@ -968,7 +968,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
|
|||
}
|
||||
};
|
||||
|
||||
let (items, inlining_map) = collector::collect_crate_mono_items(tcx, collection_mode);
|
||||
let (items, usage_map) = collector::collect_crate_mono_items(tcx, collection_mode);
|
||||
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
|
@ -979,7 +979,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
|
|||
tcx,
|
||||
&mut items.iter().copied(),
|
||||
tcx.sess.codegen_units(),
|
||||
&inlining_map,
|
||||
&usage_map,
|
||||
);
|
||||
codegen_units[0].make_primary();
|
||||
&*tcx.arena.alloc_from_iter(codegen_units)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue