From e70561b8acda9edf39b0675a992119bd3f464882 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:37:35 +0000 Subject: [PATCH] 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. --- compiler/rustc_codegen_gcc/src/back/lto.rs | 59 +++++++++----------- compiler/rustc_codegen_llvm/src/back/lto.rs | 52 +++++++++-------- compiler/rustc_codegen_ssa/src/back/lto.rs | 8 +-- compiler/rustc_codegen_ssa/src/back/write.rs | 17 +++--- 4 files changed, 64 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index aee164cf3222..401d4c244d5a 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -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::>();*/ fat_lto( diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index f6cd229cb106..7f0f0c5a05cc 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -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), } } } diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index a2c951c16d28..2fd3e1f16498 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -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. diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 1770251fcba4..8dcfad6ad682 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1264,13 +1264,16 @@ fn start_executing_work( 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 =