<div dir="ltr">Hi Rumeet,<div><br></div><div>I'm seeing some test failures after this change:</div><div><span style="color:rgb(0,0,0);white-space:pre-wrap"><br></span></div><div><span style="color:rgb(0,0,0);white-space:pre-wrap">test/ELF/lto/drop-debug-info.ll </span>fails like this:</div><div><br></div><div><div>ld.lld: error: failed to write $SRCDIR/llvm/tools/lld/test/ELF/lto/Inputs/drop-debug-info.bc.thinlto.bc: Permission denied</div></div><div><br></div><div>It looks like this patch causes lld to write output to the *input* directory (which might not be writable, and in any case is something a lit test should never do).</div><div><br></div><div>Also of note: this test does not appear to enable ThinLTO at all, and yet is apparently trying to create thinlto output.</div><div><br></div><div>Please can you take a look?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 2 May 2018 at 14:40, Rumeet Dhindsa via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rdhindsa<br>
Date: Wed May 2 14:40:07 2018<br>
New Revision: 331405<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=331405&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=331405&view=rev</a><br>
Log:<br>
Added support for ThinLTO plugin options : thinlto-index-only and thinlto-prefix-replace<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D46034" rel="noreferrer" target="_blank">https://reviews.<wbr>llvm.org/D46034</a><br>
<br>
<br>
Added:<br>
lld/trunk/test/ELF/lto/Inputs/<wbr>thinlto_empty.ll<br>
lld/trunk/test/ELF/lto/<wbr>thinlto_prefix_replace.ll<br>
Modified:<br>
lld/trunk/ELF/Config.h<br>
lld/trunk/ELF/Driver.cpp<br>
lld/trunk/ELF/InputFiles.cpp<br>
lld/trunk/ELF/InputFiles.h<br>
lld/trunk/ELF/LTO.cpp<br>
lld/trunk/ELF/LTO.h<br>
lld/trunk/ELF/SymbolTable.cpp<br>
lld/trunk/test/ELF/lto/<wbr>thinlto.ll<br>
<br>
Modified: lld/trunk/ELF/Config.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/Config.<wbr>h?rev=331405&r1=331404&r2=<wbr>331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/Config.h (original)<br>
+++ lld/trunk/ELF/Config.h Wed May 2 14:40:07 2018<br>
@@ -94,6 +94,8 @@ struct Configuration {<br>
llvm::StringRef SoName;<br>
llvm::StringRef Sysroot;<br>
llvm::StringRef ThinLTOCacheDir;<br>
+ llvm::StringRef ThinLTOIndexOnlyObjectsFile;<br>
+ llvm::StringRef ThinLTOPrefixReplace;<br>
std::string Rpath;<br>
std::vector<VersionDefinition> VersionDefinitions;<br>
std::vector<llvm::StringRef> AuxiliaryList;<br>
@@ -156,6 +158,7 @@ struct Configuration {<br>
bool SysvHash = false;<br>
bool Target1Rel;<br>
bool Trace;<br>
+ bool ThinLTOIndexOnly;<br>
bool UndefinedVersion;<br>
bool WarnBackrefs;<br>
bool WarnCommon;<br>
<br>
Modified: lld/trunk/ELF/Driver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/Driver.<wbr>cpp?rev=331405&r1=331404&r2=<wbr>331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/Driver.cpp (original)<br>
+++ lld/trunk/ELF/Driver.cpp Wed May 2 14:40:07 2018<br>
@@ -777,27 +777,37 @@ void LinkerDriver::readConfigs(opt:<wbr>:Inpu<br>
// Parse LTO plugin-related options for compatibility with gold.<br>
for (auto *Arg : Args.filtered(OPT_plugin_opt)) {<br>
StringRef S = Arg->getValue();<br>
- if (S == "disable-verify")<br>
+ if (S == "disable-verify") {<br>
Config->DisableVerify = true;<br>
- else if (S == "save-temps")<br>
+ } else if (S == "save-temps") {<br>
Config->SaveTemps = true;<br>
- else if (S.startswith("O"))<br>
+ } else if (S.startswith("O")) {<br>
Config->LTOO = parseInt(S.substr(1), Arg);<br>
- else if (S.startswith("lto-partitions=<wbr>"))<br>
+ } else if (S.startswith("lto-partitions=<wbr>")) {<br>
Config->LTOPartitions = parseInt(S.substr(15), Arg);<br>
- else if (S.startswith("jobs="))<br>
+ } else if (S.startswith("jobs=")) {<br>
Config->ThinLTOJobs = parseInt(S.substr(5), Arg);<br>
- else if (S.startswith("mcpu="))<br>
+ } else if (S.startswith("mcpu=")) {<br>
parseClangOption(Saver.save("-<wbr>" + S), Arg->getSpelling());<br>
- else if (S == "new-pass-manager")<br>
+ } else if (S == "new-pass-manager") {<br>
Config->LTONewPassManager = true;<br>
- else if (S == "debug-pass-manager")<br>
+ } else if (S == "debug-pass-manager") {<br>
Config->LTODebugPassManager = true;<br>
- else if (S.startswith("sample-profile=<wbr>"))<br>
- Config->LTOSampleProfile = S.substr(strlen("sample-<wbr>profile="));<br>
- else if (!S.startswith("/") && !S.startswith("-fresolution=") &&<br>
- !S.startswith("-pass-through="<wbr>) && !S.startswith("thinlto"))<br>
+ } else if (S.startswith("sample-profile=<wbr>")) {<br>
+ Config->LTOSampleProfile = S.substr(15);<br>
+ } else if (S == "thinlto-index-only") {<br>
+ Config->ThinLTOIndexOnly = true;<br>
+ } else if (S.startswith("thinlto-index-<wbr>only=")) {<br>
+ Config->ThinLTOIndexOnly = true;<br>
+ Config-><wbr>ThinLTOIndexOnlyObjectsFile = S.substr(19);<br>
+ } else if (S.startswith("thinlto-prefix-<wbr>replace=")) {<br>
+ Config->ThinLTOPrefixReplace = S.substr(23);<br>
+ if (!Config-><wbr>ThinLTOPrefixReplace.contains(<wbr>';'))<br>
+ error("thinlto-prefix-replace expects 'old;new' format");<br>
+ } else if (!S.startswith("/") && !S.startswith("-fresolution=") &&<br>
+ !S.startswith("-pass-through="<wbr>) && !S.startswith("thinlto")) {<br>
parseClangOption(S, Arg->getSpelling());<br>
+ }<br>
}<br>
<br>
// Parse -mllvm options.<br>
<br>
Modified: lld/trunk/ELF/InputFiles.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/<wbr>InputFiles.cpp?rev=331405&r1=<wbr>331404&r2=331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/InputFiles.cpp (original)<br>
+++ lld/trunk/ELF/InputFiles.cpp Wed May 2 14:40:07 2018<br>
@@ -42,6 +42,7 @@ bool InputFile::IsInGroup;<br>
uint32_t InputFile::NextGroupId;<br>
std::vector<BinaryFile *> elf::BinaryFiles;<br>
std::vector<BitcodeFile *> elf::BitcodeFiles;<br>
+std::vector<LazyObjFile *> elf::LazyObjFiles;<br>
std::vector<InputFile *> elf::ObjectFiles;<br>
std::vector<InputFile *> elf::SharedFiles;<br>
<br>
@@ -1024,9 +1025,10 @@ BitcodeFile::BitcodeFile(<wbr>MemoryBufferRef<br>
// this causes a collision which result in only one of the objects being<br>
// taken into consideration at LTO time (which very likely causes undefined<br>
// symbols later in the link stage).<br>
- MemoryBufferRef MBRef(MB.getBuffer(),<br>
- Saver.save(ArchiveName + MB.getBufferIdentifier() +<br>
- utostr(OffsetInArchive)));<br>
+ MemoryBufferRef MBRef(<br>
+ MB.getBuffer(),<br>
+ Saver.save(ArchiveName + MB.getBufferIdentifier() +<br>
+ (ArchiveName.empty() ? "" : utostr(OffsetInArchive))));<br>
Obj = CHECK(lto::InputFile::create(<wbr>MBRef), this);<br>
<br>
Triple T(Obj->getTargetTriple());<br>
@@ -1128,11 +1130,6 @@ void BinaryFile::parse() {<br>
Data.size(), 0, STB_GLOBAL, nullptr, nullptr);<br>
}<br>
<br>
-static bool isBitcode(MemoryBufferRef MB) {<br>
- using namespace sys::fs;<br>
- return identify_magic(MB.getBuffer()) == file_magic::bitcode;<br>
-}<br>
-<br>
InputFile *elf::createObjectFile(<wbr>MemoryBufferRef MB, StringRef ArchiveName,<br>
uint64_t OffsetInArchive) {<br>
if (isBitcode(MB))<br>
@@ -1168,9 +1165,9 @@ InputFile *elf::createSharedFile(MemoryB<br>
}<br>
<br>
MemoryBufferRef LazyObjFile::getBuffer() {<br>
- if (Seen)<br>
+ if (AddedToLink)<br>
return MemoryBufferRef();<br>
- Seen = true;<br>
+ AddedToLink = true;<br>
return MB;<br>
}<br>
<br>
<br>
Modified: lld/trunk/ELF/InputFiles.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/<wbr>InputFiles.h?rev=331405&r1=<wbr>331404&r2=331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/InputFiles.h (original)<br>
+++ lld/trunk/ELF/InputFiles.h Wed May 2 14:40:07 2018<br>
@@ -259,11 +259,11 @@ public:<br>
template <class ELFT> void parse();<br>
MemoryBufferRef getBuffer();<br>
InputFile *fetch();<br>
+ bool AddedToLink = false;<br>
<br>
private:<br>
template <class ELFT> void addElfSymbols();<br>
<br>
- bool Seen = false;<br>
uint64_t OffsetInArchive;<br>
};<br>
<br>
@@ -351,8 +351,13 @@ InputFile *createObjectFile(MemoryBuffer<br>
uint64_t OffsetInArchive = 0);<br>
InputFile *createSharedFile(<wbr>MemoryBufferRef MB, StringRef DefaultSoName);<br>
<br>
+inline bool isBitcode(MemoryBufferRef MB) {<br>
+ return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;<br>
+}<br>
+<br>
extern std::vector<BinaryFile *> BinaryFiles;<br>
extern std::vector<BitcodeFile *> BitcodeFiles;<br>
+extern std::vector<LazyObjFile *> LazyObjFiles;<br>
extern std::vector<InputFile *> ObjectFiles;<br>
extern std::vector<InputFile *> SharedFiles;<br>
<br>
<br>
Modified: lld/trunk/ELF/LTO.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/LTO.cpp?<wbr>rev=331405&r1=331404&r2=<wbr>331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/LTO.cpp (original)<br>
+++ lld/trunk/ELF/LTO.cpp Wed May 2 14:40:07 2018<br>
@@ -20,6 +20,8 @@<br>
#include "llvm/ADT/StringRef.h"<br>
#include "llvm/ADT/Twine.h"<br>
#include "llvm/BinaryFormat/ELF.h"<br>
+#include "llvm/Bitcode/BitcodeReader.h"<br>
+#include "llvm/Bitcode/BitcodeWriter.h"<br>
#include "llvm/IR/DiagnosticPrinter.h"<br>
#include "llvm/LTO/Caching.h"<br>
#include "llvm/LTO/Config.h"<br>
@@ -29,7 +31,6 @@<br>
#include "llvm/Support/Error.h"<br>
#include "llvm/Support/FileSystem.h"<br>
#include "llvm/Support/MemoryBuffer.h"<br>
-#include "llvm/Support/raw_ostream.h"<br>
#include <algorithm><br>
#include <cstddef><br>
#include <memory><br>
@@ -66,7 +67,57 @@ static void checkError(Error E) {<br>
[&](ErrorInfoBase &EIB) { error(EIB.message()); });<br>
}<br>
<br>
-static std::unique_ptr<lto::LTO> createLTO() {<br>
+// With the ThinLTOIndexOnly option, only the thin link is performed, and will<br>
+// generate index files for the ThinLTO backends in a distributed build system.<br>
+// The distributed build system may expect that index files are created for all<br>
+// input bitcode objects provided to the linker for the thin link. However,<br>
+// index files will not normally be created for input bitcode objects that<br>
+// either aren't selected by the linker (i.e. in a static library and not<br>
+// needed), or because they don't have a summary. Therefore we need to create<br>
+// empty dummy index file outputs in those cases.<br>
+// If SkipModule is true then .thinlto.bc should contain just<br>
+// SkipModuleByDistributedBackend flag which requests distributed backend<br>
+// to skip the compilation of the corresponding module and produce an empty<br>
+// object file.<br>
+static void writeEmptyDistributedBuildOutp<wbr>uts(const std::string &ModulePath,<br>
+ const std::string &OldPrefix,<br>
+ const std::string &NewPrefix,<br>
+ bool SkipModule) {<br>
+ std::string NewModulePath =<br>
+ lto::getThinLTOOutputFile(<wbr>ModulePath, OldPrefix, NewPrefix);<br>
+ std::error_code EC;<br>
+<br>
+ raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,<br>
+ sys::fs::OpenFlags::F_None);<br>
+ if (EC)<br>
+ error("failed to write " + NewModulePath + ".thinlto.bc" + ": " +<br>
+ EC.message());<br>
+<br>
+ if (SkipModule) {<br>
+ ModuleSummaryIndex Index(false);<br>
+ Index.<wbr>setSkipModuleByDistributedBack<wbr>end();<br>
+ WriteIndexToFile(Index, OS);<br>
+ }<br>
+}<br>
+<br>
+// Creates and returns output stream with a list of object files for final<br>
+// linking of distributed ThinLTO.<br>
+static std::unique_ptr<raw_fd_<wbr>ostream> createLinkedObjectsFile() {<br>
+ if (Config-><wbr>ThinLTOIndexOnlyObjectsFile.<wbr>empty())<br>
+ return nullptr;<br>
+ std::error_code EC;<br>
+ auto LinkedObjectsFile = llvm::make_unique<raw_fd_<wbr>ostream>(<br>
+ Config-><wbr>ThinLTOIndexOnlyObjectsFile, EC, sys::fs::OpenFlags::F_None);<br>
+ if (EC)<br>
+ error("cannot create " + Config-><wbr>ThinLTOIndexOnlyObjectsFile + ": " +<br>
+ EC.message());<br>
+ return LinkedObjectsFile;<br>
+}<br>
+<br>
+// Creates instance of LTO.<br>
+// LinkedObjectsFile is an output stream to write the list of object files for<br>
+// the final ThinLTO linking. Can be nullptr.<br>
+static std::unique_ptr<lto::LTO> createLTO(raw_fd_ostream *LinkedObjectsFile) {<br>
lto::Config Conf;<br>
<br>
// LLD supports the new relocations.<br>
@@ -105,6 +156,13 @@ static std::unique_ptr<lto::LTO> createL<br>
if (Config->ThinLTOJobs != -1u)<br>
Backend = lto::<wbr>createInProcessThinBackend(<wbr>Config->ThinLTOJobs);<br>
<br>
+ if (Config->ThinLTOIndexOnly) {<br>
+ std::string OldPrefix, NewPrefix;<br>
+ std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.<wbr>split(';');<br>
+ Backend = lto::<wbr>createWriteIndexesThinBackend(<wbr>OldPrefix, NewPrefix, true,<br>
+ LinkedObjectsFile, nullptr);<br>
+ }<br>
+<br>
Conf.SampleProfile = Config->LTOSampleProfile;<br>
Conf.UseNewPM = Config->LTONewPassManager;<br>
Conf.DebugPassManager = Config->LTODebugPassManager;<br>
@@ -113,7 +171,9 @@ static std::unique_ptr<lto::LTO> createL<br>
Config->LTOPartitions);<br>
}<br>
<br>
-BitcodeCompiler::<wbr>BitcodeCompiler() : LTOObj(createLTO()) {<br>
+BitcodeCompiler::<wbr>BitcodeCompiler() {<br>
+ LinkedObjects = createLinkedObjectsFile();<br>
+ LTOObj = createLTO(LinkedObjects.get())<wbr>;<br>
for (Symbol *Sym : Symtab->getSymbols()) {<br>
StringRef Name = Sym->getName();<br>
for (StringRef Prefix : {"__start_", "__stop_"})<br>
@@ -131,6 +191,13 @@ static void undefine(Symbol *S) {<br>
<br>
void BitcodeCompiler::add(<wbr>BitcodeFile &F) {<br>
lto::InputFile &Obj = *F.Obj;<br>
+<br>
+ std::string OldPrefix, NewPrefix;<br>
+ std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.<wbr>split(';');<br>
+<br>
+ // Create the empty files which, if indexed, will be overwritten later.<br>
+ writeEmptyDistributedBuildOutp<wbr>uts(Obj.getName(), OldPrefix, NewPrefix, false);<br>
+<br>
unsigned SymNum = 0;<br>
std::vector<Symbol *> Syms = F.getSymbols();<br>
std::vector<lto::<wbr>SymbolResolution> Resols(Syms.size());<br>
@@ -188,6 +255,12 @@ std::vector<InputFile *> BitcodeCompiler<br>
Buff.resize(MaxTasks);<br>
Files.resize(MaxTasks);<br>
<br>
+ // If LazyObjFile has not been added to link, emit empty index files<br>
+ if (Config->ThinLTOIndexOnly)<br>
+ for (LazyObjFile *F : LazyObjFiles)<br>
+ if (!F->AddedToLink && isBitcode(F->MB))<br>
+ addLazyObjFile(F);<br>
+<br>
// The --thinlto-cache-dir option specifies the path to a directory in which<br>
// to cache native object files for ThinLTO incremental builds. If a path was<br>
// specified, configure LTO to use it as the cache directory.<br>
@@ -222,9 +295,24 @@ std::vector<InputFile *> BitcodeCompiler<br>
Ret.push_back(Obj);<br>
}<br>
<br>
+ // ThinLTO with index only option is required to generate only the index<br>
+ // files. After that, we exit from linker and ThinLTO backend runs in a<br>
+ // distributed environment.<br>
+ if (Config->ThinLTOIndexOnly)<br>
+ exit(0);<br>
+<br>
for (std::unique_ptr<MemoryBuffer> &File : Files)<br>
if (File)<br>
Ret.push_back(<wbr>createObjectFile(*File));<br>
<br>
return Ret;<br>
}<br>
+<br>
+// For lazy object files not added to link, adds empty index files<br>
+void BitcodeCompiler::<wbr>addLazyObjFile(LazyObjFile *File) {<br>
+ StringRef Identifier = File->getBuffer().<wbr>getBufferIdentifier();<br>
+ std::string OldPrefix, NewPrefix;<br>
+ std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.<wbr>split(';');<br>
+ writeEmptyDistributedBuildOutp<wbr>uts(Identifier, OldPrefix, NewPrefix,<br>
+ /* SkipModule */ true);<br>
+}<br>
<br>
Modified: lld/trunk/ELF/LTO.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/LTO.h?<wbr>rev=331405&r1=331404&r2=<wbr>331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/LTO.h (original)<br>
+++ lld/trunk/ELF/LTO.h Wed May 2 14:40:07 2018<br>
@@ -24,6 +24,7 @@<br>
#include "lld/Common/LLVM.h"<br>
#include "llvm/ADT/DenseSet.h"<br>
#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
#include <memory><br>
#include <vector><br>
<br>
@@ -38,6 +39,7 @@ namespace elf {<br>
<br>
class BitcodeFile;<br>
class InputFile;<br>
+class LazyObjFile;<br>
<br>
class BitcodeCompiler {<br>
public:<br>
@@ -46,12 +48,14 @@ public:<br>
<br>
void add(BitcodeFile &F);<br>
std::vector<InputFile *> compile();<br>
+ void addLazyObjFile(LazyObjFile *File);<br>
<br>
private:<br>
std::unique_ptr<llvm::lto::<wbr>LTO> LTOObj;<br>
std::vector<SmallString<0>> Buff;<br>
std::vector<std::unique_ptr<<wbr>MemoryBuffer>> Files;<br>
llvm::DenseSet<StringRef> UsedStartStop;<br>
+ std::unique_ptr<llvm::raw_fd_<wbr>ostream> LinkedObjects;<br>
};<br>
} // namespace elf<br>
} // namespace lld<br>
<br>
Modified: lld/trunk/ELF/SymbolTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/<wbr>SymbolTable.cpp?rev=331405&r1=<wbr>331404&r2=331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/SymbolTable.cpp (original)<br>
+++ lld/trunk/ELF/SymbolTable.cpp Wed May 2 14:40:07 2018<br>
@@ -82,6 +82,7 @@ template <class ELFT> void SymbolTable::<br>
<br>
// Lazy object file<br>
if (auto *F = dyn_cast<LazyObjFile>(File)) {<br>
+ LazyObjFiles.push_back(F);<br>
F->parse<ELFT>();<br>
return;<br>
}<br>
<br>
Added: lld/trunk/test/ELF/lto/Inputs/<wbr>thinlto_empty.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll?rev=331405&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/test/ELF/<wbr>lto/Inputs/thinlto_empty.ll?<wbr>rev=331405&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/test/ELF/lto/Inputs/<wbr>thinlto_empty.ll (added)<br>
+++ lld/trunk/test/ELF/lto/Inputs/<wbr>thinlto_empty.ll Wed May 2 14:40:07 2018<br>
@@ -0,0 +1,2 @@<br>
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64-unknown-linux-gnu"<br>
<br>
Modified: lld/trunk/test/ELF/lto/<wbr>thinlto.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/thinlto.ll?rev=331405&r1=331404&r2=331405&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/test/ELF/<wbr>lto/thinlto.ll?rev=331405&r1=<wbr>331404&r2=331405&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/test/ELF/lto/<wbr>thinlto.ll (original)<br>
+++ lld/trunk/test/ELF/lto/<wbr>thinlto.ll Wed May 2 14:40:07 2018<br>
@@ -1,7 +1,37 @@<br>
; REQUIRES: x86<br>
+<br>
+; First ensure that the ThinLTO handling in lld handles<br>
+; bitcode without summary sections gracefully and generates index file.<br>
+; RUN: llvm-as %s -o %t.o<br>
+; RUN: llvm-as %p/Inputs/thinlto.ll -o %t2.o<br>
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-<wbr>only -shared %t.o %t2.o -o %t3<br>
+; RUN: ls %t2.o.thinlto.bc<br>
+; RUN: not test -e %t3<br>
+; RUN: ld.lld -m elf_x86_64 -shared %t.o %t2.o -o %t4<br>
+; RUN: llvm-nm %t4 | FileCheck %s --check-prefix=NM<br>
+<br>
; Basic ThinLTO tests.<br>
; RUN: opt -module-summary %s -o %t.o<br>
; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o<br>
+; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t4.o<br>
+<br>
+; Ensure lld generates an index and not a binary if requested.<br>
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-<wbr>only -shared %t.o %t2.o -o %t3<br>
+; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND1<br>
+; RUN: llvm-bcanalyzer -dump %t2.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND2<br>
+; RUN: not test -e %t3<br>
+<br>
+; Ensure lld generates an index even if the file is wrapped in --start-lib/--end-lib<br>
+; RUN: rm -f %t2.o.thinlto.bc<br>
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-<wbr>only -shared %t.o %t4.o --start-lib %t2.o --end-lib -o %t5<br>
+; RUN: ls %t2.o.thinlto.bc<br>
+<br>
+; Ensure lld generates error if unable to write to index file<br>
+; RUN: rm -f %t4.o.thinlto.bc<br>
+; RUN: touch %t4.o.thinlto.bc<br>
+; RUN: chmod 400 %t4.o.thinlto.bc<br>
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-<wbr>only -shared %t.o %t4.o -o %t5 2>&1 | FileCheck %s --check-prefix=ERR<br>
+; ERR: failed to write {{.*}}4.o.thinlto.bc: Permission denied<br>
<br>
; First force single-threaded mode<br>
; RUN: rm -f %t.lto.o %t1.lto.o<br>
@@ -15,16 +45,43 @@<br>
; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM1<br>
; RUN: llvm-nm %t22.lto.o | FileCheck %s --check-prefix=NM2<br>
<br>
-; NM1: T f<br>
-; NM1-NOT: U g<br>
-<br>
-; NM2: T g<br>
-<br>
; Then check without --thinlto-jobs (which currently default to hardware_concurrency)<br>
; We just check that we don't crash or fail (as it's not sure which tests are<br>
; stable on the final output file itself.<br>
; RUN: ld.lld -shared %t.o %t2.o -o %t2<br>
<br>
+; NM: T f<br>
+; NM1: T f<br>
+; NM1-NOT: U g<br>
+; NM2: T g<br>
+<br>
+; The backend index for this module contains summaries from itself and<br>
+; Inputs/thinlto.ll, as it imports from the latter.<br>
+; BACKEND1: <MODULE_STRTAB_BLOCK<br>
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.<wbr>o'<br>
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.<wbr>o'<br>
+; BACKEND1-NEXT: </MODULE_STRTAB_BLOCK<br>
+; BACKEND1: <GLOBALVAL_SUMMARY_BLOCK<br>
+; BACKEND1: <VERSION<br>
+; BACKEND1: <FLAGS<br>
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-<wbr>5300342847281564238}}<br>
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-<wbr>5300342847281564238}}<br>
+; BACKEND1: <COMBINED<br>
+; BACKEND1: <COMBINED<br>
+; BACKEND1: </GLOBALVAL_SUMMARY_BLOCK<br>
+<br>
+; The backend index for Input/thinlto.ll contains summaries from itself only,<br>
+; as it does not import anything.<br>
+; BACKEND2: <MODULE_STRTAB_BLOCK<br>
+; BACKEND2-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp2.o'<br>
+; BACKEND2-NEXT: </MODULE_STRTAB_BLOCK<br>
+; BACKEND2-NEXT: <GLOBALVAL_SUMMARY_BLOCK<br>
+; BACKEND2-NEXT: <VERSION<br>
+; BACKEND2-NEXT: <FLAGS<br>
+; BACKEND2-NEXT: <VALUE_GUID op0=1 op1=-5300342847281564238<br>
+; BACKEND2-NEXT: <COMBINED<br>
+; BACKEND2-NEXT: </GLOBALVAL_SUMMARY_BLOCK<br>
+<br>
target datalayout = "e-m:e-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
target triple = "x86_64-unknown-linux-gnu"<br>
<br>
<br>
Added: lld/trunk/test/ELF/lto/<wbr>thinlto_prefix_replace.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll?rev=331405&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/test/ELF/<wbr>lto/thinlto_prefix_replace.ll?<wbr>rev=331405&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/test/ELF/lto/<wbr>thinlto_prefix_replace.ll (added)<br>
+++ lld/trunk/test/ELF/lto/<wbr>thinlto_prefix_replace.ll Wed May 2 14:40:07 2018<br>
@@ -0,0 +1,23 @@<br>
+; REQUIRES: x86<br>
+; Check that changing the output path via thinlto-prefix-replace works<br>
+; RUN: mkdir -p %t/oldpath<br>
+; RUN: opt -module-summary %s -o %t/oldpath/thinlto_prefix_<wbr>replace.o<br>
+<br>
+; Ensure that there is no existing file at the new path, so we properly<br>
+; test the creation of the new file there.<br>
+; RUN: rm -f %t/newpath/thinlto_prefix_<wbr>replace.o.thinlto.bc<br>
+; RUN: ld.lld --plugin-opt=thinlto-index-<wbr>only --plugin-opt=thinlto-prefix-<wbr>replace="%t/oldpath/;%t/<wbr>newpath/" -shared %t/oldpath/thinlto_prefix_<wbr>replace.o -o %t/thinlto_prefix_replace<br>
+; RUN: ls %t/newpath/thinlto_prefix_<wbr>replace.o.thinlto.bc<br>
+<br>
+; Ensure that lld generates error if prefix replace option does not have 'old;new' format<br>
+; RUN: rm -f %t/newpath/thinlto_prefix_<wbr>replace.o.thinlto.bc<br>
+; RUN: not ld.lld --plugin-opt=thinlto-index-<wbr>only --plugin-opt=thinlto-prefix-<wbr>replace="%t/oldpath/:%t/<wbr>newpath/" -shared %t/oldpath/thinlto_prefix_<wbr>replace.o -o %t/thinlto_prefix_replace 2>&1 | FileCheck %s --check-prefix=ERR<br>
+; ERR: thinlto-prefix-replace expects 'old;new' format<br>
+<br>
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:<wbr>32:64-S128"<br>
+target triple = "x86_64-unknown-linux-gnu"<br>
+<br>
+define void @f() {<br>
+entry:<br>
+ ret void<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>