[lld] 531ed6d - [LTO][COFF] Use bitcode file names in lto native object file names.

Zequan Wu via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 22 10:20:05 PST 2022


Author: Zequan Wu
Date: 2022-11-22T10:19:58-08:00
New Revision: 531ed6d5aa65f41c6dfe2e74905d5c6c88fc95a7

URL: https://github.com/llvm/llvm-project/commit/531ed6d5aa65f41c6dfe2e74905d5c6c88fc95a7
DIFF: https://github.com/llvm/llvm-project/commit/531ed6d5aa65f41c6dfe2e74905d5c6c88fc95a7.diff

LOG: [LTO][COFF] Use bitcode file names in lto native object file names.

Currently the lto native object files have names like main.exe.lto.1.obj. In
PDB, those names are used as names for each compiland. Microsoft’s tool
SizeBench uses those names to present to users the size of each object files.
So, names like main.exe.lto.1.obj is not user friendly.

This patch makes the lto native object file names more readable by using
the bitcode file names as part of the file names. For example, if the input
bitcode file has path like "path/to/foo.obj", its corresponding lto native
object file path would be "path/to/main.exe.lto.foo.obj". Since the lto native
object file name only bothers PDB, this patch only changes the lld-linker's
behavior.

Reviewed By: tejohnson, MaskRay, #lld-macho

Differential Revision: https://reviews.llvm.org/D137217

Added: 
    

Modified: 
    clang/lib/CodeGen/BackendUtil.cpp
    clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
    lld/COFF/LTO.cpp
    lld/COFF/LTO.h
    lld/ELF/LTO.cpp
    lld/MachO/LTO.cpp
    lld/test/COFF/lto-obj-path.ll
    lld/test/COFF/pdb-thinlto.ll
    lld/test/COFF/thinlto.ll
    lld/wasm/LTO.cpp
    lldb/source/Core/DataFileCache.cpp
    llvm/include/llvm/Support/Caching.h
    llvm/lib/Debuginfod/Debuginfod.cpp
    llvm/lib/LTO/LTO.cpp
    llvm/lib/LTO/LTOBackend.cpp
    llvm/lib/LTO/LTOCodeGenerator.cpp
    llvm/lib/Support/Caching.cpp
    llvm/tools/llvm-lto/llvm-lto.cpp
    llvm/tools/llvm-lto2/llvm-lto2.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index d0cab0ceb4d3c..77b0c5b15da7d 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1110,7 +1110,7 @@ static void runThinLTOBackend(
   if (!lto::initImportList(*M, *CombinedIndex, ImportList))
     return;
 
-  auto AddStream = [&](size_t Task) {
+  auto AddStream = [&](size_t Task, const Twine &ModuleName) {
     return std::make_unique<CachedFileStream>(std::move(OS),
                                               CGOpts.ObjectFilenameForDebug);
   };

diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 500f5fdcecae2..5e0c0f92e6f53 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -843,7 +843,9 @@ Error linkBitcodeFiles(SmallVectorImpl<OffloadFile> &InputFiles,
   // Run the LTO job to compile the bitcode.
   size_t MaxTasks = LTOBackend->getMaxTasks();
   SmallVector<StringRef> Files(MaxTasks);
-  auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
+  auto AddStream =
+      [&](size_t Task,
+          const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
     int FD = -1;
     auto &TempFile = Files[Task];
     StringRef Extension = (Triple.isNVPTX()) ? "s" : "o";

diff  --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index a4b7c44a7e73b..197afabdc22b0 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -171,16 +171,18 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
   // specified, configure LTO to use it as the cache directory.
   FileCache cache;
   if (!config->ltoCache.empty())
-    cache =
-        check(localCache("ThinLTO", "Thin", config->ltoCache,
-                         [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
-                           files[task] = std::move(mb);
-                         }));
+    cache = check(localCache("ThinLTO", "Thin", config->ltoCache,
+                             [&](size_t task, const Twine &moduleName,
+                                 std::unique_ptr<MemoryBuffer> mb) {
+                               files[task].first = moduleName.str();
+                               files[task].second = std::move(mb);
+                             }));
 
   checkError(ltoObj->run(
-      [&](size_t task) {
+      [&](size_t task, const Twine &moduleName) {
+        buf[task].first = moduleName.str();
         return std::make_unique<CachedFileStream>(
-            std::make_unique<raw_svector_ostream>(buf[task]));
+            std::make_unique<raw_svector_ostream>(buf[task].second));
       },
       cache));
 
@@ -197,7 +199,7 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
   // distributed environment.
   if (config->thinLTOIndexOnly) {
     if (!config->ltoObjPath.empty())
-      saveBuffer(buf[0], config->ltoObjPath);
+      saveBuffer(buf[0].second, config->ltoObjPath);
     if (indexFile)
       indexFile->close();
     return {};
@@ -208,28 +210,40 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
 
   std::vector<InputFile *> ret;
   for (unsigned i = 0; i != maxTasks; ++i) {
-    // Assign unique names to LTO objects. This ensures they have unique names
-    // in the PDB if one is produced. The names should look like:
-    // - foo.exe.lto.obj
-    // - foo.exe.lto.1.obj
-    // - ...
-    StringRef ltoObjName =
-        saver().save(Twine(config->outputFile) + ".lto" +
-                     (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
-
+    StringRef bitcodeFilePath;
     // Get the native object contents either from the cache or from memory.  Do
     // not use the cached MemoryBuffer directly, or the PDB will not be
     // deterministic.
     StringRef objBuf;
-    if (files[i])
-      objBuf = files[i]->getBuffer();
-    else
-      objBuf = buf[i];
+    if (files[i].second) {
+      objBuf = files[i].second->getBuffer();
+      bitcodeFilePath = files[i].first;
+    } else {
+      objBuf = buf[i].second;
+      bitcodeFilePath = buf[i].first;
+    }
     if (objBuf.empty())
       continue;
 
+    // If the input bitcode file is path/to/a.obj, then the corresponding lto
+    // object file name will soemthing like: path/to/main.exe.lto.a.obj.
+    StringRef ltoObjName;
+    if (bitcodeFilePath == "ld-temp.o") {
+      ltoObjName =
+          saver().save(Twine(config->outputFile) + ".lto" +
+                       (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
+    } else {
+      StringRef directory = sys::path::parent_path(bitcodeFilePath);
+      StringRef baseName = sys::path::filename(bitcodeFilePath);
+      StringRef outputFileBaseName = sys::path::filename(config->outputFile);
+      SmallString<64> path;
+      sys::path::append(path, directory,
+                        outputFileBaseName + ".lto." + baseName);
+      sys::path::remove_dots(path, true);
+      ltoObjName = saver().save(path.str());
+    }
     if (config->saveTemps)
-      saveBuffer(buf[i], ltoObjName);
+      saveBuffer(buf[i].second, ltoObjName);
     ret.push_back(make<ObjFile>(ctx, MemoryBufferRef(objBuf, ltoObjName)));
   }
 

diff  --git a/lld/COFF/LTO.h b/lld/COFF/LTO.h
index 2cc4c7c5ea1eb..e450009101379 100644
--- a/lld/COFF/LTO.h
+++ b/lld/COFF/LTO.h
@@ -47,8 +47,8 @@ class BitcodeCompiler {
 
 private:
   std::unique_ptr<llvm::lto::LTO> ltoObj;
-  std::vector<SmallString<0>> buf;
-  std::vector<std::unique_ptr<MemoryBuffer>> files;
+  std::vector<std::pair<std::string, SmallString<0>>> buf;
+  std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>> files;
   std::unique_ptr<llvm::raw_fd_ostream> indexFile;
   llvm::DenseSet<StringRef> thinIndices;
 };

diff  --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 4d3a45b33da06..9b452bbf9a5de 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -327,15 +327,15 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
   // specified, configure LTO to use it as the cache directory.
   FileCache cache;
   if (!config->thinLTOCacheDir.empty())
-    cache =
-        check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
-                         [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
-                           files[task] = std::move(mb);
-                         }));
+    cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
+                             [&](size_t task, const Twine &moduleName,
+                                 std::unique_ptr<MemoryBuffer> mb) {
+                               files[task] = std::move(mb);
+                             }));
 
   if (!ctx.bitcodeFiles.empty())
     checkError(ltoObj->run(
-        [&](size_t task) {
+        [&](size_t task, const Twine &moduleName) {
           return std::make_unique<CachedFileStream>(
               std::make_unique<raw_svector_ostream>(buf[task]));
         },

diff  --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index 192a5fcd31d63..b7bd1a1f5f5d5 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -129,14 +129,14 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
   // specified, configure LTO to use it as the cache directory.
   FileCache cache;
   if (!config->thinLTOCacheDir.empty())
-    cache =
-        check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
-                         [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
-                           files[task] = std::move(mb);
-                         }));
+    cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
+                             [&](size_t task, const Twine &moduleName,
+                                 std::unique_ptr<MemoryBuffer> mb) {
+                               files[task] = std::move(mb);
+                             }));
 
   checkError(ltoObj->run(
-      [&](size_t task) {
+      [&](size_t task, const Twine &moduleName) {
         return std::make_unique<CachedFileStream>(
             std::make_unique<raw_svector_ostream>(buf[task]));
       },

diff  --git a/lld/test/COFF/lto-obj-path.ll b/lld/test/COFF/lto-obj-path.ll
index ab0c82e9b1704..a8336291fa0ac 100644
--- a/lld/test/COFF/lto-obj-path.ll
+++ b/lld/test/COFF/lto-obj-path.ll
@@ -2,26 +2,31 @@
 
 ; Test to ensure that thinlto-index-only with lto-obj-path creates
 ; the native object file.
-; RUN: opt -module-summary %s -o %t1.obj
-; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.obj
-; RUN: rm -f %t4.obj
-; RUN: lld-link -thinlto-index-only -lto-obj-path:%t4.obj -out:t3.exe \
-; RUN:     -entry:main %t1.obj %t2.obj
-; RUN: llvm-readobj -h %t4.obj | FileCheck %s
-; RUN: llvm-nm %t4.obj 2>&1 | FileCheck %s -check-prefix=SYMBOLS
-; RUN: llvm-nm %t4.obj 2>&1 | count 1
+; RUN: rm -rf %t.dir/objpath && mkdir -p %t.dir/objpath
+; RUN: opt -module-summary %s -o %t.dir/objpath/t1.obj
+; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t.dir/objpath/t2.obj
+; RUN: rm -f %t.dir/objpath/t4.obj
+; RUN: lld-link -thinlto-index-only -lto-obj-path:%t.dir/objpath/t4.obj \
+; RUN:     -out:%t.dir/objpath/t3.exe -entry:main %t.dir/objpath/t1.obj \
+; RUN:     %t.dir/objpath/t2.obj
+; RUN: llvm-readobj -h %t.dir/objpath/t4.obj | FileCheck %s
+; RUN: llvm-nm %t.dir/objpath/t4.obj 2>&1 | FileCheck %s -check-prefix=SYMBOLS
+; RUN: llvm-nm %t.dir/objpath/t4.obj 2>&1 | count 1
 
 ;; Ensure lld emits empty combined module if specific obj-path.
-; RUN: rm -fr %t.dir/objpath && mkdir -p %t.dir/objpath
-; RUN: lld-link /out:%t.dir/objpath/a.exe -lto-obj-path:%t4.obj \
-; RUN:     -entry:main %t1.obj %t2.obj -lldsavetemps
-; RUN: ls %t.dir/objpath/a.exe.lto.* | count 3
+; RUN: lld-link /out:%t.dir/objpath/a.exe -lto-obj-path:%t.dir/objpath/t4.obj \
+; RUN:     -entry:main %t.dir/objpath/t1.obj %t.dir/objpath/t2.obj -lldsavetemps
+; RUN: ls %t.dir/objpath/a.exe.lto.obj
+; RUN: ls %t.dir/objpath/a.exe.lto.t1.obj
+; RUN: ls %t.dir/objpath/a.exe.lto.t2.obj
 
 ;; Ensure lld does not emit empty combined module in default.
-; RUN: rm -fr %t.dir/objpath && mkdir -p %t.dir/objpath
+; RUN: rm %t.dir/objpath/a.exe.lto.*
 ; RUN: lld-link /out:%t.dir/objpath/a.exe \
-; RUN:     -entry:main %t1.obj %t2.obj -lldsavetemps
-; RUN: ls %t.dir/objpath/a.exe.lto.* | count 2
+; RUN:     -entry:main %t.dir/objpath/t1.obj %t.dir/objpath/t2.obj -lldsavetemps
+; RUN: ls %t.dir/objpath/a.exe.lto.t1.obj
+; RUN: ls %t.dir/objpath/a.exe.lto.t2.obj
+; RUN: not ls %t.dir/objpath/a.exe.lto.obj
 
 ; CHECK: Format: COFF-x86-64
 ; SYMBOLS: @feat.00

diff  --git a/lld/test/COFF/pdb-thinlto.ll b/lld/test/COFF/pdb-thinlto.ll
index 4954f841e21dc..6ea0f28e1ef1e 100644
--- a/lld/test/COFF/pdb-thinlto.ll
+++ b/lld/test/COFF/pdb-thinlto.ll
@@ -29,8 +29,8 @@ declare void @foo()
 
 ; CHECK:                           Modules
 ; CHECK: ============================================================
-; CHECK: Mod 0000 | `{{.*}}main.exe.lto.1.obj`:
-; CHECK: Obj: `{{.*}}main.exe.lto.1.obj`:
-; CHECK: Mod 0001 | `{{.*}}main.exe.lto.2.obj`:
-; CHECK: Obj: `{{.*}}main.exe.lto.2.obj`:
+; CHECK: Mod 0000 | `{{.*}}main.exe.lto.main.bc`:
+; CHECK: Obj: `{{.*}}main.exe.lto.main.bc`:
+; CHECK: Mod 0001 | `{{.*}}main.exe.lto.foo.bc`:
+; CHECK: Obj: `{{.*}}main.exe.lto.foo.bc`:
 ; CHECK: Mod 0002 | `* Linker *`:

diff  --git a/lld/test/COFF/thinlto.ll b/lld/test/COFF/thinlto.ll
index 1a3ba23a24607..bfd819dd6757f 100644
--- a/lld/test/COFF/thinlto.ll
+++ b/lld/test/COFF/thinlto.ll
@@ -4,15 +4,15 @@
 ; RUN: opt -thinlto-bc -o %T/thinlto/main.obj %s
 ; RUN: opt -thinlto-bc -o %T/thinlto/foo.obj %S/Inputs/lto-dep.ll
 ; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj
-; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
+; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
 
 ; Test various possible options for /opt:lldltojobs
 ; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=1
-; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
+; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
 ; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=all
-; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
+; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
 ; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=100
-; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
+; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
 ; RUN: not lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=foo 2>&1 | FileCheck %s --check-prefix=BAD-JOBS
 ; BAD-JOBS: error: /opt:lldltojobs: invalid job count: foo
 

diff  --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp
index ac4cfb6f25031..30243c3d05185 100644
--- a/lld/wasm/LTO.cpp
+++ b/lld/wasm/LTO.cpp
@@ -128,14 +128,14 @@ std::vector<StringRef> BitcodeCompiler::compile() {
   // specified, configure LTO to use it as the cache directory.
   FileCache cache;
   if (!config->thinLTOCacheDir.empty())
-    cache =
-        check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
-                         [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
-                           files[task] = std::move(mb);
-                         }));
+    cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
+                             [&](size_t task, const Twine &moduleName,
+                                 std::unique_ptr<MemoryBuffer> mb) {
+                               files[task] = std::move(mb);
+                             }));
 
   checkError(ltoObj->run(
-      [&](size_t task) {
+      [&](size_t task, const Twine &moduleName) {
         return std::make_unique<CachedFileStream>(
             std::make_unique<raw_svector_ostream>(buf[task]));
       },

diff  --git a/lldb/source/Core/DataFileCache.cpp b/lldb/source/Core/DataFileCache.cpp
index 36efccd296a36..b29327db5ca38 100644
--- a/lldb/source/Core/DataFileCache.cpp
+++ b/lldb/source/Core/DataFileCache.cpp
@@ -54,7 +54,8 @@ DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy poli
   // m_take_ownership member variable to indicate if we need to take
   // ownership.
 
-  auto add_buffer = [this](unsigned task, std::unique_ptr<llvm::MemoryBuffer> m) {
+  auto add_buffer = [this](unsigned task, const llvm::Twine &moduleName,
+                           std::unique_ptr<llvm::MemoryBuffer> m) {
     if (m_take_ownership)
       m_mem_buff_up = std::move(m);
   };
@@ -80,7 +81,7 @@ DataFileCache::GetCachedData(llvm::StringRef key) {
   // turn take ownership of the member buffer that is passed to the callback and
   // put it into a member variable.
   llvm::Expected<llvm::AddStreamFn> add_stream_or_err =
-      m_cache_callback(task, key);
+      m_cache_callback(task, key, "");
   m_take_ownership = false;
   // At this point we either already called the "add_buffer" lambda with
   // the data or we haven't. We can tell if we got the cached data by checking
@@ -112,7 +113,7 @@ bool DataFileCache::SetCachedData(llvm::StringRef key,
   // add_buffer lambda function from the constructor which will ignore the
   // data.
   llvm::Expected<llvm::AddStreamFn> add_stream_or_err =
-      m_cache_callback(task, key);
+      m_cache_callback(task, key, "");
   // If we reach this code then we either already called the callback with
   // the data or we haven't. We can tell if we had the cached data by checking
   // the CacheAddStream function pointer value below.
@@ -127,7 +128,7 @@ bool DataFileCache::SetCachedData(llvm::StringRef key,
     // want to write the data.
     if (add_stream) {
       llvm::Expected<std::unique_ptr<llvm::CachedFileStream>> file_or_err =
-          add_stream(task);
+          add_stream(task, "");
       if (file_or_err) {
         llvm::CachedFileStream *cfs = file_or_err->get();
         cfs->OS->write((const char *)data.data(), data.size());

diff  --git a/llvm/include/llvm/Support/Caching.h b/llvm/include/llvm/Support/Caching.h
index bef23ae757f2e..4fa57cc92e51f 100644
--- a/llvm/include/llvm/Support/Caching.h
+++ b/llvm/include/llvm/Support/Caching.h
@@ -38,28 +38,30 @@ class CachedFileStream {
 /// This type defines the callback to add a file that is generated on the fly.
 ///
 /// Stream callbacks must be thread safe.
-using AddStreamFn =
-    std::function<Expected<std::unique_ptr<CachedFileStream>>(unsigned Task)>;
+using AddStreamFn = std::function<Expected<std::unique_ptr<CachedFileStream>>(
+    unsigned Task, const Twine &ModuleName)>;
 
 /// This is the type of a file cache. To request an item from the cache, pass a
 /// unique string as the Key. For hits, the cached file will be added to the
 /// link and this function will return AddStreamFn(). For misses, the cache will
 /// return a stream callback which must be called at most once to produce
 /// content for the stream. The file stream produced by the stream callback will
-/// add the file to the link after the stream is written to.
+/// add the file to the link after the stream is written to. ModuleName is the
+/// unique module identifier for the bitcode module the cache is being checked
+/// for.
 ///
 /// Clients generally look like this:
 ///
-/// if (AddStreamFn AddStream = Cache(Task, Key))
+/// if (AddStreamFn AddStream = Cache(Task, Key, ModuleName))
 ///   ProduceContent(AddStream);
-using FileCache =
-    std::function<Expected<AddStreamFn>(unsigned Task, StringRef Key)>;
+using FileCache = std::function<Expected<AddStreamFn>(
+    unsigned Task, StringRef Key, const Twine &ModuleName)>;
 
 /// This type defines the callback to add a pre-existing file (e.g. in a cache).
 ///
 /// Buffer callbacks must be thread safe.
-using AddBufferFn =
-    std::function<void(unsigned Task, std::unique_ptr<MemoryBuffer> MB)>;
+using AddBufferFn = std::function<void(unsigned Task, const Twine &ModuleName,
+                                       std::unique_ptr<MemoryBuffer> MB)>;
 
 /// Create a local file system cache which uses the given cache name, temporary
 /// file prefix, cache directory and file callback.  This function does not
@@ -68,9 +70,10 @@ using AddBufferFn =
 /// messages for errors during caching. The temporary file prefix is used in the
 /// temporary file naming scheme used when writing files atomically.
 Expected<FileCache> localCache(
-    Twine CacheNameRef, Twine TempFilePrefixRef, Twine CacheDirectoryPathRef,
-    AddBufferFn AddBuffer = [](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
-    });
+    const Twine &CacheNameRef, const Twine &TempFilePrefixRef,
+    const Twine &CacheDirectoryPathRef,
+    AddBufferFn AddBuffer = [](size_t Task, const Twine &ModuleName,
+                               std::unique_ptr<MemoryBuffer> MB) {});
 } // namespace llvm
 
 #endif

diff  --git a/llvm/lib/Debuginfod/Debuginfod.cpp b/llvm/lib/Debuginfod/Debuginfod.cpp
index 3fde8730239f5..990bc4e32425a 100644
--- a/llvm/lib/Debuginfod/Debuginfod.cpp
+++ b/llvm/lib/Debuginfod/Debuginfod.cpp
@@ -224,7 +224,7 @@ Expected<std::string> getCachedOrDownloadArtifact(
   FileCache Cache = *CacheOrErr;
   // We choose an arbitrary Task parameter as we do not make use of it.
   unsigned Task = 0;
-  Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey);
+  Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey, "");
   if (!CacheAddStreamOrErr)
     return CacheAddStreamOrErr.takeError();
   AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
@@ -251,8 +251,8 @@ Expected<std::string> getCachedOrDownloadArtifact(
 
     // Perform the HTTP request and if successful, write the response body to
     // the cache.
-    StreamedHTTPResponseHandler Handler([&]() { return CacheAddStream(Task); },
-                                        Client);
+    StreamedHTTPResponseHandler Handler(
+        [&]() { return CacheAddStream(Task, ""); }, Client);
     HTTPRequest Request(ArtifactUrl);
     Request.Headers = getHeaders();
     Error Err = Client.perform(Request, Handler);

diff  --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 9bfbabc17a08e..81219cda35995 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -1313,7 +1313,7 @@ class InProcessThinBackend : public ThinBackendProc {
     computeLTOCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList,
                        ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
                        CfiFunctionDecls);
-    Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key);
+    Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
     if (Error Err = CacheAddStreamOrErr.takeError())
       return Err;
     AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;

diff  --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 2760f4d8b884d..5a8f60d3aebf2 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -391,7 +391,8 @@ static void codegen(const Config &Conf, TargetMachine *TM,
                          EC.message());
   }
 
-  Expected<std::unique_ptr<CachedFileStream>> StreamOrErr = AddStream(Task);
+  Expected<std::unique_ptr<CachedFileStream>> StreamOrErr =
+      AddStream(Task, Mod.getModuleIdentifier());
   if (Error Err = StreamOrErr.takeError())
     report_fatal_error(std::move(Err));
   std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;

diff  --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 68ef8d60beac7..3abfef1fd69f2 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -301,7 +301,9 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
   // make unique temp output file to put generated code
   SmallString<128> Filename;
 
-  auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
+  auto AddStream =
+      [&](size_t Task,
+          const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
     StringRef Extension(Config.CGFileType == CGFT_AssemblyFile ? "s" : "o");
 
     int FD;

diff  --git a/llvm/lib/Support/Caching.cpp b/llvm/lib/Support/Caching.cpp
index d6902f660e39e..f20f08a865c76 100644
--- a/llvm/lib/Support/Caching.cpp
+++ b/llvm/lib/Support/Caching.cpp
@@ -26,9 +26,9 @@
 
 using namespace llvm;
 
-Expected<FileCache> llvm::localCache(Twine CacheNameRef,
-                                     Twine TempFilePrefixRef,
-                                     Twine CacheDirectoryPathRef,
+Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
+                                     const Twine &TempFilePrefixRef,
+                                     const Twine &CacheDirectoryPathRef,
                                      AddBufferFn AddBuffer) {
 
   // Create local copies which are safely captured-by-copy in lambdas
@@ -37,7 +37,8 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
   TempFilePrefixRef.toVector(TempFilePrefix);
   CacheDirectoryPathRef.toVector(CacheDirectoryPath);
 
-  return [=](unsigned Task, StringRef Key) -> Expected<AddStreamFn> {
+  return [=](unsigned Task, StringRef Key,
+             const Twine &ModuleName) -> Expected<AddStreamFn> {
     // This choice of file name allows the cache to be pruned (see pruneCache()
     // in include/llvm/Support/CachePruning.h).
     SmallString<64> EntryPath;
@@ -54,7 +55,7 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
                                     /*RequiresNullTerminator=*/false);
       sys::fs::closeFile(*FDOrErr);
       if (MBOrErr) {
-        AddBuffer(Task, std::move(*MBOrErr));
+        AddBuffer(Task, ModuleName, std::move(*MBOrErr));
         return AddStreamFn();
       }
       EC = MBOrErr.getError();
@@ -77,14 +78,15 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
     struct CacheStream : CachedFileStream {
       AddBufferFn AddBuffer;
       sys::fs::TempFile TempFile;
+      std::string ModuleName;
       unsigned Task;
 
       CacheStream(std::unique_ptr<raw_pwrite_stream> OS, AddBufferFn AddBuffer,
                   sys::fs::TempFile TempFile, std::string EntryPath,
-                  unsigned Task)
+                  std::string ModuleName, unsigned Task)
           : CachedFileStream(std::move(OS), std::move(EntryPath)),
             AddBuffer(std::move(AddBuffer)), TempFile(std::move(TempFile)),
-            Task(Task) {}
+            ModuleName(ModuleName), Task(Task) {}
 
       ~CacheStream() {
         // TODO: Manually commit rather than using non-trivial destructor,
@@ -133,11 +135,12 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
                              TempFile.TmpName + " to " + ObjectPathName + ": " +
                              toString(std::move(E)) + "\n");
 
-        AddBuffer(Task, std::move(*MBOrErr));
+        AddBuffer(Task, ModuleName, std::move(*MBOrErr));
       }
     };
 
-    return [=](size_t Task) -> Expected<std::unique_ptr<CachedFileStream>> {
+    return [=](size_t Task, const Twine &ModuleName)
+               -> Expected<std::unique_ptr<CachedFileStream>> {
       // Create the cache directory if not already done. Doing this lazily
       // ensures the filesystem isn't mutated until the cache is.
       if (std::error_code EC = sys::fs::create_directories(
@@ -158,7 +161,8 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
       // This CacheStream will move the temporary file into the cache when done.
       return std::make_unique<CacheStream>(
           std::make_unique<raw_fd_ostream>(Temp->FD, /* ShouldClose */ false),
-          AddBuffer, std::move(*Temp), std::string(EntryPath.str()), Task);
+          AddBuffer, std::move(*Temp), std::string(EntryPath.str()),
+          ModuleName.str(), Task);
     };
   };
 }

diff  --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp
index 64c8c1954ec9b..79e9d93061a21 100644
--- a/llvm/tools/llvm-lto/llvm-lto.cpp
+++ b/llvm/tools/llvm-lto/llvm-lto.cpp
@@ -317,11 +317,11 @@ namespace {
       if (!CurrentActivity.empty())
         OS << ' ' << CurrentActivity;
       OS << ": ";
-  
+
       DiagnosticPrinterRawOStream DP(OS);
       DI.print(DP);
       OS << '\n';
-  
+
       if (DI.getSeverity() == DS_Error)
         exit(1);
       return true;
@@ -1099,7 +1099,9 @@ int main(int argc, char **argv) {
         error("writing merged module failed.");
     }
 
-    auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
+    auto AddStream =
+        [&](size_t Task,
+            const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
       std::string PartFilename = OutputFilename;
       if (Parallelism != 1)
         PartFilename += "." + utostr(Task);

diff  --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 87fe90a5225fc..dba231ea9d40a 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -411,7 +411,9 @@ static int run(int argc, char **argv) {
   if (HasErrors)
     return 1;
 
-  auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
+  auto AddStream =
+      [&](size_t Task,
+          const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
     std::string Path = OutputFilename + "." + utostr(Task);
 
     std::error_code EC;
@@ -420,8 +422,9 @@ static int run(int argc, char **argv) {
     return std::make_unique<CachedFileStream>(std::move(S), Path);
   };
 
-  auto AddBuffer = [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
-    *AddStream(Task)->OS << MB->getBuffer();
+  auto AddBuffer = [&](size_t Task, const Twine &ModuleName,
+                       std::unique_ptr<MemoryBuffer> MB) {
+    *AddStream(Task, ModuleName)->OS << MB->getBuffer();
   };
 
   FileCache Cache;


        


More information about the llvm-commits mailing list