Skip to content

Caching/CAS option improvements #66887

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
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
1 change: 0 additions & 1 deletion include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ REMARK(replay_output, none, "replay output file '%0': key '%1'", (StringRef, Str
REMARK(output_cache_miss, none, "cache miss output file '%0': key '%1'", (StringRef, StringRef))

// CAS related diagnostics
ERROR(error_create_cas, none, "failed to create CAS '%0' (%1)", (StringRef, StringRef))
ERROR(error_invalid_cas_id, none, "invalid CASID '%0' (%1)", (StringRef, StringRef))
ERROR(error_cas, none, "CAS error encountered: %0", (StringRef))

Expand Down
6 changes: 5 additions & 1 deletion include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "swift/Basic/LLVM.h"
#include "swift/AST/Import.h"
#include "clang/CAS/CASOptions.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -767,6 +768,9 @@ class SwiftDependencyScanningService {
ModuleDependenciesKindMap ModuleDependenciesMap;
};

/// The CASOption created the Scanning Service if used.
llvm::Optional<clang::CASOptions> CASOpts;

/// The persistent Clang dependency scanner service
Optional<clang::tooling::dependencies::DependencyScanningService>
ClangScanningService;
Expand Down Expand Up @@ -863,7 +867,7 @@ class SwiftDependencyScanningService {
void overlaySharedFilesystemCacheForCompilation(CompilerInstance &Instance);

/// Setup caching service.
void setupCachingDependencyScanningService(CompilerInstance &Instance);
bool setupCachingDependencyScanningService(CompilerInstance &Instance);
private:
/// Enforce clients not being allowed to query this cache directly, it must be
/// wrapped in an instance of `ModuleDependenciesCache`.
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Version.h"
#include "swift/Config.h"
#include "clang/CAS/CASOptions.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallString.h"
Expand Down Expand Up @@ -820,7 +821,7 @@ namespace swift {
std::string Optimization;

/// clang CASOptions.
std::string CASPath;
llvm::Optional<clang::CASOptions> CASOpts;

/// Cache key for imported bridging header.
std::string BridgingHeaderPCHCacheKey;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Frontend/CachingUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bool replayCachedCompilerOutputs(
llvm::cas::ObjectStore &CAS, llvm::cas::ActionCache &Cache,
llvm::cas::ObjectRef BaseKey, DiagnosticEngine &Diag,
const FrontendInputsAndOutputs &InputsAndOutputs,
CachingDiagnosticsProcessor &CDP);
CachingDiagnosticsProcessor &CDP, bool CacheRemarks);

/// Load the cached compile result from cache.
std::unique_ptr<llvm::MemoryBuffer> loadCachedCompileResultFromCacheKey(
Expand Down
15 changes: 11 additions & 4 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "clang/CAS/CASOptions.h"

#include <string>
#include <vector>
Expand Down Expand Up @@ -122,11 +123,17 @@ class FrontendOptions {
/// The module for which we should verify all of the generic signatures.
std::string VerifyGenericSignaturesInModule;

/// Use CAS.
bool EnableCAS = false;
/// Enable compiler caching.
bool EnableCaching = false;

/// The CAS Path.
std::string CASPath;
/// Enable compiler caching remarks.
bool EnableCachingRemarks = false;

/// Skip replaying outputs from cache.
bool CacheSkipReplay = false;

/// CASOptions
clang::CASOptions CASOpts;

/// CASFS Root.
std::vector<std::string> CASFSRootIDs;
Expand Down
17 changes: 17 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,23 @@ def always_compile_output_files :
Flag<["-"], "always-compile-output-files">,
HelpText<"Always compile output files even it might not change the results">;

// CAS/Caching related options.
def allow_unstable_cache_key_for_testing: Flag<["-"], "allow-unstable-cache-key-for-testing">,
HelpText<"Allow compilation caching with unstable inputs for testing purpose">;

def bridging_header_pch_key : Separate<["-"], "bridging-header-pch-key">,
HelpText<"Cache Key for bridging header pch">;

def clang_include_tree: Flag<["-"], "clang-include-tree">,
HelpText<"Use clang include tree">;

def cas_fs: Separate<["-"], "cas-fs">,
HelpText<"Root CASID for CAS FileSystem">, MetaVarName<"<cas-id>">;

def clang_include_tree_root: Separate<["-"], "clang-include-tree-root">,
HelpText<"Clang Include Tree CASID">, MetaVarName<"<cas-id>">;


def experimental_spi_only_imports :
Flag<["-"], "experimental-spi-only-imports">,
HelpText<"Enable use of @_spiOnly imports">;
Expand Down
40 changes: 18 additions & 22 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1812,36 +1812,32 @@ def gcc_toolchain: Separate<["-"], "gcc-toolchain">,
MetaVarName<"<path>">,
HelpText<"Specify a directory where the clang importer and clang linker can find headers and libraries">;

def cas_path: Separate<["-"], "cas-path">,
def cache_compile_job: Flag<["-"], "cache-compile-job">,
Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Path to CAS">, MetaVarName<"<path>">;
HelpText<"Enable compiler caching">;

def allow_unstable_cache_key_for_testing: Flag<["-"], "allow-unstable-cache-key-for-testing">,
Flags<[FrontendOption, HelpHidden, NoDriverOption]>,
HelpText<"Allow compilation caching with unstable inputs for testing purpose">;

def bridging_header_pch_key : Separate<["-"], "bridging-header-pch-key">,
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
HelpText<"Cache Key for bridging header pch">;
def cache_remarks: Flag<["-"], "cache-remarks">,
Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Show remarks for compiler caching">;

def clang_include_tree: Flag<["-"], "clang-include-tree">,
Flags<[FrontendOption, NoDriverOption]>,
HelpText<"Use clang include tree">;
def cache_disable_replay: Flag<["-"], "cache-disable-replay">,
Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Skip loading the compilation result from cache">;

def cas_path: Separate<["-"], "cas-path">,
Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Path to CAS">, MetaVarName<"<path>">;

// END ONLY SUPPORTED IN NEW DRIVER
def cas_plugin_path: Separate<["-"], "cas-plugin-path">,
Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Path to CAS Plugin">, MetaVarName<"<path>">;

def enable_cas: Flag<["-"], "enable-cas">,
Flags<[FrontendOption, NoDriverOption]>,
HelpText<"Enable CAS for swift-frontend">;
def cas_plugin_option: Separate<["-"], "cas-plugin-option">,
Flags<[FrontendOption, NewDriverOnlyOption]>,
HelpText<"Option pass to CAS Plugin">, MetaVarName<"<name>=<option>">;

def cas_fs: Separate<["-"], "cas-fs">,
Flags<[FrontendOption, NoDriverOption]>,
HelpText<"Root CASID for CAS FileSystem">, MetaVarName<"<cas-id>">;

def clang_include_tree_root: Separate<["-"], "clang-include-tree-root">,
Flags<[FrontendOption, NoDriverOption]>,
HelpText<"Clang Include Tree CASID">, MetaVarName<"<cas-id>">;
// END ONLY SUPPORTED IN NEW DRIVER


def plugin_search_Group : OptionGroup<"<plugin search options>">;
Expand Down
39 changes: 25 additions & 14 deletions lib/AST/ModuleDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,25 @@ void SwiftDependencyScanningService::overlaySharedFilesystemCacheForCompilation(
Instance.getSourceMgr().setFileSystem(depFS);
}

void SwiftDependencyScanningService::setupCachingDependencyScanningService(
bool SwiftDependencyScanningService::setupCachingDependencyScanningService(
CompilerInstance &Instance) {
if (!Instance.getInvocation().getFrontendOptions().EnableCAS)
return;
if (!Instance.getInvocation().getFrontendOptions().EnableCaching)
return false;

if (CASOpts) {
// If CASOption matches, the service is initialized already.
if (*CASOpts == Instance.getInvocation().getFrontendOptions().CASOpts)
return false;

// CASOption mismatch, return error.
Instance.getDiags().diagnose(
SourceLoc(), diag::error_cas,
"conflicting CAS options used in scanning service");
return true;
}

// Setup CAS.
CASOpts = Instance.getInvocation().getFrontendOptions().CASOpts;
CAS = Instance.getSharedCASInstance();

// Add SDKSetting file.
Expand Down Expand Up @@ -454,17 +467,12 @@ void SwiftDependencyScanningService::setupCachingDependencyScanningService(
auto CachingFS =
llvm::cas::createCachingOnDiskFileSystem(Instance.getObjectStore());
if (!CachingFS) {
Instance.getDiags().diagnose(SourceLoc(), diag::error_create_cas,
"CachingOnDiskFS",
Instance.getDiags().diagnose(SourceLoc(), diag::error_cas,
toString(CachingFS.takeError()));
return;
return true;
}
CacheFS = std::move(*CachingFS);

clang::CASOptions CASOpts;
CASOpts.CASPath = Instance.getInvocation().getFrontendOptions().CASPath;
CASOpts.ensurePersistentCAS();

UseClangIncludeTree =
Instance.getInvocation().getClangImporterOptions().UseClangIncludeTree;
const clang::tooling::dependencies::ScanningOutputFormat ClangScanningFormat =
Expand All @@ -474,10 +482,13 @@ void SwiftDependencyScanningService::setupCachingDependencyScanningService(

ClangScanningService.emplace(
clang::tooling::dependencies::ScanningMode::DependencyDirectivesScan,
ClangScanningFormat, CASOpts, Instance.getSharedCASInstance(),
Instance.getSharedCacheInstance(),
ClangScanningFormat,
Instance.getInvocation().getFrontendOptions().CASOpts,
Instance.getSharedCASInstance(), Instance.getSharedCacheInstance(),
UseClangIncludeTree ? nullptr : CacheFS,
/* ReuseFileManager */ false, /* OptimizeArgs */ false);

return false;
}

SwiftDependencyScanningService::ContextSpecificGlobalCacheState *
Expand Down Expand Up @@ -611,8 +622,8 @@ Optional<const ModuleDependencyInfo *> ModuleDependenciesCache::findDependency(
scannerContextHash);
// During a scan, only produce the cached source module info for the current
// module under scan.
if (optionalDep.hasValue()) {
auto dep = optionalDep.getValue();
if (optionalDep) {
auto dep = *optionalDep;
if (dep->getAsSwiftSourceModule() &&
moduleName != mainScanModuleName &&
moduleName != "DummyMainModuleForResolvingCrossImportOverlays") {
Expand Down
25 changes: 20 additions & 5 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,13 +709,28 @@ importer::getNormalInvocationArguments(
llvm::sys::path::get_separator() +
"apinotes").str());

if (!importerOpts.CASPath.empty()) {
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back("-fcas-path");
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back(importerOpts.CASPath);
if (importerOpts.CASOpts) {
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back("-fno-pch-timestamp");
if (!importerOpts.CASOpts->CASPath.empty()) {
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back("-fcas-path");
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back(importerOpts.CASOpts->CASPath);
}
if (!importerOpts.CASOpts->PluginPath.empty()) {
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back("-fcas-plugin-path");
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back(importerOpts.CASOpts->PluginPath);
for (auto Opt : importerOpts.CASOpts->PluginOptions) {
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back("-fcas-plugin-option");
invocationArgStrs.push_back("-Xclang");
invocationArgStrs.push_back(
(llvm::Twine(Opt.first) + "=" + Opt.second).str());
}
}
}
}

Expand Down
41 changes: 31 additions & 10 deletions lib/ClangImporter/ClangModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,21 @@ void ClangImporter::recordModuleDependencies(
std::string IncludeTree =
clangModuleDep.IncludeTreeID ? *clangModuleDep.IncludeTreeID : "";

if (!RootID.empty() || !IncludeTree.empty()) {
if (ctx.ClangImporterOpts.CASOpts) {
swiftArgs.push_back("-enable-cas");
swiftArgs.push_back("-cas-path");
swiftArgs.push_back(ctx.ClangImporterOpts.CASPath);
if (!ctx.ClangImporterOpts.CASOpts->CASPath.empty()) {
swiftArgs.push_back("-cas-path");
swiftArgs.push_back(ctx.ClangImporterOpts.CASOpts->CASPath);
}
if (!ctx.ClangImporterOpts.CASOpts->PluginPath.empty()) {
swiftArgs.push_back("-cas-plugin-path");
swiftArgs.push_back(ctx.ClangImporterOpts.CASOpts->PluginPath);
for (auto Opt : ctx.ClangImporterOpts.CASOpts->PluginOptions) {
swiftArgs.push_back("-cas-plugin-option");
swiftArgs.push_back(
(llvm::Twine(Opt.first) + "=" + Opt.second).str());
}
}
}

if (!RootID.empty()) {
Expand Down Expand Up @@ -334,10 +345,20 @@ void ClangImporter::recordBridgingHeaderOptions(

llvm::for_each(clangArgs, addClangArg);

if (!ctx.ClangImporterOpts.CASPath.empty()) {
if (ctx.ClangImporterOpts.CASOpts) {
swiftArgs.push_back("-enable-cas");
swiftArgs.push_back("-cas-path");
swiftArgs.push_back(ctx.ClangImporterOpts.CASPath);
if (!ctx.ClangImporterOpts.CASOpts->CASPath.empty()) {
swiftArgs.push_back("-cas-path");
swiftArgs.push_back(ctx.ClangImporterOpts.CASOpts->CASPath);
}
if (!ctx.ClangImporterOpts.CASOpts->PluginPath.empty()) {
swiftArgs.push_back("-cas-plugin-path");
swiftArgs.push_back(ctx.ClangImporterOpts.CASOpts->PluginPath);
for (auto Opt : ctx.ClangImporterOpts.CASOpts->PluginOptions) {
swiftArgs.push_back("-cas-plugin-option");
swiftArgs.push_back((llvm::Twine(Opt.first) + "=" + Opt.second).str());
}
}
}

if (auto Tree = deps.IncludeTreeID) {
Expand Down Expand Up @@ -387,12 +408,12 @@ Optional<const ModuleDependencyInfo*> ClangImporter::getModuleDependencies(
std::vector<std::string> commandLineArgs =
getClangDepScanningInvocationArguments(ctx);
auto optionalWorkingDir = computeClangWorkingDirectory(commandLineArgs, ctx);
if (!optionalWorkingDir.hasValue()) {
if (!optionalWorkingDir) {
ctx.Diags.diagnose(SourceLoc(), diag::clang_dependency_scan_error,
"Missing '-working-directory' argument");
return None;
}
std::string workingDir = optionalWorkingDir.getValue();
std::string workingDir = *optionalWorkingDir;

auto moduleCachePath = getModuleCachePathFromClang(getClangInstance());
auto lookupModuleOutput =
Expand Down Expand Up @@ -452,12 +473,12 @@ bool ClangImporter::addBridgingHeaderDependencies(
std::vector<std::string> commandLineArgs =
getClangDepScanningInvocationArguments(ctx, StringRef(bridgingHeader));
auto optionalWorkingDir = computeClangWorkingDirectory(commandLineArgs, ctx);
if (!optionalWorkingDir.hasValue()) {
if (!optionalWorkingDir) {
ctx.Diags.diagnose(SourceLoc(), diag::clang_dependency_scan_error,
"Missing '-working-directory' argument");
return true;
}
std::string workingDir = optionalWorkingDir.getValue();
std::string workingDir = *optionalWorkingDir;

auto moduleCachePath = getModuleCachePathFromClang(getClangInstance());
auto lookupModuleOutput =
Expand Down
3 changes: 2 additions & 1 deletion lib/DependencyScan/DependencyScanningTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ DependencyScanningTool::initCompilerInstanceForScan(
}

// Setup the caching service after the instance finishes setup.
ScanningService->setupCachingDependencyScanningService(*Instance);
if (ScanningService->setupCachingDependencyScanningService(*Instance))
return std::make_error_code(std::errc::invalid_argument);

(void)Instance->getMainModule();

Expand Down
10 changes: 7 additions & 3 deletions lib/DependencyScan/ScanDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ static llvm::Error resolveExplicitModuleInputs(
dependencyInfoCopy.updateCommandLine(commandLine);

// Handle CAS options.
if (instance.getInvocation().getFrontendOptions().EnableCAS) {
if (instance.getInvocation().getFrontendOptions().EnableCaching) {
// Merge CASFS from clang dependency.
auto &CASFS = cache.getScanService().getSharedCachingFS();
auto &CAS = CASFS.getCAS();
Expand Down Expand Up @@ -1764,7 +1764,9 @@ bool swift::dependencies::scanDependencies(CompilerInstance &instance) {
deserializeDependencyCache(instance, service);
// Wrap the filesystem with a caching `DependencyScanningWorkerFilesystem`
service.overlaySharedFilesystemCacheForCompilation(instance);
service.setupCachingDependencyScanningService(instance);
if (service.setupCachingDependencyScanningService(instance))
return true;

ModuleDependenciesCache cache(service,
instance.getMainModule()->getNameStr().str(),
instance.getInvocation().getModuleScanningHash());
Expand Down Expand Up @@ -1832,7 +1834,9 @@ bool swift::dependencies::batchScanDependencies(

SwiftDependencyScanningService singleUseService;
singleUseService.overlaySharedFilesystemCacheForCompilation(instance);
singleUseService.setupCachingDependencyScanningService(instance);
if (singleUseService.setupCachingDependencyScanningService(instance))
return true;

ModuleDependenciesCache cache(singleUseService,
instance.getMainModule()->getNameStr().str(),
instance.getInvocation().getModuleScanningHash());
Expand Down
Loading