Skip to content

Commit e678c51

Browse files
noajshupetrhosek
authored andcommitted
[Support][ThinLTO] Move ThinLTO caching to LLVM Support library
We would like to move ThinLTO’s battle-tested file caching mechanism to the LLVM Support library so that we can use it elsewhere in LLVM. Patch By: noajshu Differential Revision: https://reviews.llvm.org/D111371
1 parent facff46 commit e678c51

File tree

19 files changed

+145
-134
lines changed

19 files changed

+145
-134
lines changed

clang/docs/tools/clang-formatted-files.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4745,7 +4745,6 @@ llvm/include/llvm/IR/ReplaceConstant.h
47454745
llvm/include/llvm/IR/StructuralHash.h
47464746
llvm/include/llvm/IR/TrackingMDRef.h
47474747
llvm/include/llvm/IR/UseListOrder.h
4748-
llvm/include/llvm/LTO/Caching.h
47494748
llvm/include/llvm/LTO/SummaryBasedOptimizations.h
47504749
llvm/include/llvm/MC/MCAsmInfoCOFF.h
47514750
llvm/include/llvm/MC/MCAsmInfoDarwin.h
@@ -4852,6 +4851,7 @@ llvm/include/llvm/Support/BinaryStreamRef.h
48524851
llvm/include/llvm/Support/BinaryStreamWriter.h
48534852
llvm/include/llvm/Support/BuryPointer.h
48544853
llvm/include/llvm/Support/CachePruning.h
4854+
llvm/include/llvm/Support/Caching.h
48554855
llvm/include/llvm/Support/CFGDiff.h
48564856
llvm/include/llvm/Support/CFGUpdate.h
48574857
llvm/include/llvm/Support/CodeGenCoverage.h

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,7 +1561,7 @@ static void runThinLTOBackend(
15611561
return;
15621562

15631563
auto AddStream = [&](size_t Task) {
1564-
return std::make_unique<lto::NativeObjectStream>(std::move(OS));
1564+
return std::make_unique<NativeObjectStream>(std::move(OS));
15651565
};
15661566
lto::Config Conf;
15671567
if (CGOpts.SaveTempsFilePrefix != "") {

lld/COFF/LTO.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
#include "llvm/ADT/Twine.h"
2121
#include "llvm/Bitcode/BitcodeWriter.h"
2222
#include "llvm/IR/DiagnosticPrinter.h"
23-
#include "llvm/LTO/Caching.h"
2423
#include "llvm/LTO/Config.h"
2524
#include "llvm/LTO/LTO.h"
2625
#include "llvm/Object/SymbolicFile.h"
26+
#include "llvm/Support/Caching.h"
2727
#include "llvm/Support/CodeGen.h"
2828
#include "llvm/Support/Error.h"
2929
#include "llvm/Support/FileSystem.h"
@@ -164,16 +164,17 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
164164
// The /lldltocache option specifies the path to a directory in which to cache
165165
// native object files for ThinLTO incremental builds. If a path was
166166
// specified, configure LTO to use it as the cache directory.
167-
lto::NativeObjectCache cache;
167+
NativeObjectCache cache;
168168
if (!config->ltoCache.empty())
169-
cache = check(lto::localCache(
170-
config->ltoCache, [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
171-
files[task] = std::move(mb);
172-
}));
169+
cache =
170+
check(localCache("ThinLTO", "Thin", config->ltoCache,
171+
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
172+
files[task] = std::move(mb);
173+
}));
173174

174175
checkError(ltoObj->run(
175176
[&](size_t task) {
176-
return std::make_unique<lto::NativeObjectStream>(
177+
return std::make_unique<NativeObjectStream>(
177178
std::make_unique<raw_svector_ostream>(buf[task]));
178179
},
179180
cache));

lld/ELF/LTO.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
#include "llvm/Bitcode/BitcodeReader.h"
2424
#include "llvm/Bitcode/BitcodeWriter.h"
2525
#include "llvm/IR/DiagnosticPrinter.h"
26-
#include "llvm/LTO/Caching.h"
2726
#include "llvm/LTO/Config.h"
2827
#include "llvm/LTO/LTO.h"
2928
#include "llvm/Object/SymbolicFile.h"
29+
#include "llvm/Support/Caching.h"
3030
#include "llvm/Support/CodeGen.h"
3131
#include "llvm/Support/Error.h"
3232
#include "llvm/Support/FileSystem.h"
@@ -304,18 +304,18 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
304304
// The --thinlto-cache-dir option specifies the path to a directory in which
305305
// to cache native object files for ThinLTO incremental builds. If a path was
306306
// specified, configure LTO to use it as the cache directory.
307-
lto::NativeObjectCache cache;
307+
NativeObjectCache cache;
308308
if (!config->thinLTOCacheDir.empty())
309-
cache = check(
310-
lto::localCache(config->thinLTOCacheDir,
311-
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
312-
files[task] = std::move(mb);
313-
}));
309+
cache =
310+
check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
311+
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
312+
files[task] = std::move(mb);
313+
}));
314314

315315
if (!bitcodeFiles.empty())
316316
checkError(ltoObj->run(
317317
[&](size_t task) {
318-
return std::make_unique<lto::NativeObjectStream>(
318+
return std::make_unique<NativeObjectStream>(
319319
std::make_unique<raw_svector_ostream>(buf[task]));
320320
},
321321
cache));

lld/MachO/LTO.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#include "lld/Common/ErrorHandler.h"
1818
#include "lld/Common/Strings.h"
1919
#include "lld/Common/TargetOptionsCommandFlags.h"
20-
#include "llvm/LTO/Caching.h"
2120
#include "llvm/LTO/Config.h"
2221
#include "llvm/LTO/LTO.h"
22+
#include "llvm/Support/Caching.h"
2323
#include "llvm/Support/FileSystem.h"
2424
#include "llvm/Support/Path.h"
2525
#include "llvm/Support/raw_ostream.h"
@@ -105,17 +105,17 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
105105
// The -cache_path_lto option specifies the path to a directory in which
106106
// to cache native object files for ThinLTO incremental builds. If a path was
107107
// specified, configure LTO to use it as the cache directory.
108-
lto::NativeObjectCache cache;
108+
NativeObjectCache cache;
109109
if (!config->thinLTOCacheDir.empty())
110-
cache = check(
111-
lto::localCache(config->thinLTOCacheDir,
112-
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
113-
files[task] = std::move(mb);
114-
}));
110+
cache =
111+
check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
112+
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
113+
files[task] = std::move(mb);
114+
}));
115115

116116
checkError(ltoObj->run(
117117
[&](size_t task) {
118-
return std::make_unique<lto::NativeObjectStream>(
118+
return std::make_unique<NativeObjectStream>(
119119
std::make_unique<raw_svector_ostream>(buf[task]));
120120
},
121121
cache));

lld/wasm/LTO.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
#include "llvm/ADT/StringRef.h"
2020
#include "llvm/ADT/Twine.h"
2121
#include "llvm/IR/DiagnosticPrinter.h"
22-
#include "llvm/LTO/Caching.h"
2322
#include "llvm/LTO/Config.h"
2423
#include "llvm/LTO/LTO.h"
2524
#include "llvm/Object/SymbolicFile.h"
25+
#include "llvm/Support/Caching.h"
2626
#include "llvm/Support/CodeGen.h"
2727
#include "llvm/Support/Error.h"
2828
#include "llvm/Support/FileSystem.h"
@@ -127,17 +127,17 @@ std::vector<StringRef> BitcodeCompiler::compile() {
127127
// The --thinlto-cache-dir option specifies the path to a directory in which
128128
// to cache native object files for ThinLTO incremental builds. If a path was
129129
// specified, configure LTO to use it as the cache directory.
130-
lto::NativeObjectCache cache;
130+
NativeObjectCache cache;
131131
if (!config->thinLTOCacheDir.empty())
132-
cache = check(
133-
lto::localCache(config->thinLTOCacheDir,
134-
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
135-
files[task] = std::move(mb);
136-
}));
132+
cache =
133+
check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
134+
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
135+
files[task] = std::move(mb);
136+
}));
137137

138138
checkError(ltoObj->run(
139139
[&](size_t task) {
140-
return std::make_unique<lto::NativeObjectStream>(
140+
return std::make_unique<NativeObjectStream>(
141141
std::make_unique<raw_svector_ostream>(buf[task]));
142142
},
143143
cache));

llvm/include/llvm/LTO/Caching.h

Lines changed: 0 additions & 38 deletions
This file was deleted.

llvm/include/llvm/LTO/LTO.h

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/IR/ModuleSummaryIndex.h"
2222
#include "llvm/LTO/Config.h"
2323
#include "llvm/Object/IRSymtab.h"
24+
#include "llvm/Support/Caching.h"
2425
#include "llvm/Support/Error.h"
2526
#include "llvm/Support/thread.h"
2627
#include "llvm/Transforms/IPO/FunctionAttrs.h"
@@ -187,40 +188,6 @@ class InputFile {
187188
}
188189
};
189190

190-
/// This class wraps an output stream for a native object. Most clients should
191-
/// just be able to return an instance of this base class from the stream
192-
/// callback, but if a client needs to perform some action after the stream is
193-
/// written to, that can be done by deriving from this class and overriding the
194-
/// destructor.
195-
class NativeObjectStream {
196-
public:
197-
NativeObjectStream(std::unique_ptr<raw_pwrite_stream> OS) : OS(std::move(OS)) {}
198-
std::unique_ptr<raw_pwrite_stream> OS;
199-
virtual ~NativeObjectStream() = default;
200-
};
201-
202-
/// This type defines the callback to add a native object that is generated on
203-
/// the fly.
204-
///
205-
/// Stream callbacks must be thread safe.
206-
using AddStreamFn =
207-
std::function<std::unique_ptr<NativeObjectStream>(unsigned Task)>;
208-
209-
/// This is the type of a native object cache. To request an item from the
210-
/// cache, pass a unique string as the Key. For hits, the cached file will be
211-
/// added to the link and this function will return AddStreamFn(). For misses,
212-
/// the cache will return a stream callback which must be called at most once to
213-
/// produce content for the stream. The native object stream produced by the
214-
/// stream callback will add the file to the link after the stream is written
215-
/// to.
216-
///
217-
/// Clients generally look like this:
218-
///
219-
/// if (AddStreamFn AddStream = Cache(Task, Key))
220-
/// ProduceContent(AddStream);
221-
using NativeObjectCache =
222-
std::function<AddStreamFn(unsigned Task, StringRef Key)>;
223-
224191
/// A ThinBackend defines what happens after the thin-link phase during ThinLTO.
225192
/// The details of this type definition aren't important; clients can only
226193
/// create a ThinBackend using one of the create*ThinBackend() functions below.

llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ struct LTOCodeGenerator {
176176
/// created using the \p AddStream callback. Returns true on success.
177177
///
178178
/// Calls \a verifyMergedModuleOnce().
179-
bool compileOptimized(lto::AddStreamFn AddStream, unsigned ParallelismLevel);
179+
bool compileOptimized(AddStreamFn AddStream, unsigned ParallelismLevel);
180180

181181
/// Enable the Freestanding mode: indicate that the optimizer should not
182182
/// assume builtins are present on the target.

llvm/include/llvm/Support/Caching.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===- Caching.h - LLVM File Cache Handling Configuration -------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the localCache function, which allows clients to add a
10+
// filesystem cache. This is used by ThinLTO.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_SUPPORT_CACHING_H
15+
#define LLVM_SUPPORT_CACHING_H
16+
17+
#include "llvm/Support/Error.h"
18+
#include "llvm/Support/MemoryBuffer.h"
19+
#include "llvm/Support/thread.h"
20+
21+
namespace llvm {
22+
23+
/// This class wraps an output stream for a native object. Most clients should
24+
/// just be able to return an instance of this base class from the stream
25+
/// callback, but if a client needs to perform some action after the stream is
26+
/// written to, that can be done by deriving from this class and overriding the
27+
/// destructor.
28+
class NativeObjectStream {
29+
public:
30+
NativeObjectStream(std::unique_ptr<raw_pwrite_stream> OS)
31+
: OS(std::move(OS)) {}
32+
std::unique_ptr<raw_pwrite_stream> OS;
33+
virtual ~NativeObjectStream() = default;
34+
};
35+
36+
/// This type defines the callback to add a native object that is generated on
37+
/// the fly.
38+
///
39+
/// Stream callbacks must be thread safe.
40+
using AddStreamFn =
41+
std::function<std::unique_ptr<NativeObjectStream>(unsigned Task)>;
42+
43+
/// This is the type of a native object cache. To request an item from the
44+
/// cache, pass a unique string as the Key. For hits, the cached file will be
45+
/// added to the link and this function will return AddStreamFn(). For misses,
46+
/// the cache will return a stream callback which must be called at most once to
47+
/// produce content for the stream. The native object stream produced by the
48+
/// stream callback will add the file to the link after the stream is written
49+
/// to.
50+
///
51+
/// Clients generally look like this:
52+
///
53+
/// if (AddStreamFn AddStream = Cache(Task, Key))
54+
/// ProduceContent(AddStream);
55+
using NativeObjectCache =
56+
std::function<AddStreamFn(unsigned Task, StringRef Key)>;
57+
58+
/// This type defines the callback to add a pre-existing native object file
59+
/// (e.g. in a cache).
60+
///
61+
/// Buffer callbacks must be thread safe.
62+
using AddBufferFn =
63+
std::function<void(unsigned Task, std::unique_ptr<MemoryBuffer> MB)>;
64+
65+
/// Create a local file system cache which uses the given cache name, temporary
66+
/// file prefix, cache directory and file callback. This function also creates
67+
/// the cache directory if it does not already exist. The cache name appears in
68+
/// error messages for errors during caching. The temporary file prefix is used
69+
/// in the temporary file naming scheme used when writing files atomically.
70+
Expected<NativeObjectCache> localCache(Twine CacheNameRef,
71+
Twine TempFilePrefixRef,
72+
Twine CacheDirectoryPathRef,
73+
AddBufferFn AddBuffer);
74+
} // namespace llvm
75+
76+
#endif

0 commit comments

Comments
 (0)