diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 60a218500ca..748a734d1d7 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -785,10 +785,7 @@ pub fn codegen_units(&self) -> usize { // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. - match self.opts.optimize { - config::OptLevel::No => 16, - _ => 1, // FIXME(#46346) this should be 16 - } + 16 } /// Returns whether ThinLTO is enabled for this compilation diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index cb385923067..7d653494465 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1732,4 +1732,5 @@ pub fn LLVMRustThinLTOGetDICompileUnit(M: ModuleRef, CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); + pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); } diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index ba8c26bc819..29871684092 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -726,6 +726,21 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline) run_pass_manager(cgcx, tm, llmod, config, true); cgcx.save_temp_bitcode(&mtrans, "thin-lto-after-pm"); timeline.record("thin-done"); + + // FIXME: this is a hack around a bug in LLVM right now. Discovered in + // #46910 it was found out that on 32-bit MSVC LLVM will hit a codegen + // error if there's an available_externally function in the LLVM module. + // Typically we don't actually use these functions but ThinLTO makes + // heavy use of them when inlining across modules. + // + // Tracked upstream at https://bugs.llvm.org/show_bug.cgi?id=35736 this + // function call (and its definition on the C++ side of things) + // shouldn't be necessary eventually and we can safetly delete these few + // lines. + llvm::LLVMRustThinLTORemoveAvailableExternally(llmod); + cgcx.save_temp_bitcode(&mtrans, "thin-lto-after-rm-ae"); + timeline.record("no-ae"); + Ok(mtrans) } } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 776e4a3e65a..4e326c9e199 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -1182,6 +1182,15 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { MD->addOperand(Unit); } +extern "C" void +LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) { + Module *M = unwrap(Mod); + for (Function &F : M->functions()) { + if (F.hasAvailableExternallyLinkage()) + F.deleteBody(); + } +} + #else extern "C" bool @@ -1272,4 +1281,10 @@ extern "C" void LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod) { report_fatal_error("ThinLTO not available"); } + +extern "C" void +LLVMRustThinLTORemoveAvailableExternally(LLVMModuleRef Mod) { + report_fatal_error("ThinLTO not available"); +} + #endif // LLVM_VERSION_GE(4, 0)