Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2c06ca1

Browse files
committedNov 3, 2024
Auto merge of #132566 - saethlin:querify-mir-collection, r=
Querify mir collection Factored out of #131650, these changes are required for post-mono MIR opts but I want to benchmark them on their own so that I can tune the implementation. r? ghost
2 parents 7028d93 + 785a96b commit 2c06ca1

File tree

7 files changed

+100
-54
lines changed

7 files changed

+100
-54
lines changed
 

‎compiler/rustc_middle/src/mir/mono.rs

+47-24
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_target::spec::SymbolVisibility;
1919
use tracing::debug;
2020

2121
use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
22+
use crate::query::Providers;
2223
use crate::ty::{GenericArgs, Instance, InstanceKind, SymbolName, TyCtxt};
2324

2425
/// Describes how a monomorphization will be instantiated in object files.
@@ -62,30 +63,6 @@ impl<'tcx> MonoItem<'tcx> {
6263
}
6364
}
6465

65-
// Note: if you change how item size estimates work, you might need to
66-
// change NON_INCR_MIN_CGU_SIZE as well.
67-
pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
68-
match *self {
69-
MonoItem::Fn(instance) => {
70-
match instance.def {
71-
// "Normal" functions size estimate: the number of
72-
// statements, plus one for the terminator.
73-
InstanceKind::Item(..)
74-
| InstanceKind::DropGlue(..)
75-
| InstanceKind::AsyncDropGlueCtorShim(..) => {
76-
let mir = tcx.instance_mir(instance.def);
77-
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
78-
}
79-
// Other compiler-generated shims size estimate: 1
80-
_ => 1,
81-
}
82-
}
83-
// Conservatively estimate the size of a static declaration or
84-
// assembly item to be 1.
85-
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
86-
}
87-
}
88-
8966
pub fn is_generic_fn(&self) -> bool {
9067
match self {
9168
MonoItem::Fn(instance) => instance.args.non_erasable_generics().next().is_some(),
@@ -556,3 +533,49 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
556533
Symbol::intern(&cgu_name)
557534
}
558535
}
536+
537+
/// See module-level docs on some contect for "mentioned" items.
538+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
539+
pub enum CollectionMode {
540+
/// Collect items that are used, i.e., actually needed for codegen.
541+
///
542+
/// Which items are used can depend on optimization levels, as MIR optimizations can remove
543+
/// uses.
544+
UsedItems,
545+
/// Collect items that are mentioned. The goal of this mode is that it is independent of
546+
/// optimizations: the set of "mentioned" items is computed before optimizations are run.
547+
///
548+
/// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
549+
/// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
550+
/// might decide to run them before computing mentioned items.) The key property of this set is
551+
/// that it is optimization-independent.
552+
MentionedItems,
553+
}
554+
555+
// Note: if you change how item size estimates work, you might need to
556+
// change NON_INCR_MIN_CGU_SIZE as well.
557+
fn size_estimate<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> usize {
558+
match item {
559+
MonoItem::Fn(instance) => {
560+
match instance.def {
561+
// "Normal" functions size estimate: the number of
562+
// statements, plus one for the terminator.
563+
InstanceKind::Item(..)
564+
| InstanceKind::DropGlue(..)
565+
| InstanceKind::AsyncDropGlueCtorShim(..) => {
566+
let mir = tcx.instance_mir(instance.def);
567+
mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
568+
}
569+
// Other compiler-generated shims size estimate: 1
570+
_ => 1,
571+
}
572+
}
573+
// Conservatively estimate the size of a static declaration or
574+
// assembly item to be 1.
575+
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
576+
}
577+
}
578+
579+
pub fn provide(providers: &mut Providers) {
580+
providers.size_estimate = size_estimate;
581+
}

‎compiler/rustc_middle/src/query/erase.rs

+4
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) {
218218
type Result = [u8; size_of::<(&'static (), &'static [()])>()];
219219
}
220220

221+
impl<T0, T1> EraseType for (&'_ [T0], &'_ [T1]) {
222+
type Result = [u8; size_of::<(&'static [()], &'static [()])>()];
223+
}
224+
221225
impl<T0> EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) {
222226
type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()];
223227
}

‎compiler/rustc_middle/src/query/keys.rs

+18
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use rustc_span::{DUMMY_SP, Span};
88
use rustc_target::abi;
99

1010
use crate::infer::canonical::CanonicalQueryInput;
11+
use crate::mir::mono::CollectionMode;
12+
use crate::query::MonoItem;
1113
use crate::ty::fast_reject::SimplifiedType;
1214
use crate::ty::layout::{TyAndLayout, ValidityRequirement};
1315
use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
@@ -86,6 +88,14 @@ impl<'tcx> Key for ty::Instance<'tcx> {
8688
}
8789
}
8890

91+
impl<'tcx> Key for MonoItem<'tcx> {
92+
type Cache<V> = DefaultCache<Self, V>;
93+
94+
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
95+
tcx.def_span(self.def_id())
96+
}
97+
}
98+
8999
impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
90100
type Cache<V> = DefaultCache<Self, V>;
91101

@@ -591,3 +601,11 @@ impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) {
591601
}
592602
}
593603
}
604+
605+
impl<'tcx> Key for (ty::Instance<'tcx>, CollectionMode) {
606+
type Cache<V> = DefaultCache<Self, V>;
607+
608+
fn default_span(&self, _: TyCtxt<'_>) -> Span {
609+
DUMMY_SP
610+
}
611+
}

‎compiler/rustc_middle/src/query/mod.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc_session::cstore::{
4040
};
4141
use rustc_session::lint::LintExpectationId;
4242
use rustc_span::def_id::LOCAL_CRATE;
43+
use rustc_span::source_map::Spanned;
4344
use rustc_span::symbol::Symbol;
4445
use rustc_span::{DUMMY_SP, Span};
4546
use rustc_target::abi;
@@ -60,7 +61,7 @@ use crate::mir::interpret::{
6061
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
6162
EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput,
6263
};
63-
use crate::mir::mono::CodegenUnit;
64+
use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem};
6465
use crate::query::erase::{Erase, erase, restore};
6566
use crate::query::plumbing::{
6667
CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at,
@@ -2315,6 +2316,16 @@ rustc_queries! {
23152316
desc { "whether the item should be made inlinable across crates" }
23162317
separate_provide_extern
23172318
}
2319+
2320+
query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
2321+
desc { "collecting used items" }
2322+
cache_on_disk_if { true }
2323+
}
2324+
2325+
query size_estimate(key: MonoItem<'tcx>) -> usize {
2326+
desc { "estimating codegen size" }
2327+
cache_on_disk_if { true }
2328+
}
23182329
}
23192330

23202331
rustc_query_append! { define_callbacks! }

‎compiler/rustc_middle/src/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,7 @@ pub fn provide(providers: &mut Providers) {
21552155
print::provide(providers);
21562156
super::util::bug::provide(providers);
21572157
super::middle::provide(providers);
2158+
super::mir::mono::provide(providers);
21582159
*providers = Providers {
21592160
trait_impls_of: trait_def::trait_impls_of_provider,
21602161
incoherent_impls: trait_def::incoherent_impls_provider,

‎compiler/rustc_monomorphize/src/collector.rs

+15-26
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
219219
use rustc_hir::lang_items::LangItem;
220220
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
221221
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar};
222-
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
222+
use rustc_middle::mir::mono::{CollectionMode, InstantiationMode, MonoItem};
223223
use rustc_middle::mir::visit::Visitor as MirVisitor;
224224
use rustc_middle::mir::{self, Location, MentionedItem, traversal};
225225
use rustc_middle::query::TyCtxtAt;
@@ -268,24 +268,6 @@ struct SharedState<'tcx> {
268268
usage_map: MTLock<UsageMap<'tcx>>,
269269
}
270270

271-
/// See module-level docs on some contect for "mentioned" items.
272-
#[derive(Copy, Clone, Debug, PartialEq)]
273-
enum CollectionMode {
274-
/// Collect items that are used, i.e., actually needed for codegen.
275-
///
276-
/// Which items are used can depend on optimization levels, as MIR optimizations can remove
277-
/// uses.
278-
UsedItems,
279-
/// Collect items that are mentioned. The goal of this mode is that it is independent of
280-
/// optimizations: the set of "mentioned" items is computed before optimizations are run.
281-
///
282-
/// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
283-
/// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
284-
/// might decide to run them before computing mentioned items.) The key property of this set is
285-
/// that it is optimization-independent.
286-
MentionedItems,
287-
}
288-
289271
impl<'tcx> UsageMap<'tcx> {
290272
fn new() -> UsageMap<'tcx> {
291273
UsageMap { used_map: Default::default(), user_map: Default::default() }
@@ -447,13 +429,9 @@ fn collect_items_rec<'tcx>(
447429
));
448430

449431
rustc_data_structures::stack::ensure_sufficient_stack(|| {
450-
collect_items_of_instance(
451-
tcx,
452-
instance,
453-
&mut used_items,
454-
&mut mentioned_items,
455-
mode,
456-
)
432+
let (used, mentioned) = tcx.items_of_instance((instance, mode));
433+
used_items.extend(used);
434+
mentioned_items.extend(mentioned);
457435
});
458436
}
459437
MonoItem::GlobalAsm(item_id) => {
@@ -1253,6 +1231,16 @@ fn collect_items_of_instance<'tcx>(
12531231
}
12541232
}
12551233

1234+
fn items_of_instance<'tcx>(
1235+
tcx: TyCtxt<'tcx>,
1236+
(instance, mode): (Instance<'tcx>, CollectionMode),
1237+
) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
1238+
let mut used_items = MonoItems::default();
1239+
let mut mentioned_items = MonoItems::default();
1240+
collect_items_of_instance(tcx, instance, &mut used_items, &mut mentioned_items, mode);
1241+
(tcx.arena.alloc_slice(&used_items), tcx.arena.alloc_slice(&mentioned_items))
1242+
}
1243+
12561244
/// `item` must be already monomorphized.
12571245
#[instrument(skip(tcx, span, output), level = "debug")]
12581246
fn visit_mentioned_item<'tcx>(
@@ -1623,4 +1611,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
16231611

16241612
pub(crate) fn provide(providers: &mut Providers) {
16251613
providers.hooks.should_codegen_locally = should_codegen_locally;
1614+
providers.items_of_instance = items_of_instance;
16261615
}

‎compiler/rustc_monomorphize/src/partitioning.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ where
254254
if visibility == Visibility::Hidden && can_be_internalized {
255255
internalization_candidates.insert(mono_item);
256256
}
257-
let size_estimate = mono_item.size_estimate(cx.tcx);
257+
let size_estimate = cx.tcx.size_estimate(mono_item);
258258

259259
cgu.items_mut().insert(mono_item, MonoItemData {
260260
inlined: false,
@@ -279,7 +279,7 @@ where
279279
inlined: true,
280280
linkage: Linkage::Internal,
281281
visibility: Visibility::Default,
282-
size_estimate: inlined_item.size_estimate(cx.tcx),
282+
size_estimate: cx.tcx.size_estimate(inlined_item),
283283
});
284284
}
285285
}
@@ -1274,7 +1274,7 @@ fn dump_mono_items_stats<'tcx>(
12741274
.map(|(def_id, items)| {
12751275
let name = with_no_trimmed_paths!(tcx.def_path_str(def_id));
12761276
let instantiation_count = items.len();
1277-
let size_estimate = items[0].size_estimate(tcx);
1277+
let size_estimate = tcx.size_estimate(*items[0]);
12781278
let total_estimate = instantiation_count * size_estimate;
12791279
MonoItem { name, instantiation_count, size_estimate, total_estimate }
12801280
})

0 commit comments

Comments
 (0)
Failed to load comments.