Skip to content

Commit e542f4f

Browse files
committed
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
1 parent 5179ebe commit e542f4f

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)