<div dir="ltr">I have pushed the change upstream. It is included in revision r331419.<br>Differential Revision: <a href="https://reviews.llvm.org/D46372">https://reviews.llvm.org/D46372</a><br></div><br><div class="gmail_quote"><div dir="ltr">On Wed, May 2, 2018 at 4:32 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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-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.llvm.org/D46034</a><br>
<br>
<br>
Added:<br>
    lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll<br>
    lld/trunk/test/ELF/lto/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/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-project/lld/trunk/ELF/Config.h?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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-project/lld/trunk/ELF/Driver.cpp?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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::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="))<br>
+    } else if (S.startswith("lto-partitions=")) {<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("-" + 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="))<br>
-      Config->LTOSampleProfile = S.substr(strlen("sample-profile="));<br>
-    else if (!S.startswith("/") && !S.startswith("-fresolution=") &&<br>
-             !S.startswith("-pass-through=") && !S.startswith("thinlto"))<br>
+    } else if (S.startswith("sample-profile=")) {<br>
+      Config->LTOSampleProfile = S.substr(15);<br>
+    } else if (S == "thinlto-index-only") {<br>
+      Config->ThinLTOIndexOnly = true;<br>
+    } else if (S.startswith("thinlto-index-only=")) {<br>
+      Config->ThinLTOIndexOnly = true;<br>
+      Config->ThinLTOIndexOnlyObjectsFile = S.substr(19);<br>
+    } else if (S.startswith("thinlto-prefix-replace=")) {<br>
+      Config->ThinLTOPrefixReplace = S.substr(23);<br>
+      if (!Config->ThinLTOPrefixReplace.contains(';'))<br>
+        error("thinlto-prefix-replace expects 'old;new' format");<br>
+    } else if (!S.startswith("/") && !S.startswith("-fresolution=") &&<br>
+               !S.startswith("-pass-through=") && !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-project/lld/trunk/ELF/InputFiles.cpp?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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(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(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(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-project/lld/trunk/ELF/InputFiles.h?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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(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-project/lld/trunk/ELF/LTO.cpp?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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 writeEmptyDistributedBuildOutputs(const std::string &ModulePath,<br>
+                                              const std::string &OldPrefix,<br>
+                                              const std::string &NewPrefix,<br>
+                                              bool SkipModule) {<br>
+  std::string NewModulePath =<br>
+      lto::getThinLTOOutputFile(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.setSkipModuleByDistributedBackend();<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_ostream> createLinkedObjectsFile() {<br>
+  if (Config->ThinLTOIndexOnlyObjectsFile.empty())<br>
+    return nullptr;<br>
+  std::error_code EC;<br>
+  auto LinkedObjectsFile = llvm::make_unique<raw_fd_ostream>(<br>
+      Config->ThinLTOIndexOnlyObjectsFile, EC, sys::fs::OpenFlags::F_None);<br>
+  if (EC)<br>
+    error("cannot create " + Config->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::createInProcessThinBackend(Config->ThinLTOJobs);<br>
<br>
+  if (Config->ThinLTOIndexOnly) {<br>
+    std::string OldPrefix, NewPrefix;<br>
+    std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.split(';');<br>
+    Backend = lto::createWriteIndexesThinBackend(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::BitcodeCompiler() : LTOObj(createLTO()) {<br>
+BitcodeCompiler::BitcodeCompiler() {<br>
+  LinkedObjects = createLinkedObjectsFile();<br>
+  LTOObj = createLTO(LinkedObjects.get());<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(BitcodeFile &F) {<br>
   lto::InputFile &Obj = *F.Obj;<br>
+<br>
+  std::string OldPrefix, NewPrefix;<br>
+  std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.split(';');<br>
+<br>
+  // Create the empty files which, if indexed, will be overwritten later.<br>
+  writeEmptyDistributedBuildOutputs(Obj.getName(), OldPrefix, NewPrefix, false);<br>
+<br>
   unsigned SymNum = 0;<br>
   std::vector<Symbol *> Syms = F.getSymbols();<br>
   std::vector<lto::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(createObjectFile(*File));<br>
<br>
   return Ret;<br>
 }<br>
+<br>
+// For lazy object files not added to link, adds empty index files<br>
+void BitcodeCompiler::addLazyObjFile(LazyObjFile *File) {<br>
+  StringRef Identifier = File->getBuffer().getBufferIdentifier();<br>
+  std::string OldPrefix, NewPrefix;<br>
+  std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.split(';');<br>
+  writeEmptyDistributedBuildOutputs(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-project/lld/trunk/ELF/LTO.h?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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::LTO> LTOObj;<br>
   std::vector<SmallString<0>> Buff;<br>
   std::vector<std::unique_ptr<MemoryBuffer>> Files;<br>
   llvm::DenseSet<StringRef> UsedStartStop;<br>
+  std::unique_ptr<llvm::raw_fd_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-project/lld/trunk/ELF/SymbolTable.cpp?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<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/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-project/lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll?rev=331405&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll (added)<br>
+++ lld/trunk/test/ELF/lto/Inputs/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:32:64-S128"<br>
+target triple = "x86_64-unknown-linux-gnu"<br>
<br>
Modified: lld/trunk/test/ELF/lto/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-project/lld/trunk/test/ELF/lto/thinlto.ll?rev=331405&r1=331404&r2=331405&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/lto/thinlto.ll (original)<br>
+++ lld/trunk/test/ELF/lto/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-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-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-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-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{{.*}}.o'<br>
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.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|-5300342847281564238}}<br>
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-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:32:64-S128"<br>
 target triple = "x86_64-unknown-linux-gnu"<br>
<br>
<br>
Added: lld/trunk/test/ELF/lto/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-project/lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll?rev=331405&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll (added)<br>
+++ lld/trunk/test/ELF/lto/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_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_replace.o.thinlto.bc<br>
+; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace<br>
+; RUN: ls %t/newpath/thinlto_prefix_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_replace.o.thinlto.bc<br>
+; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace="%t/oldpath/:%t/newpath/" -shared %t/oldpath/thinlto_prefix_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: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>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">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/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</blockquote></div>