about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-07-09 17:00:24 +0200
committerMichael Woerister <michaelwoerister@posteo>2018-07-11 17:52:57 +0200
commit8dc7ddb9763f28b83de7bf3b3025f8042ea9e830 (patch)
treeb320cb3b1eaede7021c3bfc41504608f492dfc78 /src
parent9df56ca0eea1a8f5af945df25ce23e276b1d48a7 (diff)
downloadrust-8dc7ddb9763f28b83de7bf3b3025f8042ea9e830.tar.gz
rust-8dc7ddb9763f28b83de7bf3b3025f8042ea9e830.zip
Persist ThinLTO import data in incr. comp. session directory.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs83
-rw-r--r--src/librustc_codegen_llvm/base.rs24
-rw-r--r--src/librustc_codegen_llvm/lib.rs2
-rw-r--r--src/librustc_incremental/lib.rs1
-rw-r--r--src/librustc_incremental/persist/mod.rs1
5 files changed, 107 insertions, 4 deletions
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 28b9d2e7afa..ef03e76f946 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -27,10 +27,16 @@ use {ModuleCodegen, ModuleLlvm, ModuleKind, ModuleSource};
 use libc;
 
 use std::ffi::{CString, CStr};
+use std::fs::File;
+use std::io;
+use std::mem;
+use std::path::Path;
 use std::ptr;
 use std::slice;
 use std::sync::Arc;
 
+pub const THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME: &str = "thin-lto-imports.bin";
+
 pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
     match crate_type {
         config::CrateTypeExecutable |
@@ -194,7 +200,7 @@ pub(crate) fn run(cgcx: &CodegenContext,
         }
         Lto::Thin |
         Lto::ThinLocal => {
-            thin_lto(&diag_handler, modules, upstream_modules, &arr, timeline)
+            thin_lto(cgcx, &diag_handler, modules, upstream_modules, &arr, timeline)
         }
         Lto::No => unreachable!(),
     }
@@ -347,7 +353,8 @@ impl Drop for Linker {
 /// calculating the *index* for ThinLTO. This index will then be shared amongst
 /// all of the `LtoModuleCodegen` units returned below and destroyed once
 /// they all go out of scope.
-fn thin_lto(diag_handler: &Handler,
+fn thin_lto(cgcx: &CodegenContext,
+            diag_handler: &Handler,
             modules: Vec<ModuleCodegen>,
             serialized_modules: Vec<(SerializedModule, CString)>,
             symbol_white_list: &[*const libc::c_char],
@@ -425,6 +432,18 @@ fn thin_lto(diag_handler: &Handler,
             let msg = format!("failed to prepare thin LTO context");
             return Err(write::llvm_err(&diag_handler, msg))
         }
+
+        // Save the ThinLTO import information for incremental compilation.
+        if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir {
+            let path = incr_comp_session_dir.join(THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME);
+            let imports = ThinLTOImports::from_thin_lto_data(data);
+            if let Err(err) = imports.save_to_file(&path) {
+                let msg = format!("Error while writing ThinLTO import data: {}",
+                                  err);
+                return Err(write::llvm_err(&diag_handler, msg));
+            }
+        }
+
         let data = ThinData(data);
         info!("thin LTO data created");
         timeline.record("data");
@@ -787,6 +806,12 @@ pub struct ThinLTOImports {
 
 impl ThinLTOImports {
 
+    pub fn new_empty() -> ThinLTOImports {
+        ThinLTOImports {
+            imports: FxHashMap(),
+        }
+    }
+
     /// Load the ThinLTO import map from ThinLTOData.
     unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports {
         let raw_data: *const llvm::ThinLTOModuleImports =
@@ -842,4 +867,58 @@ impl ThinLTOImports {
             imports
         }
     }
+
+    pub fn save_to_file(&self, path: &Path) -> io::Result<()> {
+        use std::io::Write;
+
+        let file = File::create(path)?;
+        let mut writer = io::BufWriter::new(file);
+
+        for (importing_module_name, imported_modules) in &self.imports {
+            writeln!(writer, "{}", importing_module_name)?;
+
+            for imported_module in imported_modules {
+                writeln!(writer, "  {}", imported_module)?;
+            }
+
+            writeln!(writer)?;
+        }
+
+        Ok(())
+    }
+
+    pub fn load_from_file(path: &Path) -> io::Result<ThinLTOImports> {
+        use std::io::BufRead;
+
+        let mut imports = FxHashMap();
+        let mut current_module = None;
+        let mut current_imports = vec![];
+
+        let file = File::open(path)?;
+
+        for line in io::BufReader::new(file).lines() {
+            let line = line?;
+
+            if line.is_empty() {
+                let importing_module = current_module
+                    .take()
+                    .expect("Importing module not set");
+
+                imports.insert(importing_module,
+                               mem::replace(&mut current_imports, vec![]));
+            } else if line.starts_with(" ") {
+                // This is an imported module
+                assert_ne!(current_module, None);
+                current_imports.push(line.trim().to_string());
+            } else {
+                // This is the beginning of a new module
+                assert_eq!(current_module, None);
+                current_module = Some(line.trim().to_string());
+            }
+        }
+
+        Ok(ThinLTOImports {
+            imports
+        })
+    }
 }
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 179fffc4e7f..ca4b1fe44ae 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -29,7 +29,7 @@ use super::ModuleCodegen;
 use super::ModuleKind;
 
 use abi;
-use back::link;
+use back::{link, lto};
 use back::write::{self, OngoingCodegen, create_target_machine};
 use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
 use llvm;
@@ -1370,6 +1370,27 @@ mod temp_stable_hash_impls {
     }
 }
 
+#[allow(unused)]
+fn load_thin_lto_imports(sess: &Session) -> lto::ThinLTOImports {
+    let path = rustc_incremental::in_incr_comp_dir_sess(
+        sess,
+        lto::THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME
+    );
+
+    if !path.exists() {
+        return lto::ThinLTOImports::new_empty();
+    }
+
+    match lto::ThinLTOImports::load_from_file(&path) {
+        Ok(imports) => imports,
+        Err(e) => {
+            let msg = format!("Error while trying to load ThinLTO import data \
+                               for incremental compilation: {}", e);
+            sess.fatal(&msg)
+        }
+    }
+}
+
 pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
     use rustc::mir::interpret::GlobalId;
 
@@ -1408,3 +1429,4 @@ pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
         );
     }
 }
+
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index a2f28417520..a1d9f02f458 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -89,7 +89,7 @@ mod back {
     mod command;
     pub mod linker;
     pub mod link;
-    mod lto;
+    pub mod lto;
     pub mod symbol_export;
     pub mod write;
     mod rpath;
diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs
index 3839c133a6e..cc560ed4580 100644
--- a/src/librustc_incremental/lib.rs
+++ b/src/librustc_incremental/lib.rs
@@ -42,6 +42,7 @@ pub use persist::copy_cgu_workproducts_to_incr_comp_cache_dir;
 pub use persist::save_dep_graph;
 pub use persist::save_work_product_index;
 pub use persist::in_incr_comp_dir;
+pub use persist::in_incr_comp_dir_sess;
 pub use persist::prepare_session_directory;
 pub use persist::finalize_session_directory;
 pub use persist::delete_workproduct_files;
diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs
index e1f00db56d5..17d36ba3fa7 100644
--- a/src/librustc_incremental/persist/mod.rs
+++ b/src/librustc_incremental/persist/mod.rs
@@ -23,6 +23,7 @@ mod file_format;
 pub use self::fs::finalize_session_directory;
 pub use self::fs::garbage_collect_session_directories;
 pub use self::fs::in_incr_comp_dir;
+pub use self::fs::in_incr_comp_dir_sess;
 pub use self::fs::prepare_session_directory;
 pub use self::load::dep_graph_tcx_init;
 pub use self::load::load_dep_graph;