about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-08-12 19:10:16 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2022-08-12 19:10:16 +0000
commitc2f0b3a1bf5ed437df3e276960f64bf3c47222e0 (patch)
treecdb5557952c1e226182b02ce6f5e4f8fa456ab5b
parent6206c4e927595afcaef0496025512282f847f645 (diff)
downloadrust-c2f0b3a1bf5ed437df3e276960f64bf3c47222e0.tar.gz
rust-c2f0b3a1bf5ed437df3e276960f64bf3c47222e0.zip
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.
-rw-r--r--src/driver/aot.rs58
-rw-r--r--src/lib.rs30
2 files changed, 50 insertions, 38 deletions
diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index ff6310bd8af..7e5e3453834 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -23,7 +23,7 @@ use crate::{prelude::*, BackendConfig};
 struct ModuleCodegenResult {
     module_regular: CompiledModule,
     module_global_asm: Option<CompiledModule>,
-    work_product: Option<(WorkProductId, WorkProduct)>,
+    existing_work_product: Option<(WorkProductId, WorkProduct)>,
 }
 
 impl<HCX> HashStable<HCX> for ModuleCodegenResult {
@@ -41,16 +41,44 @@ pub(crate) struct 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 modules = vec![];
 
         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;
-            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);
+            } 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);
             if let Some(module_global_asm) = 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(
     tcx: TyCtxt<'_>,
-    backend_config: &BackendConfig,
     name: String,
     module: ObjectModule,
     debug: Option<DebugContext<'_>>,
@@ -101,22 +128,6 @@ fn emit_cgu(
 
     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 {
         module_regular,
         module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule {
@@ -126,7 +137,7 @@ fn emit_cgu(
             dwarf_object: None,
             bytecode: None,
         }),
-        work_product,
+        existing_work_product: None,
     }
 }
 
@@ -205,7 +216,7 @@ fn reuse_workproduct_for_cgu(tcx: TyCtxt<'_>, cgu: &CodegenUnit<'_>) -> ModuleCo
         } else {
             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", || {
         emit_cgu(
             tcx,
-            &backend_config,
             cgu.name().as_str().to_string(),
             module,
             debug_context,
diff --git a/src/lib.rs b/src/lib.rs
index 6ea160d26ce..909f4f00f1e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -25,7 +25,7 @@ extern crate rustc_target;
 extern crate rustc_driver;
 
 use std::any::Any;
-use std::cell::Cell;
+use std::cell::{Cell, RefCell};
 
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::CodegenResults;
@@ -158,7 +158,7 @@ impl<'tcx> CodegenCx<'tcx> {
 }
 
 pub struct CraneliftCodegenBackend {
-    pub config: Option<BackendConfig>,
+    pub config: RefCell<Option<BackendConfig>>,
 }
 
 impl CodegenBackend for CraneliftCodegenBackend {
@@ -168,6 +168,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
             Lto::No | Lto::ThinLocal => {}
             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> {
@@ -185,15 +192,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
         need_metadata_module: bool,
     ) -> Box<dyn Any> {
         tcx.sess.abort_if_errors();
-        let config = if let Some(config) = self.config.clone() {
-            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))
-        };
+        let config = self.config.borrow().clone().unwrap();
         match config.codegen_mode {
             CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module),
             CodegenMode::Jit | CodegenMode::JitLazy => {
@@ -209,10 +208,13 @@ impl CodegenBackend for CraneliftCodegenBackend {
     fn join_codegen(
         &self,
         ongoing_codegen: Box<dyn Any>,
-        _sess: &Session,
+        sess: &Session,
         _outputs: &OutputFilenames,
     ) -> 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(
@@ -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
 #[no_mangle]
 pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
-    Box::new(CraneliftCodegenBackend { config: None })
+    Box::new(CraneliftCodegenBackend { config: RefCell::new(None) })
 }