about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_driver/driver.rs7
-rw-r--r--src/librustc_trans/back/write.rs97
-rw-r--r--src/librustc_trans/base.rs73
3 files changed, 90 insertions, 87 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 44c046131f1..ba4a6c0d67d 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -229,7 +229,7 @@ pub fn compile_input(sess: &Session,
         sess.code_stats.borrow().print_type_sizes();
     }
 
-    let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans, &outputs);
+    let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
 
     controller_entry_point!(after_llvm,
                             sess,
@@ -1071,10 +1071,9 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 /// Run LLVM itself, producing a bitcode file, assembly file or object file
 /// as a side effect.
 pub fn phase_5_run_llvm_passes(sess: &Session,
-                               trans: write::OngoingCrateTranslation,
-                               outputs: &OutputFilenames)
+                               trans: write::OngoingCrateTranslation)
                                -> (CompileResult, trans::CrateTranslation) {
-    let trans = trans.join(sess, outputs);
+    let trans = trans.join(sess);
 
     if sess.opts.debugging_opts.incremental_info {
         write::dump_incremental_data(&trans);
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 280951e0dc8..c1c85394698 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -662,11 +662,8 @@ fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
 }
 
 pub fn run_passes(sess: &Session,
-                  modules: Vec<ModuleTranslation>,
-                  metadata_module: ModuleTranslation,
-                  allocator_module: Option<ModuleTranslation>,
                   crate_output: &OutputFilenames,
-
+                  total_work_item_count: usize,
                   crate_name: Symbol,
                   link: LinkMeta,
                   metadata: EncodedMetadata,
@@ -695,12 +692,6 @@ pub fn run_passes(sess: &Session,
         sess.opts.output_types.clone()
     };
 
-    // Sanity check
-    assert!(modules.len() == sess.opts.cg.codegen_units ||
-            sess.opts.debugging_opts.incremental.is_some() ||
-            !sess.opts.output_types.should_trans() ||
-            sess.opts.debugging_opts.no_trans);
-
     // Figure out what we actually need to build.
 
     let mut modules_config = ModuleConfig::new(sess, sess.opts.cg.passes.clone());
@@ -776,38 +767,11 @@ pub fn run_passes(sess: &Session,
     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
-    // LIFO order, just because it's a tiny bit simpler that way.  (The order
-    // doesn't actually matter.)
-    let mut work_items = Vec::with_capacity(1 + modules.len());
-
-    {
-        let work = build_work_item(metadata_module,
-                                   metadata_config.clone(sess),
-                                   crate_output.clone());
-        work_items.push(work);
-    }
-
-    if let Some(allocator) = allocator_module {
-        let work = build_work_item(allocator,
-                                   allocator_config.clone(sess),
-                                   crate_output.clone());
-        work_items.push(work);
-    }
-
-    for mtrans in modules {
-        let work = build_work_item(mtrans,
-                                   modules_config.clone(sess),
-                                   crate_output.clone());
-        work_items.push(work);
-    }
-
     let client = sess.jobserver_from_env.clone().unwrap_or_else(|| {
         // Pick a "reasonable maximum" if we don't otherwise have a jobserver in
         // our environment, capping out at 32 so we don't take everything down
         // by hogging the process run queue.
-        let num_workers = cmp::min(work_items.len() - 1, 32);
+        let num_workers = cmp::min(total_work_item_count - 1, 32);
         Client::new(num_workers).expect("failed to create jobserver")
     });
 
@@ -816,16 +780,13 @@ pub fn run_passes(sess: &Session,
     let (coordinator_send, coordinator_receive) = channel();
 
     let coordinator_thread = start_executing_work(sess,
-                                                  work_items.len(),
+                                                  total_work_item_count,
                                                   shared_emitter,
                                                   trans_worker_send,
                                                   coordinator_send.clone(),
                                                   coordinator_receive,
                                                   client,
                                                   exported_symbols.clone());
-    for work_item in work_items {
-        coordinator_send.send(Message::WorkItem(work_item)).unwrap();
-    }
 
     OngoingCrateTranslation {
         crate_name,
@@ -837,6 +798,12 @@ pub fn run_passes(sess: &Session,
         linker_info,
         no_integrated_as,
 
+        regular_module_config: modules_config,
+        metadata_module_config: metadata_config,
+        allocator_module_config: allocator_config,
+
+        output_filenames: crate_output.clone(),
+        coordinator_send,
         shared_emitter_main,
         future: coordinator_thread
     }
@@ -1583,22 +1550,29 @@ pub struct OngoingCrateTranslation {
     pub linker_info: LinkerInfo,
     pub no_integrated_as: bool,
 
+    output_filenames: OutputFilenames,
+    regular_module_config: ModuleConfig,
+    metadata_module_config: ModuleConfig,
+    allocator_module_config: ModuleConfig,
+
+    coordinator_send: Sender<Message>,
     shared_emitter_main: SharedEmitterMain,
     future: thread::JoinHandle<CompiledModules>,
 }
 
 impl OngoingCrateTranslation {
-    pub fn join(self,
-                sess: &Session,
-                outputs: &OutputFilenames)
-                -> CrateTranslation {
+    pub fn join(self, sess: &Session) -> CrateTranslation {
         self.shared_emitter_main.check(sess, true);
         let compiled_modules = self.future.join().unwrap();
 
         sess.abort_if_errors();
 
-        copy_module_artifacts_into_incr_comp_cache(sess, &compiled_modules, outputs);
-        produce_final_output_artifacts(sess, &compiled_modules, outputs);
+        copy_module_artifacts_into_incr_comp_cache(sess,
+                                                   &compiled_modules,
+                                                   &self.output_filenames);
+        produce_final_output_artifacts(sess,
+                                       &compiled_modules,
+                                       &self.output_filenames);
 
         // FIXME: time_llvm_passes support - does this use a global context or
         // something?
@@ -1621,24 +1595,41 @@ impl OngoingCrateTranslation {
         };
 
         if self.no_integrated_as {
-            run_assembler(sess, outputs);
+            run_assembler(sess,  &self.output_filenames);
 
             // HACK the linker expects the object file to be named foo.0.o but
             // `run_assembler` produces an object named just foo.o. Rename it if we
             // are going to build an executable
             if sess.opts.output_types.contains_key(&OutputType::Exe) {
-                let f = outputs.path(OutputType::Object);
+                let f =  self.output_filenames.path(OutputType::Object);
                 rename_or_copy_remove(&f,
-                         f.with_file_name(format!("{}.0.o",
-                                                  f.file_stem().unwrap().to_string_lossy()))).unwrap();
+                    f.with_file_name(format!("{}.0.o",
+                                             f.file_stem().unwrap().to_string_lossy()))).unwrap();
             }
 
             // Remove assembly source, unless --save-temps was specified
             if !sess.opts.cg.save_temps {
-                fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();
+                fs::remove_file(&self.output_filenames
+                                     .temp_path(OutputType::Assembly, None)).unwrap();
             }
         }
 
         trans
     }
+
+    pub fn submit_translated_module_to_llvm(&self,
+                                            sess: &Session,
+                                            mtrans: ModuleTranslation) {
+        let module_config = match mtrans.kind {
+            ModuleKind::Regular => self.regular_module_config.clone(sess),
+            ModuleKind::Metadata => self.metadata_module_config.clone(sess),
+            ModuleKind::Allocator => self.allocator_module_config.clone(sess),
+        };
+
+        let work_item = build_work_item(mtrans,
+                                        module_config,
+                                        self.output_filenames.clone());
+
+        drop(self.coordinator_send.send(Message::WorkItem(work_item)));
+    }
 }
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 53fb330e364..144c1efd23b 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -963,20 +963,22 @@ 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);
-        return write::run_passes(tcx.sess,
-                                 vec![],
-                                 metadata_module,
-                                 None,
-                                 output_filenames,
-
-                                 tcx.crate_name(LOCAL_CRATE),
-                                 link_meta,
-                                 metadata,
-                                 Arc::new(empty_exported_symbols),
-                                 no_builtins,
-                                 None,
-                                 linker_info,
-                                 false);
+        let ongoing_translation = write::run_passes(
+            tcx.sess,
+            output_filenames,
+            1,
+            tcx.crate_name(LOCAL_CRATE),
+            link_meta,
+            metadata,
+            Arc::new(empty_exported_symbols),
+            no_builtins,
+            None,
+            linker_info,
+            false);
+
+        ongoing_translation.submit_translated_module_to_llvm(tcx.sess, metadata_module);
+
+        return ongoing_translation;
     }
 
     let exported_symbols = Arc::new(ExportedSymbols::compute(tcx,
@@ -1236,22 +1238,33 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                               link_meta.crate_hash));
     // ---
 
-    time(sess.time_passes(),
-         "LLVM passes",
-         || write::run_passes(sess,
-                              modules,
-                              metadata_module,
-                              allocator_module,
-                              outputs,
-
-                              tcx.crate_name(LOCAL_CRATE),
-                              link_meta,
-                              metadata,
-                              exported_symbols,
-                              no_builtins,
-                              windows_subsystem,
-                              linker_info,
-                              no_integrated_as))
+    let total_module_count = modules.len() + 1 +
+        if allocator_module.is_some() { 1 } else { 0 };
+
+    let ongoing_translation = write::run_passes(
+        sess,
+        outputs,
+        total_module_count,
+        tcx.crate_name(LOCAL_CRATE),
+        link_meta,
+        metadata,
+        exported_symbols,
+        no_builtins,
+        windows_subsystem,
+        linker_info,
+        no_integrated_as);
+
+    ongoing_translation.submit_translated_module_to_llvm(sess, metadata_module);
+
+    for mtrans in modules {
+        ongoing_translation.submit_translated_module_to_llvm(sess, mtrans);
+    }
+
+    if let Some(allocator_module) = allocator_module {
+        ongoing_translation.submit_translated_module_to_llvm(sess, allocator_module);
+    }
+
+    ongoing_translation
 }
 
 #[inline(never)] // give this a place in the profiler