Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticCASKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ let Component = "CAS" in {
def err_builtin_cas_cannot_be_initialized : Error<
"CAS cannot be initialized from '%0' on disk (check -fcas-path)">,
DefaultFatal;
def err_builtin_actioncache_cannot_be_initialized : Error<
"ActionCache cannot be initialized from '%0' on disk (check -faction-cache-path)">,
DefaultFatal;
def err_cas_cannot_parse_root_id : Error<
"CAS cannot parse root-id '%0' specified by -fcas-fs">, DefaultFatal;
def err_cas_filesystem_cannot_be_initialized : Error<
Expand Down
27 changes: 22 additions & 5 deletions clang/include/clang/CAS/CASOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#include <vector>

namespace llvm {
class Error;
namespace cas {
class ActionCache;
class CASDB;
} // end namespace cas
} // end namespace llvm
Expand Down Expand Up @@ -52,10 +54,11 @@ class CASConfiguration {
/// - "auto" is an alias for an automatically chosen location in the user's
/// system cache.
std::string CASPath;
std::string CachePath;

friend bool operator==(const CASConfiguration &LHS,
const CASConfiguration &RHS) {
return LHS.CASPath == RHS.CASPath;
return LHS.CASPath == RHS.CASPath && LHS.CachePath == RHS.CachePath;
}
friend bool operator!=(const CASConfiguration &LHS,
const CASConfiguration &RHS) {
Expand All @@ -73,7 +76,7 @@ class CASConfiguration {
/// defined in CASConfiguration to enable caching a CAS instance.
///
/// CASOptions includes \a getOrCreateCAS() and \a
/// getOrCreateCASAndHideConfig() for creating a CAS and caching it.
/// getOrCreateActionCache() for creating CAS and ActionCache.
///
/// FIXME: The the caching is done here, instead of as a field in \a
/// CompilerInstance, in order to ensure that \a
Expand All @@ -92,24 +95,38 @@ class CASOptions : public CASConfiguration {
getOrCreateCAS(DiagnosticsEngine &Diags,
bool CreateEmptyCASOnFailure = false) const;

/// Get a CAS defined by the options above. Future calls will return the same
/// Get a ActionCache defined by the options above. Future calls will return
/// the same ActionCache instance... unless the configuration has changed, in
/// which case a new one will be created.
///
/// If \p CreateEmptyCacheOnFailure, returns an empty in-memory ActionCache on
/// failure. Else, returns \c nullptr on failure.
std::shared_ptr<llvm::cas::ActionCache>
getOrCreateActionCache(DiagnosticsEngine &Diags,
bool CreateEmptyCacheOnFailures = false) const;

/// Freeze CAS Configuration. Future calls will return the same
/// CAS instance, even if the configuration changes again later.
///
/// The configuration will be wiped out to prevent it being observable or
/// affecting the output of something that takes \a CASOptions as an input.
/// This also "locks in" the return value of \a getOrCreateCAS(): future
/// calls will not check if the configuration has changed.
std::shared_ptr<llvm::cas::CASDB>
getOrCreateCASAndHideConfig(DiagnosticsEngine &Diags);
void freezeConfig(DiagnosticsEngine &Diags);

/// If the configuration is not for a persistent store, it modifies it to the
/// default on-disk CAS, otherwise this is a noop.
void ensurePersistentCAS();

private:
/// Initialize Cached CAS and ActionCache.
void initCache(DiagnosticsEngine &Diags) const;

struct CachedCAS {
/// A cached CAS instance.
std::shared_ptr<llvm::cas::CASDB> CAS;
/// An ActionCache instnace.
std::shared_ptr<llvm::cas::ActionCache> AC;

/// Remember how the CAS was created.
CASConfiguration Config;
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6446,6 +6446,12 @@ def fcas_path : Separate<["-"], "fcas-path">,
" '-fcas-path=auto' chooses a path in the user's system cache.">,
MarshallingInfoString<CASOpts<"CASPath">>;

def faction_cache_path : Separate<["-"], "faction-cache-path">,
Group<f_Group>, MetaVarName<"<dir>|auto">,
HelpText<"Path to a persistent on-disk backing store for the builtin Cache."
" '-faction-cache-path=auto' chooses a path in the user's system cache.">,
MarshallingInfoString<CASOpts<"CachePath">>;

// FIXME: Add to driver once it's supported by -fdepscan.
def fcas_fs : Separate<["-"], "fcas-fs">,
Group<f_Group>, MetaVarName<"<tree>">,
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Frontend/CompilerInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ class CompilerInstance : public ModuleLoader {
/// The CAS, if any.
std::shared_ptr<llvm::cas::CASDB> CAS;

/// The ActionCache, if any.
std::shared_ptr<llvm::cas::ActionCache> ActionCache;

/// The file manager.
IntrusiveRefCntPtr<FileManager> FileMgr;

Expand Down Expand Up @@ -427,6 +430,7 @@ class CompilerInstance : public ModuleLoader {

/// Get the CAS, or create it using the configuration in CompilerInvocation.
llvm::cas::CASDB &getOrCreateCAS();
llvm::cas::ActionCache &getOrCreateActionCache();

/// }
/// @name Source Manager
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Lex/PTHManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CAS/ActionCache.h"
#include "llvm/CAS/CASDB.h"
#include "llvm/CAS/CASFileSystem.h"
#include "llvm/CAS/CASID.h"
#include "llvm/Support/Allocator.h"
Expand Down Expand Up @@ -98,6 +100,7 @@ class PTHManager {
llvm::SpecificBumpPtrAllocator<IdentifierInfo *> IdentifierInfoCacheAlloc;

llvm::cas::CASDB &CAS;
llvm::cas::ActionCache &Cache;
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
LangOptions CanonicalLangOpts;
Optional<llvm::cas::CASID> SerializedLangOpts;
Expand All @@ -120,7 +123,7 @@ class PTHManager {
~PTHManager();
PTHManager() = delete;

PTHManager(llvm::cas::CASDB &CAS,
PTHManager(llvm::cas::CASDB &CAS, llvm::cas::ActionCache &Cache,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, Preprocessor &PP);

void setPreprocessor(Preprocessor *pp) { PP = pp; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/CAS/ActionCache.h"
#include "llvm/CAS/CASID.h"
#include "llvm/CAS/CASReference.h"
#include "llvm/CAS/ThreadSafeFileSystem.h"
Expand All @@ -34,7 +35,8 @@ namespace dependencies {
class DependencyScanningCASFilesystem : public llvm::cas::ThreadSafeFileSystem {
public:
DependencyScanningCASFilesystem(
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> WorkerFS);
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> WorkerFS,
llvm::cas::ActionCache &Cache);

~DependencyScanningCASFilesystem();

Expand Down Expand Up @@ -104,6 +106,7 @@ class DependencyScanningCASFilesystem : public llvm::cas::ThreadSafeFileSystem {
llvm::cas::CachingOnDiskFileSystem &getCachingFS();

llvm::cas::CASDB &CAS;
llvm::cas::ActionCache &Cache;
Optional<llvm::cas::ObjectRef> ClangFullVersionID;
Optional<llvm::cas::ObjectRef> DepDirectivesID;
Optional<llvm::cas::ObjectRef> EmptyBlobID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clang/CAS/CASOptions.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningCASFilesystem.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
#include "llvm/CAS/ActionCache.h"

namespace clang {
namespace tooling {
Expand Down Expand Up @@ -58,6 +59,7 @@ class DependencyScanningService {
public:
DependencyScanningService(
ScanningMode Mode, ScanningOutputFormat Format, CASOptions CASOpts,
std::shared_ptr<llvm::cas::ActionCache> Cache,
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> SharedFS,
bool ReuseFileManager = true, bool OptimizeArgs = false,
bool EagerLoadModules = false, bool OverrideCASTokenCache = false);
Expand All @@ -79,6 +81,10 @@ class DependencyScanningService {
}

const CASOptions &getCASOpts() const { return CASOpts; }
llvm::cas::ActionCache &getCache() const {
assert(Cache && "Cache is not initialized");
return *Cache;
}

bool overrideCASTokenCache() const { return OverrideCASTokenCache; }

Expand All @@ -90,6 +96,7 @@ class DependencyScanningService {
const ScanningMode Mode;
const ScanningOutputFormat Format;
CASOptions CASOpts;
std::shared_ptr<llvm::cas::ActionCache> Cache;
const bool ReuseFileManager;
/// Whether to optimize the modules' command-line arguments.
const bool OptimizeArgs;
Expand Down
80 changes: 63 additions & 17 deletions clang/lib/CAS/CASOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
#include "clang/CAS/CASOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticCAS.h"
#include "llvm/CAS/ActionCache.h"
#include "llvm/CAS/CASDB.h"
#include "llvm/Support/Error.h"

using namespace clang;
using namespace llvm::cas;

static std::shared_ptr<llvm::cas::CASDB>
createCAS(const CASConfiguration &Config, DiagnosticsEngine &Diags,
bool CreateEmptyCASOnFailure) {
createCAS(const CASConfiguration &Config, DiagnosticsEngine &Diags) {
if (Config.CASPath.empty())
return llvm::cas::createInMemoryCAS();

Expand All @@ -33,7 +34,7 @@ createCAS(const CASConfiguration &Config, DiagnosticsEngine &Diags,
llvm::expectedToOptional(llvm::cas::createOnDiskCAS(Path)))
return std::move(*MaybeCAS);
Diags.Report(diag::err_builtin_cas_cannot_be_initialized) << Path;
return CreateEmptyCASOnFailure ? llvm::cas::createInMemoryCAS() : nullptr;
return nullptr;
}

std::shared_ptr<llvm::cas::CASDB>
Expand All @@ -42,22 +43,21 @@ CASOptions::getOrCreateCAS(DiagnosticsEngine &Diags,
if (Cache.Config.IsFrozen)
return Cache.CAS;

auto &CurrentConfig = static_cast<const CASConfiguration &>(*this);
if (!Cache.CAS || CurrentConfig != Cache.Config) {
Cache.Config = CurrentConfig;
Cache.CAS = createCAS(Cache.Config, Diags, CreateEmptyCASOnFailure);
}

initCache(Diags);
if (Cache.CAS)
return Cache.CAS;
if (!CreateEmptyCASOnFailure)
return nullptr;
Cache.CAS = llvm::cas::createInMemoryCAS();
return Cache.CAS;
}

std::shared_ptr<llvm::cas::CASDB>
CASOptions::getOrCreateCASAndHideConfig(DiagnosticsEngine &Diags) {
void CASOptions::freezeConfig(DiagnosticsEngine &Diags) {
if (Cache.Config.IsFrozen)
return Cache.CAS;
return;

std::shared_ptr<llvm::cas::CASDB> CAS = getOrCreateCAS(Diags);
assert(CAS == Cache.CAS && "Expected CAS to be cached");
// Make sure the cache is initialized.
initCache(Diags);

// Freeze the CAS and wipe out the visible config to hide it from future
// accesses. For example, future diagnostics cannot see this. Something that
Expand All @@ -67,13 +67,48 @@ CASOptions::getOrCreateCASAndHideConfig(DiagnosticsEngine &Diags) {
CurrentConfig = CASConfiguration();
CurrentConfig.IsFrozen = Cache.Config.IsFrozen = true;

if (CAS) {
if (Cache.CAS) {
// Set the CASPath to the hash schema, since that leaks through CASContext's
// API and is observable.
CurrentConfig.CASPath = CAS->getHashSchemaIdentifier().str();
CurrentConfig.CASPath = Cache.CAS->getHashSchemaIdentifier().str();
}
if (Cache.AC)
CurrentConfig.CachePath = "";
}

static std::shared_ptr<llvm::cas::ActionCache>
createCache(CASDB &CAS, const CASConfiguration &Config,
DiagnosticsEngine &Diags) {
if (Config.CachePath.empty())
return llvm::cas::createInMemoryActionCache(CAS);

// Compute the path.
std::string Path = Config.CASPath;
if (Path == "auto")
Path = getDefaultOnDiskActionCachePath();

return CAS;
// FIXME: Pass on the actual error from the CAS.
if (auto MaybeCache = llvm::expectedToOptional(
llvm::cas::createOnDiskActionCache(CAS, Path)))
return std::move(*MaybeCache);
Diags.Report(diag::err_builtin_actioncache_cannot_be_initialized) << Path;
return nullptr;
}

std::shared_ptr<llvm::cas::ActionCache>
CASOptions::getOrCreateActionCache(DiagnosticsEngine &Diags,
bool CreateEmptyOnFailure) const {
if (Cache.Config.IsFrozen)
return Cache.AC;

initCache(Diags);
if (Cache.AC)
return Cache.AC;
if (!CreateEmptyOnFailure)
return nullptr;

Cache.CAS = Cache.CAS ? Cache.CAS : llvm::cas::createInMemoryCAS();
return llvm::cas::createInMemoryActionCache(*Cache.CAS);
}

void CASOptions::ensurePersistentCAS() {
Expand All @@ -83,8 +118,19 @@ void CASOptions::ensurePersistentCAS() {
llvm_unreachable("Cannot ensure persistent CAS if it's unknown / frozen");
case InMemoryCAS:
CASPath = "auto";
CachePath = "auto";
break;
case OnDiskCAS:
break;
}
}

void CASOptions::initCache(DiagnosticsEngine &Diags) const {
auto &CurrentConfig = static_cast<const CASConfiguration &>(*this);
if (CurrentConfig == Cache.Config && Cache.CAS && Cache.AC)
return;

Cache.Config = CurrentConfig;
Cache.CAS = createCAS(Cache.Config, Diags);
Cache.AC = createCache(*Cache.CAS, Cache.Config, Diags);
}
14 changes: 12 additions & 2 deletions clang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,8 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
// token-caching can fall back to ingesting into an in-memory CAS itself.
llvm::vfs::FileSystem &FS = getFileManager().getVirtualFileSystem();
if (FS.isCASFS())
PP->setPTHManager(
std::make_unique<PTHManager>(getOrCreateCAS(), &FS, *PP));
PP->setPTHManager(std::make_unique<PTHManager>(
getOrCreateCAS(), getOrCreateActionCache(), &FS, *PP));
}

if (PPOpts.DetailedRecord)
Expand Down Expand Up @@ -864,6 +864,16 @@ llvm::cas::CASDB &CompilerInstance::getOrCreateCAS() {
return *CAS;
}

llvm::cas::ActionCache &CompilerInstance::getOrCreateActionCache() {
if (ActionCache)
return *ActionCache;

ActionCache = getInvocation().getCASOpts().getOrCreateActionCache(
getDiagnostics(),
/*CreateEmptyActionCacheOnFailure=*/true);
return *ActionCache;
}

std::unique_ptr<raw_pwrite_stream>
CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,
bool RemoveFileOnSignal, bool UseTemporary,
Expand Down
Loading