Skip to content

Commit 91f653b

Browse files
committed
Split exported_symbols for generic and non-generic symbols
This reduces metadata decoder overhead during the monomorphization collector.
1 parent a17780d commit 91f653b

File tree

10 files changed

+82
-37
lines changed

10 files changed

+82
-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
@@ -164,7 +164,7 @@ fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> b
164164
tcx.reachable_non_generics(def_id.krate).contains_key(&def_id)
165165
}
166166

167-
fn exported_symbols_provider_local<'tcx>(
167+
fn exported_non_generic_symbols_provider_local<'tcx>(
168168
tcx: TyCtxt<'tcx>,
169169
_: LocalCrate,
170170
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
@@ -296,6 +296,22 @@ fn exported_symbols_provider_local<'tcx>(
296296
));
297297
}
298298

299+
// Sort so we get a stable incr. comp. hash.
300+
symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx));
301+
302+
tcx.arena.alloc_from_iter(symbols)
303+
}
304+
305+
fn exported_generic_symbols_provider_local<'tcx>(
306+
tcx: TyCtxt<'tcx>,
307+
_: LocalCrate,
308+
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
309+
if !tcx.sess.opts.output_types.should_codegen() && !tcx.is_sdylib_interface_build() {
310+
return &[];
311+
}
312+
313+
let mut symbols: Vec<_> = vec![];
314+
299315
if tcx.local_crate_exports_generics() {
300316
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
301317
use rustc_middle::ty::InstanceKind;
@@ -458,7 +474,7 @@ fn upstream_monomorphizations_provider(
458474
let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn();
459475

460476
for &cnum in cnums.iter() {
461-
for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
477+
for (exported_symbol, _) in tcx.exported_generic_symbols(cnum).iter() {
462478
let (def_id, args) = match *exported_symbol {
463479
ExportedSymbol::Generic(def_id, args) => (def_id, args),
464480
ExportedSymbol::DropGlue(ty) => {
@@ -480,10 +496,7 @@ fn upstream_monomorphizations_provider(
480496
ExportedSymbol::AsyncDropGlue(def_id, ty) => (def_id, tcx.mk_args(&[ty.into()])),
481497
ExportedSymbol::NonGeneric(..)
482498
| ExportedSymbol::ThreadLocalShim(..)
483-
| ExportedSymbol::NoDefId(..) => {
484-
// These are no monomorphizations
485-
continue;
486-
}
499+
| ExportedSymbol::NoDefId(..) => unreachable!("{exported_symbol:?}"),
487500
};
488501

489502
let args_map = instances.entry(def_id).or_default();
@@ -538,7 +551,8 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId)
538551
pub(crate) fn provide(providers: &mut Providers) {
539552
providers.reachable_non_generics = reachable_non_generics_provider;
540553
providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
541-
providers.exported_symbols = exported_symbols_provider_local;
554+
providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local;
555+
providers.exported_generic_symbols = exported_generic_symbols_provider_local;
542556
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
543557
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
544558
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
@@ -1496,11 +1496,18 @@ impl<'a> CrateMetadataRef<'a> {
14961496
.map(move |v| (self.local_def_id(v.0), v.1))
14971497
}
14981498

1499-
fn exported_symbols<'tcx>(
1499+
fn exported_non_generic_symbols<'tcx>(
15001500
self,
15011501
tcx: TyCtxt<'tcx>,
15021502
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
1503-
tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
1503+
tcx.arena.alloc_from_iter(self.root.exported_non_generic_symbols.decode((self, tcx)))
1504+
}
1505+
1506+
fn exported_generic_symbols<'tcx>(
1507+
self,
1508+
tcx: TyCtxt<'tcx>,
1509+
) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
1510+
tcx.arena.alloc_from_iter(self.root.exported_generic_symbols.decode((self, tcx)))
15041511
}
15051512

15061513
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
@@ -677,9 +677,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
677677
stat!("exportable-items", || self.encode_stable_order_of_exportable_impls());
678678

679679
// Encode exported symbols info. This is prefetched in `encode_metadata`.
680-
let exported_symbols = stat!("exported-symbols", || {
681-
self.encode_exported_symbols(tcx.exported_symbols(LOCAL_CRATE))
682-
});
680+
let (exported_non_generic_symbols, exported_generic_symbols) =
681+
stat!("exported-symbols", || {
682+
(
683+
self.encode_exported_symbols(tcx.exported_non_generic_symbols(LOCAL_CRATE)),
684+
self.encode_exported_symbols(tcx.exported_generic_symbols(LOCAL_CRATE)),
685+
)
686+
});
683687

684688
// Encode the hygiene data.
685689
// IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The
@@ -745,7 +749,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
745749
incoherent_impls,
746750
exportable_items,
747751
stable_order_of_exportable_impls,
748-
exported_symbols,
752+
exported_non_generic_symbols,
753+
exported_generic_symbols,
749754
interpret_alloc_index,
750755
tables,
751756
syntax_contexts,
@@ -2356,7 +2361,13 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
23562361
// Prefetch some queries used by metadata encoding.
23572362
// This is not necessary for correctness, but is only done for performance reasons.
23582363
// It can be removed if it turns out to cause trouble or be detrimental to performance.
2359-
join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE));
2364+
join(
2365+
|| prefetch_mir(tcx),
2366+
|| {
2367+
let _ = tcx.exported_non_generic_symbols(LOCAL_CRATE);
2368+
let _ = tcx.exported_generic_symbols(LOCAL_CRATE);
2369+
},
2370+
);
23602371
}
23612372

23622373
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: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,13 +2312,28 @@ rustc_queries! {
23122312
separate_provide_extern
23132313
}
23142314

2315-
/// The list of symbols exported from the given crate.
2315+
/// The list of non-generic symbols exported from the given crate.
2316+
///
2317+
/// - All names contained in `exported_non_generic_symbols(cnum)` are
2318+
/// guaranteed to correspond to a publicly visible symbol in `cnum`
2319+
/// machine code.
2320+
/// - The `exported_non_generic_symbols` and `exported_generic_symbols`
2321+
/// sets of different crates do not intersect.
2322+
query exported_non_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
2323+
desc { "collecting exported non-generic symbols for crate `{}`", cnum}
2324+
cache_on_disk_if { *cnum == LOCAL_CRATE }
2325+
separate_provide_extern
2326+
}
2327+
2328+
/// The list of generic symbols exported from the given crate.
23162329
///
2317-
/// - All names contained in `exported_symbols(cnum)` are guaranteed to
2318-
/// correspond to a publicly visible symbol in `cnum` machine code.
2319-
/// - The `exported_symbols` sets of different crates do not intersect.
2320-
query exported_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
2321-
desc { "collecting exported symbols for crate `{}`", cnum}
2330+
/// - All names contained in `exported_generic_symbols(cnum)` are
2331+
/// guaranteed to correspond to a publicly visible symbol in `cnum`
2332+
/// machine code.
2333+
/// - The `exported_non_generic_symbols` and `exported_generic_symbols`
2334+
/// sets of different crates do not intersect.
2335+
query exported_generic_symbols(cnum: CrateNum) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
2336+
desc { "collecting exported generic symbols for crate `{}`", cnum}
23222337
cache_on_disk_if { *cnum == LOCAL_CRATE }
23232338
separate_provide_extern
23242339
}

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 {
@@ -249,10 +249,10 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
249249
// Queries overridden here affect the data stored in `rmeta` files of dependencies,
250250
// which will be used later in non-`MIRI_BE_RUSTC` mode.
251251
config.override_queries = Some(|_, local_providers| {
252-
// `exported_symbols` and `reachable_non_generics` provided by rustc always returns
252+
// `exported_non_generic_symbols` and `reachable_non_generics` provided by rustc always returns
253253
// an empty result if `tcx.sess.opts.output_types.should_codegen()` is false.
254254
// In addition we need to add #[used] symbols to exported_symbols for `lookup_link_section`.
255-
local_providers.exported_symbols = |tcx, LocalCrate| {
255+
local_providers.exported_non_generic_symbols = |tcx, LocalCrate| {
256256
let reachable_set = tcx.with_stable_hashing_context(|hcx| {
257257
tcx.reachable_set(()).to_sorted(&hcx, true)
258258
});

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)