about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-07-26 11:41:34 +0200
committerMichael Woerister <michaelwoerister@posteo.net>2017-07-31 15:15:09 +0200
commitf3ce50558f6ba3f42011833a36a43f8026bf4863 (patch)
tree83422f4510b5d0de96281b639b27e983ae86278e
parent28589ec3e474a7cce15f761d6bcd24f80aebdee1 (diff)
downloadrust-f3ce50558f6ba3f42011833a36a43f8026bf4863.tar.gz
rust-f3ce50558f6ba3f42011833a36a43f8026bf4863.zip
async-llvm(11): Delay joining ongoing translation until right before linking.
-rw-r--r--src/librustc_trans/back/write.rs105
-rw-r--r--src/librustc_trans/base.rs103
2 files changed, 98 insertions, 110 deletions
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index bae50da3209..c33d65e3e53 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -259,10 +259,10 @@ impl ModuleConfig {
         }
     }
 
-    fn set_flags(&mut self, sess: &Session, trans: &OngoingCrateTranslation) {
+    fn set_flags(&mut self, sess: &Session, no_builtins: bool) {
         self.no_verify = sess.no_verify();
         self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
-        self.no_builtins = trans.no_builtins;
+        self.no_builtins = no_builtins;
         self.time_passes = sess.time_passes();
         self.inline_threshold = sess.opts.cg.inline_threshold;
         self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;
@@ -662,12 +662,21 @@ fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
 }
 
 pub fn run_passes(sess: &Session,
-                  trans: &OngoingCrateTranslation,
                   modules: Vec<ModuleTranslation>,
                   metadata_module: ModuleTranslation,
                   allocator_module: Option<ModuleTranslation>,
-                  output_types: &OutputTypes,
-                  crate_output: &OutputFilenames) {
+                  output_types_override: &OutputTypes,
+                  crate_output: &OutputFilenames,
+
+                  crate_name: Symbol,
+                  link: LinkMeta,
+                  metadata: EncodedMetadata,
+                  exported_symbols: Arc<ExportedSymbols>,
+                  no_builtins: bool,
+                  windows_subsystem: Option<String>,
+                  linker_info: LinkerInfo,
+                  no_integrated_as: bool)
+                  -> OngoingCrateTranslation {
     // It's possible that we have `codegen_units > 1` but only one item in
     // `trans.modules`.  We could theoretically proceed and do LTO in that
     // case, but it would be confusing to have the validity of
@@ -732,7 +741,7 @@ pub fn run_passes(sess: &Session,
         modules_config.emit_bc = true;
     }
 
-    for output_type in output_types.keys() {
+    for output_type in output_types_override.keys() {
         match *output_type {
             OutputType::Bitcode => { modules_config.emit_bc = true; }
             OutputType::LlvmAssembly => { modules_config.emit_ir = true; }
@@ -758,9 +767,9 @@ pub fn run_passes(sess: &Session,
         }
     }
 
-    modules_config.set_flags(sess, trans);
-    metadata_config.set_flags(sess, trans);
-    allocator_config.set_flags(sess, trans);
+    modules_config.set_flags(sess, no_builtins);
+    metadata_config.set_flags(sess, no_builtins);
+    allocator_config.set_flags(sess, no_builtins);
 
 
     // Populate a buffer with a list of codegen threads.  Items are processed in
@@ -797,12 +806,8 @@ pub fn run_passes(sess: &Session,
         Client::new(num_workers).expect("failed to create jobserver")
     });
 
-    drop(modules_config);
-    drop(metadata_config);
-    drop(allocator_config);
-
     let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
-    let (trans_worker_send, trans_worker_receive) = channel();
+    let (trans_worker_send, _trans_worker_receive) = channel();
     let (coordinator_send, coordinator_receive) = channel();
 
     let coordinator_thread = start_executing_work(sess,
@@ -812,47 +817,24 @@ pub fn run_passes(sess: &Session,
                                                   coordinator_send.clone(),
                                                   coordinator_receive,
                                                   client,
-                                                  trans.exported_symbols.clone());
+                                                  exported_symbols.clone());
     for work_item in work_items {
         coordinator_send.send(Message::WorkItem(work_item)).unwrap();
     }
 
-    loop {
-        shared_emitter_main.check(sess, false);
-
-        match trans_worker_receive.recv() {
-            Err(_) => {
-                // An `Err` here means that all senders for this channel have
-                // been closed. This could happen because all work has
-                // completed successfully or there has been some error.
-                // At this point we don't care which it is.
-                break
-            }
-
-            Ok(Message::CheckErrorMessages) => continue,
-            Ok(msg) => {
-                bug!("unexpected message {:?}", msg);
-            }
-        }
-    }
-
-    let compiled_modules = coordinator_thread.join().unwrap();
-
-    // Just in case, check this on the way out.
-    shared_emitter_main.check(sess, false);
-    sess.diagnostic().abort_if_errors();
-
-    copy_module_artifacts_into_incr_comp_cache(sess, &compiled_modules, crate_output);
-
-    produce_final_output_artifacts(sess, &compiled_modules, crate_output);
-
-    // FIXME: time_llvm_passes support - does this use a global context or
-    // something?
-    if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
-        unsafe { llvm::LLVMRustPrintPassTimings(); }
+    OngoingCrateTranslation {
+        crate_name,
+        link,
+        metadata,
+        exported_symbols,
+        no_builtins,
+        windows_subsystem,
+        linker_info,
+        no_integrated_as,
+
+        shared_emitter_main,
+        future: coordinator_thread
     }
-
-    *trans.result.borrow_mut() = Some(compiled_modules);
 }
 
 fn copy_module_artifacts_into_incr_comp_cache(sess: &Session,
@@ -1596,8 +1578,8 @@ pub struct OngoingCrateTranslation {
     pub linker_info: LinkerInfo,
     pub no_integrated_as: bool,
 
-    // This will be replaced by a Future.
-    pub result: ::std::cell::RefCell<Option<CompiledModules>>,
+    shared_emitter_main: SharedEmitterMain,
+    future: thread::JoinHandle<CompiledModules>,
 }
 
 impl OngoingCrateTranslation {
@@ -1605,8 +1587,19 @@ impl OngoingCrateTranslation {
                 sess: &Session,
                 outputs: &OutputFilenames)
                 -> CrateTranslation {
+        self.shared_emitter_main.check(sess, true);
+        let compiled_modules = self.future.join().unwrap();
+
+        sess.abort_if_errors();
 
-        let result = self.result.borrow_mut().take().unwrap();
+        copy_module_artifacts_into_incr_comp_cache(sess, &compiled_modules, outputs);
+        produce_final_output_artifacts(sess, &compiled_modules, outputs);
+
+        // FIXME: time_llvm_passes support - does this use a global context or
+        // something?
+        if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
+            unsafe { llvm::LLVMRustPrintPassTimings(); }
+        }
 
         let trans = CrateTranslation {
             crate_name: self.crate_name,
@@ -1617,9 +1610,9 @@ impl OngoingCrateTranslation {
             windows_subsystem: self.windows_subsystem,
             linker_info: self.linker_info,
 
-            modules: result.modules,
-            metadata_module: result.metadata_module,
-            allocator_module: result.allocator_module,
+            modules: compiled_modules.modules,
+            metadata_module: compiled_modules.metadata_module,
+            allocator_module: compiled_modules.allocator_module,
         };
 
         if self.no_integrated_as {
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 6eb38dc52ee..65041e60fe3 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -32,7 +32,7 @@ use assert_module_sources;
 use back::link;
 use back::linker::LinkerInfo;
 use back::symbol_export::{self, ExportedSymbols};
-use back::write::OngoingCrateTranslation;
+use back::write::{self, OngoingCrateTranslation};
 use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
 use llvm;
 use metadata;
@@ -963,27 +963,21 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
        !tcx.sess.opts.output_types.should_trans() {
         let empty_exported_symbols = ExportedSymbols::empty();
         let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
-        let crate_translation = OngoingCrateTranslation {
-            crate_name: tcx.crate_name(LOCAL_CRATE),
-            link: link_meta,
-            metadata: metadata,
-            exported_symbols: Arc::new(empty_exported_symbols),
-            no_builtins: no_builtins,
-            linker_info: linker_info,
-            windows_subsystem: None,
-            no_integrated_as: false,
-            result: ::std::cell::RefCell::new(None),
-        };
-
-        ::back::write::run_passes(tcx.sess,
-                                  &crate_translation,
-                                  vec![],
-                                  metadata_module,
-                                  None,
-                                  &output_filenames.outputs,
-                                  output_filenames);
-
-        return crate_translation;
+        return write::run_passes(tcx.sess,
+                                 vec![],
+                                 metadata_module,
+                                 None,
+                                 &output_filenames.outputs,
+                                 output_filenames,
+
+                                 tcx.crate_name(LOCAL_CRATE),
+                                 link_meta,
+                                 metadata,
+                                 Arc::new(empty_exported_symbols),
+                                 no_builtins,
+                                 None,
+                                 linker_info,
+                                 false);
     }
 
     let exported_symbols = Arc::new(ExportedSymbols::compute(tcx,
@@ -1231,19 +1225,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
          (outputs.outputs.contains_key(&OutputType::Object) ||
           outputs.outputs.contains_key(&OutputType::Exe)));
 
-    let crate_translation = OngoingCrateTranslation {
-        crate_name: tcx.crate_name(LOCAL_CRATE),
-        link: link_meta,
-        metadata: metadata,
-        exported_symbols,
-        no_builtins,
-        linker_info,
-        windows_subsystem,
-        no_integrated_as,
-
-        result: ::std::cell::RefCell::new(None),
-    };
-
     time(sess.time_passes(),
          "assert dep graph",
          || rustc_incremental::assert_dep_graph(tcx));
@@ -1252,34 +1233,48 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
          "serialize dep graph",
          || rustc_incremental::save_dep_graph(tcx,
                                               incremental_hashes_map,
-                                              &crate_translation.metadata.hashes,
-                                              crate_translation.link.crate_hash));
+                                              &metadata.hashes,
+                                              link_meta.crate_hash));
     // ---
 
     if no_integrated_as {
         let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
         time(sess.time_passes(),
              "LLVM passes",
-             || ::back::write::run_passes(sess,
-                                          &crate_translation,
-                                          modules,
-                                          metadata_module,
-                                          allocator_module,
-                                          &output_types,
-                                          outputs))
+             || write::run_passes(sess,
+                                  modules,
+                                  metadata_module,
+                                  allocator_module,
+                                  &output_types,
+                                  outputs,
+
+                                  tcx.crate_name(LOCAL_CRATE),
+                                  link_meta,
+                                  metadata,
+                                  exported_symbols,
+                                  no_builtins,
+                                  windows_subsystem,
+                                  linker_info,
+                                  no_integrated_as))
     } else {
         time(sess.time_passes(),
              "LLVM passes",
-             || ::back::write::run_passes(sess,
-                                          &crate_translation,
-                                          modules,
-                                          metadata_module,
-                                          allocator_module,
-                                          &sess.opts.output_types,
-                                          outputs))
-    };
-
-    crate_translation
+             || write::run_passes(sess,
+                                  modules,
+                                  metadata_module,
+                                  allocator_module,
+                                  &sess.opts.output_types,
+                                  outputs,
+
+                                  tcx.crate_name(LOCAL_CRATE),
+                                  link_meta,
+                                  metadata,
+                                  exported_symbols,
+                                  no_builtins,
+                                  windows_subsystem,
+                                  linker_info,
+                                  no_integrated_as))
+    }
 }
 
 #[inline(never)] // give this a place in the profiler