[LTO][COFF] Use bitcode file names in lto native object file names.
authorZequan Wu <zequanwu@google.com>
Wed, 2 Nov 2022 00:06:01 +0000 (17:06 -0700)
committerZequan Wu <zequanwu@google.com>
Tue, 22 Nov 2022 18:19:58 +0000 (10:19 -0800)
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

19 files changed:
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

index d0cab0c..77b0c5b 100644 (file)
@@ -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);
   };
index 500f5fd..5e0c0f9 100644 (file)
@@ -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";
index a4b7c44..197afab 100644 (file)
@@ -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)));
   }
 
index 2cc4c7c..e450009 100644 (file)
@@ -47,8 +47,8 @@ public:
 
 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;
 };
index 4d3a45b..9b452bb 100644 (file)
@@ -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]));
         },
index 192a5fc..b7bd1a1 100644 (file)
@@ -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]));
       },
index ab0c82e..a833629 100644 (file)
@@ -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
index 4954f84..6ea0f28 100644 (file)
@@ -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 *`:
index 1a3ba23..bfd819d 100644 (file)
@@ -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
 
index ac4cfb6..30243c3 100644 (file)
@@ -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]));
       },
index 36efccd..b29327d 100644 (file)
@@ -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());
index bef23ae..4fa57cc 100644 (file)
@@ -38,28 +38,30 @@ public:
 /// 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
index 3fde873..990bc4e 100644 (file)
@@ -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);
index 9bfbabc..81219cd 100644 (file)
@@ -1313,7 +1313,7 @@ public:
     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;
index 2760f4d..5a8f60d 100644 (file)
@@ -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;
index 68ef8d6..3abfef1 100644 (file)
@@ -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;
index d6902f6..f20f08a 100644 (file)
@@ -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);
     };
   };
 }
index 64c8c19..79e9d93 100644 (file)
@@ -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);
index 87fe90a..dba231e 100644 (file)
@@ -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;