<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>