From de8200c5a441079cfaadd383a8b6897155bfa2c6 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Thu, 23 May 2024 14:58:30 -0400 Subject: [PATCH] thinlto: only build summary file if needed If we don't do this, some versions of LLVM (at least 17, experimentally) will double-emit some error messages, which is how I noticed this. Given that it seems to be costing some extra work, let's only request the summary bitcode production if we'll actually bother writing it down, otherwise skip it. --- compiler/rustc_codegen_llvm/src/back/lto.rs | 8 ++++---- compiler/rustc_codegen_llvm/src/back/write.rs | 6 +++--- compiler/rustc_codegen_llvm/src/lib.rs | 4 ++-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/write.rs | 2 +- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 7 +++++-- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 740939eb6bbd..0dc91524f841 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -229,9 +229,9 @@ pub(crate) fn run_thin( thin_lto(cgcx, &dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold) } -pub(crate) fn prepare_thin(module: ModuleCodegen) -> (String, ThinBuffer) { +pub(crate) fn prepare_thin(module: ModuleCodegen, emit_summary: bool) -> (String, ThinBuffer) { let name = module.name; - let buffer = ThinBuffer::new(module.module_llvm.llmod(), true); + let buffer = ThinBuffer::new(module.module_llvm.llmod(), true, emit_summary); (name, buffer) } @@ -671,9 +671,9 @@ unsafe impl Send for ThinBuffer {} unsafe impl Sync for ThinBuffer {} impl ThinBuffer { - pub fn new(m: &llvm::Module, is_thin: bool) -> ThinBuffer { + pub fn new(m: &llvm::Module, is_thin: bool, emit_summary: bool) -> ThinBuffer { unsafe { - let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin); + let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin, emit_summary); ThinBuffer(buffer) } } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 4a24bba2bb7a..a0fb110d0294 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -716,9 +716,8 @@ pub(crate) unsafe fn codegen( let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name); - let thin = ThinBuffer::new(llmod, config.emit_thin_lto); + let thin = ThinBuffer::new(llmod, config.emit_thin_lto, config.emit_thin_lto_index); let data = thin.data(); - let index_data = thin.thin_link_data(); if let Some(bitcode_filename) = bc_out.file_name() { cgcx.prof.artifact_size( @@ -728,7 +727,8 @@ pub(crate) unsafe fn codegen( ); } - if let Some(thin_link_bitcode_filename) = bc_index_out.file_name() { + if config.emit_thin_lto_index && let Some(thin_link_bitcode_filename) = bc_index_out.file_name() { + let index_data = thin.thin_link_data(); cgcx.prof.artifact_size( "llvm_bitcode_summary", thin_link_bitcode_filename.to_string_lossy(), diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 1cecf682e5db..4a9502fa897c 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -240,8 +240,8 @@ impl WriteBackendMethods for LlvmCodegenBackend { ) -> Result { back::write::codegen(cgcx, dcx, module, config) } - fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { - back::lto::prepare_thin(module) + fn prepare_thin(module: ModuleCodegen, emit_summary: bool) -> (String, Self::ThinBuffer) { + back::lto::prepare_thin(module, emit_summary) } fn serialize_module(module: ModuleCodegen) -> (String, Self::ModuleBuffer) { (module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod())) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 648e7f128900..1e84c2be3c67 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2350,7 +2350,7 @@ extern "C" { #[allow(improper_ctypes)] pub fn LLVMRustModuleInstructionStats(M: &Module, Str: &RustString); - pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool) -> &'static mut ThinLTOBuffer; + pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool, emit_summary: bool) -> &'static mut ThinLTOBuffer; pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer); pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char; pub fn LLVMRustThinLTOBufferLen(M: &ThinLTOBuffer) -> size_t; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index cee177d5eec2..0432659d371e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -891,7 +891,7 @@ fn execute_optimize_work_item( match lto_type { ComputedLtoType::No => finish_intra_module_work(cgcx, module, module_config), ComputedLtoType::Thin => { - let (name, thin_buffer) = B::prepare_thin(module); + let (name, thin_buffer) = B::prepare_thin(module, false); if let Some(path) = bitcode { fs::write(&path, thin_buffer.data()).unwrap_or_else(|e| { panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e); diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index b4b23812d4dc..21efca53a478 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -56,7 +56,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { module: ModuleCodegen, config: &ModuleConfig, ) -> Result; - fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer); + fn prepare_thin(module: ModuleCodegen, want_summary: bool) -> (String, Self::ThinBuffer); fn serialize_module(module: ModuleCodegen) -> (String, Self::ModuleBuffer); } diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c210d2531e76..3fcf3aca8afe 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1492,7 +1492,7 @@ struct LLVMRustThinLTOBuffer { }; extern "C" LLVMRustThinLTOBuffer* -LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) { +LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) { auto Ret = std::make_unique(); { auto OS = raw_string_ostream(Ret->data); @@ -1510,7 +1510,10 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) { PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); ModulePassManager MPM; - MPM.addPass(ThinLTOBitcodeWriterPass(OS, &ThinLinkOS)); + // We only pass ThinLinkOS to be filled in if we want the summary, + // because otherwise LLVM does extra work and may double-emit some + // errors or warnings. + MPM.addPass(ThinLTOBitcodeWriterPass(OS, emit_summary ? &ThinLinkOS : nullptr)); MPM.run(*unwrap(M), MAM); } else { WriteBitcodeToFile(*unwrap(M), OS);