diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index ce3741b582827..39eafdb1aae89 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -19,11 +19,11 @@ use rustc_codegen_ssa::traits::{ExtraBackendMethods, WriteBackendMethods}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; -use rustc_middle::dep_graph::WorkProduct; +use rustc_middle::dep_graph::{BorrowedIncrCompSession, WorkProduct}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mono::{MonoItem, MonoItemData, Visibility}; +use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames, OutputType}; -use rustc_session::{BorrowedIncrCompSession, Session}; use rustc_span::Symbol; use crate::base::CodegenedFunction; diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index a30dd1c3ebef3..dde5d919dab7f 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -42,9 +42,9 @@ use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back}; use rustc_data_structures::unord::UnordSet; use rustc_log::tracing::info; -use rustc_middle::dep_graph::WorkProductMap; +use rustc_middle::dep_graph::IncrCompSession; use rustc_session::config::{NATIVE_CPU, OutputFilenames}; -use rustc_session::{CodegenBackendInit, EarlySession, IncrCompSession, Session}; +use rustc_session::{CodegenBackendInit, EarlySession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{Arch, CfgAbi, Env, Os}; @@ -239,10 +239,10 @@ impl CodegenBackend for CraneliftCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - incr_comp_session: Option<&IncrCompSession>, + incr_comp_session: Option<&mut IncrCompSession>, _outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap) { + ) -> CompiledModules { ongoing_codegen .downcast::>() .unwrap() diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index dcb4bcde38b60..701e8eb1ec098 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -174,7 +174,7 @@ pub(crate) fn codegen( EmitObj::Bitcode => { debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); - if let Err(err) = link_or_copy(&bc_out, &obj_out) { + if let Err(err) = link_or_copy(&bc_out, &obj_out, true /* allow_overwrite */) { dcx.emit_err(CopyBitcode { err }); } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 414bff06866a8..bfdb84f80d740 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -89,12 +89,10 @@ use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodege use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; -use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; +use rustc_middle::dep_graph::{BorrowedIncrCompSession, IncrCompSession, WorkProduct}; use rustc_middle::ty::TyCtxt; use rustc_session::config::{OptLevel, OutputFilenames}; -use rustc_session::{ - BorrowedIncrCompSession, CodegenBackendInit, EarlySession, IncrCompSession, Session, -}; +use rustc_session::{CodegenBackendInit, EarlySession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{RelocModel, TargetTuple}; use tempfile::TempDir; @@ -305,10 +303,10 @@ impl CodegenBackend for GccCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - incr_comp_session: Option<&IncrCompSession>, + incr_comp_session: Option<&mut IncrCompSession>, _outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap) { + ) -> CompiledModules { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_llvm/src/back/llvm_backend.rs b/compiler/rustc_codegen_llvm/src/back/llvm_backend.rs index 69d63c52e4b88..cbe7b38396785 100644 --- a/compiler/rustc_codegen_llvm/src/back/llvm_backend.rs +++ b/compiler/rustc_codegen_llvm/src/back/llvm_backend.rs @@ -20,12 +20,10 @@ use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodege use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; +use rustc_middle::dep_graph::{BorrowedIncrCompSession, IncrCompSession, WorkProduct}; use rustc_middle::ty::TyCtxt; use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest}; -use rustc_session::{ - BorrowedIncrCompSession, CodegenBackendInit, EarlySession, IncrCompSession, Session, -}; +use rustc_session::{CodegenBackendInit, EarlySession, Session}; use rustc_span::{Symbol, sym}; use rustc_target::spec::{RelocModel, TlsModel}; @@ -368,11 +366,11 @@ impl CodegenBackend for LlvmCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - incr_comp_session: Option<&IncrCompSession>, + incr_comp_session: Option<&mut IncrCompSession>, outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap) { - let (compiled_modules, work_products) = ongoing_codegen + ) -> CompiledModules { + let compiled_modules = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") .join(sess, incr_comp_session, crate_info); @@ -412,7 +410,7 @@ impl CodegenBackend for LlvmCodegenBackend { } } - (compiled_modules, work_products) + compiled_modules } fn link( diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 8258c1f7c8d20..aab2f888b2f21 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -18,8 +18,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; -use rustc_middle::dep_graph::WorkProduct; -use rustc_session::{BorrowedIncrCompSession, config}; +use rustc_middle::dep_graph::{BorrowedIncrCompSession, WorkProduct}; +use rustc_session::config; use rustc_span::bug; use rustc_structures::SanitizerSet; use tracing::{debug, info}; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 7e71755ed4e70..a592d9e21b839 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1139,7 +1139,7 @@ pub(crate) fn codegen( EmitObj::Bitcode => { debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out); - if let Err(err) = link_or_copy(&bc_out, &obj_out) { + if let Err(err) = link_or_copy(&bc_out, &obj_out, true /* allow_overwrite */) { dcx.emit_err(CopyBitcode { err }); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 0d7d85320d6fd..557b08ff77da2 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -20,12 +20,12 @@ use rustc_incremental::{ }; use rustc_macros::{Decodable, Encodable}; use rustc_metadata::fs::copy_to_stdout; -use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; +use rustc_middle::dep_graph::{BorrowedIncrCompSession, IncrCompSession, WorkProduct}; use rustc_middle::ty::TyCtxt; +use rustc_session::Session; use rustc_session::config::{ self, Lto, OptLevel, OutFileName, OutputFilenames, OutputType, Passes, SwitchWithOptPath, }; -use rustc_session::{BorrowedIncrCompSession, IncrCompSession, Session}; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, FileName, InnerSpan, Span, SyntaxContext, bug}; use rustc_structures::CrateType; @@ -457,14 +457,11 @@ pub(crate) fn start_async_codegen( fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, - incr_comp_session: Option<&IncrCompSession>, + incr_comp_session: &mut IncrCompSession, compiled_modules: &CompiledModules, -) -> WorkProductMap { - let mut work_products = WorkProductMap::default(); - - if sess.opts.incremental.is_none() || sess.opts.unstable_opts.disable_incr_comp_backend_caching - { - return work_products; +) { + if sess.opts.unstable_opts.disable_incr_comp_backend_caching { + return; } let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir"); @@ -489,16 +486,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())); } - let (id, product) = copy_cgu_workproduct_to_incr_comp_cache_dir( + copy_cgu_workproduct_to_incr_comp_cache_dir( sess, - incr_comp_session.unwrap(), + incr_comp_session, &module.name, files.as_slice(), ); - work_products.insert(id, product); } - - work_products } pub fn produce_final_output_artifacts( @@ -892,7 +886,11 @@ fn execute_copy_from_cache_work_item( source_file_in_incr_comp_dir, output_path.display() ); - match link_or_copy(&source_file_in_incr_comp_dir, &output_path) { + match link_or_copy( + &source_file_in_incr_comp_dir, + &output_path, + true, // allow_overwrite + ) { Ok(_) => Some(output_path), Err(error) => { dcx.emit_err(diagnostics::CopyPathBuf { @@ -2116,9 +2114,9 @@ impl OngoingCodegen { pub fn join( self, sess: &Session, - incr_comp_session: Option<&IncrCompSession>, + incr_comp_session: Option<&mut IncrCompSession>, crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap) { + ) -> CompiledModules { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { @@ -2137,25 +2135,26 @@ impl OngoingCodegen { let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics - let compilation_output = catch_fatal_errors(|| match maybe_lto_modules { + let compiled_modules = catch_fatal_errors(|| match maybe_lto_modules { MaybeLtoModules::NoLto(compiled_modules) => { drop(shared_emitter); - let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir( - sess, - incr_comp_session, - &compiled_modules, - ); + if let Some(incr_comp_session) = incr_comp_session { + copy_all_cgu_workproducts_to_incr_comp_cache_dir( + sess, + incr_comp_session, + &compiled_modules, + ); + } - (compiled_modules, work_products) + compiled_modules } MaybeLtoModules::FatLto { cgcx, needs_fat_lto } => { let tm_factory = self.backend.target_machine_factory(sess, cgcx.opt_level); // FIXME cache local pre-LTO bitcode - let work_products = WorkProductMap::default(); - let compiled_modules = CompiledModules { + CompiledModules { modules: vec![do_fat_lto( sess, &cgcx, @@ -2166,9 +2165,7 @@ impl OngoingCodegen { needs_fat_lto, )], allocator_module: None, - }; - - (compiled_modules, work_products) + } } MaybeLtoModules::ThinLto { cgcx, needs_thin_lto } => { let tm_factory = self.backend.target_machine_factory(sess, cgcx.opt_level); @@ -2177,7 +2174,7 @@ impl OngoingCodegen { modules: do_thin_lto::( &cgcx, &sess.prof, - incr_comp_session.map(|incr_comp_session| incr_comp_session.borrow()), + incr_comp_session.as_deref().map(IncrCompSession::borrow), shared_emitter, tm_factory, &crate_info.exported_symbols_for_lto, @@ -2190,13 +2187,15 @@ impl OngoingCodegen { // FIXME include pre-LTO bitcode in workproduct tracking // FIXME add separate incr comp session for post-LTO outputs to use during link step - let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir( - sess, - incr_comp_session, - &compiled_modules, - ); + if let Some(incr_comp_session) = incr_comp_session { + copy_all_cgu_workproducts_to_incr_comp_cache_dir( + sess, + incr_comp_session, + &compiled_modules, + ); + } - (compiled_modules, work_products) + compiled_modules } }); @@ -2204,8 +2203,8 @@ impl OngoingCodegen { sess.dcx().abort_if_errors(); - let (mut compiled_modules, work_products) = - compilation_output.expect("fatal error emitted but not sent to SharedEmitter"); + let mut compiled_modules = + compiled_modules.expect("fatal error emitted but not sent to SharedEmitter"); // Regardless of what order these modules completed in, report them to // the backend in the same order every time to ensure that we're handing @@ -2214,7 +2213,7 @@ impl OngoingCodegen { produce_final_output_artifacts(sess, &compiled_modules, &self.output_filenames); - (compiled_modules, work_products) + compiled_modules } pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) { @@ -2258,19 +2257,19 @@ pub(crate) fn submit_post_lto_module_to_llvm( } pub(crate) fn submit_pre_lto_module_to_llvm( - tcx: TyCtxt<'_>, + sess: &Session, + incr_comp_session: &IncrCompSession, coordinator: &Coordinator, module: CachedModuleCodegen, ) { let filename = pre_lto_bitcode_filename(&module.name); - let old_bitcode_path = - in_old_incr_comp_dir_sess(tcx.incr_comp_session.unwrap(), &filename).unwrap(); - let bitcode_path = in_incr_comp_dir_sess(tcx.incr_comp_session.unwrap(), &filename); + let old_bitcode_path = in_old_incr_comp_dir_sess(incr_comp_session, &filename).unwrap(); + let bitcode_path = in_incr_comp_dir_sess(incr_comp_session, &filename); - match link_or_copy(&old_bitcode_path, &bitcode_path) { + match link_or_copy(&old_bitcode_path, &bitcode_path, false /* allow_overwrite */) { Ok(_) => {} Err(error) => { - tcx.sess.dcx().emit_err(diagnostics::CopyPathBuf { + sess.dcx().emit_err(diagnostics::CopyPathBuf { source_file: old_bitcode_path, output_path: bitcode_path, error, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ed2c05a20b9d4..4c98bebda1593 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -869,7 +869,8 @@ pub fn codegen_crate< } CguReuse::PreLto => { submit_pre_lto_module_to_llvm( - tcx, + tcx.sess, + tcx.incr_comp_session.unwrap(), &ongoing_codegen.coordinator, CachedModuleCodegen { name: cgu.name().to_string(), diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index bf5d67c213573..5c387d1353f00 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -5,11 +5,11 @@ use rustc_ast::expand::allocator::AllocatorMethod; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_metadata::EncodedMetadata; use rustc_metadata::creader::MetadataLoaderDyn; -use rustc_middle::dep_graph::WorkProductMap; +use rustc_middle::dep_graph::IncrCompSession; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::config::{OutputFilenames, PrintRequest}; -use rustc_session::{CodegenBackendInit, EarlySession, IncrCompSession, Session}; +use rustc_session::{CodegenBackendInit, EarlySession, Session}; use rustc_span::Symbol; use rustc_structures::CrateType; @@ -115,10 +115,10 @@ pub trait CodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - incr_comp_session: Option<&IncrCompSession>, + incr_comp_session: Option<&mut IncrCompSession>, outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap); + ) -> CompiledModules; /// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen). fn link( diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 36bc0a68d882e..35bec4801eb9d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -4,8 +4,8 @@ use std::path::PathBuf; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::DiagCtxtHandle; -use rustc_middle::dep_graph::WorkProduct; -use rustc_session::{BorrowedIncrCompSession, Session, config}; +use rustc_middle::dep_graph::{BorrowedIncrCompSession, WorkProduct}; +use rustc_session::{Session, config}; use crate::back::lto::ThinModule; use crate::back::write::{ diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs index e21da4cdddf7d..d478f7bade448 100644 --- a/compiler/rustc_fs_util/src/lib.rs +++ b/compiler/rustc_fs_util/src/lib.rs @@ -59,7 +59,11 @@ pub enum LinkOrCopy { /// Copies `p` into `q`, preferring to use hard-linking if possible. /// The result indicates which of the two operations has been performed. -pub fn link_or_copy, Q: AsRef>(p: P, q: Q) -> io::Result { +pub fn link_or_copy, Q: AsRef>( + p: P, + q: Q, + allow_overwrite: bool, +) -> io::Result { // Creating a hard-link will fail if the destination path already exists. We could defensively // call remove_file in this function, but that pessimizes callers who can avoid such calls. // Incremental compilation calls this function a lot, and is able to avoid calls that @@ -74,6 +78,9 @@ pub fn link_or_copy, Q: AsRef>(p: P, q: Q) -> io::Result
  • , - svh: Option, + mut incr_comp_session: IncrCompSession, + svh: Svh, ) { assert!(sess.dcx().has_errors_or_delayed_bugs().is_none()); - if sess.opts.incremental.is_none() { - return; - } - let mut incr_comp_session = incr_comp_session.unwrap(); - // The svh is always produced when incr. comp. is enabled. - let svh = svh.unwrap(); + sess.time("serialize_work_products", || { + crate::persist::save::save_work_product_index(sess, &incr_comp_session) + }); let _timer = sess.timer("incr_comp_finalize_session_directory"); diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 76e0bf92c6f0f..63c950b27de08 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -1,38 +1,31 @@ //! Code to load the dep-graph from files. -use std::io; -use std::path::PathBuf; use std::sync::Arc; -use rustc_data_structures::unord::UnordMap; use rustc_hashes::Hash64; -use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProductMap}; +use rustc_middle::dep_graph::{DepGraph, IncrCompSession, SerializedDepGraph, WorkProductMap}; use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Encodable}; use rustc_session::config::IncrementalStateAssertion; -use rustc_session::{IncrCompSession, Session, StableCrateId}; +use rustc_session::{Session, StableCrateId}; use rustc_span::Symbol; use tracing::{debug, warn}; -use super::data::*; use super::file_format; use super::fs::*; +use super::work_product::SerializedWorkProduct; use crate::diagnostics; use crate::persist::file_format::{OpenFile, OpenFileError}; -#[derive(Debug)] -/// Represents the result of an attempt to load incremental compilation data. -enum LoadResult { - /// Loading was successful. - Ok { prev_graph: Arc, prev_work_products: WorkProductMap }, - /// The file either didn't exist or was produced by an incompatible compiler version. - DataOutOfDate, - /// Loading failed due to an unexpected I/O error. - IoError { path: PathBuf, err: io::Error }, -} - -fn load_dep_graph(sess: &Session, incr_comp_session: &IncrCompSession) -> LoadResult { +/// Load the old dep graph and work product index. +/// +/// Returns Err(()) if a file was produced by an incompatible compiler version, didn't +/// exist or for some other reason couldn't be used. +fn load_dep_graph( + sess: &Session, + incr_comp_session: &IncrCompSession, +) -> Result<(Arc, WorkProductMap), ()> { assert!(sess.opts.incremental.is_some()); let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph"); @@ -40,14 +33,56 @@ fn load_dep_graph(sess: &Session, incr_comp_session: &IncrCompSession) -> LoadRe // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`. // Fortunately, we just checked that this isn't the case. let Some(path) = old_dep_graph_path(incr_comp_session) else { - return LoadResult::DataOutOfDate; + return Err(()); }; let expected_hash = sess.opts.dep_tracking_hash(false); - let mut prev_work_products = UnordMap::default(); + let prev_work_products = load_work_product_index(sess, incr_comp_session)?; + + let _prof_timer = sess.prof.generic_activity("incr_comp_load_dep_graph"); + + match file_format::open_incremental_file(sess, &path) { + Err(OpenFileError::NotFoundOrHeaderMismatch) => Err(()), + Err(OpenFileError::IoError { err }) => { + sess.dcx().emit_warn(diagnostics::LoadDepGraph { path, err }); + Err(()) + } + Ok(OpenFile { mmap, start_pos }) => { + let Ok(mut decoder) = MemDecoder::new(&mmap, start_pos) else { + sess.dcx().emit_warn(diagnostics::CorruptFile { path: &path }); + return Err(()); + }; + let prev_commandline_args_hash = Hash64::decode(&mut decoder); + + if prev_commandline_args_hash != expected_hash { + if sess.opts.unstable_opts.incremental_info { + eprintln!( + "[incremental] completely ignoring cache because of \ + differing commandline arguments" + ); + } + // We can't reuse the cache, purge it. + debug!("load_dep_graph_new: differing commandline arg hashes"); + + // No need to do any further work + return Err(()); + } + + let prev_graph = SerializedDepGraph::decode(&mut decoder, &sess.prof); + + Ok((prev_graph, prev_work_products)) + } + } +} + +fn load_work_product_index( + sess: &Session, + incr_comp_session: &IncrCompSession, +) -> Result { + let mut prev_work_products = WorkProductMap::default(); let Some(work_products_path) = old_work_products_path(incr_comp_session) else { - return LoadResult::DataOutOfDate; + return Err(()); }; if let Ok(OpenFile { mmap, start_pos }) = @@ -56,7 +91,7 @@ fn load_dep_graph(sess: &Session, incr_comp_session: &IncrCompSession) -> LoadRe // Decode the list of work_products let Ok(mut work_product_decoder) = MemDecoder::new(&mmap[..], start_pos) else { sess.dcx().emit_warn(diagnostics::CorruptFile { path: &work_products_path }); - return LoadResult::DataOutOfDate; + return Err(()); }; let work_products: Vec = Decodable::decode(&mut work_product_decoder); @@ -75,42 +110,12 @@ fn load_dep_graph(sess: &Session, incr_comp_session: &IncrCompSession) -> LoadRe prev_work_products.insert(swp.id, swp.work_product); } else { debug!("reconcile_work_products: some file for {:?} does not exist", swp); - return LoadResult::DataOutOfDate; + return Err(()); } } } - let _prof_timer = sess.prof.generic_activity("incr_comp_load_dep_graph"); - - match file_format::open_incremental_file(sess, &path) { - Err(OpenFileError::NotFoundOrHeaderMismatch) => LoadResult::DataOutOfDate, - Err(OpenFileError::IoError { err }) => LoadResult::IoError { path: path.to_owned(), err }, - Ok(OpenFile { mmap, start_pos }) => { - let Ok(mut decoder) = MemDecoder::new(&mmap, start_pos) else { - sess.dcx().emit_warn(diagnostics::CorruptFile { path: &path }); - return LoadResult::DataOutOfDate; - }; - let prev_commandline_args_hash = Hash64::decode(&mut decoder); - - if prev_commandline_args_hash != expected_hash { - if sess.opts.unstable_opts.incremental_info { - eprintln!( - "[incremental] completely ignoring cache because of \ - differing commandline arguments" - ); - } - // We can't reuse the cache, purge it. - debug!("load_dep_graph_new: differing commandline arg hashes"); - - // No need to do any further work - return LoadResult::DataOutOfDate; - } - - let prev_graph = SerializedDepGraph::decode(&mut decoder, &sess.prof); - - LoadResult::Ok { prev_graph, prev_work_products } - } - } + Ok(prev_work_products) } /// Attempts to load the query result cache from disk @@ -118,46 +123,31 @@ fn load_dep_graph(sess: &Session, incr_comp_session: &IncrCompSession) -> LoadRe /// If we are not in incremental compilation mode, returns `None`. /// Otherwise, tries to load the query result cache from disk, /// creating an empty cache if it could not be loaded. -pub fn load_query_result_cache( - sess: &Session, - incr_comp_session: Option<&IncrCompSession>, -) -> Option { - if sess.opts.incremental.is_none() { - return None; - } - let incr_comp_session = incr_comp_session.unwrap(); - +pub fn load_query_result_cache(sess: &Session, incr_comp_session: &IncrCompSession) -> OnDiskCache { let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache"); let Some(path) = old_query_cache_path(incr_comp_session) else { - return Some(OnDiskCache::new_empty()); + return OnDiskCache::new_empty(); }; match file_format::open_incremental_file(sess, &path) { Ok(OpenFile { mmap, start_pos }) => { - let cache = OnDiskCache::new(sess, mmap, start_pos).unwrap_or_else(|()| { + OnDiskCache::new(sess, mmap, start_pos).unwrap_or_else(|()| { sess.dcx().emit_warn(diagnostics::CorruptFile { path: &path }); OnDiskCache::new_empty() - }); - Some(cache) + }) } Err(OpenFileError::NotFoundOrHeaderMismatch | OpenFileError::IoError { .. }) => { - Some(OnDiskCache::new_empty()) + OnDiskCache::new_empty() } } } /// Emits a fatal error if the assertion in `-Zassert-incr-state` doesn't match /// the outcome of trying to load previous-session state. -fn maybe_assert_incr_state(sess: &Session, load_result: &LoadResult) { +fn maybe_assert_incr_state(sess: &Session, loaded: bool) { // Return immediately if there's nothing to assert. let Some(assertion) = sess.opts.unstable_opts.assert_incr_state else { return }; - // Match exhaustively to make sure we don't miss any cases. - let loaded = match load_result { - LoadResult::Ok { .. } => true, - LoadResult::DataOutOfDate | LoadResult::IoError { .. } => false, - }; - match assertion { IncrementalStateAssertion::Loaded => { if !loaded { @@ -201,19 +191,14 @@ pub fn setup_dep_graph( }); // Emit a fatal error if `-Zassert-incr-state` is present and unsatisfied. - maybe_assert_incr_state(sess, &load_result); + maybe_assert_incr_state(sess, load_result.is_ok()); let (prev_graph, prev_work_products) = match load_result { - LoadResult::IoError { path, err } => { - sess.dcx().emit_warn(diagnostics::LoadDepGraph { path, err }); - invalidate_old_session_dir(sess, &mut incr_comp_session); - Default::default() - } - LoadResult::DataOutOfDate => { + Ok((prev_graph, prev_work_products)) => (prev_graph, prev_work_products), + Err(()) => { invalidate_old_session_dir(sess, &mut incr_comp_session); Default::default() } - LoadResult::Ok { prev_graph, prev_work_products } => (prev_graph, prev_work_products), }; // Stream the dep-graph to an alternate file, to avoid overwriting anything in case of errors. diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index fb318357b26cb..e101d8df8e2e7 100644 --- a/compiler/rustc_incremental/src/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs @@ -3,7 +3,6 @@ //! various HIR nodes. mod clean; -mod data; mod file_format; mod fs; mod load; @@ -13,5 +12,4 @@ mod work_product; pub use fs::{finalize_session_directory, in_incr_comp_dir_sess, in_old_incr_comp_dir_sess}; pub use load::{load_query_result_cache, setup_dep_graph}; pub(crate) use save::save_dep_graph; -pub use save::save_work_product_index; pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir; diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 46f47d6c8623c..c6cc33e9bb050 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -1,21 +1,21 @@ use std::fs; use rustc_data_structures::sync::par_join; -use rustc_middle::dep_graph::{DepGraph, WorkProductMap}; +use rustc_middle::dep_graph::{IncrCompSession, WorkProductMap}; use rustc_middle::query::on_disk_cache; use rustc_middle::ty::TyCtxt; use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::FileEncoder; -use rustc_session::{IncrCompSession, Session}; +use rustc_session::Session; use tracing::debug; -use super::data::*; use super::fs::*; +use super::work_product::SerializedWorkProduct; use super::{clean, file_format}; use crate::assert_dep_graph::assert_dep_graph; use crate::diagnostics; -/// Saves and writes the [`DepGraph`] to the file system. +/// Saves and writes the [`DepGraph`](rustc_middle::dep_graph::DepGraph) to the file system. /// /// This function saves both the dep-graph and the query result cache, /// and drops the result cache. @@ -26,15 +26,14 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { let sess = tcx.sess; - if sess.opts.incremental.is_none() { + let Some(incr_comp_session) = tcx.incr_comp_session else { return; - } + }; // This is going to be deleted in finalize_session_directory, so let's not create it. if sess.dcx().has_errors_or_delayed_bugs().is_some() { return; } - let incr_comp_session = tcx.incr_comp_session.unwrap(); let query_cache_path = query_cache_path(incr_comp_session); let dep_graph_path = dep_graph_path(incr_comp_session); let staging_dep_graph_path = staging_dep_graph_path(incr_comp_session); @@ -90,34 +89,20 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { } /// Saves the work product index. -pub fn save_work_product_index( - sess: &Session, - incr_comp_session: Option<&IncrCompSession>, - dep_graph: &DepGraph, - new_work_products: WorkProductMap, -) { - if sess.opts.incremental.is_none() { - return; - } - // This is going to be deleted in finalize_session_directory, so let's not create it - if sess.dcx().has_errors().is_some() { - return; - } - +pub(super) fn save_work_product_index(sess: &Session, incr_comp_session: &IncrCompSession) { debug!("save_work_product_index()"); - dep_graph.assert_ignored(); - let path = work_products_path(incr_comp_session.unwrap()); + let path = work_products_path(incr_comp_session); file_format::save_in(sess, path, "work product index", |mut e| { - encode_work_product_index(&new_work_products, &mut e); + encode_work_product_index(&incr_comp_session.new_work_products, &mut e); e.finish() }); // Check that we did not delete one of the current work-products: debug_assert!({ - new_work_products.items().all(|(_, wp)| { + incr_comp_session.new_work_products.items().all(|(_, wp)| { wp.saved_files .items() - .all(|(_, path)| in_incr_comp_dir_sess(incr_comp_session.unwrap(), path).exists()) + .all(|(_, path)| in_incr_comp_dir_sess(incr_comp_session, path).exists()) }) }); } diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 0aaa9aa8e96c2..822faba2ca170 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -6,8 +6,9 @@ use std::path::Path; use rustc_data_structures::unord::UnordMap; use rustc_fs_util::link_or_copy; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; -use rustc_session::{IncrCompSession, Session}; +use rustc_macros::{Decodable, Encodable}; +use rustc_middle::dep_graph::{IncrCompSession, WorkProduct, WorkProductId}; +use rustc_session::Session; use tracing::debug; use crate::diagnostics; @@ -19,10 +20,10 @@ use crate::persist::fs::*; /// Panics when incr comp is disabled. pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( sess: &Session, - incr_comp_session: &IncrCompSession, + incr_comp_session: &mut IncrCompSession, cgu_name: &str, files: &[(&'static str, &Path)], -) -> (WorkProductId, WorkProduct) { +) { debug!(?cgu_name, ?files); assert!(sess.opts.incremental.is_some()); @@ -30,7 +31,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( for (ext, path) in files { let file_name = format!("{cgu_name}.{ext}"); let path_in_incr_dir = in_incr_comp_dir_sess(incr_comp_session, &file_name); - match link_or_copy(path, &path_in_incr_dir) { + match link_or_copy(path, &path_in_incr_dir, false /* allow_overwrite */) { Ok(_) => { let _ = saved_files.insert(ext.to_string(), file_name); } @@ -47,5 +48,14 @@ 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); - (work_product_id, work_product) + incr_comp_session.new_work_products.insert(work_product_id, work_product); +} + +#[derive(Debug, Encodable, Decodable)] +pub(crate) struct SerializedWorkProduct { + /// node that produced the work-product + pub id: WorkProductId, + + /// work-product data itself + pub work_product: WorkProduct, } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 6dc3f74f054f1..8e7adda5e8a96 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -29,6 +29,7 @@ use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_sto use rustc_metadata::EncodedMetadata; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; +use rustc_middle::dep_graph::IncrCompSession; use rustc_middle::middle::resolve::{ResolverAstLowering, ResolverGlobalCtxt}; use rustc_middle::ty::{self, RegisteredTools, TyCtxt}; use rustc_middle::util::Providers; @@ -36,11 +37,11 @@ use rustc_parse::lexer::StripTokens; use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::{Resolver, ResolverOutputs}; +use rustc_session::Session; use rustc_session::config::{Input, Offload, OutFileName, OutputFilenames, OutputType}; use rustc_session::diagnostics::feature_err; use rustc_session::output::{filename_for_input, invalid_output_for_target}; use rustc_session::search_paths::PathKind; -use rustc_session::{IncrCompSession, Session}; use rustc_span::{ DUMMY_SP, ErrorGuaranteed, ExpnKind, SourceFileHash, SourceFileHashAlgorithm, Span, Symbol, sym, }; @@ -979,8 +980,9 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( // incr. comp. yet. dep_graph.assert_ignored(); - let query_result_on_disk_cache = - rustc_incremental::load_query_result_cache(sess, incr_comp_session.as_ref()); + let query_result_on_disk_cache = incr_comp_session.as_ref().map(|incr_comp_session| { + rustc_incremental::load_query_result_cache(sess, incr_comp_session) + }); let codegen_backend = &compiler.codegen_backend; let mut providers = *DEFAULT_QUERY_PROVIDERS; diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 94cc1484586c8..d1fa40079180e 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -7,10 +7,10 @@ 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, WorkProduct, WorkProductMap}; +use rustc_middle::dep_graph::{DepGraph, IncrCompSession, WorkProduct}; use rustc_middle::ty::TyCtxt; +use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; -use rustc_session::{IncrCompSession, Session}; use crate::diagnostics::FailedWritingFile; use crate::passes; @@ -49,18 +49,18 @@ impl Linker { pub fn link( self, sess: &Session, - incr_comp_session: Option, + mut incr_comp_session: Option, codegen_backend: &dyn CodegenBackend, ) { - let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || { + let compiled_modules = sess.time("finish_ongoing_codegen", || { match self.ongoing_codegen.downcast::() { // This was a check only build - Ok(compiled_modules) => (*compiled_modules, WorkProductMap::default()), + Ok(compiled_modules) => *compiled_modules, Err(ongoing_codegen) => codegen_backend.join_codegen( ongoing_codegen, sess, - incr_comp_session.as_ref(), + incr_comp_session.as_mut(), &self.output_filenames, &self.crate_info, ), @@ -72,13 +72,12 @@ impl Linker { if sess.opts.incremental.is_some() && let Some(path) = self.metadata.path() { - let (id, product) = rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( + rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( sess, - incr_comp_session.as_ref().unwrap(), + incr_comp_session.as_mut().unwrap(), WorkProduct::METADATA_WORKPRODUCT_CGU_NAME, &[(OutputType::Metadata.extension(), path)], ); - work_products.insert(id, product); } if let Some(guar) = sess.dcx().has_errors_or_delayed_bugs() { @@ -87,21 +86,19 @@ impl Linker { let _timer = sess.timer("link"); - sess.time("serialize_work_products", || { - rustc_incremental::save_work_product_index( - sess, - incr_comp_session.as_ref(), - &self.dep_graph, - work_products, - ) - }); - let prof = sess.prof.clone(); prof.generic_activity("drop_dep_graph").run(move || drop(self.dep_graph)); // Now that we won't touch anything in the incremental compilation directory // any more, we can finalize it (which involves renaming it) - rustc_incremental::finalize_session_directory(sess, incr_comp_session, self.crate_hash); + if let Some(incr_comp_session) = incr_comp_session { + rustc_incremental::finalize_session_directory( + sess, + incr_comp_session, + // The svh is always produced when incr. comp. is enabled. + self.crate_hash.unwrap(), + ); + } // The `HostMetadata` offload pass only writes the kernel manifest. // Codegen was already skipped so there are no files to link. diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 53f62e8d8c04c..a97c88d4cc964 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -19,7 +19,7 @@ use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; 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::WorkProductMap; +use rustc_middle::dep_graph::IncrCompSession; use rustc_middle::ty::{CurrentGcx, TyCtxt}; use rustc_query_impl::{CollectActiveJobsKind, collect_active_query_jobs}; pub use rustc_session::config::DEFAULT_STACK_SIZE; @@ -27,7 +27,7 @@ use rustc_session::config::{ Cfg, Jobs, OptionsTargetModifiers, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple, }; -use rustc_session::{EarlyDiagCtxt, EarlySession, IncrCompSession, Session, filesearch}; +use rustc_session::{EarlyDiagCtxt, EarlySession, Session, filesearch}; use rustc_span::edition::Edition; use rustc_span::source_map::SourceMapInputs; use rustc_span::{SessionGlobals, Symbol, sym}; @@ -469,11 +469,11 @@ impl CodegenBackend for DummyCodegenBackend { &self, ongoing_codegen: Box, _sess: &Session, - _incr_comp_session: Option<&IncrCompSession>, + _incr_comp_session: Option<&mut IncrCompSession>, _outputs: &OutputFilenames, _crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap) { - (*ongoing_codegen.downcast().unwrap(), WorkProductMap::default()) + ) -> CompiledModules { + *ongoing_codegen.downcast().unwrap() } fn link( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c92b26e5c5b21..8e1070adcba71 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2610,8 +2610,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { let dep_node = tcx.metadata_dep_node(); // If the metadata dep-node is green, try to reuse the saved work product. - if tcx.dep_graph.is_fully_enabled() - && let incr_comp_session = tcx.incr_comp_session.unwrap() + if let Some(incr_comp_session) = tcx.incr_comp_session && let Some(old_incr_comp_session_dir) = &incr_comp_session.old_session_directory && let work_product_id = WorkProductId::from_cgu_name(WorkProduct::METADATA_WORKPRODUCT_CGU_NAME) @@ -2621,7 +2620,11 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { let saved_path = &work_product.saved_files[OutputType::Metadata.extension()]; let source_file_in_incr_dir = &old_incr_comp_session_dir.join(saved_path); debug!("copying preexisting metadata from {source_file_in_incr_dir:?} to {path:?}"); - match rustc_fs_util::link_or_copy(&source_file_in_incr_dir, path) { + match rustc_fs_util::link_or_copy( + &source_file_in_incr_dir, + path, + true, // allow_overwrite + ) { Ok(_) => {} Err(err) => tcx.dcx().emit_fatal(FailCreateFileEncoder { err }), }; diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index e63a281002f0d..8a049911675ce 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -1,5 +1,8 @@ use std::panic; +use std::path::PathBuf; +use std::sync::Arc; +use rustc_data_structures::flock; use tracing::instrument; pub use self::dep_node::{DepKind, DepKindVTable, DepNode, WorkProductId, dep_kind_from_label}; @@ -23,6 +26,60 @@ mod graph; mod retained; mod serialized; +/// Holds data on the current incremental compilation session, if there is one. +pub struct IncrCompSession { + /// The directory from which cached data of a previous session can be read. + pub old_session_directory: Option, + /// The directory to which cached data for the current session can be + /// written to. + pub new_session_directory: flock::LockedDir, + pub new_work_products: WorkProductMap, + borrows: Arc<()>, +} + +impl IncrCompSession { + pub fn new( + old_session_directory: Option, + new_session_directory: flock::LockedDir, + ) -> Self { + IncrCompSession { + old_session_directory, + new_session_directory, + new_work_products: WorkProductMap::default(), + borrows: Arc::new(()), + } + } + + pub fn borrow(&self) -> BorrowedIncrCompSession { + BorrowedIncrCompSession { + old_session_directory: self.old_session_directory.as_deref().map(ToOwned::to_owned), + new_session_directory: (&*self.new_session_directory).to_owned(), + _borrows: Arc::clone(&self.borrows), + } + } +} + +impl Drop for IncrCompSession { + fn drop(&mut self) { + // Check that there are no worker threads remaining that use the incr + // comp session before we unlock the old and new session dir. If there + // does exist a worker thread, there is not much we can do, but at + // least we will unconditionally complain rather than the worker thread + // sometimes crashing depending on what other rustc instances run. + assert!( + Arc::strong_count(&self.borrows) == 1, + "Incr comp session dropped while there are still references", + ); + } +} + +/// A runtime tracked borrow of the incr comp session. Can be sent to worker threads. +pub struct BorrowedIncrCompSession { + pub old_session_directory: Option, + pub new_session_directory: PathBuf, + _borrows: Arc<()>, +} + /// Describes the contents of the fingerprint generated by a given query. /// /// This is mainly for determining whether and how we can reconstruct a key diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ef9020cf6ea56..5d375ef310d6e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -40,8 +40,8 @@ use rustc_index::IndexVec; use rustc_lint_defs::Lint; use rustc_lint_defs::builtin::UNUSED_FEATURES; use rustc_macros::Diagnostic; +use rustc_session::Session; use rustc_session::config::NextSolverConfig; -use rustc_session::{IncrCompSession, Session}; use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym}; use rustc_structures::{CrateType, Limit}; @@ -55,7 +55,7 @@ use tracing::{debug, instrument}; use crate::arena::Arena; use crate::dep_graph::dep_node::make_metadata; -use crate::dep_graph::{DepGraph, DepNodeIndex}; +use crate::dep_graph::{DepGraph, DepNodeIndex, IncrCompSession}; use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo}; use crate::ich::StableHashState; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind}; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b69c26639e7e8..642f08ca19727 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::{env, io}; -use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{AppendOnlyVec, DynSend, DynSync, Lock}; @@ -1865,54 +1864,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } -/// Holds data on the current incremental compilation session, if there is one. -pub struct IncrCompSession { - /// The directory from which cached data of a previous session can be read. - pub old_session_directory: Option, - /// The directory to which cached data for the current session can be - /// written to. - pub new_session_directory: flock::LockedDir, - borrows: Arc<()>, -} - -impl IncrCompSession { - pub fn new( - old_session_directory: Option, - new_session_directory: flock::LockedDir, - ) -> Self { - IncrCompSession { old_session_directory, new_session_directory, borrows: Arc::new(()) } - } - - pub fn borrow(&self) -> BorrowedIncrCompSession { - BorrowedIncrCompSession { - old_session_directory: self.old_session_directory.as_deref().map(ToOwned::to_owned), - new_session_directory: (&*self.new_session_directory).to_owned(), - _borrows: Arc::clone(&self.borrows), - } - } -} - -impl Drop for IncrCompSession { - fn drop(&mut self) { - // Check that there are no worker threads remaining that use the incr - // comp session before we unlock the old and new session dir. If there - // does exist a worker thread, there is not much we can do, but at - // least we will unconditionally complain rather than the worker thread - // sometimes crashing depending on what other rustc instances run. - assert!( - Arc::strong_count(&self.borrows) == 1, - "Incr comp session dropped while there are still references", - ); - } -} - -/// A runtime tracked borrow of the incr comp session. Can be sent to worker threads. -pub struct BorrowedIncrCompSession { - pub old_session_directory: Option, - pub new_session_directory: PathBuf, - _borrows: Arc<()>, -} - /// A wrapper around an [`DiagCtxt`] that is used for early error emissions. pub struct EarlyDiagCtxt { dcx: DiagCtxt, diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index e3e2eef146ccc..3b51b43db10ca 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -256,10 +256,10 @@ impl CodegenBackend for MiriCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - incr_comp_session: Option<&rustc_session::IncrCompSession>, + incr_comp_session: Option<&mut rustc_middle::dep_graph::IncrCompSession>, outputs: &rustc_session::config::OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, rustc_middle::dep_graph::WorkProductMap) { + ) -> CompiledModules { self.dummy.join_codegen(ongoing_codegen, sess, incr_comp_session, outputs, crate_info) } diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index a147e3ddf6942..5cfcb5df1cb56 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -15,10 +15,10 @@ use std::any::Any; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::WorkProductMap; +use rustc_middle::dep_graph::IncrCompSession; use rustc_middle::ty::TyCtxt; +use rustc_session::Session; use rustc_session::config::OutputFilenames; -use rustc_session::{IncrCompSession, Session}; struct TheBackend; @@ -39,14 +39,13 @@ impl CodegenBackend for TheBackend { &self, ongoing_codegen: Box, _sess: &Session, - _incr_comp_session: Option<&IncrCompSession>, + _incr_comp_session: Option<&mut IncrCompSession>, _outputs: &OutputFilenames, _crate_info: &CrateInfo, - ) -> (CompiledModules, WorkProductMap) { - let codegen_results = ongoing_codegen + ) -> CompiledModules { + *ongoing_codegen .downcast::() - .expect("in join_codegen: ongoing_codegen is not a CompiledModules"); - (*codegen_results, WorkProductMap::default()) + .expect("in join_codegen: ongoing_codegen is not a CompiledModules") } fn link(