Run linking and incremental saving / finalizing in parallel by Zoxc · Pull Request #121880 · rust-lang/rust (original) (raw)

Something like this. I also fixed a pre-existing incr comp issue where finalize_session_directory is called before the dep graph is actually written, resulting in a broken incr comp cache if you interrupt the build at just the right moment.

diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index df7778cd512..9376fa9552c 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -5,11 +5,10 @@ use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::CodegenResults; -use rustc_data_structures::jobserver; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{ - join, task, AppendOnlyIndexVec, DynSend, FreezeLock, Lrc, OnceLock, Task, WorkerLocal, + task, AppendOnlyIndexVec, DynSend, FreezeLock, Lrc, OnceLock, Task, WorkerLocal, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; @@ -26,8 +25,7 @@ use rustc_session::Session; use rustc_span::symbol::sym; use std::any::Any; -use std::cell::{RefCell, RefMut}; -use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; +use std::cell::{OnceCell, RefCell, RefMut}; use std::sync::Arc; /// Represent the result of a query. @@ -89,26 +87,23 @@ pub struct Queries<'tcx> { arena: WorkerLocal<Arena<'tcx>>, hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>, - dep_graph_serialized_rx: Steal<Receiver<()>>, - dep_graph_serialized_tx: SyncSender<()>,

 parse: Query<ast::Crate>,
 // This just points to what's in `gcx_cell`.
 gcx: Query<&'tcx GlobalCtxt<'tcx>>,

} impl<'tcx> Queries<'tcx> { pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { - let (tx, rx) = sync_channel(1); Queries { compiler, - dep_graph_serialized_rx: Steal::new(rx), - dep_graph_serialized_tx: tx, gcx_cell: OnceLock::new(), arena: WorkerLocal::new(|| Arena::default()), hir_arena: WorkerLocal::new(|| rustc_hir::Arena::default()), parse: Default::default(), gcx: Default::default(), + crate_hash: Default::default(), } } @@ -245,31 +240,27 @@ pub fn codegen_and_build_linker(&'tcx self) -> Result<Task<Result<()>>> { let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx); let linker = Linker { - dep_graph_serialized_rx: self.dep_graph_serialized_rx.steal(), dep_graph: tcx.dep_graph.clone(), output_filenames: tcx.output_filenames(()).clone(), - crate_hash: if tcx.needs_crate_hash() { - Some(tcx.crate_hash(LOCAL_CRATE)) - } else { - None - }, ongoing_codegen, }; let sess = self.compiler.sess.clone(); let codegen_backend = self.compiler.codegen_backend.clone(); + // Ensure the crate hash is computed if necessary + self.crate_hash + .set(if tcx.needs_crate_hash() { Some(tcx.crate_hash(LOCAL_CRATE)) } else { None }) + .unwrap(); + Ok(task(move || linker.link(&sess, &*codegen_backend))) }) } } struct Linker { - dep_graph_serialized_rx: Receiver<()>, dep_graph: DepGraph, output_filenames: Arc, - // Only present when incr. comp. is enabled. - crate_hash: Option, ongoing_codegen: Box<dyn Any + DynSend>, } @@ -286,54 +277,34 @@ fn link(self, sess: &Lrc, codegen_backend: &dyn CodegenBackend) -> Resu rustc_incremental::save_work_product_index(sess, &self.dep_graph, work_products) }); - let dep_graph_serialized_rx = self.dep_graph_serialized_rx; + let prof = sess.prof.clone(); + prof.generic_activity("drop_dep_graph").run(move || drop(self.dep_graph)); - join( - || { - if !sess - .opts - .output_types - .keys() - .any(|&i| i == OutputType::Exe || i == OutputType::Metadata) - { - return Ok(()); - }

@@ -362,16 +333,20 @@ pub fn enter<F, T>(&self, f: F) -> T self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); }