about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2017-07-21 15:14:21 +0200
committerMichael Woerister <michaelwoerister@posteo.net>2017-07-31 14:55:13 +0200
commitc4adeceb37e4bdf9be3b70ff2454b121531466ce (patch)
treece35b127f2b0880bdebf05d04c9401584bd329cf
parent2a6828e7f1ed3163a2797f0a111570ef130f7b6b (diff)
downloadrust-c4adeceb37e4bdf9be3b70ff2454b121531466ce.tar.gz
rust-c4adeceb37e4bdf9be3b70ff2454b121531466ce.zip
async-llvm(1): Run LLVM already in trans_crate().
-rw-r--r--src/librustc_driver/driver.rs57
-rw-r--r--src/librustc_trans/back/write.rs12
-rw-r--r--src/librustc_trans/base.rs66
-rw-r--r--src/librustc_trans/lib.rs66
4 files changed, 129 insertions, 72 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index c592882a1e4..1bc3f59ed04 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -15,8 +15,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_mir as mir;
 use rustc::session::{Session, CompileResult};
 use rustc::session::CompileIncomplete;
-use rustc::session::config::{self, Input, OutputFilenames, OutputType,
-                             OutputTypes};
+use rustc::session::config::{self, Input, OutputFilenames, OutputType};
 use rustc::session::search_paths::PathKind;
 use rustc::lint;
 use rustc::middle::{self, dependency_format, stability, reachable};
@@ -26,7 +25,6 @@ use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
 use rustc::traits;
 use rustc::util::common::{ErrorReported, time};
 use rustc::util::nodemap::NodeSet;
-use rustc::util::fs::rename_or_copy_remove;
 use rustc_allocator as allocator;
 use rustc_borrowck as borrowck;
 use rustc_incremental::{self, IncrementalHashesMap};
@@ -231,7 +229,7 @@ pub fn compile_input(sess: &Session,
         sess.code_stats.borrow().print_type_sizes();
     }
 
-    let phase5_result = phase_5_run_llvm_passes(sess, &trans, &outputs);
+    let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans, &outputs);
 
     controller_entry_point!(after_llvm,
                             sess,
@@ -1057,7 +1055,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                            analysis: ty::CrateAnalysis,
                                            incremental_hashes_map: &IncrementalHashesMap,
                                            output_filenames: &OutputFilenames)
-                                           -> trans::CrateTranslation {
+                                           -> trans::OngoingCrateTranslation {
     let time_passes = tcx.sess.time_passes();
 
     time(time_passes,
@@ -1069,61 +1067,26 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
              "translation",
              move || trans::trans_crate(tcx, analysis, &incremental_hashes_map, output_filenames));
 
-    time(time_passes,
-         "assert dep graph",
-         || rustc_incremental::assert_dep_graph(tcx));
-
-    time(time_passes,
-         "serialize dep graph",
-         || rustc_incremental::save_dep_graph(tcx,
-                                              &incremental_hashes_map,
-                                              &translation.metadata.hashes,
-                                              translation.link.crate_hash));
     translation
 }
 
 /// 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: &trans::CrateTranslation,
-                               outputs: &OutputFilenames) -> CompileResult {
-    if sess.opts.cg.no_integrated_as ||
-        (sess.target.target.options.no_integrated_as &&
-         (outputs.outputs.contains_key(&OutputType::Object) ||
-          outputs.outputs.contains_key(&OutputType::Exe)))
-    {
-        let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
-        time(sess.time_passes(),
-             "LLVM passes",
-             || write::run_passes(sess, trans, &output_types, outputs));
-
-        write::run_assembler(sess, outputs);
-
-        // 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);
-            rename_or_copy_remove(&f,
-                     f.with_file_name(format!("{}.0.o",
-                                              f.file_stem().unwrap().to_string_lossy()))).unwrap();
-        }
+                               trans: trans::OngoingCrateTranslation,
+                               outputs: &OutputFilenames)
+                               -> (CompileResult, trans::CrateTranslation) {
+    let trans = trans.join(sess, outputs);
 
-        // Remove assembly source, unless --save-temps was specified
-        if !sess.opts.cg.save_temps {
-            fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();
-        }
-    } else {
-        time(sess.time_passes(),
-             "LLVM passes",
-             || write::run_passes(sess, trans, &sess.opts.output_types, outputs));
+    if sess.opts.debugging_opts.incremental_info {
+        write::dump_incremental_data(&trans);
     }
 
     time(sess.time_passes(),
          "serialize work products",
          move || rustc_incremental::save_work_products(sess));
 
-    sess.compile_status()
+    (sess.compile_status(), trans)
 }
 
 /// Run the linker on any artifacts that resulted from the LLVM run.
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 26553c85023..4af4ee664a2 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -18,7 +18,7 @@ use rustc::session::Session;
 use llvm;
 use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
 use llvm::SMDiagnosticRef;
-use {CrateTranslation, ModuleLlvm, ModuleSource, ModuleTranslation};
+use {CrateTranslation, OngoingCrateTranslation, ModuleLlvm, ModuleSource, ModuleTranslation};
 use rustc::hir::def_id::CrateNum;
 use rustc::util::common::{time, time_depth, set_time_depth, path2cstr};
 use rustc::util::fs::link_or_copy;
@@ -255,7 +255,7 @@ impl ModuleConfig {
         }
     }
 
-    fn set_flags(&mut self, sess: &Session, trans: &CrateTranslation) {
+    fn set_flags(&mut self, sess: &Session, trans: &OngoingCrateTranslation) {
         self.no_verify = sess.no_verify();
         self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
         self.no_builtins = trans.no_builtins;
@@ -614,7 +614,7 @@ pub fn cleanup_llvm(trans: &CrateTranslation) {
 }
 
 pub fn run_passes(sess: &Session,
-                  trans: &CrateTranslation,
+                  trans: &OngoingCrateTranslation,
                   output_types: &OutputTypes,
                   crate_output: &OutputFilenames) {
     // It's possible that we have `codegen_units > 1` but only one item in
@@ -748,10 +748,6 @@ pub fn run_passes(sess: &Session,
         work_items.push(work);
     }
 
-    if sess.opts.debugging_opts.incremental_info {
-        dump_incremental_data(&trans);
-    }
-
     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
@@ -938,7 +934,7 @@ pub fn run_passes(sess: &Session,
     }
 }
 
-fn dump_incremental_data(trans: &CrateTranslation) {
+pub fn dump_incremental_data(trans: &CrateTranslation) {
     let mut reuse = 0;
     for mtrans in trans.modules.iter() {
         match mtrans.source {
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 7b836399f9c..1fd871d31b5 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -23,7 +23,7 @@
 //!     but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
 //!     int) and rec(x=int, y=int, z=int) will have the same TypeRef.
 
-use super::CrateTranslation;
+use super::OngoingCrateTranslation;
 use super::ModuleLlvm;
 use super::ModuleSource;
 use super::ModuleTranslation;
@@ -43,9 +43,9 @@ use rustc::dep_graph::AssertDepGraphSafe;
 use rustc::middle::cstore::LinkMeta;
 use rustc::hir::map as hir_map;
 use rustc::util::common::time;
-use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
+use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, OutputTypes};
 use rustc::session::Session;
-use rustc_incremental::IncrementalHashesMap;
+use rustc_incremental::{self, IncrementalHashesMap};
 use abi;
 use allocator;
 use mir::lvalue::LvalueRef;
@@ -922,7 +922,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              analysis: ty::CrateAnalysis,
                              incremental_hashes_map: &IncrementalHashesMap,
                              output_filenames: &OutputFilenames)
-                             -> CrateTranslation {
+                             -> OngoingCrateTranslation {
     // Be careful with this krate: obviously it gives access to the
     // entire contents of the krate. So if you push any subtasks of
     // `TransCrate`, you need to be careful to register "reads" of the
@@ -961,17 +961,18 @@ 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 CrateTranslation {
+        return OngoingCrateTranslation {
             crate_name: tcx.crate_name(LOCAL_CRATE),
             modules: vec![],
             metadata_module: metadata_module,
             allocator_module: None,
             link: link_meta,
             metadata: metadata,
-            exported_symbols: empty_exported_symbols,
+            exported_symbols: Arc::new(empty_exported_symbols),
             no_builtins: no_builtins,
             linker_info: linker_info,
             windows_subsystem: None,
+            no_integrated_as: false,
         };
     }
 
@@ -1210,19 +1211,52 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         subsystem.to_string()
     });
 
-    CrateTranslation {
+    let outputs = output_filenames;
+
+    let no_integrated_as = sess.opts.cg.no_integrated_as ||
+        (sess.target.target.options.no_integrated_as &&
+         (outputs.outputs.contains_key(&OutputType::Object) ||
+          outputs.outputs.contains_key(&OutputType::Exe)));
+
+    let crate_translation = OngoingCrateTranslation {
         crate_name: tcx.crate_name(LOCAL_CRATE),
-        modules: modules,
-        metadata_module: metadata_module,
-        allocator_module: allocator_module,
         link: link_meta,
         metadata: metadata,
-        exported_symbols: Arc::try_unwrap(exported_symbols)
-            .expect("There's still a reference to exported_symbols?"),
-        no_builtins: no_builtins,
-        linker_info: linker_info,
-        windows_subsystem: windows_subsystem,
-    }
+        exported_symbols,
+        no_builtins,
+        linker_info,
+        windows_subsystem,
+        no_integrated_as,
+
+        modules,
+        metadata_module,
+        allocator_module,
+    };
+
+    time(sess.time_passes(),
+         "assert dep graph",
+         || rustc_incremental::assert_dep_graph(tcx));
+
+    time(sess.time_passes(),
+         "serialize dep graph",
+         || rustc_incremental::save_dep_graph(tcx,
+                                              incremental_hashes_map,
+                                              &crate_translation.metadata.hashes,
+                                              crate_translation.link.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, &output_types, outputs))
+    } else {
+        time(sess.time_passes(),
+             "LLVM passes",
+             || ::back::write::run_passes(sess, &crate_translation, &sess.opts.output_types, outputs))
+    };
+
+    crate_translation
 }
 
 #[inline(never)] // give this a place in the profiler
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 70337a91731..c386d11fa84 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -35,7 +35,12 @@
 #![feature(conservative_impl_trait)]
 
 use rustc::dep_graph::WorkProduct;
+use rustc::session::Session;
+use rustc::session::config::{OutputType, OutputFilenames};
+use rustc::util::fs::rename_or_copy_remove;
 use syntax_pos::symbol::Symbol;
+use std::fs;
+use std::sync::Arc;
 
 extern crate flate2;
 extern crate crossbeam;
@@ -167,10 +172,69 @@ pub struct CrateTranslation {
     pub allocator_module: Option<ModuleTranslation>,
     pub link: rustc::middle::cstore::LinkMeta,
     pub metadata: rustc::middle::cstore::EncodedMetadata,
-    pub exported_symbols: back::symbol_export::ExportedSymbols,
+    pub exported_symbols: Arc<back::symbol_export::ExportedSymbols>,
     pub no_builtins: bool,
     pub windows_subsystem: Option<String>,
     pub linker_info: back::linker::LinkerInfo
 }
 
+pub struct OngoingCrateTranslation {
+    pub crate_name: Symbol,
+    pub link: rustc::middle::cstore::LinkMeta,
+    pub metadata: rustc::middle::cstore::EncodedMetadata,
+    pub exported_symbols: Arc<back::symbol_export::ExportedSymbols>,
+    pub no_builtins: bool,
+    pub windows_subsystem: Option<String>,
+    pub linker_info: back::linker::LinkerInfo,
+    pub no_integrated_as: bool,
+
+    // These will be replaced by a Future.
+    pub modules: Vec<ModuleTranslation>,
+    pub metadata_module: ModuleTranslation,
+    pub allocator_module: Option<ModuleTranslation>,
+}
+
+impl OngoingCrateTranslation {
+    pub fn join(self,
+                sess: &Session,
+                outputs: &OutputFilenames)
+                -> CrateTranslation {
+
+        let trans = CrateTranslation {
+            crate_name: self.crate_name,
+            link: self.link,
+            metadata: self.metadata,
+            exported_symbols: self.exported_symbols,
+            no_builtins: self.no_builtins,
+            windows_subsystem: self.windows_subsystem,
+            linker_info: self.linker_info,
+
+            modules: self.modules,
+            metadata_module: self.metadata_module,
+            allocator_module: self.allocator_module,
+        };
+
+        if self.no_integrated_as {
+            back::write::run_assembler(sess, outputs);
+
+            // 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);
+                rename_or_copy_remove(&f,
+                         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();
+            }
+        }
+
+        trans
+    }
+}
+
 __build_diagnostic_array! { librustc_trans, DIAGNOSTICS }