Remove the ThinLTO CU hack
This reverts #46722, commite0ab5d5feb
. Since #111167, commit10b69dde3f
, we are generating DWARF subprograms in a way that is meant to be more compatible with LLVM's expectations, so hopefully we don't need this workaround rewriting CUs anymore.
This commit is contained in:
parent
ce042889f7
commit
c836c24994
@ -25,7 +25,6 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ptr;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -709,17 +708,6 @@ pub unsafe fn optimize_thin_module(
|
|||||||
let llmod = module.module_llvm.llmod();
|
let llmod = module.module_llvm.llmod();
|
||||||
save_temp_bitcode(cgcx, &module, "thin-lto-input");
|
save_temp_bitcode(cgcx, &module, "thin-lto-input");
|
||||||
|
|
||||||
// Before we do much else find the "main" `DICompileUnit` that we'll be
|
|
||||||
// using below. If we find more than one though then rustc has changed
|
|
||||||
// in a way we're not ready for, so generate an ICE by returning
|
|
||||||
// an error.
|
|
||||||
let mut cu1 = ptr::null_mut();
|
|
||||||
let mut cu2 = ptr::null_mut();
|
|
||||||
llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2);
|
|
||||||
if !cu2.is_null() {
|
|
||||||
return Err(write::llvm_err(&diag_handler, LlvmError::MultipleSourceDiCompileUnit));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Up next comes the per-module local analyses that we do for Thin LTO.
|
// Up next comes the per-module local analyses that we do for Thin LTO.
|
||||||
// Each of these functions is basically copied from the LLVM
|
// Each of these functions is basically copied from the LLVM
|
||||||
// implementation and then tailored to suit this implementation. Ideally
|
// implementation and then tailored to suit this implementation. Ideally
|
||||||
@ -766,43 +754,6 @@ pub unsafe fn optimize_thin_module(
|
|||||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
|
save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok now this is a bit unfortunate. This is also something you won't
|
|
||||||
// find upstream in LLVM's ThinLTO passes! This is a hack for now to
|
|
||||||
// work around bugs in LLVM.
|
|
||||||
//
|
|
||||||
// First discovered in #45511 it was found that as part of ThinLTO
|
|
||||||
// importing passes LLVM will import `DICompileUnit` metadata
|
|
||||||
// information across modules. This means that we'll be working with one
|
|
||||||
// LLVM module that has multiple `DICompileUnit` instances in it (a
|
|
||||||
// bunch of `llvm.dbg.cu` members). Unfortunately there's a number of
|
|
||||||
// bugs in LLVM's backend which generates invalid DWARF in a situation
|
|
||||||
// like this:
|
|
||||||
//
|
|
||||||
// https://bugs.llvm.org/show_bug.cgi?id=35212
|
|
||||||
// https://bugs.llvm.org/show_bug.cgi?id=35562
|
|
||||||
//
|
|
||||||
// While the first bug there is fixed the second ended up causing #46346
|
|
||||||
// which was basically a resurgence of #45511 after LLVM's bug 35212 was
|
|
||||||
// fixed.
|
|
||||||
//
|
|
||||||
// This function below is a huge hack around this problem. The function
|
|
||||||
// below is defined in `PassWrapper.cpp` and will basically "merge"
|
|
||||||
// all `DICompileUnit` instances in a module. Basically it'll take all
|
|
||||||
// the objects, rewrite all pointers of `DISubprogram` to point to the
|
|
||||||
// first `DICompileUnit`, and then delete all the other units.
|
|
||||||
//
|
|
||||||
// This is probably mangling to the debug info slightly (but hopefully
|
|
||||||
// not too much) but for now at least gets LLVM to emit valid DWARF (or
|
|
||||||
// so it appears). Hopefully we can remove this once upstream bugs are
|
|
||||||
// fixed in LLVM.
|
|
||||||
{
|
|
||||||
let _timer = cgcx
|
|
||||||
.prof
|
|
||||||
.generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name());
|
|
||||||
llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1);
|
|
||||||
save_temp_bitcode(cgcx, &module, "thin-lto-after-patch");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alright now that we've done everything related to the ThinLTO
|
// Alright now that we've done everything related to the ThinLTO
|
||||||
// analysis it's time to run some optimizations! Here we use the same
|
// analysis it's time to run some optimizations! Here we use the same
|
||||||
// `run_pass_manager` as the "fat" LTO above except that we tell it to
|
// `run_pass_manager` as the "fat" LTO above except that we tell it to
|
||||||
|
@ -2480,12 +2480,6 @@ pub fn LLVMRustGetBitcodeSliceFromObjectData(
|
|||||||
len: usize,
|
len: usize,
|
||||||
out_len: &mut usize,
|
out_len: &mut usize,
|
||||||
) -> *const u8;
|
) -> *const u8;
|
||||||
pub fn LLVMRustThinLTOGetDICompileUnit(
|
|
||||||
M: &Module,
|
|
||||||
CU1: &mut *mut c_void,
|
|
||||||
CU2: &mut *mut c_void,
|
|
||||||
);
|
|
||||||
pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void);
|
|
||||||
|
|
||||||
pub fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>;
|
pub fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>;
|
||||||
pub fn LLVMRustLinkerAdd(
|
pub fn LLVMRustLinkerAdd(
|
||||||
|
@ -1460,63 +1460,6 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
|
|||||||
return BitcodeOrError->getBufferStart();
|
return BitcodeOrError->getBufferStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
|
|
||||||
// the comment in `back/lto.rs` for why this exists.
|
|
||||||
extern "C" void
|
|
||||||
LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
|
|
||||||
DICompileUnit **A,
|
|
||||||
DICompileUnit **B) {
|
|
||||||
Module *M = unwrap(Mod);
|
|
||||||
DICompileUnit **Cur = A;
|
|
||||||
DICompileUnit **Next = B;
|
|
||||||
for (DICompileUnit *CU : M->debug_compile_units()) {
|
|
||||||
*Cur = CU;
|
|
||||||
Cur = Next;
|
|
||||||
Next = nullptr;
|
|
||||||
if (Cur == nullptr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
|
|
||||||
// the comment in `back/lto.rs` for why this exists.
|
|
||||||
extern "C" void
|
|
||||||
LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
|
|
||||||
Module *M = unwrap(Mod);
|
|
||||||
|
|
||||||
// If the original source module didn't have a `DICompileUnit` then try to
|
|
||||||
// merge all the existing compile units. If there aren't actually any though
|
|
||||||
// then there's not much for us to do so return.
|
|
||||||
if (Unit == nullptr) {
|
|
||||||
for (DICompileUnit *CU : M->debug_compile_units()) {
|
|
||||||
Unit = CU;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Unit == nullptr)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
|
|
||||||
// process it recursively. Note that we used to specifically iterate over
|
|
||||||
// instructions to ensure we feed everything into it, but `processModule`
|
|
||||||
// started doing this the same way in LLVM 7 (commit d769eb36ab2b8).
|
|
||||||
DebugInfoFinder Finder;
|
|
||||||
Finder.processModule(*M);
|
|
||||||
|
|
||||||
// After we've found all our debuginfo, rewrite all subprograms to point to
|
|
||||||
// the same `DICompileUnit`.
|
|
||||||
for (auto &F : Finder.subprograms()) {
|
|
||||||
F->replaceUnit(Unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase any other references to other `DICompileUnit` instances, the verifier
|
|
||||||
// will later ensure that we don't actually have any other stale references to
|
|
||||||
// worry about.
|
|
||||||
auto *MD = M->getNamedMetadata("llvm.dbg.cu");
|
|
||||||
MD->clearOperands();
|
|
||||||
MD->addOperand(Unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Computes the LTO cache key for the provided 'ModId' in the given 'Data',
|
// Computes the LTO cache key for the provided 'ModId' in the given 'Data',
|
||||||
// storing the result in 'KeyOut'.
|
// storing the result in 'KeyOut'.
|
||||||
// Currently, this cache key is a SHA-1 hash of anything that could affect
|
// Currently, this cache key is a SHA-1 hash of anything that could affect
|
||||||
|
Loading…
Reference in New Issue
Block a user