From 753c73a34961ae3c431dbb76afbfe48b81d93c90 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:19:57 +0000 Subject: Split exported_symbols for generic and non-generic symbols This reduces metadata decoder overhead during the monomorphization collector. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 5 +++- .../rustc_codegen_ssa/src/back/symbol_export.rs | 28 ++++++++++++++++------ compiler/rustc_codegen_ssa/src/back/write.rs | 3 ++- 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'compiler/rustc_codegen_ssa/src') diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index cd08c0fc30f..e726c0f8b5b 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1794,7 +1794,10 @@ fn for_each_exported_symbols_include_dep<'tcx>( for (cnum, dep_format) in deps.iter_enumerated() { // For each dependency that we are linking to statically ... if *dep_format == Linkage::Static { - for &(symbol, info) in tcx.exported_symbols(cnum).iter() { + for &(symbol, info) in tcx.exported_non_generic_symbols(cnum).iter() { + callback(symbol, info, cnum); + } + for &(symbol, info) in tcx.exported_generic_symbols(cnum).iter() { callback(symbol, info, cnum); } } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 19c005d418e..85c4530fd65 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -164,7 +164,7 @@ fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> b tcx.reachable_non_generics(def_id.krate).contains_key(&def_id) } -fn exported_symbols_provider_local<'tcx>( +fn exported_non_generic_symbols_provider_local<'tcx>( tcx: TyCtxt<'tcx>, _: LocalCrate, ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { @@ -296,6 +296,22 @@ fn exported_symbols_provider_local<'tcx>( )); } + // Sort so we get a stable incr. comp. hash. + symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx)); + + tcx.arena.alloc_from_iter(symbols) +} + +fn exported_generic_symbols_provider_local<'tcx>( + tcx: TyCtxt<'tcx>, + _: LocalCrate, +) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] { + if !tcx.sess.opts.output_types.should_codegen() && !tcx.is_sdylib_interface_build() { + return &[]; + } + + let mut symbols: Vec<_> = vec![]; + if tcx.local_crate_exports_generics() { use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility}; use rustc_middle::ty::InstanceKind; @@ -458,7 +474,7 @@ fn upstream_monomorphizations_provider( let async_drop_in_place_fn_def_id = tcx.lang_items().async_drop_in_place_fn(); for &cnum in cnums.iter() { - for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() { + for (exported_symbol, _) in tcx.exported_generic_symbols(cnum).iter() { let (def_id, args) = match *exported_symbol { ExportedSymbol::Generic(def_id, args) => (def_id, args), ExportedSymbol::DropGlue(ty) => { @@ -480,10 +496,7 @@ fn upstream_monomorphizations_provider( ExportedSymbol::AsyncDropGlue(def_id, ty) => (def_id, tcx.mk_args(&[ty.into()])), ExportedSymbol::NonGeneric(..) | ExportedSymbol::ThreadLocalShim(..) - | ExportedSymbol::NoDefId(..) => { - // These are no monomorphizations - continue; - } + | ExportedSymbol::NoDefId(..) => unreachable!("{exported_symbol:?}"), }; let args_map = instances.entry(def_id).or_default(); @@ -538,7 +551,8 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId) pub(crate) fn provide(providers: &mut Providers) { providers.reachable_non_generics = reachable_non_generics_provider; providers.is_reachable_non_generic = is_reachable_non_generic_provider_local; - providers.exported_symbols = exported_symbols_provider_local; + providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local; + providers.exported_generic_symbols = exported_generic_symbols_provider_local; providers.upstream_monomorphizations = upstream_monomorphizations_provider; providers.is_unreachable_local_definition = is_unreachable_local_definition_provider; providers.upstream_drop_glue_for = upstream_drop_glue_for_provider; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index c3bfe4c13cd..8330e4f7af0 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1124,8 +1124,9 @@ fn start_executing_work( let copy_symbols = |cnum| { let symbols = tcx - .exported_symbols(cnum) + .exported_non_generic_symbols(cnum) .iter() + .chain(tcx.exported_generic_symbols(cnum)) .map(|&(s, lvl)| (symbol_name_for_instance_in_crate(tcx, s, cnum), lvl)) .collect(); Arc::new(symbols) -- cgit 1.4.1-3-g733a5