Skip to content

Commit 3c460cc

Browse files
committed
[clang][cas] Avoid calling freezeConfig for every cache key
With the libclang caching APIs, it is possible to configure CASOptions separately from the CAS used for scanning. In this setup, the CAS is not pre-cached in the CASOptions and ends up being re-opened for every cache key, which is expensive with some plugin CAS. Instead, get the hash identifier from the already open CAS and only freezeConfig when canonicalizing for an actual compilation. rdar://141555438
1 parent a18e9de commit 3c460cc

File tree

1 file changed

+43
-36
lines changed

1 file changed

+43
-36
lines changed

clang/lib/Frontend/CompileJobCacheKey.cpp

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ canonicalizeForCaching(llvm::cas::ObjectStore &CAS, DiagnosticsEngine &Diags,
207207
//
208208
// TODO: Extract CASOptions.Path first if we need it later since it'll
209209
// disappear here.
210-
Invocation.getCASOpts().freezeConfig(Diags);
210+
Invocation.getCASOpts() = {};
211+
// Set the CASPath to the hash schema to match CASOptions::freezeConfig.
212+
Invocation.getCASOpts().CASPath =
213+
CAS.getContext().getHashSchemaIdentifier().str();
211214

212215
// TODO: Canonicalize DiagnosticOptions here to be "serialized" only. Pass in
213216
// a hook to mirror diagnostics to stderr (when writing there), and handle
@@ -223,47 +226,51 @@ clang::canonicalizeAndCreateCacheKeys(ObjectStore &CAS,
223226
DiagnosticsEngine &Diags,
224227
CompilerInvocation &CI,
225228
CompileJobCachingOptions &Opts) {
226-
if (!CI.getFrontendOpts().CASInputFileCacheKey.empty()) {
227-
Opts = canonicalizeForCaching(CAS, Diags, CI);
228-
auto CacheKey = createCompileJobCacheKeyImpl(CAS, Diags, CI);
229-
if (!CacheKey)
230-
return std::nullopt;
231-
232-
auto ID = CAS.parseID(CI.getFrontendOpts().CASInputFileCacheKey);
233-
if (!ID) {
234-
Diags.Report(diag::err_cas_cannot_parse_input_cache_key)
235-
<< CI.getFrontendOpts().CASInputFileCacheKey;
236-
return std::nullopt;
237-
}
238-
auto Value = Cache.get(*ID);
239-
if (!Value) {
240-
Diags.Report(diag::err_cas_cannot_lookup_input_cache_key)
241-
<< Value.takeError();
242-
return std::nullopt;
243-
}
244-
if (!*Value) {
245-
Diags.Report(diag::err_cas_missing_input_cache_entry)
246-
<< llvm::cas::ObjectStore::createUnknownObjectError(*ID);
247-
return std::nullopt;
248-
}
229+
// Preserve and freeze CASOptions so that we do not modify behaviour of
230+
// Invocation.getCASOpts().getOrCreateDatabases().
231+
CASOptions CASOpts(CI.getCASOpts());
232+
CASOpts.freezeConfig(Diags);
249233

250-
CI.getFrontendOpts().CASInputFileCASID = Value.get()->toString();
251-
CI.getFrontendOpts().CASInputFileCacheKey.clear();
234+
Opts = canonicalizeForCaching(CAS, Diags, CI);
235+
auto CacheKey = createCompileJobCacheKeyImpl(CAS, Diags, CI);
236+
if (!CacheKey)
237+
return std::nullopt;
252238

253-
CompilerInvocation CICopy = CI;
254-
(void)canonicalizeForCaching(CAS, Diags, CICopy);
255-
auto CanonicalCacheKey = createCompileJobCacheKeyImpl(CAS, Diags, CICopy);
256-
if (!CanonicalCacheKey)
257-
return std::nullopt;
239+
assert(CI.getCASOpts().CASPath == CASOpts.CASPath &&
240+
"cas instance has incompatible hash with cas options");
241+
CI.getCASOpts() = std::move(CASOpts);
258242

259-
return std::make_pair(*CacheKey, *CanonicalCacheKey);
243+
if (CI.getFrontendOpts().CASInputFileCacheKey.empty())
244+
return std::make_pair(*CacheKey, *CacheKey);
245+
246+
auto ID = CAS.parseID(CI.getFrontendOpts().CASInputFileCacheKey);
247+
if (!ID) {
248+
Diags.Report(diag::err_cas_cannot_parse_input_cache_key)
249+
<< CI.getFrontendOpts().CASInputFileCacheKey;
250+
return std::nullopt;
251+
}
252+
auto Value = Cache.get(*ID);
253+
if (!Value) {
254+
Diags.Report(diag::err_cas_cannot_lookup_input_cache_key)
255+
<< Value.takeError();
256+
return std::nullopt;
257+
}
258+
if (!*Value) {
259+
Diags.Report(diag::err_cas_missing_input_cache_entry)
260+
<< llvm::cas::ObjectStore::createUnknownObjectError(*ID);
261+
return std::nullopt;
260262
}
261263

262-
Opts = canonicalizeForCaching(CAS, Diags, CI);
263-
auto CacheKey = createCompileJobCacheKeyImpl(CAS, Diags, CI);
264-
if (!CacheKey)
264+
CI.getFrontendOpts().CASInputFileCASID = Value.get()->toString();
265+
CI.getFrontendOpts().CASInputFileCacheKey.clear();
266+
267+
CompilerInvocation CICopy = CI;
268+
(void)canonicalizeForCaching(CAS, Diags, CICopy);
269+
auto CanonicalCacheKey = createCompileJobCacheKeyImpl(CAS, Diags, CICopy);
270+
if (!CanonicalCacheKey)
265271
return std::nullopt;
266-
return std::make_pair(*CacheKey, *CacheKey);
272+
273+
return std::make_pair(*CacheKey, *CanonicalCacheKey);
267274
}
268275

269276
std::optional<llvm::cas::CASID>

0 commit comments

Comments
 (0)