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:
@@ -103,12 +103,14 @@ impl OngoingCodegen {
|
||||
("o", &module_regular.object.as_ref().unwrap()),
|
||||
("asm.o", &module_global_asm.object.as_ref().unwrap()),
|
||||
],
|
||||
&[],
|
||||
)
|
||||
} else {
|
||||
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
|
||||
sess,
|
||||
&module_regular.name,
|
||||
&[("o", &module_regular.object.as_ref().unwrap())],
|
||||
&[],
|
||||
)
|
||||
};
|
||||
if let Some((work_product_id, work_product)) = work_product {
|
||||
@@ -381,6 +383,7 @@ fn emit_cgu(
|
||||
bytecode: None,
|
||||
assembly: None,
|
||||
llvm_ir: None,
|
||||
links_from_incr_cache: Vec::new(),
|
||||
}),
|
||||
existing_work_product: None,
|
||||
})
|
||||
@@ -437,6 +440,7 @@ fn emit_module(
|
||||
bytecode: None,
|
||||
assembly: None,
|
||||
llvm_ir: None,
|
||||
links_from_incr_cache: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -460,22 +464,23 @@ fn reuse_workproduct_for_cgu(
|
||||
err
|
||||
));
|
||||
}
|
||||
|
||||
let obj_out_global_asm =
|
||||
crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm");
|
||||
let has_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") {
|
||||
let source_file_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") {
|
||||
let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o);
|
||||
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm)
|
||||
{
|
||||
return Err(format!(
|
||||
"unable to copy {} to {}: {}",
|
||||
source_file_regular.display(),
|
||||
obj_out_regular.display(),
|
||||
source_file_global_asm.display(),
|
||||
obj_out_global_asm.display(),
|
||||
err
|
||||
));
|
||||
}
|
||||
true
|
||||
Some(source_file_global_asm)
|
||||
} else {
|
||||
false
|
||||
None
|
||||
};
|
||||
|
||||
Ok(ModuleCodegenResult {
|
||||
@@ -487,8 +492,9 @@ fn reuse_workproduct_for_cgu(
|
||||
bytecode: None,
|
||||
assembly: None,
|
||||
llvm_ir: None,
|
||||
links_from_incr_cache: vec![source_file_regular],
|
||||
},
|
||||
module_global_asm: has_global_asm.then(|| CompiledModule {
|
||||
module_global_asm: source_file_global_asm.map(|source_file| CompiledModule {
|
||||
name: cgu.name().to_string(),
|
||||
kind: ModuleKind::Regular,
|
||||
object: Some(obj_out_global_asm),
|
||||
@@ -496,6 +502,7 @@ fn reuse_workproduct_for_cgu(
|
||||
bytecode: None,
|
||||
assembly: None,
|
||||
llvm_ir: None,
|
||||
links_from_incr_cache: vec![source_file],
|
||||
}),
|
||||
existing_work_product: Some((cgu.work_product_id(), work_product)),
|
||||
})
|
||||
@@ -637,6 +644,7 @@ fn emit_metadata_module(tcx: TyCtxt<'_>, metadata: &EncodedMetadata) -> Compiled
|
||||
bytecode: None,
|
||||
assembly: None,
|
||||
llvm_ir: None,
|
||||
links_from_incr_cache: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user