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
This commit is contained in:
commit
48b36c9d59
6 changed files with 57 additions and 26 deletions
|
@ -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,
|
||||
|
|
|
@ -658,6 +658,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
|||
bytecode: None,
|
||||
assembly: None,
|
||||
llvm_ir: None,
|
||||
links_from_incr_cache: Vec::new(),
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue