Skip to content

Commit 7dc1328

Browse files
committed
Basic: Introduce 'split caching' for requests
1 parent 7ba2b76 commit 7dc1328

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

include/swift/AST/Evaluator.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,31 @@ class Evaluator {
271271
recorder.clearRequest<Request>(request);
272272
}
273273

274+
/// Store a value in the request evaluator's cache for a split-cached request.
275+
/// The request chooses to do this itself for storing some suitable definition of
276+
/// "non-empty" value.
277+
template<typename Request,
278+
typename std::enable_if<Request::hasSplitCache>::type* = nullptr>
279+
void cacheNonEmptyOutput(const Request &request,
280+
typename Request::OutputType &&output) {
281+
bool inserted = cache.insert<Request>(request, std::move(output));
282+
assert(inserted && "Request result was already cached");
283+
(void) inserted;
284+
}
285+
286+
/// Consults the request evaluator's cache for a split-cached request.
287+
/// The request should perform this check after consulting it's own optimized
288+
/// representation for storing an empty value.
289+
template<typename Request,
290+
typename std::enable_if<Request::hasSplitCache>::type* = nullptr>
291+
std::optional<typename Request::OutputType>
292+
getCachedNonEmptyOutput(const Request &request) {
293+
auto found = cache.find_as(request);
294+
if (found == cache.end<Request>())
295+
return std::nullopt;
296+
return found->second;
297+
}
298+
274299
/// Clear the cache stored within this evaluator.
275300
///
276301
/// Note that this does not clear the caches of requests that use external

include/swift/AST/SimpleRequest.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,23 @@ class Evaluator;
3636
enum class RequestFlags {
3737
/// The result for a particular request should never be cached.
3838
Uncached = 1 << 0,
39+
3940
/// The result for a particular request should be cached within the
4041
/// evaluator itself.
4142
Cached = 1 << 1,
43+
4244
/// The result of a particular request will be cached via some separate
4345
/// mechanism, such as a mutable data structure.
4446
SeparatelyCached = 1 << 2,
47+
48+
/// The result is separately cached, but the request can also make use
49+
/// of the request evaluator's cache for out-of-line storage. This
50+
/// is used to optimize caching of requests where the usual case is
51+
/// that the value is empty. In this case, the separate mechanism
52+
/// can represent the empty state more efficiently than adding a new
53+
/// entry to the request evaluator's cache.
54+
SplitCached = 1 << 3,
55+
4556
/// This request introduces the source component of a source-sink
4657
/// incremental dependency pair and defines a new dependency scope.
4758
///
@@ -50,7 +61,7 @@ enum class RequestFlags {
5061
///
5162
/// For further discussion on incremental dependencies
5263
/// see DependencyAnalysis.md.
53-
DependencySource = 1 << 3,
64+
DependencySource = 1 << 4,
5465
/// This request introduces the sink component of a source-sink
5566
/// incremental dependency pair and is a consumer of the current
5667
/// dependency scope.
@@ -60,7 +71,7 @@ enum class RequestFlags {
6071
///
6172
/// For further discussion on incremental dependencies
6273
/// see DependencyAnalysis.md.
63-
DependencySink = 1 << 4,
74+
DependencySink = 1 << 5,
6475
};
6576

6677
static constexpr inline RequestFlags operator|(RequestFlags lhs, RequestFlags rhs) {
@@ -167,6 +178,10 @@ constexpr bool hasExternalCache(RequestFlags kind) {
167178
return cacheContains(kind, RequestFlags::SeparatelyCached);
168179
}
169180

181+
constexpr bool hasSplitCache(RequestFlags kind) {
182+
return cacheContains(kind, RequestFlags::SplitCached);
183+
}
184+
170185
constexpr bool isDependencySource(RequestFlags kind) {
171186
return cacheContains(kind, RequestFlags::DependencySource);
172187
}
@@ -279,6 +294,7 @@ class SimpleRequest<Derived, Output(Inputs...), Caching> {
279294
public:
280295
constexpr static bool isEverCached = detail::isEverCached(Caching);
281296
constexpr static bool hasExternalCache = detail::hasExternalCache(Caching);
297+
constexpr static bool hasSplitCache = detail::hasSplitCache(Caching);
282298

283299
public:
284300
constexpr static bool isDependencySource = detail::isDependencySource(Caching);

0 commit comments

Comments
 (0)