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