From 9419baeee856724fba345c114aef34569a2120b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:01:07 +0000 Subject: [PATCH 1/2] Use WorkProductMap instead of FxIndexMap This is an UnordMap internally. Iteration order for the work product map should not matter aside from the place it is serialized where sorting by WorkProductId is sufficient. --- compiler/rustc_codegen_cranelift/src/lib.rs | 6 +++--- compiler/rustc_codegen_gcc/src/lib.rs | 5 ++--- compiler/rustc_codegen_llvm/src/lib.rs | 5 ++--- compiler/rustc_codegen_ssa/src/back/write.rs | 13 ++++--------- compiler/rustc_codegen_ssa/src/traits/backend.rs | 5 ++--- compiler/rustc_incremental/src/persist/save.rs | 15 ++++++--------- compiler/rustc_interface/src/queries.rs | 5 ++--- compiler/rustc_interface/src/util.rs | 7 +++---- .../codegen-backend/auxiliary/the_backend.rs | 15 ++++----------- 9 files changed, 28 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 38cb986034859..af783f31a2136 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -40,7 +40,7 @@ use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back}; use rustc_log::tracing::info; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; @@ -88,7 +88,7 @@ mod prelude { }; pub(crate) use cranelift_module::{self, DataDescription, FuncId, Linkage, Module}; pub(crate) use rustc_abi::{BackendRepr, FIRST_VARIANT, FieldIdx, Scalar, Size, VariantIdx}; - pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; + pub(crate) use rustc_data_structures::fx::FxHashMap; pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub(crate) use rustc_index::Idx; pub(crate) use rustc_middle::mir::{self, *}; @@ -235,7 +235,7 @@ impl CodegenBackend for CraneliftCodegenBackend { sess: &Session, _outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .unwrap() diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 9669f40166287..850b67c7b25af 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -89,11 +89,10 @@ use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; @@ -301,7 +300,7 @@ impl CodegenBackend for GccCodegenBackend { sess: &Session, _outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 7c05ecbab6d1c..c0593bb467796 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -32,11 +32,10 @@ use rustc_codegen_ssa::back::write::{ }; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; @@ -358,7 +357,7 @@ impl CodegenBackend for LlvmCodegenBackend { sess: &Session, outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { let (compiled_modules, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 1b7817cb17bfe..2262db392f54e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -6,7 +6,6 @@ use std::sync::mpsc::{Receiver, Sender, channel}; use std::{assert_matches, fs, io, mem, str, thread}; use rustc_abi::Size; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_errors::emitter::Emitter; @@ -22,7 +21,7 @@ use rustc_incremental::{ use rustc_macros::{Decodable, Encodable}; use rustc_metadata::fs::copy_to_stdout; use rustc_middle::bug; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{ @@ -460,8 +459,8 @@ pub(crate) fn start_async_codegen( fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, compiled_modules: &CompiledModules, -) -> FxIndexMap { - let mut work_products = FxIndexMap::default(); +) -> WorkProductMap { + let mut work_products = WorkProductMap::default(); if sess.opts.incremental.is_none() || sess.opts.unstable_opts.disable_incr_comp_backend_caching { @@ -2099,11 +2098,7 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join( - self, - sess: &Session, - crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + pub fn join(self, sess: &Session, crate_info: &CrateInfo) -> (CompiledModules, WorkProductMap) { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 6bee9f7cadee7..6014f1af4bfc3 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -2,11 +2,10 @@ use std::any::Any; use std::hash::Hash; use rustc_ast::expand::allocator::AllocatorMethod; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_metadata::EncodedMetadata; use rustc_metadata::creader::MetadataLoaderDyn; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; @@ -130,7 +129,7 @@ pub trait CodegenBackend { sess: &Session, outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap); + ) -> (CompiledModules, WorkProductMap); fn print_pass_timings(&self) {} diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index ab695dddf06e6..69705f28aa114 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -1,8 +1,7 @@ use std::fs; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::par_join; -use rustc_middle::dep_graph::{DepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{DepGraph, WorkProductMap}; use rustc_middle::query::on_disk_cache; use rustc_middle::ty::TyCtxt; use rustc_serialize::Encodable as RustcEncodable; @@ -93,7 +92,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { pub fn save_work_product_index( sess: &Session, dep_graph: &DepGraph, - new_work_products: FxIndexMap, + new_work_products: WorkProductMap, ) { if sess.opts.incremental.is_none() { return; @@ -126,18 +125,16 @@ pub fn save_work_product_index( // Check that we did not delete one of the current work-products: debug_assert!({ - new_work_products.iter().all(|(_, wp)| { + new_work_products.items().all(|(_, wp)| { wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess(sess, path).exists()) }) }); } -fn encode_work_product_index( - work_products: &FxIndexMap, - encoder: &mut FileEncoder, -) { +fn encode_work_product_index(work_products: &WorkProductMap, encoder: &mut FileEncoder) { let serialized_products: Vec<_> = work_products - .iter() + .to_sorted_stable_ord() + .into_iter() .map(|(id, work_product)| SerializedWorkProduct { id: *id, work_product: work_product.clone(), diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 20ac6e258ed16..7a106e1089e2c 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -3,12 +3,11 @@ use std::sync::Arc; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo}; -use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::svh::Svh; use rustc_errors::timings::TimingSection; use rustc_hir::def_id::LOCAL_CRATE; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::DepGraph; +use rustc_middle::dep_graph::{DepGraph, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; @@ -51,7 +50,7 @@ impl Linker { let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || { match self.ongoing_codegen.downcast::() { // This was a check only build - Ok(compiled_modules) => (*compiled_modules, IndexMap::default()), + Ok(compiled_modules) => (*compiled_modules, WorkProductMap::default()), Err(ongoing_codegen) => codegen_backend.join_codegen( ongoing_codegen, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d7d306918fd0d..4cb4876284706 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -14,11 +14,10 @@ use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig}; use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib}; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::{CurrentGcx, TyCtxt}; use rustc_query_impl::{CollectActiveJobsKind, collect_active_query_jobs}; use rustc_session::config::{ @@ -418,8 +417,8 @@ impl CodegenBackend for DummyCodegenBackend { _sess: &Session, _outputs: &OutputFilenames, _crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { - (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default()) + ) -> (CompiledModules, WorkProductMap) { + (*ongoing_codegen.downcast().unwrap(), WorkProductMap::default()) } fn link( diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 8a7cacf20e2e4..610a4990a5a4b 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -4,24 +4,17 @@ #![deny(warnings)] extern crate rustc_codegen_ssa; -extern crate rustc_data_structures; -extern crate rustc_driver; -extern crate rustc_errors; -extern crate rustc_hir; +extern crate rustc_driver as _; extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; -extern crate rustc_span; -extern crate rustc_symbol_mangling; -extern crate rustc_target; use std::any::Any; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo}; -use rustc_data_structures::fx::FxIndexMap; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::OutputFilenames; @@ -47,11 +40,11 @@ impl CodegenBackend for TheBackend { _sess: &Session, _outputs: &OutputFilenames, _crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { let codegen_results = ongoing_codegen .downcast::() .expect("in join_codegen: ongoing_codegen is not a CompiledModules"); - (*codegen_results, FxIndexMap::default()) + (*codegen_results, WorkProductMap::default()) } fn link( From f4846298634c8c06b7c6929b2bf4cd44794ba132 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:39:13 +0000 Subject: [PATCH 2/2] Assert incr comp in copy_cgu_workproduct_to_incr_comp_cache_dir It was already only called when incr comp is enabled and this allows cleaning up the callers a bit. --- compiler/rustc_codegen_ssa/src/back/write.rs | 7 +++---- .../rustc_incremental/src/persist/work_product.rs | 8 +++++--- compiler/rustc_interface/src/queries.rs | 13 ++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 2262db392f54e..112cf45ebbf2e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -489,14 +489,13 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( if let Some(path) = &module.bytecode { files.push((OutputType::Bitcode.extension(), path.as_path())); } - if let Some((id, product)) = copy_cgu_workproduct_to_incr_comp_cache_dir( + let (id, product) = copy_cgu_workproduct_to_incr_comp_cache_dir( sess, &module.name, files.as_slice(), &module.links_from_incr_cache, - ) { - work_products.insert(id, product); - } + ); + work_products.insert(id, product); } work_products diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 7b1eb0a82e397..64dae5c0869b9 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -16,14 +16,16 @@ use crate::persist::fs::*; /// Copies a CGU work product to the incremental compilation directory, so next compilation can /// find and reuse it. +/// +/// Panics when incr comp is disabled. pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( sess: &Session, cgu_name: &str, files: &[(&'static str, &Path)], known_links: &[PathBuf], -) -> Option<(WorkProductId, WorkProduct)> { +) -> (WorkProductId, WorkProduct) { debug!(?cgu_name, ?files); - sess.opts.incremental.as_ref()?; + assert!(sess.opts.incremental.is_some()); let mut saved_files = UnordMap::default(); for (ext, path) in files { @@ -50,7 +52,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_files }; debug!(?work_product); let work_product_id = WorkProductId::from_cgu_name(cgu_name); - Some((work_product_id, work_product)) + (work_product_id, work_product) } /// Removes files for a given work product. diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 7a106e1089e2c..6026cfd5f71fe 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -89,14 +89,13 @@ impl Linker { if sess.opts.incremental.is_some() && let Some(path) = self.metadata.path() - && let Some((id, product)) = - rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( - sess, - "metadata", - &[("rmeta", path)], - &[], - ) { + let (id, product) = rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( + sess, + "metadata", + &[("rmeta", path)], + &[], + ); work_products.insert(id, product); }