Skip to content

Commit

Permalink
Auto merge of #111364 - cuviper:unhack-thinlto, r=nikic
Browse files Browse the repository at this point in the history
Remove the ThinLTO CU hack

This reverts #46722, commit e0ab5d5.

Since #111167, commit 10b69dd, 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.
  • Loading branch information
bors committed May 18, 2023
2 parents 24c180c + c836c24 commit 77fb0cd
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 112 deletions.
49 changes: 0 additions & 49 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use std::fs::File;
use std::io;
use std::iter;
use std::path::Path;
use std::ptr;
use std::slice;
use std::sync::Arc;

Expand Down Expand Up @@ -709,17 +708,6 @@ pub unsafe fn optimize_thin_module(
let llmod = module.module_llvm.llmod();
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.
// Each of these functions is basically copied from the LLVM
// implementation and then tailored to suit this implementation. Ideally
Expand Down Expand Up @@ -766,43 +754,6 @@ pub unsafe fn optimize_thin_module(
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
// 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
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2484,12 +2484,6 @@ extern "C" {
len: usize,
out_len: &mut usize,
) -> *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 LLVMRustLinkerAdd(
Expand Down
57 changes: 0 additions & 57 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1463,63 +1463,6 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data,
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',
// storing the result in 'KeyOut'.
// Currently, this cache key is a SHA-1 hash of anything that could affect
Expand Down

0 comments on commit 77fb0cd

Please sign in to comment.