Improve error message for -thinlto-object-suffix-replace and simplify code.

llvm-svn: 332643
This commit is contained in:
Rui Ueyama 2018-05-17 18:27:12 +00:00
parent d6c6678766
commit f06d494f46
5 changed files with 51 additions and 49 deletions

View File

@ -1024,22 +1024,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
: InputFile(BitcodeKind, MB) {
this->ArchiveName = ArchiveName;
// Here we pass a new MemoryBufferRef which is identified by ArchiveName
// (the fully resolved path of the archive) + member name + offset of the
// member in the archive.
// ThinLTO uses the MemoryBufferRef identifier to access its internal
// data structures and if two archives define two members with the same name,
// this causes a collision which result in only one of the objects being
// taken into consideration at LTO time (which very likely causes undefined
// symbols later in the link stage).
std::string Path = MB.getBufferIdentifier().str();
if (Config->ThinLTOIndexOnly)
Path = updateSuffixInPath(MB.getBufferIdentifier());
Path = replaceThinLTOSuffix(MB.getBufferIdentifier());
// ThinLTO assumes that all MemoryBufferRefs given to it have a unique
// name. If two archives define two members with the same name, this
// causes a collision which result in only one of the objects being taken
// into consideration at LTO time (which very likely causes undefined
// symbols later in the link stage). So we append file offset to make
// filename unique.
MemoryBufferRef MBRef(
MB.getBuffer(),
Saver.save(ArchiveName + Path +
(ArchiveName.empty() ? "" : utostr(OffsetInArchive))));
Obj = CHECK(lto::InputFile::create(MBRef), this);
Triple T(Obj->getTargetTriple());
@ -1242,6 +1241,18 @@ template <class ELFT> void LazyObjFile::addElfSymbols() {
}
}
std::string elf::replaceThinLTOSuffix(StringRef Path) {
StringRef Suffix = Config->ThinLTOObjectSuffixReplace.first;
StringRef Repl = Config->ThinLTOObjectSuffixReplace.second;
if (!Path.endswith(Suffix)) {
error("-thinlto-object-suffix-replace=" + Suffix + ";" + Repl +
" was given, but " + Path + " does not ends with the suffix");
return "";
}
return (Path.drop_back(Suffix.size()) + Repl).str();
}
template void ArchiveFile::parse<ELF32LE>();
template void ArchiveFile::parse<ELF32BE>();
template void ArchiveFile::parse<ELF64LE>();

View File

@ -355,19 +355,7 @@ inline bool isBitcode(MemoryBufferRef MB) {
return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
}
inline std::string updateSuffixInPath(llvm::StringRef Path) {
if (Path.endswith(Config->ThinLTOObjectSuffixReplace.first)) {
size_t pos = Path.rfind(Config->ThinLTOObjectSuffixReplace.first);
std::string SuffixedPath =
(Path.str().substr(0, pos) +
Config->ThinLTOObjectSuffixReplace.second.str());
return SuffixedPath;
} else {
error("cannot find suffix " +
Config->ThinLTOObjectSuffixReplace.first.str());
return "";
}
}
std::string replaceThinLTOSuffix(StringRef Path);
extern std::vector<BinaryFile *> BinaryFiles;
extern std::vector<BitcodeFile *> BitcodeFiles;

View File

@ -221,11 +221,28 @@ void BitcodeCompiler::add(BitcodeFile &F) {
checkError(LTOObj->add(std::move(F.Obj), Resols));
}
static void createEmptyIndex(StringRef ModulePath) {
std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(ModulePath));
if (Path.empty())
return;
std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
if (!OS)
return;
ModuleSummaryIndex M(false);
M.setSkipModuleByDistributedBackend();
WriteIndexToFile(M, *OS);
if (Config->ThinLTOEmitImportsFiles)
openFile(Path + ".imports");
}
// Merge all the bitcode files we have seen, codegen the result
// and return the resulting ObjectFile(s).
std::vector<InputFile *> BitcodeCompiler::compile() {
unsigned MaxTasks = LTOObj->getMaxTasks();
Buff.resize(MaxTasks);
Buf.resize(MaxTasks);
Files.resize(MaxTasks);
// The --thinlto-cache-dir option specifies the path to a directory in which
@ -242,7 +259,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
checkError(LTOObj->run(
[&](size_t Task) {
return llvm::make_unique<lto::NativeObjectStream>(
llvm::make_unique<raw_svector_ostream>(Buff[Task]));
llvm::make_unique<raw_svector_ostream>(Buf[Task]));
},
Cache));
@ -262,26 +279,12 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
// This is needed because this is what GNU gold plugin does and we have a
// distributed build system that depends on that behavior.
if (Config->ThinLTOIndexOnly) {
for (LazyObjFile *F : LazyObjFiles) {
if (F->AddedToLink || !isBitcode(F->MB))
continue;
std::string Path = updateSuffixInPath(getThinLTOOutputFile(F->getName()));
std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
if (!OS)
continue;
ModuleSummaryIndex M(false);
M.setSkipModuleByDistributedBackend();
WriteIndexToFile(M, *OS);
if (Config->ThinLTOEmitImportsFiles)
openFile(Path + ".imports");
}
for (LazyObjFile *F : LazyObjFiles)
if (!F->AddedToLink && isBitcode(F->MB))
createEmptyIndex(F->getName());
if (!Config->LTOObjPath.empty())
saveBuffer(Buff[0], Config->LTOObjPath);
saveBuffer(Buf[0], Config->LTOObjPath);
// ThinLTO with index only option is required to generate only the index
// files. After that, we exit from linker and ThinLTO backend runs in a
@ -290,20 +293,21 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
IndexFile->close();
return {};
}
if (!Config->ThinLTOCacheDir.empty())
pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
std::vector<InputFile *> Ret;
for (unsigned I = 0; I != MaxTasks; ++I) {
if (Buff[I].empty())
if (Buf[I].empty())
continue;
if (Config->SaveTemps) {
if (I == 0)
saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
saveBuffer(Buf[I], Config->OutputFile + ".lto.o");
else
saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o");
saveBuffer(Buf[I], Config->OutputFile + Twine(I) + ".lto.o");
}
InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp"));
InputFile *Obj = createObjectFile(MemoryBufferRef(Buf[I], "lto.tmp"));
Ret.push_back(Obj);
}

View File

@ -51,7 +51,7 @@ public:
private:
std::unique_ptr<llvm::lto::LTO> LTOObj;
std::vector<SmallString<0>> Buff;
std::vector<SmallString<0>> Buf;
std::vector<std::unique_ptr<MemoryBuffer>> Files;
llvm::DenseSet<StringRef> UsedStartStop;
std::unique_ptr<llvm::raw_fd_ostream> IndexFile;

View File

@ -34,8 +34,7 @@
; RUN: not ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-only \
; RUN: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc \
; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR2
; ERR2: cannot find suffix .abc
; ERR2: error: -thinlto-object-suffix-replace=.abc;.o was given, but {{.*}} does not ends with the suffix
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"