Skip to content
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

[Dependency Scanner] Refactor the global scanning service to no longer maintain scanner cache state #77794

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
15 changes: 2 additions & 13 deletions include/swift-c/DependencyScan/DependencyScan.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
/// The version constants for the SwiftDependencyScan C API.
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
#define SWIFTSCAN_VERSION_MAJOR 0
#define SWIFTSCAN_VERSION_MINOR 10
#define SWIFTSCAN_VERSION_MAJOR 1
#define SWIFTSCAN_VERSION_MINOR 0

SWIFTSCAN_BEGIN_DECLS

Expand Down Expand Up @@ -481,17 +481,6 @@ swiftscan_source_location_get_column_number(swiftscan_source_location_t source_l
// to allow clients to perform incremental dependency scans by having the
// scanner's state be serializable and re-usable.

/// For the specified \c scanner instance, serialize its state to the specified file-system \c path .
SWIFTSCAN_PUBLIC void
swiftscan_scanner_cache_serialize(swiftscan_scanner_t scanner,
const char * path);

/// For the specified \c scanner instance, load in scanner state from a file at
/// the specified file-system \c path .
SWIFTSCAN_PUBLIC bool
swiftscan_scanner_cache_load(swiftscan_scanner_t scanner,
const char * path);

/// For the specified \c scanner instance, reset its internal state, ensuring subsequent
/// scanning queries are done "from-scratch".
SWIFTSCAN_PUBLIC void
Expand Down
111 changes: 14 additions & 97 deletions include/swift/AST/ModuleDependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -971,10 +971,6 @@ using ModuleNameToDependencyMap = llvm::StringMap<ModuleDependencyInfo>;
using ModuleDependenciesKindMap =
std::unordered_map<ModuleDependencyKind, ModuleNameToDependencyMap,
ModuleDependencyKindHash>;
using ModuleDependenciesKindRefMap =
std::unordered_map<ModuleDependencyKind,
llvm::StringMap<const ModuleDependencyInfo *>,
ModuleDependencyKindHash>;

// MARK: SwiftDependencyTracker
/// Track swift dependency
Expand Down Expand Up @@ -1005,23 +1001,8 @@ class SwiftDependencyTracker {

// MARK: SwiftDependencyScanningService
/// A carrier of state shared among possibly multiple invocations of the
/// dependency scanner. Acts as a global cache of discovered module dependencies
/// and filesystem state. It is not to be queried directly, but is rather meant
/// to be wrapped in an instance of `ModuleDependenciesCache`, responsible for
/// recording new dependencies and answering cache queries in a given scan.
/// dependency scanner.
class SwiftDependencyScanningService {
/// Global cache contents specific to a specific scanner invocation context
struct ContextSpecificGlobalCacheState {
/// All cached module dependencies, in the order in which they were
/// encountered.
std::vector<ModuleDependencyID> AllModules;

/// Dependencies for modules that have already been computed.
/// This maps a dependency kind to a map of a module's name to a Dependency
/// object
ModuleDependenciesKindMap ModuleDependenciesMap;
};

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

Expand All @@ -1046,27 +1027,9 @@ class SwiftDependencyScanningService {
clang::tooling::dependencies::DependencyScanningFilesystemSharedCache>
SharedFilesystemCache;

/// A map from a String representing the target triple of a scanner invocation
/// to the corresponding cached dependencies discovered so far when using this
/// triple.
llvm::StringMap<std::unique_ptr<ContextSpecificGlobalCacheState>>
ContextSpecificCacheMap;

/// The context hashes used by scanners using this cache, in the order in
/// which they were used
std::vector<std::string> AllContextHashes;

/// Shared state mutual-exclusivity lock
mutable llvm::sys::SmartMutex<true> ScanningServiceGlobalLock;

/// Retrieve the dependencies map that corresponds to the given dependency
/// kind.
ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind,
StringRef scanContextHash);
const ModuleNameToDependencyMap &
getDependenciesMap(ModuleDependencyKind kind,
StringRef scanContextHash) const;

public:
SwiftDependencyScanningService();
SwiftDependencyScanningService(const SwiftDependencyScanningService &) =
Expand Down Expand Up @@ -1136,54 +1099,6 @@ class SwiftDependencyScanningService {
friend class ModuleDependenciesCache;
friend class ModuleDependencyScanner;
friend class ModuleDependencyScanningWorker;
friend class ModuleDependenciesCacheDeserializer;
friend class ModuleDependenciesCacheSerializer;

/// Configure the current state of the cache to respond to queries
/// for the specified scanning context hash.
void configureForContextHash(StringRef scanningContextHash);

/// Return context hashes of all scanner invocations that have used
/// this cache instance.
const std::vector<std::string> &getAllContextHashes() const {
return AllContextHashes;
}

/// Whether we have cached dependency information for the given module.
bool hasDependency(StringRef moduleName,
std::optional<ModuleDependencyKind> kind,
StringRef scanContextHash) const;

/// Return a pointer to the cache state of the specified context hash.
ContextSpecificGlobalCacheState *
getCacheForScanningContextHash(StringRef scanContextHash) const;

/// Look for module dependencies for a module with the given name
///
/// \returns the cached result, or \c None if there is no cached entry.
std::optional<const ModuleDependencyInfo *>
findDependency(StringRef moduleName, std::optional<ModuleDependencyKind> kind,
StringRef scanContextHash) const;

/// Record dependencies for the given module.
const ModuleDependencyInfo *
recordDependency(StringRef moduleName, ModuleDependencyInfo dependencies,
StringRef scanContextHash);

/// Update stored dependencies for the given module.
const ModuleDependencyInfo *
updateDependency(ModuleDependencyID moduleID,
ModuleDependencyInfo dependencies,
StringRef scanContextHash);

/// Reference the list of all module dependency infos for a given scanning
/// context
const std::vector<ModuleDependencyID> &
getAllModules(StringRef scanningContextHash) const {
auto contextSpecificCache =
getCacheForScanningContextHash(scanningContextHash);
return contextSpecificCache->AllModules;
}
};

// MARK: ModuleDependenciesCache
Expand All @@ -1195,11 +1110,10 @@ class SwiftDependencyScanningService {
class ModuleDependenciesCache {
private:
SwiftDependencyScanningService &globalScanningService;
/// References to data in the `globalScanningService` for module dependencies
ModuleDependenciesKindRefMap ModuleDependenciesMap;
/// Discovered dependencies
ModuleDependenciesKindMap ModuleDependenciesMap;
/// Set containing all of the Clang modules that have already been seen.
llvm::DenseSet<clang::tooling::dependencies::ModuleID>
alreadySeenClangModules;
llvm::DenseSet<clang::tooling::dependencies::ModuleID> alreadySeenClangModules;
/// Name of the module under scan
std::string mainScanModuleName;
/// The context hash of the current scanning invocation
Expand All @@ -1223,6 +1137,11 @@ class ModuleDependenciesCache {
ModuleDependenciesCache &operator=(const ModuleDependenciesCache &) = delete;

public:
/// Retrieve the dependencies map that corresponds to the given dependency
/// kind.
ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind);
const ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind) const;

/// Whether we have cached dependency information for the given module.
bool hasDependency(const ModuleDependencyID &moduleID) const;
/// Whether we have cached dependency information for the given module.
Expand Down Expand Up @@ -1283,13 +1202,7 @@ class ModuleDependenciesCache {
/// \returns the cached result, or \c None if there is no cached entry.
std::optional<const ModuleDependencyInfo *>
findDependency(StringRef moduleName,
std::optional<ModuleDependencyKind> kind) const;

/// Look for module dependencies for a module with the given name
///
/// \returns the cached result, or \c None if there is no cached entry.
std::optional<const ModuleDependencyInfo *>
findDependency(StringRef moduleName) const;
std::optional<ModuleDependencyKind> kind = std::nullopt) const;

/// Look for Swift module dependencies for a module with the given name
///
Expand Down Expand Up @@ -1340,6 +1253,10 @@ class ModuleDependenciesCache {
const ArrayRef<ModuleDependencyID> dependencyIDs);

StringRef getMainModuleName() const { return mainScanModuleName; }

private:
friend class ModuleDependenciesCacheDeserializer;
friend class ModuleDependenciesCacheSerializer;
};
} // namespace swift

Expand Down
5 changes: 0 additions & 5 deletions include/swift/DependencyScan/DependencyScanningTool.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ class DependencyScanningTool {
const llvm::StringSet<> &PlaceholderModules,
StringRef WorkingDirectory);

/// Writes the current `SharedCache` instance to a specified FileSystem path.
void serializeCache(llvm::StringRef path);
/// Loads an instance of a `SwiftDependencyScanningService` to serve as the `SharedCache`
/// from a specified FileSystem path.
bool loadCache(llvm::StringRef path);
/// Discard the tool's current `SharedCache` and start anew.
void resetCache();
/// Query diagnostics consumed so far.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,24 @@ using ClangModuleDetailsLayout =
/// Tries to read the dependency graph from the given buffer.
/// Returns \c true if there was an error.
bool readInterModuleDependenciesCache(llvm::MemoryBuffer &buffer,
SwiftDependencyScanningService &cache);
ModuleDependenciesCache &cache);

/// Tries to read the dependency graph from the given path name.
/// Returns true if there was an error.
bool readInterModuleDependenciesCache(llvm::StringRef path,
SwiftDependencyScanningService &cache);
ModuleDependenciesCache &cache);

/// Tries to write the dependency graph to the given path name.
/// Returns true if there was an error.
bool writeInterModuleDependenciesCache(DiagnosticEngine &diags,
llvm::vfs::OutputBackend &backend,
llvm::StringRef path,
const SwiftDependencyScanningService &cache);
const ModuleDependenciesCache &cache);

/// Tries to write out the given dependency cache with the given
/// bitstream writer.
void writeInterModuleDependenciesCache(llvm::BitstreamWriter &Out,
const SwiftDependencyScanningService &cache);
const ModuleDependenciesCache &cache);

} // end namespace module_dependency_cache_serialization
} // end namespace dependencies
Expand Down
Loading