diff options
| author | bors <bors@rust-lang.org> | 2025-03-21 21:03:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-03-21 21:03:49 +0000 |
| commit | 48b36c9d5943a4aef49aa04b8059b92d65ff31a9 (patch) | |
| tree | 5c0c4be8b5a7dc98914aea80c6cffcb18e3f3d58 /compiler/rustc_codegen_ssa | |
| parent | be73c1f4617c97bce81b2694a767353300a75072 (diff) | |
| parent | e21502cf9ed247bbf879132b8c62e423d959bd38 (diff) | |
Auto merge of #128320 - saethlin:link-me-maybe, r=compiler-errors
Avoid no-op unlink+link dances in incr comp Incremental compilation scales quite poorly with the number of CGUs. This PR improves one reason for that. The incr comp process hard-links all the files from an old session into a new one, then it runs the backend, which may just hard-link the new session files into the output directory. Then codegen hard-links all the output files back to the new session directory. This PR (perhaps unimaginatively) fixes the silliness that ensues in the last step. The old `link_or_copy` implementation would be passed pairs of paths which are already the same inode, then it would blindly delete the destination and re-create the hard-link that it just deleted. This PR lets us skip both those operations. We don't skip the other two hard-links. `cargo +stage1 b && touch crates/core/main.rs && strace -cfw -elink,linkat,unlink,unlinkat cargo +stage1 b` before and then after on `ripgrep-13.0.0`: ``` % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 52.56 0.024950 25 978 485 unlink 34.38 0.016318 22 727 linkat 13.06 0.006200 24 249 unlinkat ------ ----------- ----------- --------- --------- ---------------- 100.00 0.047467 24 1954 485 total ``` ``` % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 42.83 0.014521 57 252 unlink 38.41 0.013021 26 486 linkat 18.77 0.006362 25 249 unlinkat ------ ----------- ----------- --------- --------- ---------------- 100.00 0.033904 34 987 total ``` This reduces the number of hard-links that are causing perf troubles, noted in https://github.com/rust-lang/rust/issues/64291 and https://github.com/rust-lang/rust/issues/137560
Diffstat (limited to 'compiler/rustc_codegen_ssa')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/write.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/base.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/lib.rs | 2 |
3 files changed, 18 insertions, 6 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 2ec203458a3..216a18e72ed 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -546,9 +546,12 @@ 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(sess, &module.name, files.as_slice()) - { + if let Some((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); } } @@ -934,7 +937,9 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( ) -> WorkItemResult<B> { let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); - let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { + let mut links_from_incr_cache = Vec::new(); + + let mut load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { let source_file = in_incr_comp_dir(incr_comp_session_dir, saved_path); debug!( "copying preexisting module `{}` from {:?} to {}", @@ -943,7 +948,10 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( output_path.display() ); match link_or_copy(&source_file, &output_path) { - Ok(_) => Some(output_path), + Ok(_) => { + links_from_incr_cache.push(source_file); + Some(output_path) + } Err(error) => { cgcx.create_dcx().handle().emit_err(errors::CopyPathBuf { source_file, @@ -966,7 +974,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( load_from_incr_comp_dir(dwarf_obj_out, saved_dwarf_object_file) }); - let load_from_incr_cache = |perform, output_type: OutputType| { + let mut load_from_incr_cache = |perform, output_type: OutputType| { if perform { let saved_file = module.source.saved_files.get(output_type.extension())?; let output_path = cgcx.output_filenames.temp_path(output_type, Some(&module.name)); @@ -986,6 +994,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( } WorkItemResult::Finished(CompiledModule { + links_from_incr_cache, name: module.name, kind: ModuleKind::Regular, object, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 396febcc637..a739743be8c 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -658,6 +658,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>( bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: Vec::new(), } }) }); diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 44b8cc459cf..93c34a2f576 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -122,6 +122,7 @@ impl<M> ModuleCodegen<M> { bytecode, assembly, llvm_ir, + links_from_incr_cache: Vec::new(), } } } @@ -135,6 +136,7 @@ pub struct CompiledModule { pub bytecode: Option<PathBuf>, pub assembly: Option<PathBuf>, // --emit=asm pub llvm_ir: Option<PathBuf>, // --emit=llvm-ir, llvm-bc is in bytecode + pub links_from_incr_cache: Vec<PathBuf>, } impl CompiledModule { |
