1
Fork 0

Move copy to incr comp cache to codegen join phase

The copy depends on Session, which is only available on the main thread.
As such the copy can't be done on future codegen threads.
This commit is contained in:
bjorn3 2022-08-12 19:10:16 +00:00
parent 6206c4e927
commit c2f0b3a1bf
2 changed files with 50 additions and 38 deletions

View file

@ -23,7 +23,7 @@ use crate::{prelude::*, BackendConfig};
struct ModuleCodegenResult { struct ModuleCodegenResult {
module_regular: CompiledModule, module_regular: CompiledModule,
module_global_asm: Option<CompiledModule>, module_global_asm: Option<CompiledModule>,
work_product: Option<(WorkProductId, WorkProduct)>, existing_work_product: Option<(WorkProductId, WorkProduct)>,
} }
impl<HCX> HashStable<HCX> for ModuleCodegenResult { impl<HCX> HashStable<HCX> for ModuleCodegenResult {
@ -41,16 +41,44 @@ pub(crate) struct OngoingCodegen {
} }
impl OngoingCodegen { impl OngoingCodegen {
pub(crate) fn join(self) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) { pub(crate) fn join(
self,
sess: &Session,
backend_config: &BackendConfig,
) -> (CodegenResults, FxHashMap<WorkProductId, WorkProduct>) {
let mut work_products = FxHashMap::default(); let mut work_products = FxHashMap::default();
let mut modules = vec![]; let mut modules = vec![];
for module_codegen_result in self.modules { for module_codegen_result in self.modules {
let ModuleCodegenResult { module_regular, module_global_asm, work_product } = let ModuleCodegenResult { module_regular, module_global_asm, existing_work_product } =
module_codegen_result; module_codegen_result;
if let Some((work_product_id, work_product)) = work_product {
if let Some((work_product_id, work_product)) = existing_work_product {
work_products.insert(work_product_id, work_product); work_products.insert(work_product_id, work_product);
} else {
let work_product = if backend_config.disable_incr_cache {
None
} else if let Some(module_global_asm) = &module_global_asm {
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
sess,
&module_regular.name,
&[
("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 {
work_products.insert(work_product_id, work_product);
}
} }
modules.push(module_regular); modules.push(module_regular);
if let Some(module_global_asm) = module_global_asm { if let Some(module_global_asm) = module_global_asm {
modules.push(module_global_asm); modules.push(module_global_asm);
@ -84,7 +112,6 @@ fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) ->
fn emit_cgu( fn emit_cgu(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
backend_config: &BackendConfig,
name: String, name: String,
module: ObjectModule, module: ObjectModule,
debug: Option<DebugContext<'_>>, debug: Option<DebugContext<'_>>,
@ -101,22 +128,6 @@ fn emit_cgu(
let module_regular = emit_module(tcx, product.object, ModuleKind::Regular, name.clone()); let module_regular = emit_module(tcx, product.object, ModuleKind::Regular, name.clone());
let work_product = if backend_config.disable_incr_cache {
None
} else if let Some(global_asm_object_file) = &global_asm_object_file {
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
tcx.sess,
&name,
&[("o", &module_regular.object.as_ref().unwrap()), ("asm.o", global_asm_object_file)],
)
} else {
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
tcx.sess,
&name,
&[("o", &module_regular.object.as_ref().unwrap())],
)
};
ModuleCodegenResult { ModuleCodegenResult {
module_regular, module_regular,
module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule { module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule {
@ -126,7 +137,7 @@ fn emit_cgu(
dwarf_object: None, dwarf_object: None,
bytecode: None, bytecode: None,
}), }),
work_product, existing_work_product: None,
} }
} }
@ -205,7 +216,7 @@ fn reuse_workproduct_for_cgu(tcx: TyCtxt<'_>, cgu: &CodegenUnit<'_>) -> ModuleCo
} else { } else {
None None
}, },
work_product: Some((cgu.work_product_id(), work_product)), existing_work_product: Some((cgu.work_product_id(), work_product)),
} }
} }
@ -271,7 +282,6 @@ fn module_codegen(
let codegen_result = tcx.sess.time("write object file", || { let codegen_result = tcx.sess.time("write object file", || {
emit_cgu( emit_cgu(
tcx, tcx,
&backend_config,
cgu.name().as_str().to_string(), cgu.name().as_str().to_string(),
module, module,
debug_context, debug_context,

View file

@ -25,7 +25,7 @@ extern crate rustc_target;
extern crate rustc_driver; extern crate rustc_driver;
use std::any::Any; use std::any::Any;
use std::cell::Cell; use std::cell::{Cell, RefCell};
use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::CodegenResults;
@ -158,7 +158,7 @@ impl<'tcx> CodegenCx<'tcx> {
} }
pub struct CraneliftCodegenBackend { pub struct CraneliftCodegenBackend {
pub config: Option<BackendConfig>, pub config: RefCell<Option<BackendConfig>>,
} }
impl CodegenBackend for CraneliftCodegenBackend { impl CodegenBackend for CraneliftCodegenBackend {
@ -168,6 +168,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
Lto::No | Lto::ThinLocal => {} Lto::No | Lto::ThinLocal => {}
Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."), Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."),
} }
let mut config = self.config.borrow_mut();
if config.is_none() {
let new_config = BackendConfig::from_opts(&sess.opts.cg.llvm_args)
.unwrap_or_else(|err| sess.fatal(&err));
*config = Some(new_config);
}
} }
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> { fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<rustc_span::Symbol> {
@ -185,15 +192,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
need_metadata_module: bool, need_metadata_module: bool,
) -> Box<dyn Any> { ) -> Box<dyn Any> {
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
let config = if let Some(config) = self.config.clone() { let config = self.config.borrow().clone().unwrap();
config
} else {
if !tcx.sess.unstable_options() && !tcx.sess.opts.cg.llvm_args.is_empty() {
tcx.sess.fatal("`-Z unstable-options` must be passed to allow configuring cg_clif");
}
BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
.unwrap_or_else(|err| tcx.sess.fatal(&err))
};
match config.codegen_mode { match config.codegen_mode {
CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module), CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module),
CodegenMode::Jit | CodegenMode::JitLazy => { CodegenMode::Jit | CodegenMode::JitLazy => {
@ -209,10 +208,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
fn join_codegen( fn join_codegen(
&self, &self,
ongoing_codegen: Box<dyn Any>, ongoing_codegen: Box<dyn Any>,
_sess: &Session, sess: &Session,
_outputs: &OutputFilenames, _outputs: &OutputFilenames,
) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> { ) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorGuaranteed> {
Ok(ongoing_codegen.downcast::<driver::aot::OngoingCodegen>().unwrap().join()) Ok(ongoing_codegen
.downcast::<driver::aot::OngoingCodegen>()
.unwrap()
.join(sess, self.config.borrow().as_ref().unwrap()))
} }
fn link( fn link(
@ -309,5 +311,5 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
/// This is the entrypoint for a hot plugged rustc_codegen_cranelift /// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle] #[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> { pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
Box::new(CraneliftCodegenBackend { config: None }) Box::new(CraneliftCodegenBackend { config: RefCell::new(None) })
} }