Skip to content

Commit 951ebf6

Browse files
pnkfelixMark-Simulacrum
authored andcommitted
If an LLVM module's exports change, cannot reuse its post-LTO object file in
incremental compilation. This is symmetric to PR rust-lang#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 rust-lang#69798
1 parent 934ae77 commit 951ebf6

File tree

1 file changed

+33
-4
lines changed
  • src/librustc_codegen_llvm/back

1 file changed

+33
-4
lines changed

src/librustc_codegen_llvm/back/lto.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -517,11 +517,20 @@ fn thin_lto(
517517

518518
let prev_imports = prev_import_map.modules_imported_by(module_name);
519519
let curr_imports = curr_import_map.modules_imported_by(module_name);
520+
let prev_exports = prev_import_map.modules_exported_by(module_name);
521+
let curr_exports = curr_import_map.modules_exported_by(module_name);
520522
let imports_all_green = curr_imports
521523
.iter()
522524
.all(|imported_module| green_modules.contains_key(imported_module));
525+
let exports_all_green = curr_exports
526+
.iter()
527+
.all(|exported_module| green_modules.contains_key(exported_module));
523528

524-
if imports_all_green && equivalent_as_sets(prev_imports, curr_imports) {
529+
if imports_all_green
530+
&& equivalent_as_sets(prev_imports, curr_imports)
531+
&& exports_all_green
532+
&& equivalent_as_sets(prev_exports, curr_exports)
533+
{
525534
let work_product = green_modules[module_name].clone();
526535
copy_jobs.push(work_product);
527536
info!(" - {}: re-used", module_name);
@@ -885,13 +894,19 @@ pub unsafe fn optimize_thin_module(
885894
pub struct ThinLTOImports {
886895
// key = llvm name of importing module, value = list of modules it imports from
887896
imports: FxHashMap<String, Vec<String>>,
897+
// key = llvm name of exporting module, value = list of modules it exports to
898+
exports: FxHashMap<String, Vec<String>>,
888899
}
889900

890901
impl ThinLTOImports {
891902
fn modules_imported_by(&self, llvm_module_name: &str) -> &[String] {
892903
self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
893904
}
894905

906+
fn modules_exported_by(&self, llvm_module_name: &str) -> &[String] {
907+
self.exports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
908+
}
909+
895910
fn save_to_file(&self, path: &Path) -> io::Result<()> {
896911
use std::io::Write;
897912
let file = File::create(path)?;
@@ -909,13 +924,17 @@ impl ThinLTOImports {
909924
fn load_from_file(path: &Path) -> io::Result<ThinLTOImports> {
910925
use std::io::BufRead;
911926
let mut imports = FxHashMap::default();
912-
let mut current_module = None;
913-
let mut current_imports = vec![];
927+
let mut exports: FxHashMap<_, Vec<_>> = FxHashMap::default();
928+
let mut current_module: Option<String> = None;
929+
let mut current_imports: Vec<String> = vec![];
914930
let file = File::open(path)?;
915931
for line in io::BufReader::new(file).lines() {
916932
let line = line?;
917933
if line.is_empty() {
918934
let importing_module = current_module.take().expect("Importing module not set");
935+
for imported in &current_imports {
936+
exports.entry(imported.clone()).or_default().push(importing_module.clone());
937+
}
919938
imports.insert(importing_module, mem::replace(&mut current_imports, vec![]));
920939
} else if line.starts_with(' ') {
921940
// Space marks an imported module
@@ -927,7 +946,7 @@ impl ThinLTOImports {
927946
current_module = Some(line.trim().to_string());
928947
}
929948
}
930-
Ok(ThinLTOImports { imports })
949+
Ok(ThinLTOImports { imports, exports })
931950
}
932951

933952
/// Loads the ThinLTO import map from ThinLTOData.
@@ -951,7 +970,17 @@ impl ThinLTOImports {
951970
.get_mut(importing_module_name)
952971
.unwrap()
953972
.push(imported_module_name.to_owned());
973+
974+
if !map.exports.contains_key(imported_module_name) {
975+
map.exports.insert(imported_module_name.to_owned(), vec![]);
976+
}
977+
978+
map.exports
979+
.get_mut(imported_module_name)
980+
.unwrap()
981+
.push(importing_module_name.to_owned());
954982
}
983+
955984
let mut map = ThinLTOImports::default();
956985
llvm::LLVMRustGetThinLTOModuleImports(
957986
data,

0 commit comments

Comments
 (0)