Persist ThinLTO import data in incr. comp. session directory.
This commit is contained in:
parent
9df56ca0ee
commit
8dc7ddb976
@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user