Skip to content

Commit 62b26b1

Browse files
authored
Merge pull request #62411 from artemcm/BetterDependencyCaching-ContextHash
[Dependency Scanning] Simplify the persistent dependency scanning cache
2 parents 395064f + f39c638 commit 62b26b1

17 files changed

+323
-444
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,12 @@ class IRGenOptions {
554554
return llvm::hash_value(0);
555555
}
556556

557+
/// Return a hash code of any components from these options that should
558+
/// contribute to a Swift Dependency Scanning hash.
559+
llvm::hash_code getModuleScanningHashComponents() const {
560+
return llvm::hash_value(0);
561+
}
562+
557563
bool hasMultipleIRGenThreads() const { return !UseSingleModuleLLVMEmission && NumThreads > 1; }
558564
bool shouldPerformIRGenerationInParallel() const { return !UseSingleModuleLLVMEmission && NumThreads != 0; }
559565
bool hasMultipleIGMs() const { return hasMultipleIRGenThreads(); }

include/swift/AST/ModuleDependencies.h

Lines changed: 55 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@ struct ModuleDependenciesKindHash {
7676
}
7777
};
7878

79-
/// Details of a given module used for dependency scanner cache queries.
80-
struct ModuleLookupSpecifics {
81-
Optional<ModuleDependenciesKind> kind;
82-
llvm::StringSet<> currentSearchPaths;
83-
};
84-
8579
/// Base class for the variant storage of ModuleDependencies.
8680
///
8781
/// This class is mostly an implementation detail for \c ModuleDependencies.
@@ -331,6 +325,7 @@ class ModuleDependencies {
331325
: storage(std::move(storage)) { }
332326

333327
public:
328+
ModuleDependencies() = default;
334329
ModuleDependencies(const ModuleDependencies &other)
335330
: storage(other.storage->clone()) { }
336331
ModuleDependencies(ModuleDependencies &&other) = default;
@@ -481,9 +476,10 @@ class ModuleDependencies {
481476

482477
using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
483478
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
479+
using ModuleNameToDependencyMap = llvm::StringMap<ModuleDependencies>;
484480
using ModuleDependenciesKindMap =
485481
std::unordered_map<ModuleDependenciesKind,
486-
llvm::StringMap<ModuleDependenciesVector>,
482+
ModuleNameToDependencyMap,
487483
ModuleDependenciesKindHash>;
488484
using ModuleDependenciesKindRefMap =
489485
std::unordered_map<ModuleDependenciesKind,
@@ -497,20 +493,15 @@ using ModuleDependenciesKindRefMap =
497493
/// `DependencyScanningTool`). It is not to be queried directly, but is rather
498494
/// meant to be wrapped in an instance of `ModuleDependenciesCache`, responsible
499495
/// for recording new dependencies and answering cache queries in a given scan.
500-
/// Queries to this cache must be disambiguated with a set of search paths to
501-
/// ensure that the returned cached dependency was one that can be found in the
502-
/// current scanning action's filesystem view.
503496
class GlobalModuleDependenciesCache {
504-
/// Global cache contents specific to a target-triple specified on a scanner invocation
505-
struct TargetSpecificGlobalCacheState {
497+
/// Global cache contents specific to a specific scanner invocation context
498+
struct ContextSpecificGlobalCacheState {
506499
/// All cached module dependencies, in the order in which they were
507500
/// encountered.
508501
std::vector<ModuleDependencyID> AllModules;
509502

510503
/// Dependencies for modules that have already been computed.
511-
/// This maps a dependency kind to a map of a module's name to a vector of Dependency objects,
512-
/// which correspond to instances of the same module that may have been found
513-
/// in different sets of search paths.
504+
/// This maps a dependency kind to a map of a module's name to a Dependency object
514505
ModuleDependenciesKindMap ModuleDependenciesMap;
515506
};
516507

@@ -522,23 +513,23 @@ class GlobalModuleDependenciesCache {
522513

523514
/// Dependencies for all Swift source-based modules discovered. Each one is the main
524515
/// module of a prior invocation of the scanner.
525-
llvm::StringMap<ModuleDependencies> SwiftSourceModuleDependenciesMap;
516+
ModuleNameToDependencyMap SwiftSourceModuleDependenciesMap;
526517

527518
/// A map from a String representing the target triple of a scanner invocation to the corresponding
528519
/// cached dependencies discovered so far when using this triple.
529-
llvm::StringMap<std::unique_ptr<TargetSpecificGlobalCacheState>> TargetSpecificCacheMap;
520+
llvm::StringMap<std::unique_ptr<ContextSpecificGlobalCacheState>> ContextSpecificCacheMap;
530521

531-
/// The current target triple cache configuration
532-
Optional<std::string> CurrentTriple;
522+
/// The current context hash configuration
523+
Optional<std::string> CurrentContextHash;
533524

534-
/// The triples used by scanners using this cache, in the order in which they were used
535-
std::vector<std::string> AllTriples;
525+
/// The context hashes used by scanners using this cache, in the order in which they were used
526+
std::vector<std::string> AllContextHashes;
536527

537528
/// Retrieve the dependencies map that corresponds to the given dependency
538529
/// kind.
539-
llvm::StringMap<ModuleDependenciesVector> &
530+
ModuleNameToDependencyMap &
540531
getDependenciesMap(ModuleDependenciesKind kind);
541-
const llvm::StringMap<ModuleDependenciesVector> &
532+
const ModuleNameToDependencyMap &
542533
getDependenciesMap(ModuleDependenciesKind kind) const;
543534

544535
public:
@@ -548,47 +539,43 @@ class GlobalModuleDependenciesCache {
548539
operator=(const GlobalModuleDependenciesCache &) = delete;
549540
virtual ~GlobalModuleDependenciesCache() {}
550541

551-
void configureForTriple(std::string triple);
552-
553-
const std::vector<std::string>& getAllTriples() const {
554-
return AllTriples;
555-
}
556-
557542
private:
558543
/// Enforce clients not being allowed to query this cache directly, it must be
559544
/// wrapped in an instance of `ModuleDependenciesCache`.
560545
friend class ModuleDependenciesCache;
546+
friend class ModuleDependenciesCacheDeserializer;
547+
friend class ModuleDependenciesCacheSerializer;
548+
549+
/// Configure the current state of the cache to respond to queries
550+
/// for the specified scanning context hash.
551+
void configureForContextHash(std::string scanningContextHash);
552+
553+
/// Return context hashes of all scanner invocations that have used
554+
/// this cache instance.
555+
const std::vector<std::string>& getAllContextHashes() const {
556+
return AllContextHashes;
557+
}
561558

562559
/// Whether we have cached dependency information for the given module.
563560
bool hasDependencies(StringRef moduleName,
564-
ModuleLookupSpecifics details) const;
561+
Optional<ModuleDependenciesKind> kind) const;
565562

566-
/// Look for module dependencies for a module with the given name given
567-
/// current search paths.
568-
///
569-
/// \returns the cached result, or \c None if there is no cached entry.
570-
Optional<ModuleDependencies>
571-
findDependencies(StringRef moduleName, ModuleLookupSpecifics details) const;
563+
/// Return a pointer to the context-specific cache state of the current scanning action.
564+
ContextSpecificGlobalCacheState* getCurrentCache() const;
572565

573-
/// Return a pointer to the target-specific cache state of the current triple configuration.
574-
TargetSpecificGlobalCacheState* getCurrentCache() const;
566+
/// Return a pointer to the cache state of the specified context hash.
567+
ContextSpecificGlobalCacheState* getCacheForScanningContextHash(StringRef scanningContextHash) const;
575568

576-
/// Return a pointer to the target-specific cache state of the specified triple configuration.
577-
TargetSpecificGlobalCacheState* getCacheForTriple(StringRef triple) const;
569+
/// Look for source-based module dependency details
570+
Optional<ModuleDependencies>
571+
findSourceModuleDependency(StringRef moduleName) const;
578572

579-
public:
580-
/// Look for module dependencies for a module with the given name.
581-
/// This method has a deliberately-obtuse name to indicate that it is not to
582-
/// be used for general queries.
573+
/// Look for module dependencies for a module with the given name
583574
///
584575
/// \returns the cached result, or \c None if there is no cached entry.
585-
Optional<ModuleDependenciesVector>
586-
findAllDependenciesIrrespectiveOfSearchPaths(
587-
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const;
588-
589-
/// Look for source-based module dependency details
590576
Optional<ModuleDependencies>
591-
findSourceModuleDependency(StringRef moduleName) const;
577+
findDependencies(StringRef moduleName,
578+
Optional<ModuleDependenciesKind> kind) const;
592579

593580
/// Record dependencies for the given module.
594581
const ModuleDependencies *recordDependencies(StringRef moduleName,
@@ -600,9 +587,9 @@ class GlobalModuleDependenciesCache {
600587

601588
/// Reference the list of all module dependencies that are not source-based modules
602589
/// (i.e. interface dependencies, binary dependencies, clang dependencies).
603-
const std::vector<ModuleDependencyID> &getAllNonSourceModules(StringRef triple) const {
604-
auto targetSpecificCache = getCacheForTriple(triple);
605-
return targetSpecificCache->AllModules;
590+
const std::vector<ModuleDependencyID> &getAllNonSourceModules(StringRef scanningContextHash) const {
591+
auto contextSpecificCache = getCacheForScanningContextHash(scanningContextHash);
592+
return contextSpecificCache->AllModules;
606593
}
607594

608595
/// Return the list of all source-based modules discovered by this cache
@@ -616,8 +603,7 @@ class GlobalModuleDependenciesCache {
616603
/// scanning action, and wraps an instance of a `GlobalModuleDependenciesCache`
617604
/// which may carry cached scanning information from prior scanning actions.
618605
/// This cache maintains a store of references to all dependencies found within
619-
/// the current scanning action (with their values stored in the global Cache),
620-
/// since these do not require clients to disambiguate them with search paths.
606+
/// the current scanning action (with their values stored in the global Cache).
621607
class ModuleDependenciesCache {
622608
private:
623609
GlobalModuleDependenciesCache &globalCache;
@@ -628,12 +614,14 @@ class ModuleDependenciesCache {
628614
ModuleDependenciesKindRefMap ModuleDependenciesMap;
629615

630616
/// Name of the module under scan
631-
StringRef mainScanModuleName;
617+
std::string mainScanModuleName;
618+
/// The context hash of the current scanning invocation
619+
std::string scannerContextHash;
620+
632621
/// Set containing all of the Clang modules that have already been seen.
633622
llvm::StringSet<> alreadySeenClangModules;
634623
/// The Clang dependency scanner tool
635624
clang::tooling::dependencies::DependencyScanningTool clangScanningTool;
636-
637625
/// Discovered Clang modules are only cached locally.
638626
llvm::StringMap<ModuleDependenciesVector> clangModuleDependencies;
639627

@@ -646,25 +634,26 @@ class ModuleDependenciesCache {
646634

647635
/// Local cache results lookup, only for modules which were discovered during
648636
/// the current scanner invocation.
649-
bool hasDependencies(StringRef moduleName,
650-
Optional<ModuleDependenciesKind> kind) const;
637+
bool hasDependenciesLocalOnly(StringRef moduleName,
638+
Optional<ModuleDependenciesKind> kind) const;
651639

652640
/// Local cache results lookup, only for modules which were discovered during
653641
/// the current scanner invocation.
654642
Optional<const ModuleDependencies *>
655-
findDependencies(StringRef moduleName,
656-
Optional<ModuleDependenciesKind> kind) const;
643+
findDependenciesLocalOnly(StringRef moduleName,
644+
Optional<ModuleDependenciesKind> kind) const;
657645

658646
public:
659647
ModuleDependenciesCache(GlobalModuleDependenciesCache &globalCache,
660-
StringRef mainScanModuleName);
648+
std::string mainScanModuleName,
649+
std::string scanningContextHash);
661650
ModuleDependenciesCache(const ModuleDependenciesCache &) = delete;
662651
ModuleDependenciesCache &operator=(const ModuleDependenciesCache &) = delete;
663652

664653
public:
665654
/// Whether we have cached dependency information for the given module.
666655
bool hasDependencies(StringRef moduleName,
667-
ModuleLookupSpecifics details) const;
656+
Optional<ModuleDependenciesKind> kind) const;
668657

669658
/// Produce a reference to the Clang scanner tool associated with this cache
670659
clang::tooling::dependencies::DependencyScanningTool& getClangScannerTool() {
@@ -674,24 +663,12 @@ class ModuleDependenciesCache {
674663
return alreadySeenClangModules;
675664
}
676665

677-
/// Look for module dependencies for a module with the given name given
678-
/// current search paths.
666+
/// Look for module dependencies for a module with the given name
679667
///
680668
/// \returns the cached result, or \c None if there is no cached entry.
681669
Optional<ModuleDependencies>
682-
findDependencies(StringRef moduleName, ModuleLookupSpecifics details) const;
683-
684-
/// Look for module dependencies for a module with the given name.
685-
/// This method has a deliberately-obtuse name to indicate that it is not to
686-
/// be used for general queries.
687-
///
688-
/// \returns the cached result, or \c None if there is no cached entry.
689-
Optional<ModuleDependenciesVector>
690-
findAllDependenciesIrrespectiveOfSearchPaths(
691-
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const {
692-
return globalCache.findAllDependenciesIrrespectiveOfSearchPaths(moduleName,
693-
kind);
694-
}
670+
findDependencies(StringRef moduleName,
671+
Optional<ModuleDependenciesKind> kind) const;
695672

696673
/// Record dependencies for the given module.
697674
void recordDependencies(StringRef moduleName,

include/swift/AST/SILOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ class SILOptions {
281281
return llvm::hash_value(0);
282282
}
283283

284+
/// Return a hash code of any components from these options that should
285+
/// contribute to a Swift Dependency Scanning hash.
286+
llvm::hash_code getModuleScanningHashComponents() const {
287+
return llvm::hash_value(0);
288+
}
289+
284290
bool shouldOptimize() const {
285291
return OptMode > OptimizationMode::NoOptimization;
286292
}

include/swift/AST/SearchPathOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,12 @@ class SearchPathOptions {
421421
RuntimeLibraryImportPaths.end()),
422422
DisableModulesValidateSystemDependencies);
423423
}
424+
425+
/// Return a hash code of any components from these options that should
426+
/// contribute to a Swift Dependency Scanning hash.
427+
llvm::hash_code getModuleScanningHashComponents() const {
428+
return getPCHHashComponents();
429+
}
424430
};
425431
}
426432

include/swift/Basic/DiagnosticOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ class DiagnosticOptions {
8686
// Nothing here that contributes anything significant when emitting the PCH.
8787
return llvm::hash_value(0);
8888
}
89+
90+
/// Return a hash code of any components from these options that should
91+
/// contribute to a Swift Dependency Scanning hash.
92+
llvm::hash_code getModuleScanningHashComponents() const {
93+
return llvm::hash_value(0);
94+
}
8995
};
9096

9197
} // end namespace swift

include/swift/Basic/LangOptions.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,12 @@ namespace swift {
628628
return llvm::hash_combine(Target.str(), OS.str());
629629
}
630630

631+
/// Return a hash code of any components from these options that should
632+
/// contribute to a Swift Dependency Scanning hash.
633+
llvm::hash_code getModuleScanningHashComponents() const {
634+
return getPCHHashComponents();
635+
}
636+
631637
private:
632638
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>, 6>
633639
PlatformConditionValues;
@@ -832,6 +838,12 @@ namespace swift {
832838
EnableClangSPI);
833839
}
834840

841+
/// Return a hash code of any components from these options that should
842+
/// contribute to a Swift Dependency Scanning hash.
843+
llvm::hash_code getModuleScanningHashComponents() const {
844+
return getPCHHashComponents();
845+
}
846+
835847
std::vector<std::string> getRemappedExtraArgs(
836848
std::function<std::string(StringRef)> pathRemapCallback) const;
837849
};

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ using llvm::BCRecordLayout;
3535
using llvm::BCVBR;
3636

3737
/// Every .moddepcache file begins with these 4 bytes, for easy identification.
38-
const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D',
39-
'C'};
40-
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 2;
38+
const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D','C'};
39+
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 3;
4140
/// Increment this on every change.
4241
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 0;
4342

@@ -56,7 +55,7 @@ using IdentifierIDArryField = llvm::BCArray<IdentifierIDField>;
5655

5756
/// Identifiers used to refer to the above arrays
5857
using FileIDArrayIDField = IdentifierIDField;
59-
using TripleIDField = IdentifierIDField;
58+
using ContextHashIDField = IdentifierIDField;
6059
using DependencyIDArrayIDField = IdentifierIDField;
6160
using FlagIDArrayIDField = IdentifierIDField;
6261

@@ -118,7 +117,7 @@ using IdentifierArrayLayout =
118117
using ModuleInfoLayout =
119118
BCRecordLayout<MODULE_NODE, // ID
120119
IdentifierIDField, // module name
121-
TripleIDField, // target triple
120+
ContextHashIDField, //
122121
DependencyIDArrayIDField // directDependencies
123122
>;
124123

include/swift/Frontend/Frontend.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ class CompilerInvocation {
345345
/// in generating a cached PCH file for the bridging header.
346346
std::string getPCHHash() const;
347347

348+
/// Retrieve a module hash string that is suitable for uniquely
349+
/// identifying the conditions under which the current module is built,
350+
/// from the perspective of a dependency scanning action.
351+
std::string getModuleScanningHash() const;
352+
348353
/// Retrieve the stdlib kind to implicitly import.
349354
ImplicitStdlibKind getImplicitStdlibKind() const {
350355
if (FrontendOpts.InputMode == FrontendOptions::ParseInputMode::SIL) {

include/swift/Frontend/FrontendOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,12 @@ class FrontendOptions {
430430
return llvm::hash_value(0);
431431
}
432432

433+
/// Return a hash code of any components from these options that should
434+
/// contribute to a Swift Dependency Scanning hash.
435+
llvm::hash_code getModuleScanningHashComponents() const {
436+
return llvm::hash_value(0);
437+
}
438+
433439
StringRef determineFallbackModuleName() const;
434440

435441
bool isCompilingExactlyOneSwiftFile() const {

0 commit comments

Comments
 (0)