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 ee4a56e

Browse files
committedNov 17, 2024
Auto merge of #132566 - saethlin:querify-mir-collection, r=cjgillot
Querify MonoItem collection Factored out of #131650. These changes are required for post-mono MIR opts, because the previous implementation would load the MIR for every Instance that we traverse (as well as invoke queries on it). The cost of that would grow massively with post-mono MIR opts because we'll need to load new MIR for every Instance, instead of re-using the `optimized_mir` for every Instance with the same DefId. So the approach here is to add two new queries, `items_of_instance` and `size_estimate`, which contain the specific information about an Instance's MIR that MirUsedCollector and CGU partitioning need, respectively. Caching these significantly increases the size of the query cache, but that's justified by our improved incrementality (I'm sure walking all the MIR for a huge crate scales quite poorly). This also changes `MonoItems` into a type that will retain the traversal order (otherwise we perturb a bunch of diagnostics), and will also eliminate duplicate findings. Eliminating duplicates removes about a quarter of the query cache size growth. The perf improvements in this PR are inflated because rustc-perf uses `-Zincremental-verify-ich`, which makes loading MIR a lot slower because MIR contains a lot of Spans and computing the stable hash of a Span is slow. And the primary goal of this PR is to load less MIR. Some squinting at `collector profile_local perf-record +stage1` runs suggests the magnitude of the improvements in this PR would be decreased by between a third and a half if that flag weren't being used. Though this effect may apply to the regressions too since most are incr-full and this change also causes such builds to encode more Spans.
2 parents 5afd5ad + f6e913b commit ee4a56e

File tree

9 files changed

+165
-67
lines changed

9 files changed

+165
-67
lines changed
 

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

+20-15
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub enum InstantiationMode {
4646
LocalCopy,
4747
}
4848

49-
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable)]
49+
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable, TyEncodable, TyDecodable)]
5050
pub enum MonoItem<'tcx> {
5151
Fn(Instance<'tcx>),
5252
Static(DefId),
@@ -66,20 +66,7 @@ impl<'tcx> MonoItem<'tcx> {
6666
// change NON_INCR_MIN_CGU_SIZE as well.
6767
pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
6868
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-
}
69+
MonoItem::Fn(instance) => tcx.size_estimate(instance),
8370
// Conservatively estimate the size of a static declaration or
8471
// assembly item to be 1.
8572
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1,
@@ -556,3 +543,21 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> {
556543
Symbol::intern(&cgu_name)
557544
}
558545
}
546+
547+
/// See module-level docs of `rustc_monomorphize::collector` on some context for "mentioned" items.
548+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
549+
pub enum CollectionMode {
550+
/// Collect items that are used, i.e., actually needed for codegen.
551+
///
552+
/// Which items are used can depend on optimization levels, as MIR optimizations can remove
553+
/// uses.
554+
UsedItems,
555+
/// Collect items that are mentioned. The goal of this mode is that it is independent of
556+
/// optimizations: the set of "mentioned" items is computed before optimizations are run.
557+
///
558+
/// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
559+
/// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
560+
/// might decide to run them before computing mentioned items.) The key property of this set is
561+
/// that it is optimization-independent.
562+
MentionedItems,
563+
}

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

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

219+
impl<T0, T1> EraseType for (&'_ [T0], &'_ [T1]) {
220+
type Result = [u8; size_of::<(&'static [()], &'static [()])>()];
221+
}
222+
219223
impl<T0> EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) {
220224
type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()];
221225
}

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

+9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_span::symbol::{Ident, Symbol};
77
use rustc_span::{DUMMY_SP, Span};
88

99
use crate::infer::canonical::CanonicalQueryInput;
10+
use crate::mir::mono::CollectionMode;
1011
use crate::ty::fast_reject::SimplifiedType;
1112
use crate::ty::layout::{TyAndLayout, ValidityRequirement};
1213
use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
@@ -590,3 +591,11 @@ impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) {
590591
}
591592
}
592593
}
594+
595+
impl<'tcx> Key for (ty::Instance<'tcx>, CollectionMode) {
596+
type Cache<V> = DefaultCache<Self, V>;
597+
598+
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
599+
self.0.default_span(tcx)
600+
}
601+
}

‎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::spec::PanicStrategy;
@@ -59,7 +60,7 @@ use crate::mir::interpret::{
5960
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
6061
EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput,
6162
};
62-
use crate::mir::mono::CodegenUnit;
63+
use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem};
6364
use crate::query::erase::{Erase, erase, restore};
6465
use crate::query::plumbing::{
6566
CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at,
@@ -2339,6 +2340,16 @@ rustc_queries! {
23392340
arena_cache
23402341
desc { "functions to skip for move-size check" }
23412342
}
2343+
2344+
query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
2345+
desc { "collecting items used by `{}`", key.0 }
2346+
cache_on_disk_if { true }
2347+
}
2348+
2349+
query size_estimate(key: ty::Instance<'tcx>) -> usize {
2350+
desc { "estimating codegen size of `{}`", key }
2351+
cache_on_disk_if { true }
2352+
}
23422353
}
23432354

23442355
rustc_query_append! { define_callbacks! }

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_index::{Idx, IndexVec};
1212
use rustc_macros::{Decodable, Encodable};
1313
use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
1414
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
15+
use rustc_middle::mir::mono::MonoItem;
1516
use rustc_middle::mir::{self, interpret};
1617
use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
1718
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -22,7 +23,7 @@ use rustc_session::Session;
2223
use rustc_span::hygiene::{
2324
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
2425
};
25-
use rustc_span::source_map::SourceMap;
26+
use rustc_span::source_map::{SourceMap, Spanned};
2627
use rustc_span::{
2728
BytePos, CachingSourceMapView, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span,
2829
SpanDecoder, SpanEncoder, StableSourceFileId, Symbol,
@@ -773,6 +774,13 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsm
773774
}
774775
}
775776

777+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Spanned<MonoItem<'tcx>>] {
778+
#[inline]
779+
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
780+
RefDecodable::decode(d)
781+
}
782+
}
783+
776784
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
777785
for &'tcx crate::traits::specialization_graph::Graph
778786
{

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

+11
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ use std::marker::DiscriminantKind;
1313
use rustc_abi::{FieldIdx, VariantIdx};
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_hir::def_id::LocalDefId;
16+
use rustc_middle::mir::mono::MonoItem;
1617
use rustc_middle::ty::TyCtxt;
1718
use rustc_serialize::{Decodable, Encodable};
1819
use rustc_span::Span;
20+
use rustc_span::source_map::Spanned;
1921
pub use rustc_type_ir::{TyDecoder, TyEncoder};
2022

2123
use crate::arena::ArenaAllocatable;
@@ -397,6 +399,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
397399
}
398400
}
399401

402+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [Spanned<MonoItem<'tcx>>] {
403+
fn decode(decoder: &mut D) -> &'tcx Self {
404+
decoder
405+
.interner()
406+
.arena
407+
.alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
408+
}
409+
}
410+
400411
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
401412
for ty::List<ty::BoundVariableKind>
402413
{
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.