Move some thin local LTO handling to start_executing_work

By not pushing any crates to each_linked_rlib_for_lto when no
cross-crate LTO is used, we can avoid special cases elsewhere.
This commit is contained in:
bjorn3
2026-02-12 11:37:35 +00:00
parent 2bd7a97871
commit e70561b8ac
4 changed files with 64 additions and 72 deletions
+26 -33
View File
@@ -31,7 +31,6 @@
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_errors::{DiagCtxt, DiagCtxtHandle};
use rustc_log::tracing::info;
use rustc_session::config::Lto;
use tempfile::{TempDir, tempdir};
use crate::back::write::{codegen, save_temp_bitcode};
@@ -45,11 +44,7 @@ struct LtoData {
tmp_path: TempDir,
}
fn prepare_lto(
cgcx: &CodegenContext,
each_linked_rlib_for_lto: &[PathBuf],
dcx: DiagCtxtHandle<'_>,
) -> LtoData {
fn prepare_lto(each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>) -> LtoData {
let tmp_path = match tempdir() {
Ok(tmp_path) => tmp_path,
Err(error) => {
@@ -64,32 +59,30 @@ fn prepare_lto(
// We save off all the bytecode and GCC module file path for later processing
// with either fat or thin LTO
let mut upstream_modules = Vec::new();
if cgcx.lto != Lto::ThinLocal {
for path in each_linked_rlib_for_lto {
let archive_data = unsafe {
Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib")
};
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let obj_files = archive
.members()
.filter_map(|child| {
child.ok().and_then(|c| {
std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))
})
})
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
let path = tmp_path.path().join(name);
match save_as_file(child.data(&*archive_data).expect("corrupt rlib"), &path) {
Ok(()) => {
let buffer = ModuleBuffer::new(path);
let module = SerializedModule::Local(buffer);
upstream_modules.push((module, CString::new(name).unwrap()));
}
Err(e) => {
dcx.emit_fatal(e);
}
for path in each_linked_rlib_for_lto {
let archive_data = unsafe {
Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib")
};
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let obj_files = archive
.members()
.filter_map(|child| {
child
.ok()
.and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)))
})
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
let path = tmp_path.path().join(name);
match save_as_file(child.data(&*archive_data).expect("corrupt rlib"), &path) {
Ok(()) => {
let buffer = ModuleBuffer::new(path);
let module = SerializedModule::Local(buffer);
upstream_modules.push((module, CString::new(name).unwrap()));
}
Err(e) => {
dcx.emit_fatal(e);
}
}
}
@@ -115,7 +108,7 @@ pub(crate) fn run_fat(
) -> CompiledModule {
let dcx = DiagCtxt::new(Box::new(shared_emitter.clone()));
let dcx = dcx.handle();
let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx);
let lto_data = prepare_lto(each_linked_rlib_for_lto, dcx);
/*let symbols_below_threshold =
lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
fat_lto(
+25 -27
View File
@@ -20,7 +20,7 @@
use rustc_hir::attrs::SanitizerSet;
use rustc_middle::bug;
use rustc_middle::dep_graph::WorkProduct;
use rustc_session::config::{self, Lto};
use rustc_session::config;
use tracing::{debug, info};
use crate::back::write::{
@@ -90,33 +90,31 @@ fn prepare_lto(
// We save off all the bytecode and LLVM module ids for later processing
// with either fat or thin LTO
let mut upstream_modules = Vec::new();
if cgcx.lto != Lto::ThinLocal {
for path in each_linked_rlib_for_lto {
let archive_data = unsafe {
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
.expect("couldn't map rlib")
};
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let obj_files = archive
.members()
.filter_map(|child| {
child.ok().and_then(|c| {
std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))
})
})
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
match get_bitcode_slice_from_object_data(
child.data(&*archive_data).expect("corrupt rlib"),
cgcx,
) {
Ok(data) => {
let module = SerializedModule::FromRlib(data.to_vec());
upstream_modules.push((module, CString::new(name).unwrap()));
}
Err(e) => dcx.emit_fatal(e),
for path in each_linked_rlib_for_lto {
let archive_data = unsafe {
Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
.expect("couldn't map rlib")
};
let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let obj_files = archive
.members()
.filter_map(|child| {
child
.ok()
.and_then(|c| std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c)))
})
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
match get_bitcode_slice_from_object_data(
child.data(&*archive_data).expect("corrupt rlib"),
cgcx,
) {
Ok(data) => {
let module = SerializedModule::FromRlib(data.to_vec());
upstream_modules.push((module, CString::new(name).unwrap()));
}
Err(e) => dcx.emit_fatal(e),
}
}
}
+3 -5
View File
@@ -110,11 +110,9 @@ pub(super) fn exported_symbols_for_lto(
// If we're performing LTO for the entire crate graph, then for each of our
// upstream dependencies, include their exported symbols.
if tcx.sess.lto() != Lto::ThinLocal {
for &cnum in each_linked_rlib_for_lto {
let _timer = tcx.prof.generic_activity("lto_generate_symbols_below_threshold");
symbols_below_threshold.extend(copy_symbols(cnum));
}
for &cnum in each_linked_rlib_for_lto {
let _timer = tcx.prof.generic_activity("lto_generate_symbols_below_threshold");
symbols_below_threshold.extend(copy_symbols(cnum));
}
// Mark allocator shim symbols as exported only if they were generated.
+10 -7
View File
@@ -1264,13 +1264,16 @@ fn start_executing_work<B: ExtraBackendMethods>(
let mut each_linked_rlib_for_lto = Vec::new();
let mut each_linked_rlib_file_for_lto = Vec::new();
drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
if link::ignored_for_lto(sess, crate_info, cnum) {
return;
}
each_linked_rlib_for_lto.push(cnum);
each_linked_rlib_file_for_lto.push(path.to_path_buf());
}));
if sess.lto() != Lto::No && sess.lto() != Lto::ThinLocal {
drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
if link::ignored_for_lto(sess, crate_info, cnum) {
return;
}
each_linked_rlib_for_lto.push(cnum);
each_linked_rlib_file_for_lto.push(path.to_path_buf());
}));
}
// Compute the set of symbols we need to retain when doing LTO (if we need to)
let exported_symbols_for_lto =