Skip to content

Commit 076a0a2

Browse files
committed
Auto merge of #143013 - bjorn3:split_exported_symbols, r=oli-obk
Split exported_symbols for generic and non-generic symbols This reduces metadata decoder overhead during the monomorphization collector.
2 parents 86e05cd + 753c73a commit 076a0a2

File tree

10 files changed

+86
-37
lines changed

10 files changed

+86
-37
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1794,7 +1794,10 @@ fn for_each_exported_symbols_include_dep<'tcx>(
17941794
for (cnum, dep_format) in deps.iter_enumerated() {
17951795
// For each dependency that we are linking to statically ...
17961796
if *dep_format == Linkage::Static {
1797-
for &(symbol, info) in tcx.exported_symbols(cnum).iter() {
1797+
for &(symbol, info) in tcx.exported_non_generic_symbols(cnum).iter() {
1798+
callback(symbol, info, cnum);
1799+
}
1800+
for &(symbol, info) in tcx.exported_generic_symbols(cnum).iter() {
17981801
callback(symbol, info, cnum);
17991802
}
18001803
}

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> b
168168
tcx.reachable_non_generics(def_id.krate).contains_key(&def_id)
169169
}
170170

171-
fn exported_symbols_provider_local<'tcx>(
171+
fn exported_non_generic_symbols_provider_local<'tcx>(
172172
tcx: TyCtxt<'tcx>,
173173
_: LocalCrate,
174174
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
@@ -306,6 +306,22 @@ fn exported_symbols_provider_local<'tcx>(
306306
));
307307
}
308308

309+
// Sort so we get a stable incr. comp. hash.
310+
symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx));
311+
312+
tcx.arena.alloc_from_iter(symbols)
313+
}
314+
315+
fn exported_generic_symbols_provider_local<'tcx>(
316+
tcx: TyCtxt<'tcx>,
317+
_: LocalCrate,
318+
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
319+
if !tcx.sess.opts.output_types.should_codegen() && !tcx.is_sdylib_interface_build() {
320+
return &[];
321+
}
322+
323+
let mut symbols: Vec<_> = vec![];
324+
309325
if tcx.local_crate_exports_generics() {
310326
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
311327
use rustc_middle::ty::InstanceKind;
@@ -474,7 +490,7 @@ fn upstream_monomorphizations_provider(
474490
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();
475491

476492
for &cnum in cnums.iter() {
477-
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
493+
for (exported_symbol, _) in tcx.exported_generic_symbols(cnum).iter() {
478494
let (def_id, args) = match *exported_symbol {
479495
ExportedSymbol::Generic(def_id, args) => (def_id, args),
480496
ExportedSymbol::DropGlue(ty) => {
@@ -496,10 +512,7 @@ fn upstream_monomorphizations_provider(
496512
ExportedSymbol::AsyncDropGlue(def_id, ty) => (def_id, tcx.mk_args(&[ty.into()])),
497513
ExportedSymbol::NonGeneric(..)
498514
| ExportedSymbol::ThreadLocalShim(..)
499-
| ExportedSymbol::NoDefId(..) => {
500-
// These are no monomorphizations
501-
continue;
502-
}
515+
| ExportedSymbol::NoDefId(..) => unreachable!("{exported_symbol:?}"),
503516
};
504517

505518
let args_map = instances.entry(def_id).or_default();
@@ -554,7 +567,8 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId)
554567
pub(crate) fn provide(providers: &mut Providers) {
555568
providers.reachable_non_generics = reachable_non_generics_provider;
556569
providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
557-
providers.exported_symbols = exported_symbols_provider_local;
570+
providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local;
571+
providers.exported_generic_symbols = exported_generic_symbols_provider_local;
558572
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
559573
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
560574
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,8 +1124,9 @@ fn start_executing_work<B: ExtraBackendMethods>(
11241124

11251125
let copy_symbols = |cnum| {
11261126
let symbols = tcx
1127-
.exported_symbols(cnum)
1127+
.exported_non_generic_symbols(cnum)
11281128
.iter()
1129+
.chain(tcx.exported_generic_symbols(cnum))
11291130
.map(|&(s, lvl)| (symbol_name_for_instance_in_crate(tcx, s, cnum), lvl))
11301131
.collect();
11311132
Arc::new(symbols)

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,11 +1510,18 @@ impl<'a> CrateMetadataRef<'a> {
15101510
.map(move |v| (self.local_def_id(v.0), v.1))
15111511
}
15121512

1513-
fn exported_symbols<'tcx>(
1513+
fn exported_non_generic_symbols<'tcx>(
15141514
self,
15151515
tcx: TyCtxt<'tcx>,
15161516
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
1517-
tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
1517+
tcx.arena.alloc_from_iter(self.root.exported_non_generic_symbols.decode((self, tcx)))
1518+
}
1519+
1520+
fn exported_generic_symbols<'tcx>(
1521+
self,
1522+
tcx: TyCtxt<'tcx>,
1523+
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
1524+
tcx.arena.alloc_from_iter(self.root.exported_generic_symbols.decode((self, tcx)))
15181525
}
15191526

15201527
fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ provide! { tcx, def_id, other, cdata,
358358
specialization_enabled_in => { cdata.root.specialization_enabled_in }
359359
reachable_non_generics => {
360360
let reachable_non_generics = tcx
361-
.exported_symbols(cdata.cnum)
361+
.exported_non_generic_symbols(cdata.cnum)
362362
.iter()
363363
.filter_map(|&(exported_symbol, export_info)| {
364364
if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
@@ -408,15 +408,8 @@ provide! { tcx, def_id, other, cdata,
408408

409409
exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items()) }
410410
stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls().collect()) }
411-
exported_symbols => {
412-
let syms = cdata.exported_symbols(tcx);
413-
414-
// FIXME rust-lang/rust#64319, rust-lang/rust#64872: We want
415-
// to block export of generics from dylibs, but we must fix
416-
// rust-lang/rust#65890 before we can do that robustly.
417-
418-
syms
419-
}
411+
exported_non_generic_symbols => { cdata.exported_non_generic_symbols(tcx) }
412+
exported_generic_symbols => { cdata.exported_generic_symbols(tcx) }
420413

421414
crate_extern_paths => { cdata.source().paths().cloned().collect() }
422415
expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
692692
stat!("exportable-items", || self.encode_stable_order_of_exportable_impls());
693693

694694
// Encode exported symbols info. This is prefetched in `encode_metadata`.
695-
let exported_symbols = stat!("exported-symbols", || {
696-
self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE))
697-
});
695+
let (exported_non_generic_symbols, exported_generic_symbols) =
696+
stat!("exported-symbols", || {
697+
(
698+
self.encode_exported_symbols(tcx.exported_non_generic_symbols(LOCAL_CRATE)),
699+
self.encode_exported_symbols(tcx.exported_generic_symbols(LOCAL_CRATE)),
700+
)
701+
});
698702

699703
// Encode the hygiene data.
700704
// IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The
@@ -760,7 +764,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
760764
incoherent_impls,
761765
exportable_items,
762766
stable_order_of_exportable_impls,
763-
exported_symbols,
767+
exported_non_generic_symbols,
768+
exported_generic_symbols,
764769
interpret_alloc_index,
765770
tables,
766771
syntax_contexts,
@@ -2375,7 +2380,13 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
23752380
// Prefetch some queries used by metadata encoding.
23762381
// This is not necessary for correctness, but is only done for performance reasons.
23772382
// It can be removed if it turns out to cause trouble or be detrimental to performance.
2378-
join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE));
2383+
join(
2384+
|| prefetch_mir(tcx),
2385+
|| {
2386+
let _ = tcx.exported_non_generic_symbols(LOCAL_CRATE);
2387+
let _ = tcx.exported_generic_symbols(LOCAL_CRATE);
2388+
},
2389+
);
23792390
}
23802391

23812392
with_encode_metadata_header(tcx, path, |ecx| {

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ pub(crate) struct CrateRoot {
282282

283283
exportable_items: LazyArray<DefIndex>,
284284
stable_order_of_exportable_impls: LazyArray<(DefIndex, usize)>,
285-
exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
285+
exported_non_generic_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
286+
exported_generic_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
286287

287288
syntax_contexts: SyntaxContextTable,
288289
expn_data: ExpnDataTable,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,13 +2317,32 @@ rustc_queries! {
23172317
separate_provide_extern
23182318
}
23192319

2320-
/// The list of symbols exported from the given crate.
2320+
/// The list of non-generic symbols exported from the given crate.
2321+
///
2322+
/// This is separate from exported_generic_symbols to avoid having
2323+
/// to deserialize all non-generic symbols too for upstream crates
2324+
/// in the upstream_monomorphizations query.
2325+
///
2326+
/// - All names contained in `exported_non_generic_symbols(cnum)` are
2327+
/// guaranteed to correspond to a publicly visible symbol in `cnum`
2328+
/// machine code.
2329+
/// - The `exported_non_generic_symbols` and `exported_generic_symbols`
2330+
/// sets of different crates do not intersect.
2331+
query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
2332+
desc { "collecting exported non-generic symbols for crate `{}`", cnum}
2333+
cache_on_disk_if { *cnum == LOCAL_CRATE }
2334+
separate_provide_extern
2335+
}
2336+
2337+
/// The list of generic symbols exported from the given crate.
23212338
///
2322-
/// - All names contained in `exported_symbols(cnum)` are guaranteed to
2323-
/// correspond to a publicly visible symbol in `cnum` machine code.
2324-
/// - The `exported_symbols` sets of different crates do not intersect.
2325-
query exported_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
2326-
desc { "collecting exported symbols for crate `{}`", cnum}
2339+
/// - All names contained in `exported_generic_symbols(cnum)` are
2340+
/// guaranteed to correspond to a publicly visible symbol in `cnum`
2341+
/// machine code.
2342+
/// - The `exported_non_generic_symbols` and `exported_generic_symbols`
2343+
/// sets of different crates do not intersect.
2344+
query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
2345+
desc { "collecting exported generic symbols for crate `{}`", cnum}
23272346
cache_on_disk_if { *cnum == LOCAL_CRATE }
23282347
separate_provide_extern
23292348
}

src/tools/miri/src/bin/miri.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
8585
return (def_id, MiriEntryFnType::Rustc(entry_type));
8686
}
8787
// Look for a symbol in the local crate named `miri_start`, and treat that as the entry point.
88-
let sym = tcx.exported_symbols(LOCAL_CRATE).iter().find_map(|(sym, _)| {
88+
let sym = tcx.exported_non_generic_symbols(LOCAL_CRATE).iter().find_map(|(sym, _)| {
8989
if sym.symbol_name_for_local_instance(tcx).name == "miri_start" { Some(sym) } else { None }
9090
});
9191
if let Some(ExportedSymbol::NonGeneric(id)) = sym {
@@ -250,10 +250,10 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
250250
// Queries overridden here affect the data stored in `rmeta` files of dependencies,
251251
// which will be used later in non-`MIRI_BE_RUSTC` mode.
252252
config.override_queries = Some(|_, local_providers| {
253-
// `exported_symbols` and `reachable_non_generics` provided by rustc always returns
253+
// `exported_non_generic_symbols` and `reachable_non_generics` provided by rustc always returns
254254
// an empty result if `tcx.sess.opts.output_types.should_codegen()` is false.
255255
// In addition we need to add #[used] symbols to exported_symbols for `lookup_link_section`.
256-
local_providers.exported_symbols = |tcx, LocalCrate| {
256+
local_providers.exported_non_generic_symbols = |tcx, LocalCrate| {
257257
let reachable_set = tcx.with_stable_hashing_context(|hcx| {
258258
tcx.reachable_set(()).to_sorted(&hcx, true)
259259
});

src/tools/miri/src/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ pub fn iter_exported_symbols<'tcx>(
162162

163163
// We can ignore `_export_info` here: we are a Rust crate, and everything is exported
164164
// from a Rust crate.
165-
for &(symbol, _export_info) in tcx.exported_symbols(cnum) {
165+
for &(symbol, _export_info) in tcx.exported_non_generic_symbols(cnum) {
166166
if let ExportedSymbol::NonGeneric(def_id) = symbol {
167167
f(cnum, def_id)?;
168168
}

0 commit comments

Comments
 (0)