<div dir="ltr">Should be fixed by r282313.<div><br></div><div>Peter</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 23, 2016 at 4:11 PM, Zachary Turner <span dir="ltr"><<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Peter, I'm getting compilation failures with this.<div><br></div><div><div>[748/3638] Building CXX object lib\LTO\CMakeFiles\LLVMLTO.<wbr>dir\Caching.cpp.obj</div><div>FAILED: C:\PROGRA~2\MICROS~1.0\VC\bin\<wbr>AMD64_~2\cl.exe   /nologo /TP -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib\LTO -ID:\src\llvm\lib\LTO -Iinclude -ID:\src\llvm\include /DWIN32 /D_WINDOWS   /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /Zc:sizedDealloc- /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1    /EHs-c- /GR- /showIncludes /Folib\LTO\CMakeFiles\LLVMLTO.<wbr>dir\Caching.cpp.obj /Fdlib\LTO\CMakeFiles\LLVMLTO.<wbr>dir\ /FS -c D:\src\llvm\lib\LTO\Caching.<wbr>cpp</div><div>D:\src\llvm\lib\LTO\Caching.<wbr>cpp(96): error C2668: 'llvm::make_unique': ambiguous call to overloaded function                       D:\src\llvm\include\llvm/ADT/<wbr>STLExtras.h(563): note: could be 'std::unique_ptr<llvm::lto::<wbr>localCache::<lambda_<wbr>24b0b9154e270ae79e71d53f81fee0<wbr>dc>::()::CacheStream,std::<wbr>default_delete<_Ty>> llvm::make_unique<llvm::lto::<wbr>localCache::<lambda_<wbr>24b0b9154e270ae79e71d53f81fee0<wbr>dc>::()::CacheStream,std::<wbr>unique_ptr<llvm::raw_fd_<wbr>ostream,std::default_delete<<wbr>llvm::raw_fd_ostream>>,const llvm::lto::AddFileFn&,llvm::<wbr>StringRef,llvm::StringRef,<wbr>size_t&>(std::unique_ptr<llvm:<wbr>:raw_fd_ostream,std::default_<wbr>delete<llvm::raw_fd_ostream>> &&,const llvm::lto::AddFileFn &,llvm::StringRef &&,llvm::StringRef &&,size_t &)'                                                                   with                                                                                                                               [                                                                                                                                      _Ty=llvm::lto::localCache::<<wbr>lambda_<wbr>24b0b9154e270ae79e71d53f81fee0<wbr>dc>::()::CacheStream</div><div>        ]                                                                                                                          C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\memory(1628): note: or       'std::unique_ptr<llvm::lto::<wbr>localCache::<lambda_<wbr>24b0b9154e270ae79e71d53f81fee0<wbr>dc>::()::CacheStream,std::<wbr>default_delete<_Ty>> std::make_unique<llvm::lto::<wbr>localCache::<lambda_<wbr>24b0b9154e270ae79e71d53f81fee0<wbr>dc>::()::CacheStream,std::<wbr>unique_ptr<llvm::raw_fd_<wbr>ostream,std::default_delete<<wbr>llvm::raw_fd_ostream>>,const llvm::lto::AddFileFn&,llvm::<wbr>StringRef,llvm::StringRef,<wbr>size_t&>(std::unique_ptr<llvm:<wbr>:raw_fd_ostream,std::default_<wbr>delete<llvm::raw_fd_ostream>> &&,const llvm::lto::AddFileFn &,llvm::StringRef &&,llvm::StringRef &&,size_t &)' [found using argument-dependent lookup]                                                                                                                                 with                                                                                                                               [</div><div>            _Ty=llvm::lto::localCache::<<wbr>lambda_<wbr>24b0b9154e270ae79e71d53f81fee0<wbr>dc>::()::CacheStream                                          ]                                                                                                                          D:\src\llvm\lib\LTO\Caching.<wbr>cpp(96): note: while trying to match the argument list '(std::unique_ptr<llvm::raw_<wbr>fd_ostream,std::default_<wbr>delete<_Ty>>, const llvm::lto::AddFileFn, llvm::StringRef, llvm::StringRef, std::size_t)'                                              with                                                                                                                               [                                                                                                                                      _Ty=llvm::raw_fd_ostream                                                                                                       ]                                                                                                                          [748/3638] Building AMDGPUGenInstrInfo.inc...</div><div>ninja: build stopped: subcommand failed.                </div></div></div><div class="HOEnZb"><div class="h5"><br><div class="gmail_quote"><div dir="ltr">On Fri, Sep 23, 2016 at 2:42 PM Peter Collingbourne via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: pcc<br>
Date: Fri Sep 23 16:33:43 2016<br>
New Revision: 282299<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=282299&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=282299&view=rev</a><br>
Log:<br>
LTO: Simplify caching interface.<br>
<br>
The NativeObjectOutput class has a design problem: it mixes up the caching<br>
policy with the interface for output streams, which makes the client-side<br>
code hard to follow and would for example make it harder to replace the<br>
cache implementation in an arbitrary client.<br>
<br>
This change separates the two aspects by moving the caching policy<br>
to a separate field in Config, replacing NativeObjectOutput with a<br>
NativeObjectStream class which only deals with streams and does not need to<br>
be overridden by most clients and introducing an AddFile callback for adding<br>
files (e.g. from the cache) to the link.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D24622" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D24622</a><br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/LTO/<wbr>Caching.h<br>
    llvm/trunk/include/llvm/LTO/<wbr>Config.h<br>
    llvm/trunk/include/llvm/LTO/<wbr>LTO.h<br>
    llvm/trunk/include/llvm/LTO/<wbr>LTOBackend.h<br>
    llvm/trunk/lib/LTO/Caching.cpp<br>
    llvm/trunk/lib/LTO/LTO.cpp<br>
    llvm/trunk/lib/LTO/LTOBackend.<wbr>cpp<br>
    llvm/trunk/tools/gold/gold-<wbr>plugin.cpp<br>
    llvm/trunk/tools/llvm-lto2/<wbr>llvm-lto2.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/LTO/<wbr>Caching.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/Caching.h?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/LTO/Caching.h?rev=282299&<wbr>r1=282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/LTO/<wbr>Caching.h (original)<br>
+++ llvm/trunk/include/llvm/LTO/<wbr>Caching.h Fri Sep 23 16:33:43 2016<br>
@@ -7,92 +7,29 @@<br>
 //<br>
 //===------------------------<wbr>------------------------------<wbr>----------------===//<br>
 //<br>
-// This file defines the lto::CacheObjectOutput data structure, which allows<br>
-// clients to add a filesystem cache to ThinLTO<br>
+// This file defines the localCache function, which allows clients to add a<br>
+// filesystem cache to ThinLTO.<br>
 //<br>
 //===------------------------<wbr>------------------------------<wbr>----------------===//<br>
<br>
 #ifndef LLVM_LTO_CACHING_H<br>
 #define LLVM_LTO_CACHING_H<br>
<br>
-#include "llvm/ADT/SmallString.h"<br>
-#include "llvm/LTO/Config.h"<br>
-#include "llvm/Support/MemoryBuffer.h"<br>
+#include "llvm/LTO/LTO.h"<br>
+#include <string><br>
<br>
 namespace llvm {<br>
 namespace lto {<br>
-/// Type for client-supplied callback when a buffer is loaded from the cache.<br>
-typedef std::function<void(std::<wbr>string)> AddBufferFn;<br>
<br>
-/// Manage caching on the filesystem.<br>
+/// This type defines the callback to add a pre-existing native object file<br>
+/// (e.g. in a cache).<br>
 ///<br>
-/// The general scheme is the following:<br>
-///<br>
-/// void do_stuff(AddBufferFn CallBack) {<br>
-///   /* ... */<br>
-///   {<br>
-///     /* Create the CacheObjectOutput pointing to a cache directory */<br>
-///     auto Output = CacheObjectOutput("/tmp/cache"<wbr>, CallBack)<br>
-///<br>
-///     /* Call some processing function */<br>
-///     process(Output);<br>
-///<br>
-///   } /* Callback is only called now, on destruction of the Output object */<br>
-///   /* ... */<br>
-/// }<br>
-///<br>
-///<br>
-/// void process(NativeObjectOutput &Output) {<br>
-///   /* check if caching is supported */<br>
-///   if (Output.isCachingEnabled()) {<br>
-///     auto Key = ComputeKeyForEntry(...); // "expensive" call<br>
-///     if (Output.tryLoadFromCache())<br>
-///        return; // Cache hit<br>
-///   }<br>
-///<br>
-///   auto OS = Output.getStream();<br>
-///<br>
-///   OS << ...;<br>
-///   /* Note that the callback is not called here, but only when the caller<br>
-///      destroys Output */<br>
-/// }<br>
-///<br>
-class CacheObjectOutput : public NativeObjectOutput {<br>
-  /// Path to the on-disk cache directory<br>
-  StringRef CacheDirectoryPath;<br>
-  /// Path to this entry in the cache, initialized by tryLoadFromCache().<br>
-  SmallString<128> EntryPath;<br>
-  /// Path to temporary file used to buffer output that will be committed to the<br>
-  /// cache entry when this object is destroyed<br>
-  SmallString<128> TempFilename;<br>
-  /// User-supplied callback, used to provide path to cache entry<br>
-  /// (potentially after creating it).<br>
-  AddBufferFn AddBuffer;<br>
-<br>
-public:<br>
-  /// The destructor pulls the entry from the cache and calls the AddBuffer<br>
-  /// callback, after committing the entry into the cache on miss.<br>
-  ~CacheObjectOutput();<br>
-<br>
-  /// Create a CacheObjectOutput: the client is supposed to create it in the<br>
-  /// callback supplied to LTO::run. The \p CacheDirectoryPath points to the<br>
-  /// directory on disk where to store the cache, and \p AddBuffer will be<br>
-  /// called when the buffer is ready to be pulled out of the cache<br>
-  /// (potentially after creating it).<br>
-  CacheObjectOutput(StringRef CacheDirectoryPath, AddBufferFn AddBuffer)<br>
-      : CacheDirectoryPath(<wbr>CacheDirectoryPath), AddBuffer(AddBuffer) {}<br>
-<br>
-  /// Return an allocated stream for the output, or null in case of failure.<br>
-  std::unique_ptr<raw_pwrite_<wbr>stream> getStream() override;<br>
-<br>
-  /// Set EntryPath, try loading from a possible cache first, return true on<br>
-  /// cache hit.<br>
-  bool tryLoadFromCache(StringRef Key) override;<br>
-<br>
-  /// Returns true to signal that this implementation of NativeObjectFile<br>
-  /// support caching.<br>
-  bool isCachingEnabled() const override { return true; }<br>
-};<br>
+/// File callbacks must be thread safe.<br>
+typedef std::function<void(unsigned Task, StringRef Path)> AddFileFn;<br>
+<br>
+/// Create a local file system cache which uses the given cache directory and<br>
+/// file callback.<br>
+NativeObjectCache localCache(std::string CacheDirectoryPath, AddFileFn AddFile);<br>
<br>
 } // namespace lto<br>
 } // namespace llvm<br>
<br>
Modified: llvm/trunk/include/llvm/LTO/<wbr>Config.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/Config.h?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/LTO/Config.h?rev=282299&<wbr>r1=282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/LTO/<wbr>Config.h (original)<br>
+++ llvm/trunk/include/llvm/LTO/<wbr>Config.h Fri Sep 23 16:33:43 2016<br>
@@ -30,38 +30,6 @@ class raw_pwrite_stream;<br>
<br>
 namespace lto {<br>
<br>
-/// Abstract class representing a single Task output to be implemented by the<br>
-/// client of the LTO API.<br>
-///<br>
-/// The general scheme the API is called is the following:<br>
-///<br>
-/// void process(NativeObjectOutput &Output) {<br>
-///   /* check if caching is supported */<br>
-///   if (Output.isCachingEnabled()) {<br>
-///     auto Key = ComputeKeyForEntry(...); // "expensive" call<br>
-///     if (Output.tryLoadFromCache())<br>
-///        return; // Cache hit<br>
-///   }<br>
-///<br>
-///   auto OS = Output.getStream();<br>
-///<br>
-///   OS << ....;<br>
-/// }<br>
-///<br>
-class NativeObjectOutput {<br>
-public:<br>
-  // Return an allocated stream for the output, or null in case of failure.<br>
-  virtual std::unique_ptr<raw_pwrite_<wbr>stream> getStream() = 0;<br>
-<br>
-  // Try loading from a possible cache first, return true on cache hit.<br>
-  virtual bool tryLoadFromCache(StringRef Key) { return false; }<br>
-<br>
-  // Returns true if a cache is available<br>
-  virtual bool isCachingEnabled() const { return false; }<br>
-<br>
-  virtual ~NativeObjectOutput() = default;<br>
-};<br>
-<br>
 /// LTO configuration. A linker can configure LTO by setting fields in this data<br>
 /// structure and passing it to the lto::LTO constructor.<br>
 struct Config {<br>
@@ -235,13 +203,6 @@ struct Config {<br>
                      bool UseInputModulePath = false);<br>
 };<br>
<br>
-/// This type defines the callback to add a native object that is generated on<br>
-/// the fly.<br>
-///<br>
-/// Output callbacks must be thread safe.<br>
-typedef std::function<std::unique_ptr<<wbr>NativeObjectOutput>(unsigned Task)><br>
-    AddOutputFn;<br>
-<br>
 /// A derived class of LLVMContext that initializes itself according to a given<br>
 /// Config object. The purpose of this class is to tie ownership of the<br>
 /// diagnostic handler to the context, as opposed to the Config object (which<br>
<br>
Modified: llvm/trunk/include/llvm/LTO/<wbr>LTO.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTO.h?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/LTO/LTO.h?rev=282299&r1=<wbr>282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/LTO/<wbr>LTO.h (original)<br>
+++ llvm/trunk/include/llvm/LTO/<wbr>LTO.h Fri Sep 23 16:33:43 2016<br>
@@ -247,13 +247,47 @@ public:<br>
   }<br>
 };<br>
<br>
+/// This class wraps an output stream for a native object. Most clients should<br>
+/// just be able to return an instance of this base class from the stream<br>
+/// callback, but if a client needs to perform some action after the stream is<br>
+/// written to, that can be done by deriving from this class and overriding the<br>
+/// destructor.<br>
+class NativeObjectStream {<br>
+public:<br>
+  NativeObjectStream(std::<wbr>unique_ptr<raw_pwrite_stream> OS) : OS(std::move(OS)) {}<br>
+  std::unique_ptr<raw_pwrite_<wbr>stream> OS;<br>
+  virtual ~NativeObjectStream() = default;<br>
+};<br>
+<br>
+/// This type defines the callback to add a native object that is generated on<br>
+/// the fly.<br>
+///<br>
+/// Stream callbacks must be thread safe.<br>
+typedef std::function<std::unique_ptr<<wbr>NativeObjectStream>(unsigned Task)><br>
+    AddStreamFn;<br>
+<br>
+/// This is the type of a native object cache. To request an item from the<br>
+/// cache, pass a unique string as the Key. For hits, the cached file will be<br>
+/// added to the link and this function will return AddStreamFn(). For misses,<br>
+/// the cache will return a stream callback which must be called at most once to<br>
+/// produce content for the stream. The native object stream produced by the<br>
+/// stream callback will add the file to the link after the stream is written<br>
+/// to.<br>
+///<br>
+/// Clients generally look like this:<br>
+///<br>
+/// if (AddStreamFn AddStream = Cache(Task, Key))<br>
+///   ProduceContent(AddStream);<br>
+typedef std::function<AddStreamFn(<wbr>unsigned Task, StringRef Key)><br>
+    NativeObjectCache;<br>
+<br>
 /// A ThinBackend defines what happens after the thin-link phase during ThinLTO.<br>
 /// The details of this type definition aren't important; clients can only<br>
 /// create a ThinBackend using one of the create*ThinBackend() functions below.<br>
 typedef std::function<std::unique_ptr<<wbr>ThinBackendProc>(<br>
     Config &C, ModuleSummaryIndex &CombinedIndex,<br>
     StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,<br>
-    AddOutputFn AddOutput)><br>
+    AddStreamFn AddStream, NativeObjectCache Cache)><br>
     ThinBackend;<br>
<br>
 /// This ThinBackend runs the individual backend jobs in-process.<br>
@@ -286,8 +320,9 @@ ThinBackend createWriteIndexesThinBacken<br>
 ///   and pass it and an array of symbol resolutions to the add() function.<br>
 /// - Call the getMaxTasks() function to get an upper bound on the number of<br>
 ///   native object files that LTO may add to the link.<br>
-/// - Call the run() function. This function will use the supplied AddOutput<br>
-///   function to add up to getMaxTasks() native object files to the link.<br>
+/// - Call the run() function. This function will use the supplied AddStream<br>
+///   and Cache functions to add up to getMaxTasks() native object files to<br>
+///   the link.<br>
 class LTO {<br>
   friend InputFile;<br>
<br>
@@ -310,9 +345,15 @@ public:<br>
   /// full description of tasks see LTOBackend.h.<br>
   unsigned getMaxTasks() const;<br>
<br>
-  /// Runs the LTO pipeline. This function calls the supplied AddOutput function<br>
-  /// to add native object files to the link.<br>
-  Error run(AddOutputFn AddOutput);<br>
+  /// Runs the LTO pipeline. This function calls the supplied AddStream<br>
+  /// function to add native object files to the link.<br>
+  ///<br>
+  /// The Cache parameter is optional. If supplied, it will be used to cache<br>
+  /// native object files and add them to the link.<br>
+  ///<br>
+  /// The client will receive at most one callback (via either AddStream or<br>
+  /// Cache) for each task identifier.<br>
+  Error run(AddStreamFn AddStream, NativeObjectCache Cache = nullptr);<br>
<br>
 private:<br>
   Config Conf;<br>
@@ -393,8 +434,9 @@ private:<br>
   Error addThinLTO(std::unique_ptr<<wbr>InputFile> Input,<br>
                    ArrayRef<SymbolResolution> Res);<br>
<br>
-  Error runRegularLTO(AddOutputFn AddOutput);<br>
-  Error runThinLTO(AddOutputFn AddOutput, bool HasRegularLTO);<br>
+  Error runRegularLTO(AddStreamFn AddStream);<br>
+  Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,<br>
+                   bool HasRegularLTO);<br>
<br>
   mutable bool CalledGetMaxTasks = false;<br>
 };<br>
<br>
Modified: llvm/trunk/include/llvm/LTO/<wbr>LTOBackend.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOBackend.h?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/LTO/LTOBackend.h?rev=<wbr>282299&r1=282298&r2=282299&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/LTO/<wbr>LTOBackend.h (original)<br>
+++ llvm/trunk/include/llvm/LTO/<wbr>LTOBackend.h Fri Sep 23 16:33:43 2016<br>
@@ -20,7 +20,7 @@<br>
 #include "llvm/ADT/MapVector.h"<br>
 #include "llvm/IR/DiagnosticInfo.h"<br>
 #include "llvm/IR/ModuleSummaryIndex.h"<br>
-#include "llvm/LTO/Config.h"<br>
+#include "llvm/LTO/LTO.h"<br>
 #include "llvm/Support/MemoryBuffer.h"<br>
 #include "llvm/Target/TargetOptions.h"<br>
 #include "llvm/Transforms/IPO/<wbr>FunctionImport.h"<br>
@@ -34,12 +34,12 @@ class Target;<br>
 namespace lto {<br>
<br>
 /// Runs a regular LTO backend.<br>
-Error backend(Config &C, AddOutputFn AddStream,<br>
+Error backend(Config &C, AddStreamFn AddStream,<br>
               unsigned ParallelCodeGenParallelismLeve<wbr>l,<br>
               std::unique_ptr<Module> M);<br>
<br>
 /// Runs a ThinLTO backend.<br>
-Error thinBackend(Config &C, unsigned Task, AddOutputFn AddStream, Module &M,<br>
+Error thinBackend(Config &C, unsigned Task, AddStreamFn AddStream, Module &M,<br>
                   ModuleSummaryIndex &CombinedIndex,<br>
                   const FunctionImporter::ImportMapTy &ImportList,<br>
                   const GVSummaryMapTy &DefinedGlobals,<br>
<br>
Modified: llvm/trunk/lib/LTO/Caching.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/Caching.cpp?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/LTO/<wbr>Caching.cpp?rev=282299&r1=<wbr>282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/LTO/Caching.cpp (original)<br>
+++ llvm/trunk/lib/LTO/Caching.cpp Fri Sep 23 16:33:43 2016<br>
@@ -12,13 +12,9 @@<br>
 //===------------------------<wbr>------------------------------<wbr>----------------===//<br>
<br>
 #include "llvm/LTO/Caching.h"<br>
-<br>
-#ifdef HAVE_LLVM_REVISION<br>
-#include "LLVMLTORevision.h"<br>
-#endif<br>
-<br>
 #include "llvm/ADT/StringExtras.h"<br>
 #include "llvm/Support/FileSystem.h"<br>
+#include "llvm/Support/MemoryBuffer.h"<br>
 #include "llvm/Support/Path.h"<br>
 #include "llvm/Support/raw_ostream.h"<br>
<br>
@@ -30,6 +26,8 @@ static void commitEntry(StringRef TempFi<br>
   auto EC = sys::fs::rename(TempFilename, EntryPath);<br>
   if (EC) {<br>
     // Renaming failed, probably not the same filesystem, copy and delete.<br>
+    // FIXME: Avoid needing to do this by creating the temporary file in the<br>
+    // cache directory.<br>
     {<br>
       auto ReloadedBufferOrErr = MemoryBuffer::getFile(<wbr>TempFilename);<br>
       if (auto EC = ReloadedBufferOrErr.getError()<wbr>)<br>
@@ -48,51 +46,54 @@ static void commitEntry(StringRef TempFi<br>
   }<br>
 }<br>
<br>
-CacheObjectOutput::~<wbr>CacheObjectOutput() {<br>
-  if (EntryPath.empty())<br>
-    // The entry was never used by the client (tryLoadFromCache() wasn't called)<br>
-    return;<br>
-  // TempFilename is only set if getStream() was called, i.e. on cache miss when<br>
-  // tryLoadFromCache() returned false. And EntryPath is valid if a Key was<br>
-  // submitted, otherwise it has been set to CacheDirectoryPath in<br>
-  // tryLoadFromCache.<br>
-  if (!TempFilename.empty()) {<br>
-    if (EntryPath == CacheDirectoryPath)<br>
-      // The Key supplied to tryLoadFromCache was empty, do not commit the temp.<br>
-      EntryPath = TempFilename;<br>
-    else<br>
-      // We commit the tempfile into the cache now, by moving it to EntryPath.<br>
-      commitEntry(TempFilename, EntryPath);<br>
-  }<br>
-  // Supply the cache path to the user.<br>
-  AddBuffer(EntryPath.str());<br>
-}<br>
-<br>
-// Return an allocated stream for the output, or null in case of failure.<br>
-std::unique_ptr<raw_pwrite_<wbr>stream> CacheObjectOutput::getStream() {<br>
-  assert(!EntryPath.empty() && "API Violation: client didn't call "<br>
-                               "tryLoadFromCache() before getStream()");<br>
-  // Write to a temporary to avoid race condition<br>
-  int TempFD;<br>
-  std::error_code EC =<br>
-      sys::fs::createTemporaryFile("<wbr>Thin", "tmp.o", TempFD, TempFilename);<br>
-  if (EC) {<br>
-    errs() << "Error: " << EC.message() << "\n";<br>
-    report_fatal_error("ThinLTO: Can't get a temporary file");<br>
-  }<br>
-  return llvm::make_unique<raw_fd_<wbr>ostream>(TempFD, /* ShouldClose */ true);<br>
-}<br>
+NativeObjectCache lto::localCache(std::string CacheDirectoryPath,<br>
+                                  AddFileFn AddFile) {<br>
+  return [=](unsigned Task, StringRef Key) -> AddStreamFn {<br>
+    // First, see if we have a cache hit.<br>
+    SmallString<64> EntryPath;<br>
+    sys::path::append(EntryPath, CacheDirectoryPath, Key);<br>
+    if (sys::fs::exists(EntryPath)) {<br>
+      AddFile(Task, EntryPath);<br>
+      return AddStreamFn();<br>
+    }<br>
<br>
-// Try loading from a possible cache first, return true on cache hit.<br>
-bool CacheObjectOutput::<wbr>tryLoadFromCache(StringRef Key) {<br>
-  assert(!CacheDirectoryPath.<wbr>empty() &&<br>
-         "CacheObjectOutput was initialized without a cache path");<br>
-  if (Key.empty()) {<br>
-    // Client didn't compute a valid key. EntryPath has been set to<br>
-    // CacheDirectoryPath.<br>
-    EntryPath = CacheDirectoryPath;<br>
-    return false;<br>
-  }<br>
-  sys::path::append(EntryPath, CacheDirectoryPath, Key);<br>
-  return sys::fs::exists(EntryPath);<br>
+    // This native object stream is responsible for commiting the resulting<br>
+    // file to the cache and calling AddFile to add it to the link.<br>
+    struct CacheStream : NativeObjectStream {<br>
+      AddFileFn AddFile;<br>
+      std::string TempFilename;<br>
+      std::string EntryPath;<br>
+      unsigned Task;<br>
+<br>
+      CacheStream(std::unique_ptr<<wbr>raw_pwrite_stream> OS, AddFileFn AddFile,<br>
+                  std::string TempFilename, std::string EntryPath,<br>
+                  unsigned Task)<br>
+          : NativeObjectStream(std::move(<wbr>OS)), AddFile(AddFile),<br>
+            TempFilename(TempFilename), EntryPath(EntryPath), Task(Task) {}<br>
+<br>
+      ~CacheStream() {<br>
+        // Make sure the file is closed before committing it.<br>
+        OS.reset();<br>
+        commitEntry(TempFilename, EntryPath);<br>
+        AddFile(Task, EntryPath);<br>
+      }<br>
+    };<br>
+<br>
+    return [=](size_t Task) -> std::unique_ptr<<wbr>NativeObjectStream> {<br>
+      // Write to a temporary to avoid race condition<br>
+      int TempFD;<br>
+      SmallString<64> TempFilename;<br>
+      std::error_code EC =<br>
+          sys::fs::createTemporaryFile("<wbr>Thin", "tmp.o", TempFD, TempFilename);<br>
+      if (EC) {<br>
+        errs() << "Error: " << EC.message() << "\n";<br>
+        report_fatal_error("ThinLTO: Can't get a temporary file");<br>
+      }<br>
+<br>
+      // This CacheStream will move the temporary file into the cache when done.<br>
+      return make_unique<CacheStream>(<br>
+          llvm::make_unique<raw_fd_<wbr>ostream>(TempFD, /* ShouldClose */ true),<br>
+          AddFile, TempFilename.str(), EntryPath.str(), Task);<br>
+    };<br>
+  };<br>
 }<br>
<br>
Modified: llvm/trunk/lib/LTO/LTO.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTO.cpp?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/LTO/<wbr>LTO.cpp?rev=282299&r1=282298&<wbr>r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/LTO/LTO.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTO.cpp Fri Sep 23 16:33:43 2016<br>
@@ -409,19 +409,19 @@ unsigned LTO::getMaxTasks() const {<br>
   return RegularLTO.<wbr>ParallelCodeGenParallelismLeve<wbr>l + ThinLTO.ModuleMap.size();<br>
 }<br>
<br>
-Error LTO::run(AddOutputFn AddOutput) {<br>
+Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) {<br>
   // Save the status of having a regularLTO combined module, as<br>
   // this is needed for generating the ThinLTO Task ID, and<br>
   // the CombinedModule will be moved at the end of runRegularLTO.<br>
   bool HasRegularLTO = RegularLTO.CombinedModule != nullptr;<br>
   // Invoke regular LTO if there was a regular LTO module to start with.<br>
   if (HasRegularLTO)<br>
-    if (auto E = runRegularLTO(AddOutput))<br>
+    if (auto E = runRegularLTO(AddStream))<br>
       return E;<br>
-  return runThinLTO(AddOutput, HasRegularLTO);<br>
+  return runThinLTO(AddStream, Cache, HasRegularLTO);<br>
 }<br>
<br>
-Error LTO::runRegularLTO(AddOutputFn AddOutput) {<br>
+Error LTO::runRegularLTO(AddStreamFn AddStream) {<br>
   // Make sure commons have the right size/alignment: we kept the largest from<br>
   // all the prevailing when adding the inputs, and we apply it here.<br>
   const DataLayout &DL = RegularLTO.CombinedModule-><wbr>getDataLayout();<br>
@@ -478,7 +478,7 @@ Error LTO::runRegularLTO(AddOutputFn Add<br>
         !Conf.<wbr>PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))<br>
       return Error();<br>
   }<br>
-  return backend(Conf, AddOutput, RegularLTO.<wbr>ParallelCodeGenParallelismLeve<wbr>l,<br>
+  return backend(Conf, AddStream, RegularLTO.<wbr>ParallelCodeGenParallelismLeve<wbr>l,<br>
                  std::move(RegularLTO.<wbr>CombinedModule));<br>
 }<br>
<br>
@@ -507,7 +507,8 @@ public:<br>
<br>
 class InProcessThinBackend : public ThinBackendProc {<br>
   ThreadPool BackendThreadPool;<br>
-  AddOutputFn AddOutput;<br>
+  AddStreamFn AddStream;<br>
+  NativeObjectCache Cache;<br>
<br>
   Optional<Error> Err;<br>
   std::mutex ErrMu;<br>
@@ -517,42 +518,40 @@ public:<br>
       Config &Conf, ModuleSummaryIndex &CombinedIndex,<br>
       unsigned ThinLTOParallelismLevel,<br>
       const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,<br>
-      AddOutputFn AddOutput)<br>
+      AddStreamFn AddStream, NativeObjectCache Cache)<br>
       : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries),<br>
         BackendThreadPool(<wbr>ThinLTOParallelismLevel),<br>
-        AddOutput(std::move(AddOutput)<wbr>) {}<br>
+        AddStream(std::move(AddStream)<wbr>), Cache(std::move(Cache)) {}<br>
<br>
   Error runThinLTOBackendThread(<br>
-      AddOutputFn AddOutput, unsigned Task, MemoryBufferRef MBRef,<br>
-      ModuleSummaryIndex &CombinedIndex,<br>
+      AddStreamFn AddStream, NativeObjectCache Cache, unsigned Task,<br>
+      MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex,<br>
       const FunctionImporter::ImportMapTy &ImportList,<br>
       const FunctionImporter::ExportSetTy &ExportList,<br>
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,<br>
       const GVSummaryMapTy &DefinedGlobals,<br>
       MapVector<StringRef, MemoryBufferRef> &ModuleMap) {<br>
+    auto RunThinBackend = [&](AddStreamFn AddStream) {<br>
+      LTOLLVMContext BackendContext(Conf);<br>
+      ErrorOr<std::unique_ptr<<wbr>Module>> MOrErr =<br>
+          parseBitcodeFile(MBRef, BackendContext);<br>
+      assert(MOrErr && "Unable to load module in thread?");<br>
<br>
-    auto ModuleIdentifier = MBRef.getBufferIdentifier();<br>
-    auto Output = AddOutput(Task);<br>
-    if (Output->isCachingEnabled()) {<br>
-      SmallString<40> Key;<br>
-      // The module may be cached, this helps handling it.<br>
-      computeCacheKey(Key, CombinedIndex, ModuleIdentifier, ImportList,<br>
-                      ExportList, ResolvedODR, DefinedGlobals);<br>
-      if (Output->tryLoadFromCache(Key)<wbr>)<br>
-        return Error();<br>
-    }<br>
-<br>
-    LTOLLVMContext BackendContext(Conf);<br>
-    ErrorOr<std::unique_ptr<<wbr>Module>> MOrErr =<br>
-        parseBitcodeFile(MBRef, BackendContext);<br>
-    assert(MOrErr && "Unable to load module in thread?");<br>
-<br>
-    auto AddOutputWrapper = [&](unsigned TaskId) {<br>
-      assert(Task == TaskId && "Unexpexted TaskId mismatch");<br>
-      return std::move(Output);<br>
+      return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,<br>
+                         ImportList, DefinedGlobals, ModuleMap);<br>
     };<br>
-    return thinBackend(Conf, Task, AddOutputWrapper, **MOrErr, CombinedIndex,<br>
-                       ImportList, DefinedGlobals, ModuleMap);<br>
+<br>
+    if (!Cache)<br>
+      return RunThinBackend(AddStream);<br>
+<br>
+    SmallString<40> Key;<br>
+    // The module may be cached, this helps handling it.<br>
+    computeCacheKey(Key, CombinedIndex, MBRef.getBufferIdentifier(),<br>
+                    ImportList, ExportList, ResolvedODR, DefinedGlobals);<br>
+    if (AddStreamFn CacheAddStream = Cache(Task, Key))<br>
+      return RunThinBackend(CacheAddStream)<wbr>;<br>
+<br>
+    return Error();<br>
   }<br>
<br>
   Error start(<br>
@@ -574,8 +573,8 @@ public:<br>
             const GVSummaryMapTy &DefinedGlobals,<br>
             MapVector<StringRef, MemoryBufferRef> &ModuleMap) {<br>
           Error E = runThinLTOBackendThread(<br>
-              AddOutput, Task, MBRef, CombinedIndex, ImportList, ExportList,<br>
-              ResolvedODR, DefinedGlobals, ModuleMap);<br>
+              AddStream, Cache, Task, MBRef, CombinedIndex, ImportList,<br>
+              ExportList, ResolvedODR, DefinedGlobals, ModuleMap);<br>
           if (E) {<br>
             std::unique_lock<std::mutex> L(ErrMu);<br>
             if (Err)<br>
@@ -602,10 +601,10 @@ public:<br>
 ThinBackend lto::<wbr>createInProcessThinBackend(<wbr>unsigned ParallelismLevel) {<br>
   return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex,<br>
              const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,<br>
-             AddOutputFn AddOutput) {<br>
+             AddStreamFn AddStream, NativeObjectCache Cache) {<br>
     return llvm::make_unique<<wbr>InProcessThinBackend>(<br>
         Conf, CombinedIndex, ParallelismLevel, ModuleToDefinedGVSummaries,<br>
-        AddOutput);<br>
+        AddStream, Cache);<br>
   };<br>
 }<br>
<br>
@@ -693,14 +692,15 @@ ThinBackend lto::createWriteIndexesThinB<br>
                                                std::string LinkedObjectsFile) {<br>
   return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex,<br>
              const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,<br>
-             AddOutputFn AddOutput) {<br>
+             AddStreamFn AddStream, NativeObjectCache Cache) {<br>
     return llvm::make_unique<<wbr>WriteIndexesThinBackend>(<br>
         Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix, NewPrefix,<br>
         ShouldEmitImportsFiles, LinkedObjectsFile);<br>
   };<br>
 }<br>
<br>
-Error LTO::runThinLTO(AddOutputFn AddOutput, bool HasRegularLTO) {<br>
+Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,<br>
+                      bool HasRegularLTO) {<br>
   if (ThinLTO.ModuleMap.empty())<br>
     return Error();<br>
<br>
@@ -759,8 +759,9 @@ Error LTO::runThinLTO(AddOutputFn AddOut<br>
   <wbr>thinLTOResolveWeakForLinkerInI<wbr>ndex(ThinLTO.CombinedIndex, isPrevailing,<br>
                                      recordNewLinkage);<br>
<br>
-  std::unique_ptr<<wbr>ThinBackendProc> BackendProc = ThinLTO.Backend(<br>
-      Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, AddOutput);<br>
+  std::unique_ptr<<wbr>ThinBackendProc> BackendProc =<br>
+      ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,<br>
+                      AddStream, Cache);<br>
<br>
   // Partition numbers for ThinLTO jobs start at 1 (see comments for<br>
   // GlobalResolution in LTO.h). Task numbers, however, start at<br>
<br>
Modified: llvm/trunk/lib/LTO/LTOBackend.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOBackend.cpp?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/LTO/<wbr>LTOBackend.cpp?rev=282299&r1=<wbr>282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/LTO/LTOBackend.<wbr>cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTOBackend.<wbr>cpp Fri Sep 23 16:33:43 2016<br>
@@ -199,34 +199,20 @@ bool opt(Config &Conf, TargetMachine *TM<br>
   return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);<br>
 }<br>
<br>
-/// Monolithic LTO does not support caching (yet), this is a convenient wrapper<br>
-/// around AddOutput to workaround this.<br>
-static AddOutputFn getUncachedOutputWrapper(<wbr>AddOutputFn &AddOutput,<br>
-                                            unsigned Task) {<br>
-  return [Task, &AddOutput](unsigned TaskId) {<br>
-    auto Output = AddOutput(Task);<br>
-    if (Output->isCachingEnabled() && Output->tryLoadFromCache(""))<br>
-      report_fatal_error("Cache hit without a valid key?");<br>
-    assert(Task == TaskId && "Unexpexted TaskId mismatch");<br>
-    return Output;<br>
-  };<br>
-}<br>
-<br>
-void codegen(Config &Conf, TargetMachine *TM, AddOutputFn AddOutput,<br>
+void codegen(Config &Conf, TargetMachine *TM, AddStreamFn AddStream,<br>
              unsigned Task, Module &Mod) {<br>
   if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(<wbr>Task, Mod))<br>
     return;<br>
<br>
-  auto Output = AddOutput(Task);<br>
-  std::unique_ptr<raw_pwrite_<wbr>stream> OS = Output->getStream();<br>
+  auto Stream = AddStream(Task);<br>
   legacy::PassManager CodeGenPasses;<br>
-  if (TM->addPassesToEmitFile(<wbr>CodeGenPasses, *OS,<br>
+  if (TM->addPassesToEmitFile(<wbr>CodeGenPasses, *Stream->OS,<br>
                               TargetMachine::CGFT_<wbr>ObjectFile))<br>
     report_fatal_error("Failed to setup codegen");<br>
   CodeGenPasses.run(Mod);<br>
 }<br>
<br>
-void splitCodeGen(Config &C, TargetMachine *TM, AddOutputFn AddOutput,<br>
+void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream,<br>
                   unsigned ParallelCodeGenParallelismLeve<wbr>l,<br>
                   std::unique_ptr<Module> Mod) {<br>
   ThreadPool CodegenThreadPool(<wbr>ParallelCodeGenParallelismLeve<wbr>l);<br>
@@ -260,9 +246,7 @@ void splitCodeGen(Config &C, TargetMachi<br>
               std::unique_ptr<<wbr>TargetMachine> TM =<br>
                   createTargetMachine(C, MPartInCtx->getTargetTriple(), T);<br>
<br>
-              codegen(C, TM.get(),<br>
-                      getUncachedOutputWrapper(<wbr>AddOutput, ThreadId), ThreadId,<br>
-                      *MPartInCtx);<br>
+              codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx);<br>
             },<br>
             // Pass BC using std::move to ensure that it get moved rather than<br>
             // copied into the thread's context.<br>
@@ -299,7 +283,7 @@ static void handleAsmUndefinedRefs(Modul<br>
   updateCompilerUsed(Mod, TM, AsmUndefinedRefs);<br>
 }<br>
<br>
-Error lto::backend(Config &C, AddOutputFn AddOutput,<br>
+Error lto::backend(Config &C, AddStreamFn AddStream,<br>
                    unsigned ParallelCodeGenParallelismLeve<wbr>l,<br>
                    std::unique_ptr<Module> Mod) {<br>
   Expected<const Target *> TOrErr = initAndLookupTarget(C, *Mod);<br>
@@ -316,15 +300,15 @@ Error lto::backend(Config &C, AddOutputF<br>
       return Error();<br>
<br>
   if (<wbr>ParallelCodeGenParallelismLeve<wbr>l == 1) {<br>
-    codegen(C, TM.get(), getUncachedOutputWrapper(<wbr>AddOutput, 0), 0, *Mod);<br>
+    codegen(C, TM.get(), AddStream, 0, *Mod);<br>
   } else {<br>
-    splitCodeGen(C, TM.get(), AddOutput, ParallelCodeGenParallelismLeve<wbr>l,<br>
+    splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLeve<wbr>l,<br>
                  std::move(Mod));<br>
   }<br>
   return Error();<br>
 }<br>
<br>
-Error lto::thinBackend(Config &Conf, unsigned Task, AddOutputFn AddOutput,<br>
+Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,<br>
                        Module &Mod, ModuleSummaryIndex &CombinedIndex,<br>
                        const FunctionImporter::ImportMapTy &ImportList,<br>
                        const GVSummaryMapTy &DefinedGlobals,<br>
@@ -339,7 +323,7 @@ Error lto::thinBackend(Config &Conf, uns<br>
   handleAsmUndefinedRefs(Mod, *TM);<br>
<br>
   if (Conf.CodeGenOnly) {<br>
-    codegen(Conf, TM.get(), AddOutput, Task, Mod);<br>
+    codegen(Conf, TM.get(), AddStream, Task, Mod);<br>
     return Error();<br>
   }<br>
<br>
@@ -379,6 +363,6 @@ Error lto::thinBackend(Config &Conf, uns<br>
   if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLto=*/true))<br>
     return Error();<br>
<br>
-  codegen(Conf, TM.get(), AddOutput, Task, Mod);<br>
+  codegen(Conf, TM.get(), AddStream, Task, Mod);<br>
   return Error();<br>
 }<br>
<br>
Modified: llvm/trunk/tools/gold/gold-<wbr>plugin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/tools/gold/<wbr>gold-plugin.cpp?rev=282299&r1=<wbr>282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/tools/gold/gold-<wbr>plugin.cpp (original)<br>
+++ llvm/trunk/tools/gold/gold-<wbr>plugin.cpp Fri Sep 23 16:33:43 2016<br>
@@ -675,24 +675,6 @@ static void getThinLTOOldAndNewPrefix(st<br>
   NewPrefix = Split.second.str();<br>
 }<br>
<br>
-namespace {<br>
-// Define the LTOOutput handling<br>
-class LTOOutput : public lto::NativeObjectOutput {<br>
-  StringRef Path;<br>
-<br>
-public:<br>
-  LTOOutput(StringRef Path) : Path(Path) {}<br>
-  // Open the filename \p Path and allocate a stream.<br>
-  std::unique_ptr<raw_pwrite_<wbr>stream> getStream() override {<br>
-    int FD;<br>
-    std::error_code EC = sys::fs::openFileForWrite(<wbr>Path, FD, sys::fs::F_None);<br>
-    if (EC)<br>
-      message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str());<br>
-    return llvm::make_unique<llvm::raw_<wbr>fd_ostream>(FD, true);<br>
-  }<br>
-};<br>
-}<br>
-<br>
 static std::unique_ptr<LTO> createLTO() {<br>
   Config Conf;<br>
   ThinBackend Backend;<br>
@@ -831,21 +813,27 @@ static ld_plugin_status allSymbolsReadHo<br>
   std::vector<uintptr_t> IsTemporary(MaxTasks);<br>
   std::vector<SmallString<128>> Filenames(MaxTasks);<br>
<br>
-  auto AddOutput =<br>
-      [&](size_t Task) -> std::unique_ptr<lto::<wbr>NativeObjectOutput> {<br>
-    auto &OutputName = Filenames[Task];<br>
-    getOutputFileName(Filename, /*TempOutFile=*/!SaveTemps, OutputName,<br>
+  auto AddStream =<br>
+      [&](size_t Task) -> std::unique_ptr<lto::<wbr>NativeObjectStream> {<br>
+    IsTemporary[Task] = !SaveTemps;<br>
+    getOutputFileName(Filename, /*TempOutFile=*/!SaveTemps, Filenames[Task],<br>
                       MaxTasks > 1 ? Task : -1);<br>
-    IsTemporary[Task] = !SaveTemps && options::cache_dir.empty();<br>
-    if (options::cache_dir.empty())<br>
-      return llvm::make_unique<LTOOutput>(<wbr>OutputName);<br>
-<br>
-    return llvm::make_unique<<wbr>CacheObjectOutput>(<br>
-        options::cache_dir,<br>
-        [&OutputName](std::string EntryPath) { OutputName = EntryPath; });<br>
+    int FD;<br>
+    std::error_code EC =<br>
+        sys::fs::openFileForWrite(<wbr>Filenames[Task], FD, sys::fs::F_None);<br>
+    if (EC)<br>
+      message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str());<br>
+    return llvm::make_unique<lto::<wbr>NativeObjectStream>(<br>
+        llvm::make_unique<llvm::raw_<wbr>fd_ostream>(FD, true));<br>
   };<br>
<br>
-  check(Lto->run(AddOutput));<br>
+  auto AddFile = [&](size_t Task, StringRef Path) { Filenames[Task] = Path; };<br>
+<br>
+  NativeObjectCache Cache;<br>
+  if (!options::cache_dir.empty())<br>
+    Cache = localCache(options::cache_dir, AddFile);<br>
+<br>
+  check(Lto->run(AddStream, Cache));<br>
<br>
   if (options::TheOutputType == options::OT_DISABLE ||<br>
       options::TheOutputType == options::OT_BC_ONLY)<br>
<br>
Modified: llvm/trunk/tools/llvm-lto2/<wbr>llvm-lto2.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto2/llvm-lto2.cpp?rev=282299&r1=282298&r2=282299&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/tools/llvm-<wbr>lto2/llvm-lto2.cpp?rev=282299&<wbr>r1=282298&r2=282299&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/tools/llvm-lto2/<wbr>llvm-lto2.cpp (original)<br>
+++ llvm/trunk/tools/llvm-lto2/<wbr>llvm-lto2.cpp Fri Sep 23 16:33:43 2016<br>
@@ -95,22 +95,6 @@ template <typename T> static T check(Err<br>
   return T();<br>
 }<br>
<br>
-namespace {<br>
-// Define the LTOOutput handling<br>
-class LTOOutput : public lto::NativeObjectOutput {<br>
-  std::string Path;<br>
-<br>
-public:<br>
-  LTOOutput(std::string Path) : Path(std::move(Path)) {}<br>
-  std::unique_ptr<raw_pwrite_<wbr>stream> getStream() override {<br>
-    std::error_code EC;<br>
-    auto S = llvm::make_unique<raw_fd_<wbr>ostream>(Path, EC, sys::fs::F_None);<br>
-    check(EC, Path);<br>
-    return std::move(S);<br>
-  }<br>
-};<br>
-}<br>
-<br>
 int main(int argc, char **argv) {<br>
   InitializeAllTargets();<br>
   InitializeAllTargetMCs();<br>
@@ -203,23 +187,28 @@ int main(int argc, char **argv) {<br>
   if (HasErrors)<br>
     return 1;<br>
<br>
-  auto AddOutput =<br>
-      [&](size_t Task) -> std::unique_ptr<lto::<wbr>NativeObjectOutput> {<br>
+  auto AddStream =<br>
+      [&](size_t Task) -> std::unique_ptr<lto::<wbr>NativeObjectStream> {<br>
     std::string Path = OutputFilename + "." + utostr(Task);<br>
-    if (CacheDir.empty())<br>
-      return llvm::make_unique<LTOOutput>(<wbr>std::move(Path));<br>
<br>
-    return llvm::make_unique<<wbr>CacheObjectOutput>(<br>
-        CacheDir, [Path](std::string EntryPath) {<br>
-          // Load the entry from the cache now.<br>
-          auto ReloadedBufferOrErr = MemoryBuffer::getFile(<wbr>EntryPath);<br>
-          if (auto EC = ReloadedBufferOrErr.getError()<wbr>)<br>
-            report_fatal_error(Twine("Can'<wbr>t reload cached file '") + EntryPath +<br>
-                               "': " + EC.message() + "\n");<br>
+    std::error_code EC;<br>
+    auto S = llvm::make_unique<raw_fd_<wbr>ostream>(Path, EC, sys::fs::F_None);<br>
+    check(EC, Path);<br>
+    return llvm::make_unique<lto::<wbr>NativeObjectStream>(std::move(<wbr>S));<br>
+  };<br>
+<br>
+  auto AddFile = [&](size_t Task, StringRef Path) {<br>
+    auto ReloadedBufferOrErr = MemoryBuffer::getFile(Path);<br>
+    if (auto EC = ReloadedBufferOrErr.getError()<wbr>)<br>
+      report_fatal_error(Twine("Can'<wbr>t reload cached file '") + Path + "': " +<br>
+                         EC.message() + "\n");<br>
<br>
-          *LTOOutput(Path).getStream() << (*ReloadedBufferOrErr)-><wbr>getBuffer();<br>
-        });<br>
+    *AddStream(Task)->OS << (*ReloadedBufferOrErr)-><wbr>getBuffer();<br>
   };<br>
<br>
-  check(Lto.run(AddOutput), "LTO::run failed");<br>
+  NativeObjectCache Cache;<br>
+  if (!CacheDir.empty())<br>
+    Cache = localCache(CacheDir, AddFile);<br>
+<br>
+  check(Lto.run(AddStream, Cache), "LTO::run failed");<br>
 }<br>
<br>
<br>
______________________________<wbr>_________________<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/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">-- <div>Peter</div></div></div>
</div>