forked from OSchip/llvm-project
Improve error message for -thinlto-object-suffix-replace and simplify code.
llvm-svn: 332643
This commit is contained in:
parent
d6c6678766
commit
f06d494f46
|
|
@ -1024,22 +1024,21 @@ BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
|
||||||
: InputFile(BitcodeKind, MB) {
|
: InputFile(BitcodeKind, MB) {
|
||||||
this->ArchiveName = ArchiveName;
|
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();
|
std::string Path = MB.getBufferIdentifier().str();
|
||||||
if (Config->ThinLTOIndexOnly)
|
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(
|
MemoryBufferRef MBRef(
|
||||||
MB.getBuffer(),
|
MB.getBuffer(),
|
||||||
Saver.save(ArchiveName + Path +
|
Saver.save(ArchiveName + Path +
|
||||||
(ArchiveName.empty() ? "" : utostr(OffsetInArchive))));
|
(ArchiveName.empty() ? "" : utostr(OffsetInArchive))));
|
||||||
|
|
||||||
Obj = CHECK(lto::InputFile::create(MBRef), this);
|
Obj = CHECK(lto::InputFile::create(MBRef), this);
|
||||||
|
|
||||||
Triple T(Obj->getTargetTriple());
|
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<ELF32LE>();
|
||||||
template void ArchiveFile::parse<ELF32BE>();
|
template void ArchiveFile::parse<ELF32BE>();
|
||||||
template void ArchiveFile::parse<ELF64LE>();
|
template void ArchiveFile::parse<ELF64LE>();
|
||||||
|
|
|
||||||
|
|
@ -355,19 +355,7 @@ inline bool isBitcode(MemoryBufferRef MB) {
|
||||||
return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
|
return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string updateSuffixInPath(llvm::StringRef Path) {
|
std::string replaceThinLTOSuffix(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 "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern std::vector<BinaryFile *> BinaryFiles;
|
extern std::vector<BinaryFile *> BinaryFiles;
|
||||||
extern std::vector<BitcodeFile *> BitcodeFiles;
|
extern std::vector<BitcodeFile *> BitcodeFiles;
|
||||||
|
|
|
||||||
|
|
@ -221,11 +221,28 @@ void BitcodeCompiler::add(BitcodeFile &F) {
|
||||||
checkError(LTOObj->add(std::move(F.Obj), Resols));
|
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
|
// Merge all the bitcode files we have seen, codegen the result
|
||||||
// and return the resulting ObjectFile(s).
|
// and return the resulting ObjectFile(s).
|
||||||
std::vector<InputFile *> BitcodeCompiler::compile() {
|
std::vector<InputFile *> BitcodeCompiler::compile() {
|
||||||
unsigned MaxTasks = LTOObj->getMaxTasks();
|
unsigned MaxTasks = LTOObj->getMaxTasks();
|
||||||
Buff.resize(MaxTasks);
|
Buf.resize(MaxTasks);
|
||||||
Files.resize(MaxTasks);
|
Files.resize(MaxTasks);
|
||||||
|
|
||||||
// The --thinlto-cache-dir option specifies the path to a directory in which
|
// 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(
|
checkError(LTOObj->run(
|
||||||
[&](size_t Task) {
|
[&](size_t Task) {
|
||||||
return llvm::make_unique<lto::NativeObjectStream>(
|
return llvm::make_unique<lto::NativeObjectStream>(
|
||||||
llvm::make_unique<raw_svector_ostream>(Buff[Task]));
|
llvm::make_unique<raw_svector_ostream>(Buf[Task]));
|
||||||
},
|
},
|
||||||
Cache));
|
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
|
// This is needed because this is what GNU gold plugin does and we have a
|
||||||
// distributed build system that depends on that behavior.
|
// distributed build system that depends on that behavior.
|
||||||
if (Config->ThinLTOIndexOnly) {
|
if (Config->ThinLTOIndexOnly) {
|
||||||
for (LazyObjFile *F : LazyObjFiles) {
|
for (LazyObjFile *F : LazyObjFiles)
|
||||||
if (F->AddedToLink || !isBitcode(F->MB))
|
if (!F->AddedToLink && isBitcode(F->MB))
|
||||||
continue;
|
createEmptyIndex(F->getName());
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Config->LTOObjPath.empty())
|
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
|
// 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
|
// files. After that, we exit from linker and ThinLTO backend runs in a
|
||||||
|
|
@ -290,20 +293,21 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
|
||||||
IndexFile->close();
|
IndexFile->close();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Config->ThinLTOCacheDir.empty())
|
if (!Config->ThinLTOCacheDir.empty())
|
||||||
pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
|
pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
|
||||||
|
|
||||||
std::vector<InputFile *> Ret;
|
std::vector<InputFile *> Ret;
|
||||||
for (unsigned I = 0; I != MaxTasks; ++I) {
|
for (unsigned I = 0; I != MaxTasks; ++I) {
|
||||||
if (Buff[I].empty())
|
if (Buf[I].empty())
|
||||||
continue;
|
continue;
|
||||||
if (Config->SaveTemps) {
|
if (Config->SaveTemps) {
|
||||||
if (I == 0)
|
if (I == 0)
|
||||||
saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
|
saveBuffer(Buf[I], Config->OutputFile + ".lto.o");
|
||||||
else
|
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);
|
Ret.push_back(Obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<llvm::lto::LTO> LTOObj;
|
std::unique_ptr<llvm::lto::LTO> LTOObj;
|
||||||
std::vector<SmallString<0>> Buff;
|
std::vector<SmallString<0>> Buf;
|
||||||
std::vector<std::unique_ptr<MemoryBuffer>> Files;
|
std::vector<std::unique_ptr<MemoryBuffer>> Files;
|
||||||
llvm::DenseSet<StringRef> UsedStartStop;
|
llvm::DenseSet<StringRef> UsedStartStop;
|
||||||
std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
|
std::unique_ptr<llvm::raw_fd_ostream> IndexFile;
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@
|
||||||
; RUN: not ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-only \
|
; 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: --plugin-opt=thinlto-object-suffix-replace=".abc;.o" -shared %t1.thinlink.bc \
|
||||||
; RUN: -o %t3 2>&1 | FileCheck %s --check-prefix=ERR2
|
; 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 datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue