mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[SwiftScan][Caching] Add support for plugin CAS for caching
Teach libSwiftScan about plugin CAS and add API to create plugin CAS to use for dependency scanning and cas operations.
This commit is contained in:
@@ -14,21 +14,55 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/Basic/LLVMInitialize.h"
|
||||
#include "swift/Basic/InitializeSwiftModules.h"
|
||||
#include "swift/DriverTool/DriverTool.h"
|
||||
#include "swift/Basic/LLVMInitialize.h"
|
||||
#include "swift/DependencyScan/DependencyScanImpl.h"
|
||||
#include "swift/DependencyScan/DependencyScanningTool.h"
|
||||
#include "swift/DependencyScan/StringUtils.h"
|
||||
#include "swift/Frontend/CachingUtils.h"
|
||||
#include "swift/DriverTool/DriverTool.h"
|
||||
#include "swift/Frontend/CompileJobCacheKey.h"
|
||||
#include "swift/Option/Options.h"
|
||||
#include "clang/CAS/CASOptions.h"
|
||||
#include "llvm/CAS/ActionCache.h"
|
||||
#include "llvm/CAS/BuiltinUnifiedCASDatabases.h"
|
||||
#include "llvm/CAS/ObjectStore.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace swift::dependencies;
|
||||
using namespace swift::cas;
|
||||
|
||||
namespace {
|
||||
/// Helper class to manage CAS/Caching from libSwiftScan C APIs.
|
||||
class SwiftScanCAS {
|
||||
public:
|
||||
// Compute the CASID for PCH output from invocation.
|
||||
llvm::Expected<std::string> computeCacheKey(llvm::ArrayRef<const char *> Args,
|
||||
llvm::StringRef InputPath,
|
||||
swift::file_types::ID OutputKind);
|
||||
|
||||
// Store content into CAS.
|
||||
llvm::Expected<std::string> storeContent(llvm::StringRef Content);
|
||||
|
||||
// Construct SwiftScanCAS.
|
||||
static llvm::Expected<SwiftScanCAS *>
|
||||
createSwiftScanCAS(llvm::StringRef Path);
|
||||
|
||||
static llvm::Expected<SwiftScanCAS *>
|
||||
createSwiftScanCAS(clang::CASOptions &CASOpts);
|
||||
|
||||
private:
|
||||
SwiftScanCAS(std::shared_ptr<llvm::cas::ObjectStore> CAS,
|
||||
std::shared_ptr<llvm::cas::ActionCache> Cache)
|
||||
: CAS(CAS), Cache(Cache) {}
|
||||
|
||||
std::shared_ptr<llvm::cas::ObjectStore> CAS;
|
||||
std::shared_ptr<llvm::cas::ActionCache> Cache;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScanningTool, swiftscan_scanner_t)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(CachingTool, swiftscan_cas_t)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::CASOptions, swiftscan_cas_options_t)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SwiftScanCAS, swiftscan_cas_t)
|
||||
|
||||
//=== Private Cleanup Functions -------------------------------------------===//
|
||||
|
||||
@@ -671,26 +705,58 @@ swiftscan_diagnostics_set_dispose(swiftscan_diagnostic_set_t* diagnostics){
|
||||
|
||||
//=== CAS Functions ----------------------------------------------------------//
|
||||
|
||||
swiftscan_cas_t swiftscan_cas_create(const char *path) {
|
||||
std::string CASPath(path);
|
||||
if (CASPath.empty())
|
||||
CASPath = llvm::cas::getDefaultOnDiskCASPath();
|
||||
swiftscan_cas_options_t swiftscan_cas_options_create() {
|
||||
clang::CASOptions *CASOpts = new clang::CASOptions();
|
||||
return wrap(CASOpts);
|
||||
}
|
||||
|
||||
CachingTool *tool = new CachingTool(CASPath);
|
||||
if (!tool->isValid()) {
|
||||
delete tool;
|
||||
void swiftscan_cas_options_dispose(swiftscan_cas_options_t options) {
|
||||
delete unwrap(options);
|
||||
}
|
||||
|
||||
void swiftscan_cas_options_set_ondisk_path(swiftscan_cas_options_t options,
|
||||
const char *path) {
|
||||
unwrap(options)->CASPath = path;
|
||||
}
|
||||
|
||||
void swiftscan_cas_options_set_plugin_path(swiftscan_cas_options_t options,
|
||||
const char *path) {
|
||||
unwrap(options)->PluginPath = path;
|
||||
}
|
||||
|
||||
bool swiftscan_cas_options_set_option(swiftscan_cas_options_t options,
|
||||
const char *name, const char *value,
|
||||
swiftscan_string_ref_t *error) {
|
||||
unwrap(options)->PluginOptions.emplace_back(name, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
swiftscan_cas_t
|
||||
swiftscan_cas_create_from_options(swiftscan_cas_options_t options,
|
||||
swiftscan_string_ref_t *error) {
|
||||
clang::CASOptions *opts = unwrap(options);
|
||||
auto cas = SwiftScanCAS::createSwiftScanCAS(*opts);
|
||||
if (!cas) {
|
||||
*error =
|
||||
swift::c_string_utils::create_clone(toString(cas.takeError()).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
return wrap(tool);
|
||||
return wrap(*cas);
|
||||
}
|
||||
|
||||
void swiftscan_cas_dispose(swiftscan_cas_t cas) { delete unwrap(cas); }
|
||||
|
||||
swiftscan_string_ref_t
|
||||
swiftscan_cas_store(swiftscan_cas_t cas, uint8_t *data, unsigned size) {
|
||||
swiftscan_string_ref_t swiftscan_cas_store(swiftscan_cas_t cas, uint8_t *data,
|
||||
unsigned size,
|
||||
swiftscan_string_ref_t *error) {
|
||||
llvm::StringRef StrContent((char*)data, size);
|
||||
auto ID = unwrap(cas)->storeContent(StrContent);
|
||||
return swift::c_string_utils::create_clone(ID.c_str());
|
||||
if (!ID) {
|
||||
*error =
|
||||
swift::c_string_utils::create_clone(toString(ID.takeError()).c_str());
|
||||
return swift::c_string_utils::create_null();
|
||||
}
|
||||
return swift::c_string_utils::create_clone(ID->c_str());
|
||||
}
|
||||
|
||||
static swift::file_types::ID
|
||||
@@ -713,14 +779,62 @@ getFileTypeFromScanOutputKind(swiftscan_output_kind_t kind) {
|
||||
|
||||
swiftscan_string_ref_t
|
||||
swiftscan_compute_cache_key(swiftscan_cas_t cas, int argc, const char **argv,
|
||||
const char *input, swiftscan_output_kind_t kind) {
|
||||
const char *input, swiftscan_output_kind_t kind,
|
||||
swiftscan_string_ref_t *error) {
|
||||
std::vector<const char *> Compilation;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
Compilation.push_back(argv[i]);
|
||||
|
||||
auto ID = unwrap(cas)->computeCacheKey(Compilation, input,
|
||||
getFileTypeFromScanOutputKind(kind));
|
||||
return swift::c_string_utils::create_clone(ID.c_str());
|
||||
if (!ID) {
|
||||
*error =
|
||||
swift::c_string_utils::create_clone(toString(ID.takeError()).c_str());
|
||||
return swift::c_string_utils::create_null();
|
||||
}
|
||||
return swift::c_string_utils::create_clone(ID->c_str());
|
||||
}
|
||||
|
||||
llvm::Expected<SwiftScanCAS *>
|
||||
SwiftScanCAS::createSwiftScanCAS(llvm::StringRef Path) {
|
||||
clang::CASOptions Opts;
|
||||
Opts.CASPath = Path;
|
||||
|
||||
return createSwiftScanCAS(Opts);
|
||||
}
|
||||
|
||||
llvm::Expected<SwiftScanCAS *>
|
||||
SwiftScanCAS::createSwiftScanCAS(clang::CASOptions &CASOpts) {
|
||||
auto DB = CASOpts.getOrCreateDatabases();
|
||||
if (!DB)
|
||||
return DB.takeError();
|
||||
|
||||
return new SwiftScanCAS(std::move(DB->first), std::move(DB->second));
|
||||
}
|
||||
|
||||
llvm::Expected<std::string>
|
||||
SwiftScanCAS::computeCacheKey(llvm::ArrayRef<const char *> Args,
|
||||
llvm::StringRef InputPath,
|
||||
swift::file_types::ID OutputKind) {
|
||||
auto BaseKey = swift::createCompileJobBaseCacheKey(*CAS, Args);
|
||||
if (!BaseKey)
|
||||
return BaseKey.takeError();
|
||||
|
||||
auto Key = swift::createCompileJobCacheKeyForOutput(*CAS, *BaseKey, InputPath,
|
||||
OutputKind);
|
||||
if (!Key)
|
||||
return Key.takeError();
|
||||
|
||||
return CAS->getID(*Key).toString();
|
||||
}
|
||||
|
||||
llvm::Expected<std::string>
|
||||
SwiftScanCAS::storeContent(llvm::StringRef Content) {
|
||||
auto Result = CAS->storeFromString({}, Content);
|
||||
if (!Result)
|
||||
return Result.takeError();
|
||||
|
||||
return CAS->getID(*Result).toString();
|
||||
}
|
||||
|
||||
//=== Experimental Compiler Invocation Functions ------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user