Skip to content

Request Evaluator: save malloc traffic by canonicalizing AnyRequests #20999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions include/swift/AST/Evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class Evaluator {
llvm::Expected<typename Request::OutputType>
operator()(const Request &request) {
// Check for a cycle.
if (checkDependency(AnyRequest(request))) {
if (checkDependency(getCanonicalRequest(request))) {
return llvm::Error(
llvm::make_unique<CyclicalRequestError<Request>>(request, *this));
}
Expand Down Expand Up @@ -293,6 +293,17 @@ class Evaluator {
void clearCache() { cache.clear(); }

private:
template <typename Request>
const AnyRequest &getCanonicalRequest(const Request &request) {
// FIXME: DenseMap ought to let us do this with one hash lookup.
auto iter = dependencies.find_as(request);
if (iter != dependencies.end())
return iter->first;
auto insertResult = dependencies.insert({AnyRequest(request), {}});
assert(insertResult.second && "just checked if the key was already there");
return insertResult.first->first;
}

/// Diagnose a cycle detected in the evaluation of the given
/// request.
void diagnoseCycle(const AnyRequest &request);
Expand Down Expand Up @@ -335,7 +346,7 @@ class Evaluator {
getResultUncached(const Request &request) {
// Clear out the dependencies on this request; we're going to recompute
// them now anyway.
dependencies[AnyRequest(request)].clear();
dependencies.find_as(request)->second.clear();

PrettyStackTraceRequest<Request> prettyStackTrace(request);

Expand Down Expand Up @@ -377,7 +388,6 @@ class Evaluator {
typename std::enable_if<!Request::hasExternalCache>::type * = nullptr>
llvm::Expected<typename Request::OutputType>
getResultCached(const Request &request) {
AnyRequest anyRequest{request};
// If we already have an entry for this request in the cache, return it.
auto known = cache.find_as(request);
if (known != cache.end()) {
Expand All @@ -390,7 +400,7 @@ class Evaluator {
return result;

// Cache the result.
cache.insert({AnyRequest(request), *result});
cache.insert({getCanonicalRequest(request), *result});
return result;
}

Expand Down