[DTLTO] Fix handling of multi-module bitcode inputs (#174624)
This change fixes two issues when processing multi-module bitcode files in DTLTO: 1. The DTLTO archive handling code incorrectly uses getSingleBitcodeModule(), which asserts when the bitcode file contains more than one module. 2. The temporary file containing the contents of an input archive member was not emitted for multi-module bitcode files. This was due to incorrect logic for recording whether a bitcode input contains any ThinLTO modules. In a typical multi-module bitcode file, the first module is a ThinLTO module while a subsequent auxiliary module is non-ThinLTO. When modules are processed in order, the auxiliary module causes the entire bitcode file to be classified as non-ThinLTO, and the archive-member emission logic then incorrectly skips it. In addition, this patch adds a test that verifies that multi-module bitcode files can be successfully linked with DTLTO. The test reproduces both issues as they existed prior to this change. SIE Tracker: TOOLCHAIN-21008
This commit is contained in:
parent
d7b6df77d0
commit
663647f1b2
42
cross-project-tests/dtlto/multimodule.test
Normal file
42
cross-project-tests/dtlto/multimodule.test
Normal file
@ -0,0 +1,42 @@
|
||||
REQUIRES: x86-registered-target,ld.lld,llvm-ar
|
||||
|
||||
# Test that a DTLTO link succeeds with a multi-module (via -fsplit-lto-unit)
|
||||
# bitcode file. We use an archive, as archive member inputs exercise more of
|
||||
# the DTLTO specific code than other input file types.
|
||||
|
||||
RUN: rm -rf %t && split-file %s %t && cd %t
|
||||
|
||||
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c usebar.cc \
|
||||
RUN: -fno-rtti -fno-exceptions -fsplit-lto-unit
|
||||
|
||||
# Sanity check that multi-module bitcode was produced.
|
||||
RUN: not llvm-modextract -n 2 usebar.o -o - 2>&1 \
|
||||
RUN: | FileCheck %s --check-prefix=TWO
|
||||
TWO: bitcode file contains 2 module(s)
|
||||
|
||||
# Create an archive.
|
||||
RUN: llvm-ar rcs usebar.a usebar.o
|
||||
|
||||
# Build with DTLTO.
|
||||
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -fuse-ld=lld \
|
||||
RUN: -nostdlib -shared -Wl,--whole-archive,--allow-shlib-undefined usebar.a \
|
||||
RUN: -fthinlto-distributor=%python \
|
||||
RUN: -Xthinlto-distributor=%llvm_src_root/utils/dtlto/local.py \
|
||||
RUN: -Wl,--save-temps
|
||||
|
||||
RUN: ls | sort | FileCheck %s
|
||||
|
||||
# DTLTO JSON file - confirms DTLTO occurred.
|
||||
CHECK: .dist-file.json
|
||||
|
||||
# .native.o exists - confirms archive member usebar.o participated in DTLTO.
|
||||
CHECK: {{^}}usebar.a(usebar.o
|
||||
CHECK-SAME: .native.o
|
||||
|
||||
#--- usebar.cc
|
||||
// Minimal C++ input to exercise multi-module emission with -fsplit-lto-unit.
|
||||
struct A { virtual int foo(); };
|
||||
int bar(A *a);
|
||||
|
||||
struct B : A { int foo() { return 2; } };
|
||||
int use() { static B b; return bar(&b); }
|
||||
@ -194,6 +194,8 @@ public:
|
||||
|
||||
// Returns the only BitcodeModule from InputFile.
|
||||
LLVM_ABI BitcodeModule &getSingleBitcodeModule();
|
||||
// Returns the primary BitcodeModule from InputFile.
|
||||
LLVM_ABI BitcodeModule &getPrimaryBitcodeModule();
|
||||
// Returns the memory buffer reference for this input file.
|
||||
MemoryBufferRef getFileBuffer() const { return MbRef; }
|
||||
// Returns true if this input file is a member of an archive.
|
||||
|
||||
@ -146,7 +146,7 @@ lto::DTLTO::addInput(std::unique_ptr<lto::InputFile> InputPtr) {
|
||||
return Input;
|
||||
|
||||
SmallString<64> NewModuleId;
|
||||
BitcodeModule &BM = Input->getSingleBitcodeModule();
|
||||
BitcodeModule &BM = Input->getPrimaryBitcodeModule();
|
||||
|
||||
// Check if the archive is a thin archive.
|
||||
Expected<bool> IsThin = isThinArchive(ArchivePath);
|
||||
|
||||
@ -606,6 +606,8 @@ BitcodeModule &InputFile::getSingleBitcodeModule() {
|
||||
return Mods[0];
|
||||
}
|
||||
|
||||
BitcodeModule &InputFile::getPrimaryBitcodeModule() { return Mods[0]; }
|
||||
|
||||
LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
|
||||
const Config &Conf)
|
||||
: ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
|
||||
@ -804,7 +806,7 @@ LTO::addModule(InputFile &Input, ArrayRef<SymbolResolution> InputRes,
|
||||
// If any of the modules inside of a input bitcode file was compiled with
|
||||
// ThinLTO, we assume that the whole input file also was compiled with
|
||||
// ThinLTO.
|
||||
Input.IsThinLTO = IsThinLTO;
|
||||
Input.IsThinLTO |= IsThinLTO;
|
||||
|
||||
auto ModSyms = Input.module_symbols(ModI);
|
||||
addModuleToGlobalRes(ModSyms, Res,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user