Skip to content

Commit c358f27

Browse files
authored
Merge pull request #6337 from akyrtzi/pr/stable/ondisk-cas-revamp
[stable] Cherry-pick commits for on-disk CAS revamp
2 parents 2e68068 + 9518785 commit c358f27

File tree

94 files changed

+4098
-2426
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+4098
-2426
lines changed

clang/include/clang/Basic/DiagnosticCASKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
let Component = "CAS" in {
1010

1111
def err_builtin_cas_cannot_be_initialized : Error<
12-
"CAS cannot be initialized from '%0' on disk (check -fcas-path)">,
12+
"CAS cannot be initialized from '%0' on disk (check -fcas-path): %1">,
1313
DefaultFatal;
1414
def err_builtin_actioncache_cannot_be_initialized : Error<
15-
"ActionCache cannot be initialized from '%0' on disk (check -faction-cache-path)">,
15+
"ActionCache cannot be initialized from '%0' on disk (check -fcas-path)">,
1616
DefaultFatal;
1717
def err_cas_cannot_parse_root_id : Error<
1818
"CAS cannot parse root-id '%0' specified by -fcas-fs">, DefaultFatal;

clang/include/clang/CAS/CASOptions.h

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
#ifndef LLVM_CLANG_CAS_CASOPTIONS_H
1515
#define LLVM_CLANG_CAS_CASOPTIONS_H
1616

17-
#include <memory>
17+
#include "llvm/ADT/SmallVector.h"
1818
#include <string>
19-
#include <vector>
2019

2120
namespace llvm {
22-
class Error;
2321
namespace cas {
2422
class ActionCache;
2523
class ObjectStore;
@@ -30,6 +28,9 @@ namespace clang {
3028

3129
class DiagnosticsEngine;
3230

31+
/// Set \p Path to a reasonable default on-disk cache path for the current user.
32+
void getClangDefaultCachePath(llvm::SmallVectorImpl<char> &Path);
33+
3334
/// Base class for options configuring which CAS to use. Separated for the
3435
/// fields where we don't need special move/copy logic.
3536
///
@@ -54,11 +55,10 @@ class CASConfiguration {
5455
/// - "auto" is an alias for an automatically chosen location in the user's
5556
/// system cache.
5657
std::string CASPath;
57-
std::string CachePath;
5858

5959
friend bool operator==(const CASConfiguration &LHS,
6060
const CASConfiguration &RHS) {
61-
return LHS.CASPath == RHS.CASPath && LHS.CachePath == RHS.CachePath;
61+
return LHS.CASPath == RHS.CASPath;
6262
}
6363
friend bool operator!=(const CASConfiguration &LHS,
6464
const CASConfiguration &RHS) {
@@ -75,8 +75,8 @@ class CASConfiguration {
7575
/// Options configuring which CAS to use. User-accessible fields should be
7676
/// defined in CASConfiguration to enable caching a CAS instance.
7777
///
78-
/// CASOptions includes \a getOrCreateObjectStore() and \a
79-
/// getOrCreateActionCache() for creating CAS and ActionCache.
78+
/// CASOptions includes \a getOrCreateDatabases() for creating CAS and
79+
/// ActionCache.
8080
///
8181
/// FIXME: The the caching is done here, instead of as a field in \a
8282
/// CompilerInstance, in order to ensure that \a
@@ -85,32 +85,23 @@ class CASConfiguration {
8585
/// it would be better to update all callers and remove it from here.
8686
class CASOptions : public CASConfiguration {
8787
public:
88-
/// Get a CAS defined by the options above. Future calls will return the same
89-
/// CAS instance... unless the configuration has changed, in which case a new
90-
/// one will be created.
91-
///
92-
/// If \p CreateEmptyCASOnFailure, returns an empty in-memory CAS on failure.
93-
/// Else, returns \c nullptr on failure.
94-
std::shared_ptr<llvm::cas::ObjectStore>
95-
getOrCreateObjectStore(DiagnosticsEngine &Diags,
96-
bool CreateEmptyCASOnFailure = false) const;
97-
98-
/// Get a ActionCache defined by the options above. Future calls will return
99-
/// the same ActionCache instance... unless the configuration has changed, in
100-
/// which case a new one will be created.
88+
/// Get a CAS & ActionCache defined by the options above. Future calls will
89+
/// return the same instances... unless the configuration has changed, in
90+
/// which case new ones will be created.
10191
///
102-
/// If \p CreateEmptyCacheOnFailure, returns an empty in-memory ActionCache on
92+
/// If \p CreateEmptyDBsOnFailure, returns empty in-memory databases on
10393
/// failure. Else, returns \c nullptr on failure.
104-
std::shared_ptr<llvm::cas::ActionCache>
105-
getOrCreateActionCache(DiagnosticsEngine &Diags,
106-
bool CreateEmptyCacheOnFailures = false) const;
94+
std::pair<std::shared_ptr<llvm::cas::ObjectStore>,
95+
std::shared_ptr<llvm::cas::ActionCache>>
96+
getOrCreateDatabases(DiagnosticsEngine &Diags,
97+
bool CreateEmptyDBsOnFailure = false) const;
10798

10899
/// Freeze CAS Configuration. Future calls will return the same
109100
/// CAS instance, even if the configuration changes again later.
110101
///
111102
/// The configuration will be wiped out to prevent it being observable or
112103
/// affecting the output of something that takes \a CASOptions as an input.
113-
/// This also "locks in" the return value of \a getOrCreateObjectStore():
104+
/// This also "locks in" the return value of \a getOrCreateDatabases():
114105
/// future calls will not check if the configuration has changed.
115106
void freezeConfig(DiagnosticsEngine &Diags);
116107

clang/include/clang/Driver/Options.td

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6591,12 +6591,6 @@ def fcas_path : Separate<["-"], "fcas-path">,
65916591
" '-fcas-path=auto' chooses a path in the user's system cache.">,
65926592
MarshallingInfoString<CASOpts<"CASPath">>;
65936593

6594-
def faction_cache_path : Separate<["-"], "faction-cache-path">,
6595-
Group<f_Group>, MetaVarName<"<dir>|auto">,
6596-
HelpText<"Path to a persistent on-disk backing store for the builtin Cache."
6597-
" '-faction-cache-path=auto' chooses a path in the user's system cache.">,
6598-
MarshallingInfoString<CASOpts<"CachePath">>;
6599-
66006594
// FIXME: Add to driver once it's supported by -fdepscan.
66016595
def fcas_fs : Separate<["-"], "fcas-fs">,
66026596
Group<f_Group>, MetaVarName<"<tree>">,

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class CompilerInstance : public ModuleLoader {
186186
/// Force an output buffer.
187187
std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
188188

189+
void createCASDatabases();
190+
189191
CompilerInstance(const CompilerInstance &) = delete;
190192
void operator=(const CompilerInstance &) = delete;
191193
public:

clang/lib/CAS/CASOptions.cpp

Lines changed: 37 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,33 @@
1010
#include "clang/Basic/Diagnostic.h"
1111
#include "clang/Basic/DiagnosticCAS.h"
1212
#include "llvm/CAS/ActionCache.h"
13+
#include "llvm/CAS/BuiltinUnifiedCASDatabases.h"
1314
#include "llvm/CAS/ObjectStore.h"
14-
#include "llvm/Support/Error.h"
15+
#include "llvm/Support/Path.h"
1516

1617
using namespace clang;
1718
using namespace llvm::cas;
1819

19-
static std::shared_ptr<llvm::cas::ObjectStore>
20-
createObjectStore(const CASConfiguration &Config, DiagnosticsEngine &Diags) {
21-
if (Config.CASPath.empty())
22-
return llvm::cas::createInMemoryCAS();
23-
24-
// Compute the path.
25-
SmallString<128> Storage;
26-
StringRef Path = Config.CASPath;
27-
if (Path == "auto") {
28-
llvm::cas::getDefaultOnDiskCASPath(Storage);
29-
Path = Storage;
30-
}
31-
32-
// FIXME: Pass on the actual error from the CAS.
33-
if (auto MaybeCAS =
34-
llvm::expectedToOptional(llvm::cas::createOnDiskCAS(Path)))
35-
return std::move(*MaybeCAS);
36-
Diags.Report(diag::err_builtin_cas_cannot_be_initialized) << Path;
37-
return nullptr;
20+
void clang::getClangDefaultCachePath(SmallVectorImpl<char> &Path) {
21+
// FIXME: Should this return 'Error' instead of hard-failing?
22+
if (!llvm::sys::path::cache_directory(Path))
23+
llvm::report_fatal_error("cannot get default cache directory");
24+
llvm::sys::path::append(Path, "clang-cache");
3825
}
3926

40-
std::shared_ptr<llvm::cas::ObjectStore>
41-
CASOptions::getOrCreateObjectStore(DiagnosticsEngine &Diags,
42-
bool CreateEmptyCASOnFailure) const {
27+
std::pair<std::shared_ptr<llvm::cas::ObjectStore>,
28+
std::shared_ptr<llvm::cas::ActionCache>>
29+
CASOptions::getOrCreateDatabases(DiagnosticsEngine &Diags,
30+
bool CreateEmptyDBsOnFailure) const {
4331
if (Cache.Config.IsFrozen)
44-
return Cache.CAS;
32+
return {Cache.CAS, Cache.AC};
4533

4634
initCache(Diags);
47-
if (Cache.CAS)
48-
return Cache.CAS;
49-
if (!CreateEmptyCASOnFailure)
50-
return nullptr;
51-
Cache.CAS = llvm::cas::createInMemoryCAS();
52-
return Cache.CAS;
35+
if (!Cache.CAS && CreateEmptyDBsOnFailure)
36+
Cache.CAS = llvm::cas::createInMemoryCAS();
37+
if (!Cache.AC && CreateEmptyDBsOnFailure)
38+
Cache.AC = llvm::cas::createInMemoryActionCache();
39+
return {Cache.CAS, Cache.AC};
5340
}
5441

5542
void CASOptions::freezeConfig(DiagnosticsEngine &Diags) {
@@ -73,53 +60,15 @@ void CASOptions::freezeConfig(DiagnosticsEngine &Diags) {
7360
CurrentConfig.CASPath =
7461
Cache.CAS->getContext().getHashSchemaIdentifier().str();
7562
}
76-
if (Cache.AC)
77-
CurrentConfig.CachePath = "";
78-
}
79-
80-
static std::shared_ptr<llvm::cas::ActionCache>
81-
createCache(ObjectStore &CAS, const CASConfiguration &Config,
82-
DiagnosticsEngine &Diags) {
83-
if (Config.CachePath.empty())
84-
return llvm::cas::createInMemoryActionCache();
85-
86-
// Compute the path.
87-
std::string Path = Config.CachePath;
88-
if (Path == "auto")
89-
Path = getDefaultOnDiskActionCachePath();
90-
91-
// FIXME: Pass on the actual error from the CAS.
92-
if (auto MaybeCache =
93-
llvm::expectedToOptional(llvm::cas::createOnDiskActionCache(Path)))
94-
return std::move(*MaybeCache);
95-
Diags.Report(diag::err_builtin_actioncache_cannot_be_initialized) << Path;
96-
return nullptr;
97-
}
98-
99-
std::shared_ptr<llvm::cas::ActionCache>
100-
CASOptions::getOrCreateActionCache(DiagnosticsEngine &Diags,
101-
bool CreateEmptyOnFailure) const {
102-
if (Cache.Config.IsFrozen)
103-
return Cache.AC;
104-
105-
initCache(Diags);
106-
if (Cache.AC)
107-
return Cache.AC;
108-
if (!CreateEmptyOnFailure)
109-
return nullptr;
110-
111-
Cache.CAS = Cache.CAS ? Cache.CAS : llvm::cas::createInMemoryCAS();
112-
return llvm::cas::createInMemoryActionCache();
11363
}
11464

11565
void CASOptions::ensurePersistentCAS() {
11666
assert(!IsFrozen && "Expected to check for a persistent CAS before freezing");
11767
switch (getKind()) {
11868
case UnknownCAS:
119-
llvm_unreachable("Cannot ensure persistent CAS if it's unknown / frozen");
69+
llvm_unreachable("Cannot ensure persistent CAS if it's unknown / frozen");
12070
case InMemoryCAS:
12171
CASPath = "auto";
122-
CachePath = "auto";
12372
break;
12473
case OnDiskCAS:
12574
break;
@@ -132,6 +81,23 @@ void CASOptions::initCache(DiagnosticsEngine &Diags) const {
13281
return;
13382

13483
Cache.Config = CurrentConfig;
135-
Cache.CAS = createObjectStore(Cache.Config, Diags);
136-
Cache.AC = createCache(*Cache.CAS, Cache.Config, Diags);
84+
StringRef CASPath = Cache.Config.CASPath;
85+
if (CASPath.empty()) {
86+
Cache.CAS = llvm::cas::createInMemoryCAS();
87+
Cache.AC = llvm::cas::createInMemoryActionCache();
88+
return;
89+
}
90+
91+
SmallString<256> PathBuf;
92+
if (CASPath == "auto") {
93+
getClangDefaultCachePath(PathBuf);
94+
CASPath = PathBuf;
95+
}
96+
std::pair<std::unique_ptr<ObjectStore>, std::unique_ptr<ActionCache>> DBs;
97+
if (llvm::Error E = createOnDiskUnifiedCASDatabases(CASPath).moveInto(DBs)) {
98+
Diags.Report(diag::err_builtin_cas_cannot_be_initialized)
99+
<< CASPath << toString(std::move(E));
100+
return;
101+
}
102+
std::tie(Cache.CAS, Cache.AC) = std::move(DBs);
137103
}

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -902,25 +902,24 @@ llvm::vfs::OutputBackend &CompilerInstance::getOrCreateOutputBackend() {
902902
return getOutputBackend();
903903
}
904904

905-
llvm::cas::ObjectStore &CompilerInstance::getOrCreateObjectStore() {
906-
if (CAS)
907-
return *CAS;
908-
909-
// Create a new CAS instance from the CompilerInvocation. Future calls to
905+
void CompilerInstance::createCASDatabases() {
906+
// Create a new CAS databases from the CompilerInvocation. Future calls to
910907
// createFileManager() will use the same CAS.
911-
CAS = getInvocation().getCASOpts().getOrCreateObjectStore(
912-
getDiagnostics(),
913-
/*CreateEmptyCASOnFailure=*/true);
908+
std::tie(CAS, ActionCache) =
909+
getInvocation().getCASOpts().getOrCreateDatabases(
910+
getDiagnostics(),
911+
/*CreateEmptyCASOnFailure=*/true);
912+
}
913+
914+
llvm::cas::ObjectStore &CompilerInstance::getOrCreateObjectStore() {
915+
if (!CAS)
916+
createCASDatabases();
914917
return *CAS;
915918
}
916919

917920
llvm::cas::ActionCache &CompilerInstance::getOrCreateActionCache() {
918-
if (ActionCache)
919-
return *ActionCache;
920-
921-
ActionCache = getInvocation().getCASOpts().getOrCreateActionCache(
922-
getDiagnostics(),
923-
/*CreateEmptyActionCacheOnFailure=*/true);
921+
if (!ActionCache)
922+
createCASDatabases();
924923
return *ActionCache;
925924
}
926925

@@ -2445,4 +2444,4 @@ bool CompileCacheASTReaderHelper::readCASFileSystemRootID(StringRef RootID,
24452444
return true;
24462445
}
24472446
return false;
2448-
}
2447+
}

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ createBaseFS(const FileSystemOptions &FSOpts, const FrontendOptions &FEOpts,
13471347
// If no CAS was provided, create one with CASOptions.
13481348
std::shared_ptr<llvm::cas::ObjectStore> CAS = std::move(OverrideCAS);
13491349
if (!CAS)
1350-
CAS = CASOpts.getOrCreateObjectStore(Diags);
1350+
CAS = CASOpts.getOrCreateDatabases(Diags).first;
13511351

13521352
// Helper for creating a valid (but empty) CASFS if an error is encountered.
13531353
auto makeEmptyCASFS = [&CAS]() {
@@ -2988,7 +2988,7 @@ static void determineInputFromIncludeTree(
29882988
Diags.Report(diag::err_fe_unable_to_load_include_tree)
29892989
<< IncludeTreeID << llvm::toString(std::move(E));
29902990
};
2991-
auto CAS = CASOpts.getOrCreateObjectStore(Diags);
2991+
auto CAS = CASOpts.getOrCreateDatabases(Diags).first;
29922992
if (!CAS)
29932993
return;
29942994
auto ID = CAS->parseID(IncludeTreeID);

clang/test/CAS/cached-diagnostics.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
// RUN: %clang_cc1 -triple x86_64-apple-macos12 -fsyntax-only %t/src/main.c -I %t/src/inc -Wunknown-pragmas 2> %t/regular-diags1.txt
66

77
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -fdepscan-prefix-map=%t/src=/^src -o %t/t1.rsp -cc1-args \
8-
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas -faction-cache-path %t/cache \
8+
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas \
99
// RUN: -emit-obj %t/src/main.c -o %t/out/output.o -I %t/src/inc -Wunknown-pragmas
1010

1111
// Compare diagnostics after a miss.
1212
// RUN: %clang @%t/t1.rsp 2> %t/diags1.txt
1313
// RUN: diff -u %t/regular-diags1.txt %t/diags1.txt
1414

1515
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -o %t/t1.noprefix.rsp -cc1-args \
16-
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas -faction-cache-path %t/cache \
16+
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas \
1717
// RUN: -emit-obj %t/src/main.c -o %t/out/output.o -I %t/src/inc -Wunknown-pragmas
1818

1919
// Compare diagnostics without prefix mappings.
@@ -42,7 +42,7 @@
4242
// RUN: %clang_cc1 -triple x86_64-apple-macos12 -fsyntax-only %t/src2/main.c -I %t/src2/inc -Wunknown-pragmas 2> %t/regular-diags2.txt
4343

4444
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -fdepscan-prefix-map=%t/src2=/^src -o %t/t2.rsp -cc1-args \
45-
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas -faction-cache-path %t/cache \
45+
// RUN: -cc1 -triple x86_64-apple-macos12 -fcas-path %t/cas \
4646
// RUN: -emit-obj %t/src2/main.c -o %t/out2/output.o -I %t/src2/inc -Wunknown-pragmas
4747
// RUN: %clang @%t/t2.rsp -Rcompile-job-cache 2> %t/diags-hit2.txt
4848

clang/test/CAS/daemon-cwd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
// RUN: -fdepscan-prefix-map=%t=/^build \
1212
// RUN: -fdepscan-prefix-map-toolchain=/^toolchain \
1313
// RUN: -fdepscan-daemon=%{clang-daemon-dir}/%basename_t \
14-
// RUN: -Xclang -fcas-path -Xclang %t/cas -Xclang -faction-cache-path -Xclang %t/cache \
14+
// RUN: -Xclang -fcas-path -Xclang %t/cas \
1515
// RUN: -MD -MF %t/test.d -Iinclude \
1616
// RUN: -fsyntax-only -x c %s >> %t/cmd.sh
1717
// RUN: chmod +x %t/cmd.sh
1818

1919
// RUN: %clang -cc1depscand -execute %{clang-daemon-dir}/%basename_t \
20-
// RUN: -cas-args -fcas-path %t/cas -faction-cache-path %t/cache -- %t/cmd.sh
20+
// RUN: -cas-args -fcas-path %t/cas -- %t/cmd.sh
2121
// RUN: (cd %t && %clang -target x86_64-apple-macos11 -MD -MF %t/test2.d \
2222
// RUN: -Iinclude -fsyntax-only -x c %s)
2323
// RUN: diff %t/test.d %t/test2.d

clang/test/CAS/depscan-dependency-file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
// RUN: split-file %s %t
33

44
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -o %t/t.rsp -cc1-args \
5-
// RUN: -cc1 -fcas-path %t/cas -faction-cache-path %t/cache -triple x86_64-apple-macos11 %t/main.c -emit-obj -o %t/output.o -isystem %t/sys \
5+
// RUN: -cc1 -fcas-path %t/cas -triple x86_64-apple-macos11 %t/main.c -emit-obj -o %t/output.o -isystem %t/sys \
66
// RUN: -MT deps -dependency-file %t/t.d
77
// RUN: FileCheck %s -input-file=%t/t.d -check-prefix=NOSYS
88
// RUN: FileCheck %s -input-file=%t/t.d -check-prefix=COMMON
99

1010
// Including system headers.
1111
// RUN: %clang -cc1depscan -fdepscan=inline -fdepscan-include-tree -o %t/t.rsp -cc1-args \
12-
// RUN: -cc1 -fcas-path %t/cas -faction-cache-path %t/cache -triple x86_64-apple-macos11 %t/main.c -emit-obj -o %t/output.o -isystem %t/sys \
12+
// RUN: -cc1 -fcas-path %t/cas -triple x86_64-apple-macos11 %t/main.c -emit-obj -o %t/output.o -isystem %t/sys \
1313
// RUN: -MT deps -sys-header-deps -dependency-file %t/t-sys.d
1414
// RUN: FileCheck %s -input-file=%t/t-sys.d -check-prefix=WITHSYS -check-prefix=COMMON
1515

0 commit comments

Comments
 (0)