Skip to content

Commit 962f221

Browse files
authored
Merge pull request #38761 from artemcm/WrapGlobalCache
[Dependency Scanning] Split the ModuleDependencyCache into two: current scan cache & global.
2 parents 9f71ee1 + 9429136 commit 962f221

13 files changed

+435
-240
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 147 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/StringSet.h"
2626
#include <string>
2727
#include <vector>
28+
#include <unordered_map>
2829

2930
namespace swift {
3031

@@ -35,7 +36,8 @@ class Identifier;
3536

3637
/// Which kind of module dependencies we are looking for.
3738
enum class ModuleDependenciesKind : int8_t {
38-
SwiftTextual,
39+
FirstKind,
40+
SwiftTextual = FirstKind,
3941
SwiftBinary,
4042
// Placeholder dependencies are a kind of dependencies used only by the
4143
// dependency scanner. They are swift modules that the scanner will not be
@@ -61,6 +63,14 @@ enum class ModuleDependenciesKind : int8_t {
6163
// of all targets, individually, have been computed.
6264
SwiftPlaceholder,
6365
Clang,
66+
LastKind = Clang + 1
67+
};
68+
69+
struct ModuleDependenciesKindHash {
70+
std::size_t operator()(ModuleDependenciesKind k) const {
71+
using UnderlyingType = std::underlying_type<ModuleDependenciesKind>::type;
72+
return std::hash<UnderlyingType>{}(static_cast<UnderlyingType>(k));
73+
}
6474
};
6575

6676
/// Details of a given module used for dependency scanner cache queries.
@@ -409,29 +419,30 @@ class ModuleDependencies {
409419
};
410420

411421
using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
422+
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
412423

413424
/// A cache describing the set of module dependencies that has been queried
414-
/// thus far.
415-
class ModuleDependenciesCache {
416-
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
417-
425+
/// thus far. This cache records/stores the actual Dependency values and can be
426+
/// preserved across different scanning actions (e.g. in
427+
/// `DependencyScanningTool`). It is not to be queried directly, but is rather
428+
/// meant to be wrapped in an instance of `ModuleDependenciesCache`, responsible
429+
/// for recording new dependencies and answering cache queries in a given scan.
430+
/// Queries to this cache must be disambiguated with a set of search paths to
431+
/// ensure that the returned cached dependency was one that can be found in the
432+
/// current scanning action's filesystem view.
433+
class GlobalModuleDependenciesCache {
418434
/// All cached module dependencies, in the order in which they were
419435
/// encountered.
420436
std::vector<ModuleDependencyID> AllModules;
421437

422-
/// Dependencies for Textual Swift modules that have already been computed.
423-
/// This maps a module's id (name, kind) to a vector of Dependency objects, which correspond
424-
/// to instances of the same module that may have been found in different sets of search paths.
425-
llvm::StringMap<ModuleDependenciesVector> SwiftTextualModuleDependencies;
426-
427-
/// Dependencies for Binary Swift modules that have already been computed.
428-
llvm::StringMap<ModuleDependenciesVector> SwiftBinaryModuleDependencies;
429-
430-
/// Dependencies for Swift placeholder dependency modules that have already been computed.
431-
llvm::StringMap<ModuleDependenciesVector> SwiftPlaceholderModuleDependencies;
432-
433-
/// Dependencies for Clang modules that have already been computed.
434-
llvm::StringMap<ModuleDependenciesVector> ClangModuleDependencies;
438+
/// Dependencies for modules that have already been computed.
439+
/// This maps a dependency kind to a map of a module's name to a vector of Dependency objects,
440+
/// which correspond to instances of the same module that may have been found
441+
/// in different sets of search paths.
442+
std::unordered_map<ModuleDependenciesKind,
443+
llvm::StringMap<ModuleDependenciesVector>,
444+
ModuleDependenciesKindHash>
445+
ModuleDependenciesKindMap;
435446

436447
/// Additional information needed for Clang dependency scanning.
437448
ClangModuleDependenciesCacheImpl *clangImpl = nullptr;
@@ -447,55 +458,148 @@ class ModuleDependenciesCache {
447458

448459
/// Retrieve the dependencies map that corresponds to the given dependency
449460
/// kind.
450-
llvm::StringMap<ModuleDependenciesVector> &getDependenciesMap(
451-
ModuleDependenciesKind kind);
452-
const llvm::StringMap<ModuleDependenciesVector> &getDependenciesMap(
453-
ModuleDependenciesKind kind) const;
461+
llvm::StringMap<ModuleDependenciesVector> &
462+
getDependenciesMap(ModuleDependenciesKind kind);
463+
const llvm::StringMap<ModuleDependenciesVector> &
464+
getDependenciesMap(ModuleDependenciesKind kind) const;
454465

455466
public:
456-
ModuleDependenciesCache() { }
467+
GlobalModuleDependenciesCache();
468+
GlobalModuleDependenciesCache(const GlobalModuleDependenciesCache &) = delete;
469+
GlobalModuleDependenciesCache &
470+
operator=(const GlobalModuleDependenciesCache &) = delete;
457471

458-
ModuleDependenciesCache(const ModuleDependenciesCache &) = delete;
459-
ModuleDependenciesCache &operator=(const ModuleDependenciesCache &) = delete;
472+
virtual ~GlobalModuleDependenciesCache() { destroyClangImpl(); }
460473

461-
~ModuleDependenciesCache() {
462-
destroyClangImpl();
463-
}
474+
private:
475+
/// Enforce clients not being allowed to query this cache directly, it must be
476+
/// wrapped in an instance of `ModuleDependenciesCache`.
477+
friend class ModuleDependenciesCache;
464478

465479
/// Set the Clang-specific implementation data.
466-
void setClangImpl(
467-
ClangModuleDependenciesCacheImpl *clangImpl,
468-
void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
480+
virtual void
481+
setClangImpl(ClangModuleDependenciesCacheImpl *clangImpl,
482+
void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
469483
destroyClangImpl();
470484

471485
this->clangImpl = clangImpl;
472486
this->clangImplDeleter = clangImplDeleter;
473487
}
474488

489+
/// Retrieve the Clang-specific implementation data;
490+
ClangModuleDependenciesCacheImpl *getClangImpl() const { return clangImpl; }
491+
492+
/// Whether we have cached dependency information for the given module.
493+
bool hasDependencies(StringRef moduleName,
494+
ModuleLookupSpecifics details) const;
495+
496+
/// Look for module dependencies for a module with the given name given
497+
/// current search paths.
498+
///
499+
/// \returns the cached result, or \c None if there is no cached entry.
500+
Optional<ModuleDependencies>
501+
findDependencies(StringRef moduleName, ModuleLookupSpecifics details) const;
502+
503+
public:
504+
/// Look for module dependencies for a module with the given name.
505+
/// This method has a deliberately-obtuse name to indicate that it is not to
506+
/// be used for general queries.
507+
///
508+
/// \returns the cached result, or \c None if there is no cached entry.
509+
Optional<ModuleDependenciesVector>
510+
findAllDependenciesIrrespectiveOfSearchPaths(
511+
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const;
512+
513+
/// Record dependencies for the given module.
514+
const ModuleDependencies *recordDependencies(StringRef moduleName,
515+
ModuleDependencies dependencies);
516+
517+
/// Update stored dependencies for the given module.
518+
const ModuleDependencies *updateDependencies(ModuleDependencyID moduleID,
519+
ModuleDependencies dependencies);
520+
521+
/// Reference the list of all module dependencies.
522+
const std::vector<ModuleDependencyID> &getAllModules() const {
523+
return AllModules;
524+
}
525+
};
526+
527+
/// This "local" dependencies cache persists only for the duration of a given
528+
/// scanning action, and wraps an instance of a `GlobalModuleDependenciesCache`
529+
/// which may carry cached scanning information from prior scanning actions.
530+
/// This cache maintains a store of references to all dependencies found within
531+
/// the current scanning action (with their values stored in the global Cache),
532+
/// since these do not require clients to disambiguate them with search paths.
533+
class ModuleDependenciesCache {
534+
private:
535+
GlobalModuleDependenciesCache &globalCache;
536+
537+
/// References to data in `globalCache` for dependencies accimulated during
538+
/// the current scanning action.
539+
std::unordered_map<ModuleDependenciesKind,
540+
llvm::StringMap<const ModuleDependencies *>,
541+
ModuleDependenciesKindHash>
542+
ModuleDependenciesKindMap;
543+
544+
/// Retrieve the dependencies map that corresponds to the given dependency
545+
/// kind.
546+
llvm::StringMap<const ModuleDependencies *> &
547+
getDependencyReferencesMap(ModuleDependenciesKind kind);
548+
const llvm::StringMap<const ModuleDependencies *> &
549+
getDependencyReferencesMap(ModuleDependenciesKind kind) const;
550+
551+
/// Local cache results lookup, only for modules which were discovered during
552+
/// the current scanner invocation.
553+
bool hasDependencies(StringRef moduleName,
554+
Optional<ModuleDependenciesKind> kind) const;
555+
556+
/// Local cache results lookup, only for modules which were discovered during
557+
/// the current scanner invocation.
558+
Optional<const ModuleDependencies *>
559+
findDependencies(StringRef moduleName,
560+
Optional<ModuleDependenciesKind> kind) const;
561+
562+
public:
563+
ModuleDependenciesCache(GlobalModuleDependenciesCache &globalCache);
564+
ModuleDependenciesCache(const ModuleDependenciesCache &) = delete;
565+
ModuleDependenciesCache &operator=(const ModuleDependenciesCache &) = delete;
566+
virtual ~ModuleDependenciesCache() {}
567+
568+
public:
569+
/// Set the Clang-specific implementation data.
570+
void
571+
setClangImpl(ClangModuleDependenciesCacheImpl *clangImpl,
572+
void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
573+
globalCache.setClangImpl(clangImpl, clangImplDeleter);
574+
}
575+
475576
/// Retrieve the Clang-specific implementation data;
476577
ClangModuleDependenciesCacheImpl *getClangImpl() const {
477-
return clangImpl;
578+
return globalCache.getClangImpl();
478579
}
479580

480581
/// Whether we have cached dependency information for the given module.
481582
bool hasDependencies(StringRef moduleName,
482583
ModuleLookupSpecifics details) const;
483584

484-
/// Look for module dependencies for a module with the given name given current search paths.
585+
/// Look for module dependencies for a module with the given name given
586+
/// current search paths.
485587
///
486588
/// \returns the cached result, or \c None if there is no cached entry.
487-
Optional<ModuleDependencies> findDependencies(
488-
StringRef moduleName,
489-
ModuleLookupSpecifics details) const;
589+
Optional<ModuleDependencies>
590+
findDependencies(StringRef moduleName, ModuleLookupSpecifics details) const;
490591

491592
/// Look for module dependencies for a module with the given name.
492-
/// This method has a deliberately-obtuse name to indicate that it is not to be used for general
493-
/// queries.
593+
/// This method has a deliberately-obtuse name to indicate that it is not to
594+
/// be used for general queries.
494595
///
495596
/// \returns the cached result, or \c None if there is no cached entry.
496-
Optional<ModuleDependenciesVector> findAllDependenciesIrrespectiveOfSearchPaths(
497-
StringRef moduleName,
498-
Optional<ModuleDependenciesKind> kind) const;
597+
Optional<ModuleDependenciesVector>
598+
findAllDependenciesIrrespectiveOfSearchPaths(
599+
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const {
600+
return globalCache.findAllDependenciesIrrespectiveOfSearchPaths(moduleName,
601+
kind);
602+
}
499603

500604
/// Record dependencies for the given module.
501605
void recordDependencies(StringRef moduleName,
@@ -507,10 +611,10 @@ class ModuleDependenciesCache {
507611

508612
/// Reference the list of all module dependencies.
509613
const std::vector<ModuleDependencyID> &getAllModules() const {
510-
return AllModules;
614+
return globalCache.getAllModules();
511615
}
512616
};
513617

514-
}
618+
} // namespace swift
515619

516620
#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */

include/swift/DependencyScan/DependencyScanningTool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class DependencyScanningTool {
5959

6060
/// Writes the current `SharedCache` instance to a specified FileSystem path.
6161
void serializeCache(llvm::StringRef path);
62-
/// Loads an instance of a `ModuleDependenciesCache` to serve as the `SharedCache`
62+
/// Loads an instance of a `GlobalModuleDependenciesCache` to serve as the `SharedCache`
6363
/// from a specified FileSystem path.
6464
bool loadCache(llvm::StringRef path);
6565
/// Discard the tool's current `SharedCache` and start anew.
@@ -73,7 +73,7 @@ class DependencyScanningTool {
7373

7474
/// Shared cache of module dependencies, re-used by individual full-scan queries
7575
/// during the lifetime of this Tool.
76-
std::unique_ptr<ModuleDependenciesCache> SharedCache;
76+
std::unique_ptr<GlobalModuleDependenciesCache> SharedCache;
7777

7878
/// Shared cache of compiler instances created during batch scanning, corresponding to
7979
/// command-line options specified in the batch scan input entry.

include/swift/DependencyScan/ScanDependencies.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,18 @@ namespace swift {
2727
class CompilerInvocation;
2828
class CompilerInstance;
2929
class ModuleDependenciesCache;
30+
class GlobalModuleDependenciesCache;
3031

3132
namespace dependencies {
3233

34+
//using CompilerArgInstanceCacheMap =
35+
// llvm::StringMap<std::pair<std::unique_ptr<CompilerInstance>,
36+
// std::unique_ptr<ModuleDependenciesCache>>>;
37+
3338
using CompilerArgInstanceCacheMap =
34-
llvm::StringMap<std::pair<std::unique_ptr<CompilerInstance>,
35-
std::unique_ptr<ModuleDependenciesCache>>>;
39+
llvm::StringMap<std::tuple<std::unique_ptr<CompilerInstance>,
40+
std::unique_ptr<GlobalModuleDependenciesCache>,
41+
std::unique_ptr<ModuleDependenciesCache>>>;
3642

3743
struct BatchScanInput {
3844
llvm::StringRef moduleName;

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class MemoryBuffer;
2323
namespace swift {
2424

2525
class DiagnosticEngine;
26-
class ModuleDependenciesCache;
26+
class GlobalModuleDependenciesCache;
2727

2828
namespace dependencies {
2929
namespace module_dependency_cache_serialization {
@@ -160,23 +160,23 @@ using ClangModuleDetailsLayout =
160160
/// Tries to read the dependency graph from the given buffer.
161161
/// Returns \c true if there was an error.
162162
bool readInterModuleDependenciesCache(llvm::MemoryBuffer &buffer,
163-
ModuleDependenciesCache &cache);
163+
GlobalModuleDependenciesCache &cache);
164164

165165
/// Tries to read the dependency graph from the given path name.
166166
/// Returns true if there was an error.
167167
bool readInterModuleDependenciesCache(llvm::StringRef path,
168-
ModuleDependenciesCache &cache);
168+
GlobalModuleDependenciesCache &cache);
169169

170170
/// Tries to write the dependency graph to the given path name.
171171
/// Returns true if there was an error.
172172
bool writeInterModuleDependenciesCache(DiagnosticEngine &diags,
173173
llvm::StringRef path,
174-
const ModuleDependenciesCache &cache);
174+
const GlobalModuleDependenciesCache &cache);
175175

176176
/// Tries to write out the given dependency cache with the given
177177
/// bitstream writer.
178178
void writeInterModuleDependenciesCache(llvm::BitstreamWriter &Out,
179-
const ModuleDependenciesCache &cache);
179+
const GlobalModuleDependenciesCache &cache);
180180

181181
} // end namespace module_dependency_cache_serialization
182182
} // end namespace dependencies

include/swift/Frontend/FrontendOptions.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,6 @@ class FrontendOptions {
310310
/// Emit remarks indicating use of the serialized module dependency scanning cache
311311
bool EmitDependencyScannerCacheRemarks = false;
312312

313-
/// After performing a dependency scanning action, serialize and deserialize the
314-
/// dependency cache before producing the result.
315-
bool TestDependencyScannerCacheSerialization = false;
316-
317313
/// When performing an incremental build, ensure that cross-module incremental
318314
/// build metadata is available in any swift modules emitted by this frontend
319315
/// job.

0 commit comments

Comments
 (0)