Skip to content

Commit ab1027a

Browse files
authored
Rollup merge of rust-lang#97058 - bjorn3:multi_artifact_work_products, r=nagisa
Various refactors to the incr comp workproduct handling This is the result of me looking into adding support for having multiple object files for a single codegen unit to incr comp. This is necessary to support inline assembly in cg_clif without requiring partial linking which is not supported on Windows and seems to fail on macOS for some reason. Cg_clif uses an external assembler to handle inline asm and thus produces one object file with regular functions and one object file containing compiled inline asm for each codegen unit which uses inline asm. Current incr comp can't handle this. This PR doesn't yet add support for this, but it makes it easier to do so.
2 parents bb55bd4 + e16c3b4 commit ab1027a

File tree

9 files changed

+75
-102
lines changed

9 files changed

+75
-102
lines changed

compiler/rustc_codegen_cranelift/src/driver/aot.rs

+12-21
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,7 @@ fn emit_module(
6666
let work_product = if backend_config.disable_incr_cache {
6767
None
6868
} else {
69-
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
70-
tcx.sess,
71-
&name,
72-
&Some(tmp_file.clone()),
73-
)
69+
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(tcx.sess, &name, &tmp_file)
7470
};
7571

7672
ModuleCodegenResult(
@@ -84,29 +80,24 @@ fn reuse_workproduct_for_cgu(
8480
cgu: &CodegenUnit<'_>,
8581
work_products: &mut FxHashMap<WorkProductId, WorkProduct>,
8682
) -> CompiledModule {
87-
let mut object = None;
88-
let work_product = cgu.work_product(tcx);
89-
if let Some(saved_file) = &work_product.saved_file {
90-
let obj_out =
91-
tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
92-
object = Some(obj_out.clone());
93-
let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &saved_file);
94-
if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
95-
tcx.sess.err(&format!(
96-
"unable to copy {} to {}: {}",
97-
source_file.display(),
98-
obj_out.display(),
99-
err
100-
));
101-
}
83+
let work_product = cgu.previous_work_product(tcx);
84+
let obj_out = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu.name().as_str()));
85+
let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &work_product.saved_file);
86+
if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
87+
tcx.sess.err(&format!(
88+
"unable to copy {} to {}: {}",
89+
source_file.display(),
90+
obj_out.display(),
91+
err
92+
));
10293
}
10394

10495
work_products.insert(cgu.work_product_id(), work_product);
10596

10697
CompiledModule {
10798
name: cgu.name().to_string(),
10899
kind: ModuleKind::Regular,
109-
object,
100+
object: Some(obj_out),
110101
dwarf_object: None,
111102
bytecode: None,
112103
}

compiler/rustc_codegen_ssa/src/back/write.rs

+25-29
Original file line numberDiff line numberDiff line change
@@ -494,12 +494,12 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
494494
let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir");
495495

496496
for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
497-
let path = module.object.as_ref().cloned();
498-
499-
if let Some((id, product)) =
500-
copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, &path)
501-
{
502-
work_products.insert(id, product);
497+
if let Some(path) = &module.object {
498+
if let Some((id, product)) =
499+
copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, path)
500+
{
501+
work_products.insert(id, product);
502+
}
503503
}
504504
}
505505

@@ -853,35 +853,31 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
853853
module: CachedModuleCodegen,
854854
module_config: &ModuleConfig,
855855
) -> WorkItemResult<B> {
856+
assert!(module_config.emit_obj != EmitObj::None);
857+
856858
let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap();
857-
let mut object = None;
858-
if let Some(saved_file) = module.source.saved_file {
859-
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name));
860-
object = Some(obj_out.clone());
861-
let source_file = in_incr_comp_dir(&incr_comp_session_dir, &saved_file);
862-
debug!(
863-
"copying pre-existing module `{}` from {:?} to {}",
864-
module.name,
865-
source_file,
866-
obj_out.display()
867-
);
868-
if let Err(err) = link_or_copy(&source_file, &obj_out) {
869-
let diag_handler = cgcx.create_diag_handler();
870-
diag_handler.err(&format!(
871-
"unable to copy {} to {}: {}",
872-
source_file.display(),
873-
obj_out.display(),
874-
err
875-
));
876-
}
859+
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name));
860+
let source_file = in_incr_comp_dir(&incr_comp_session_dir, &module.source.saved_file);
861+
debug!(
862+
"copying pre-existing module `{}` from {:?} to {}",
863+
module.name,
864+
source_file,
865+
obj_out.display()
866+
);
867+
if let Err(err) = link_or_copy(&source_file, &obj_out) {
868+
let diag_handler = cgcx.create_diag_handler();
869+
diag_handler.err(&format!(
870+
"unable to copy {} to {}: {}",
871+
source_file.display(),
872+
obj_out.display(),
873+
err
874+
));
877875
}
878876

879-
assert_eq!(object.is_some(), module_config.emit_obj != EmitObj::None);
880-
881877
WorkItemResult::Compiled(CompiledModule {
882878
name: module.name,
883879
kind: ModuleKind::Regular,
884-
object,
880+
object: Some(obj_out),
885881
dwarf_object: None,
886882
bytecode: None,
887883
})

compiler/rustc_codegen_ssa/src/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
716716
&ongoing_codegen.coordinator_send,
717717
CachedModuleCodegen {
718718
name: cgu.name().to_string(),
719-
source: cgu.work_product(tcx),
719+
source: cgu.previous_work_product(tcx),
720720
},
721721
);
722722
true
@@ -727,7 +727,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
727727
&ongoing_codegen.coordinator_send,
728728
CachedModuleCodegen {
729729
name: cgu.name().to_string(),
730-
source: cgu.work_product(tcx),
730+
source: cgu.previous_work_product(tcx),
731731
},
732732
);
733733
true

compiler/rustc_incremental/src/persist/load.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,16 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
162162

163163
for swp in work_products {
164164
let mut all_files_exist = true;
165-
if let Some(ref file_name) = swp.work_product.saved_file {
166-
let path = in_incr_comp_dir_sess(sess, file_name);
167-
if !path.exists() {
168-
all_files_exist = false;
169-
170-
if sess.opts.debugging_opts.incremental_info {
171-
eprintln!(
172-
"incremental: could not find file for work \
165+
let path = in_incr_comp_dir_sess(sess, &swp.work_product.saved_file);
166+
if !path.exists() {
167+
all_files_exist = false;
168+
169+
if sess.opts.debugging_opts.incremental_info {
170+
eprintln!(
171+
"incremental: could not find file for work \
173172
product: {}",
174-
path.display()
175-
);
176-
}
173+
path.display()
174+
);
177175
}
178176
}
179177

compiler/rustc_incremental/src/persist/save.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,15 @@ pub fn save_work_product_index(
107107
for (id, wp) in previous_work_products.iter() {
108108
if !new_work_products.contains_key(id) {
109109
work_product::delete_workproduct_files(sess, wp);
110-
debug_assert!(
111-
wp.saved_file.as_ref().map_or(true, |file_name| {
112-
!in_incr_comp_dir_sess(sess, &file_name).exists()
113-
})
114-
);
110+
debug_assert!(!in_incr_comp_dir_sess(sess, &wp.saved_file).exists());
115111
}
116112
}
117113

118114
// Check that we did not delete one of the current work-products:
119115
debug_assert!({
120116
new_work_products
121117
.iter()
122-
.flat_map(|(_, wp)| wp.saved_file.iter())
123-
.map(|name| in_incr_comp_dir_sess(sess, name))
118+
.map(|(_, wp)| in_incr_comp_dir_sess(sess, &wp.saved_file))
124119
.all(|path| path.exists())
125120
});
126121
}

compiler/rustc_incremental/src/persist/work_product.rs

+23-29
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,30 @@ use rustc_fs_util::link_or_copy;
77
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
88
use rustc_session::Session;
99
use std::fs as std_fs;
10-
use std::path::PathBuf;
10+
use std::path::Path;
1111

1212
/// Copies a CGU work product to the incremental compilation directory, so next compilation can find and reuse it.
1313
pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
1414
sess: &Session,
1515
cgu_name: &str,
16-
path: &Option<PathBuf>,
16+
path: &Path,
1717
) -> Option<(WorkProductId, WorkProduct)> {
1818
debug!("copy_cgu_workproduct_to_incr_comp_cache_dir({:?},{:?})", cgu_name, path);
1919
sess.opts.incremental.as_ref()?;
2020

21-
let saved_file = if let Some(path) = path {
22-
let file_name = format!("{}.o", cgu_name);
23-
let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
24-
match link_or_copy(path, &path_in_incr_dir) {
25-
Ok(_) => Some(file_name),
26-
Err(err) => {
27-
sess.warn(&format!(
28-
"error copying object file `{}` to incremental directory as `{}`: {}",
29-
path.display(),
30-
path_in_incr_dir.display(),
31-
err
32-
));
33-
return None;
34-
}
21+
let file_name = format!("{}.o", cgu_name);
22+
let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
23+
let saved_file = match link_or_copy(path, &path_in_incr_dir) {
24+
Ok(_) => file_name,
25+
Err(err) => {
26+
sess.warn(&format!(
27+
"error copying object file `{}` to incremental directory as `{}`: {}",
28+
path.display(),
29+
path_in_incr_dir.display(),
30+
err
31+
));
32+
return None;
3533
}
36-
} else {
37-
None
3834
};
3935

4036
let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_file };
@@ -45,17 +41,15 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
4541

4642
/// Removes files for a given work product.
4743
pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) {
48-
if let Some(ref file_name) = work_product.saved_file {
49-
let path = in_incr_comp_dir_sess(sess, file_name);
50-
match std_fs::remove_file(&path) {
51-
Ok(()) => {}
52-
Err(err) => {
53-
sess.warn(&format!(
54-
"file-system error deleting outdated file `{}`: {}",
55-
path.display(),
56-
err
57-
));
58-
}
44+
let path = in_incr_comp_dir_sess(sess, &work_product.saved_file);
45+
match std_fs::remove_file(&path) {
46+
Ok(()) => {}
47+
Err(err) => {
48+
sess.warn(&format!(
49+
"file-system error deleting outdated file `{}`: {}",
50+
path.display(),
51+
err
52+
));
5953
}
6054
}
6155
}

compiler/rustc_middle/src/mir/mono.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ impl<'tcx> CodegenUnit<'tcx> {
336336
WorkProductId::from_cgu_name(self.name().as_str())
337337
}
338338

339-
pub fn work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
339+
pub fn previous_work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
340340
let work_product_id = self.work_product_id();
341341
tcx.dep_graph
342342
.previous_work_product(&work_product_id)

compiler/rustc_query_system/src/dep_graph/dep_node.rs

-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ pub struct WorkProductId {
164164
impl WorkProductId {
165165
pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
166166
let mut hasher = StableHasher::new();
167-
cgu_name.len().hash(&mut hasher);
168167
cgu_name.hash(&mut hasher);
169168
WorkProductId { hash: hasher.finish() }
170169
}

compiler/rustc_query_system/src/dep_graph/graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ impl<K: DepKind> DepGraph<K> {
887887
pub struct WorkProduct {
888888
pub cgu_name: String,
889889
/// Saved file associated with this CGU.
890-
pub saved_file: Option<String>,
890+
pub saved_file: String,
891891
}
892892

893893
// Index type for `DepNodeData`'s edges.

0 commit comments

Comments
 (0)