diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2020-04-14 09:47:03 -0400 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2020-04-14 09:47:03 -0400 |
| commit | e542f4fa59a2d1ae33bebcd1e11149f7644db5da (patch) | |
| tree | 3b5b072be37c51aa705237979044109ea26a0116 | |
| parent | 5179ebe2064e15196c5be1f8df950736140b8fdd (diff) | |
| download | rust-e542f4fa59a2d1ae33bebcd1e11149f7644db5da.tar.gz rust-e542f4fa59a2d1ae33bebcd1e11149f7644db5da.zip | |
If an LLVM module's exports change, cannot reuse its post-LTO object file in
incremental compilation. This is symmetric to PR #67020, which handled the case where the LLVM module's *imports* changed. This commit builds upon the infrastructure added there; the export map is just the inverse of the import map, so we can build the export map at the same time that we load the serialized import map. Fix #69798
| -rw-r--r-- | src/librustc_codegen_llvm/back/lto.rs | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 816329e06c7..c97e108b0f5 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -517,11 +517,20 @@ fn thin_lto( let prev_imports = prev_import_map.modules_imported_by(module_name); let curr_imports = curr_import_map.modules_imported_by(module_name); + let prev_exports = prev_import_map.modules_exported_by(module_name); + let curr_exports = curr_import_map.modules_exported_by(module_name); let imports_all_green = curr_imports .iter() .all(|imported_module| green_modules.contains_key(imported_module)); + let exports_all_green = curr_exports + .iter() + .all(|exported_module| green_modules.contains_key(exported_module)); - if imports_all_green && equivalent_as_sets(prev_imports, curr_imports) { + if imports_all_green + && equivalent_as_sets(prev_imports, curr_imports) + && exports_all_green + && equivalent_as_sets(prev_exports, curr_exports) + { let work_product = green_modules[module_name].clone(); copy_jobs.push(work_product); info!(" - {}: re-used", module_name); @@ -885,6 +894,8 @@ pub unsafe fn optimize_thin_module( pub struct ThinLTOImports { // key = llvm name of importing module, value = list of modules it imports from imports: FxHashMap<String, Vec<String>>, + // key = llvm name of exporting module, value = list of modules it exports to + exports: FxHashMap<String, Vec<String>>, } impl ThinLTOImports { @@ -892,6 +903,10 @@ impl ThinLTOImports { self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[]) } + fn modules_exported_by(&self, llvm_module_name: &str) -> &[String] { + self.exports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[]) + } + fn save_to_file(&self, path: &Path) -> io::Result<()> { use std::io::Write; let file = File::create(path)?; @@ -909,13 +924,17 @@ impl ThinLTOImports { fn load_from_file(path: &Path) -> io::Result<ThinLTOImports> { use std::io::BufRead; let mut imports = FxHashMap::default(); - let mut current_module = None; - let mut current_imports = vec![]; + let mut exports: FxHashMap<_, Vec<_>> = FxHashMap::default(); + let mut current_module: Option<String> = None; + let mut current_imports: Vec<String> = 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"); + for imported in ¤t_imports { + exports.entry(imported.clone()).or_default().push(importing_module.clone()); + } imports.insert(importing_module, mem::replace(&mut current_imports, vec![])); } else if line.starts_with(' ') { // Space marks an imported module @@ -927,7 +946,7 @@ impl ThinLTOImports { current_module = Some(line.trim().to_string()); } } - Ok(ThinLTOImports { imports }) + Ok(ThinLTOImports { imports, exports }) } /// Loads the ThinLTO import map from ThinLTOData. @@ -951,7 +970,17 @@ impl ThinLTOImports { .get_mut(importing_module_name) .unwrap() .push(imported_module_name.to_owned()); + + if !map.exports.contains_key(imported_module_name) { + map.exports.insert(imported_module_name.to_owned(), vec![]); + } + + map.exports + .get_mut(imported_module_name) + .unwrap() + .push(importing_module_name.to_owned()); } + let mut map = ThinLTOImports::default(); llvm::LLVMRustGetThinLTOModuleImports( data, |
