Skip to content

Commit 9d66ae6

Browse files
authored
Merge pull request #68252 from artemcm/ParallelScan
[Dependency Scanning] Implement parallel imported module resolution
2 parents 9c53465 + b4dfb6b commit 9d66ae6

32 files changed

+1911
-1535
lines changed

include/swift/AST/ASTContext.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ namespace swift {
9292
class LazyIterableDeclContextData;
9393
class LazyMemberLoader;
9494
struct MacroDiscriminatorContext;
95-
class ModuleDependencyInfo;
9695
class PatternBindingDecl;
9796
class PatternBindingInitializer;
9897
class PluginLoader;
@@ -1045,27 +1044,6 @@ class ASTContext final {
10451044
/// Retrieve the module interface checker associated with this AST context.
10461045
ModuleInterfaceChecker *getModuleInterfaceChecker() const;
10471046

1048-
/// Retrieve the module dependencies for the module with the given name.
1049-
///
1050-
llvm::Optional<const ModuleDependencyInfo *> getModuleDependencies(
1051-
StringRef moduleName, ModuleDependenciesCache &cache,
1052-
InterfaceSubContextDelegate &delegate,
1053-
bool optionalDependencyLookup = false, bool isTestableImport = false,
1054-
llvm::Optional<std::pair<std::string, swift::ModuleDependencyKind>>
1055-
dependencyOf = llvm::None);
1056-
1057-
/// Retrieve the module dependencies for the Clang module with the given name.
1058-
llvm::Optional<const ModuleDependencyInfo *>
1059-
getClangModuleDependencies(StringRef moduleName,
1060-
ModuleDependenciesCache &cache,
1061-
InterfaceSubContextDelegate &delegate);
1062-
1063-
/// Retrieve the module dependencies for the Swift module with the given name.
1064-
llvm::Optional<const ModuleDependencyInfo *>
1065-
getSwiftModuleDependencies(StringRef moduleName,
1066-
ModuleDependenciesCache &cache,
1067-
InterfaceSubContextDelegate &delegate);
1068-
10691047
/// Compute the extra implicit framework search paths on Apple platforms:
10701048
/// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
10711049
std::vector<std::string> getDarwinImplicitFrameworkSearchPaths() const;

include/swift/AST/ModuleDependencies.h

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "llvm/Support/VirtualFileSystem.h"
4040
#include <string>
4141
#include <unordered_map>
42+
#include <unordered_set>
4243
#include <vector>
4344

4445
namespace swift {
@@ -86,17 +87,38 @@ enum class ModuleDependencyKind : int8_t {
8687
LastKind = SwiftPlaceholder + 1
8788
};
8889

89-
using ModuleDependencyID = std::pair<std::string, ModuleDependencyKind>;
90-
using ModuleDependencyIDSetVector =
91-
llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
92-
std::set<ModuleDependencyID>>;
90+
/// This is used to identify a specific module.
91+
struct ModuleDependencyID {
92+
std::string ModuleName;
93+
ModuleDependencyKind Kind;
94+
bool operator==(const ModuleDependencyID &Other) const {
95+
return std::tie(ModuleName, Kind) ==
96+
std::tie(Other.ModuleName, Other.Kind);
97+
}
98+
bool operator<(const ModuleDependencyID& Other) const {
99+
return std::tie(ModuleName, Kind) <
100+
std::tie(Other.ModuleName, Other.Kind);
101+
}
102+
};
93103

94104
struct ModuleDependencyKindHash {
95105
std::size_t operator()(ModuleDependencyKind k) const {
96106
using UnderlyingType = std::underlying_type<ModuleDependencyKind>::type;
97107
return std::hash<UnderlyingType>{}(static_cast<UnderlyingType>(k));
98108
}
99109
};
110+
struct ModuleDependencyIDHash {
111+
std::size_t operator()(ModuleDependencyID id) const {
112+
return llvm::hash_combine(id.ModuleName, id.Kind);
113+
}
114+
};
115+
116+
using ModuleDependencyIDSet =
117+
std::unordered_set<ModuleDependencyID,
118+
ModuleDependencyIDHash>;
119+
using ModuleDependencyIDSetVector =
120+
llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
121+
std::set<ModuleDependencyID>>;
100122

101123
namespace dependencies {
102124
std::string createEncodedModuleKindAndName(ModuleDependencyID id);
@@ -645,6 +667,9 @@ class ModuleDependencyInfo {
645667
/// Whether the dependencies are for a Swift module: either Textual, Source, Binary, or Placeholder.
646668
bool isSwiftModule() const;
647669

670+
/// Whether the dependencies are for a textual interface Swift module or a Source Swift module.
671+
bool isTextualSwiftModule() const;
672+
648673
/// Whether the dependencies are for a textual Swift module.
649674
bool isSwiftInterfaceModule() const;
650675

@@ -750,6 +775,7 @@ class ModuleDependencyInfo {
750775
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName) const;
751776
};
752777

778+
using ModuleDependencyVector = llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>;
753779
using ModuleNameToDependencyMap = llvm::StringMap<ModuleDependencyInfo>;
754780
using ModuleDependenciesKindMap =
755781
std::unordered_map<ModuleDependencyKind,
@@ -861,6 +887,7 @@ class SwiftDependencyScanningService {
861887
}
862888

863889
bool usingCachingFS() const { return !UseClangIncludeTree && (bool)CacheFS; }
890+
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> getCachingFS() const { return CacheFS; }
864891

865892
llvm::cas::CachingOnDiskFileSystem &getSharedCachingFS() const {
866893
assert(CacheFS && "Expect CachingOnDiskFileSystem");
@@ -895,9 +922,10 @@ class SwiftDependencyScanningService {
895922
/// Enforce clients not being allowed to query this cache directly, it must be
896923
/// wrapped in an instance of `ModuleDependenciesCache`.
897924
friend class ModuleDependenciesCache;
925+
friend class ModuleDependencyScanner;
926+
friend class ModuleDependencyScanningWorker;
898927
friend class ModuleDependenciesCacheDeserializer;
899928
friend class ModuleDependenciesCacheSerializer;
900-
friend class DependencyScanningTool;
901929

902930
/// Configure the current state of the cache to respond to queries
903931
/// for the specified scanning context hash.
@@ -964,8 +992,6 @@ class ModuleDependenciesCache {
964992
std::string scannerContextHash;
965993
/// The location of where the built modules will be output to
966994
std::string moduleOutputPath;
967-
/// The Clang dependency scanner tool
968-
clang::tooling::dependencies::DependencyScanningTool clangScanningTool;
969995

970996
/// Retrieve the dependencies map that corresponds to the given dependency
971997
/// kind.
@@ -983,38 +1009,60 @@ class ModuleDependenciesCache {
9831009
ModuleDependenciesCache &operator=(const ModuleDependenciesCache &) = delete;
9841010

9851011
public:
1012+
/// Whether we have cached dependency information for the given module.
1013+
bool hasDependency(const ModuleDependencyID &moduleID) const;
9861014
/// Whether we have cached dependency information for the given module.
9871015
bool hasDependency(StringRef moduleName,
9881016
llvm::Optional<ModuleDependencyKind> kind) const;
1017+
/// Whether we have cached dependency information for the given module Name.
1018+
bool hasDependency(StringRef moduleName) const;
9891019

990-
/// Produce a reference to the Clang scanner tool associated with this cache
991-
clang::tooling::dependencies::DependencyScanningTool& getClangScannerTool() {
992-
return clangScanningTool;
993-
}
9941020
SwiftDependencyScanningService &getScanService() {
9951021
return globalScanningService;
9961022
}
997-
llvm::DenseSet<clang::tooling::dependencies::ModuleID>& getAlreadySeenClangModules() {
1023+
const SwiftDependencyScanningService &getScanService() const {
1024+
return globalScanningService;
1025+
}
1026+
const llvm::DenseSet<clang::tooling::dependencies::ModuleID>& getAlreadySeenClangModules() const {
9981027
return alreadySeenClangModules;
9991028
}
10001029
void addSeenClangModule(clang::tooling::dependencies::ModuleID newModule) {
10011030
alreadySeenClangModules.insert(newModule);
10021031
}
1003-
std::string getModuleOutputPath() {
1032+
std::string getModuleOutputPath() const {
10041033
return moduleOutputPath;
10051034
}
10061035

1036+
/// Query all dependencies, direct and Swift overlay.
1037+
std::vector<ModuleDependencyID>
1038+
getAllDependencies(const ModuleDependencyID &moduleID) const;
1039+
1040+
/// Look for module dependencies for a module with the given ID
1041+
///
1042+
/// \returns the cached result, or \c None if there is no cached entry.
1043+
llvm::Optional<const ModuleDependencyInfo *>
1044+
findDependency(const ModuleDependencyID moduleID) const;
1045+
10071046
/// Look for module dependencies for a module with the given name
10081047
///
10091048
/// \returns the cached result, or \c None if there is no cached entry.
10101049
llvm::Optional<const ModuleDependencyInfo *>
10111050
findDependency(StringRef moduleName,
10121051
llvm::Optional<ModuleDependencyKind> kind) const;
10131052

1053+
/// Look for module dependencies for a module with the given name
1054+
///
1055+
/// \returns the cached result, or \c None if there is no cached entry.
1056+
llvm::Optional<const ModuleDependencyInfo *>
1057+
findDependency(StringRef moduleName) const;
1058+
10141059
/// Record dependencies for the given module.
10151060
void recordDependency(StringRef moduleName,
10161061
ModuleDependencyInfo dependencies);
10171062

1063+
/// Record dependencies for the given module collection.
1064+
void recordDependencies(ModuleDependencyVector moduleDependencies);
1065+
10181066
/// Update stored dependencies for the given module.
10191067
void updateDependency(ModuleDependencyID moduleID,
10201068
ModuleDependencyInfo dependencies);
@@ -1039,12 +1087,8 @@ class ModuleDependenciesCache {
10391087
namespace std {
10401088
template <>
10411089
struct hash<swift::ModuleDependencyID> {
1042-
using UnderlyingKindType = std::underlying_type<swift::ModuleDependencyKind>::type;
10431090
std::size_t operator()(const swift::ModuleDependencyID &id) const {
1044-
auto underlyingKindValue = static_cast<UnderlyingKindType>(id.second);
1045-
1046-
return (hash<string>()(id.first) ^
1047-
(hash<UnderlyingKindType>()(underlyingKindValue)));
1091+
return llvm::hash_combine(id.ModuleName, id.Kind);
10481092
}
10491093
};
10501094
} // namespace std

include/swift/AST/ModuleLoader.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/ADT/SetVector.h"
2929
#include "llvm/ADT/StringSet.h"
3030
#include "llvm/ADT/TinyPtrVector.h"
31+
#include "llvm/ADT/IntrusiveRefCntPtr.h"
3132
#include "llvm/Support/VersionTuple.h"
3233
#include <system_error>
3334

@@ -36,10 +37,19 @@ class FileCollectorBase;
3637
namespace vfs {
3738
class OutputBackend;
3839
}
40+
namespace cas {
41+
class CachingOnDiskFileSystem;
42+
}
3943
}
4044

4145
namespace clang {
4246
class DependencyCollector;
47+
namespace tooling {
48+
namespace dependencies {
49+
struct ModuleID;
50+
class DependencyScanningTool;
51+
}
52+
}
4353
}
4454

4555
namespace swift {
@@ -51,6 +61,7 @@ class ClassDecl;
5161
class FileUnit;
5262
class ModuleDecl;
5363
class ModuleDependencyInfo;
64+
struct ModuleDependencyID;
5465
class ModuleDependenciesCache;
5566
class NominalTypeDecl;
5667
class SourceFile;
@@ -327,8 +338,12 @@ class ModuleLoader {
327338

328339
/// Retrieve the dependencies for the given, named module, or \c None
329340
/// if no such module exists.
330-
virtual llvm::Optional<const ModuleDependencyInfo *>
331-
getModuleDependencies(StringRef moduleName, ModuleDependenciesCache &cache,
341+
virtual llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
342+
getModuleDependencies(StringRef moduleName,
343+
StringRef moduleOutputPath,
344+
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
345+
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
346+
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
332347
InterfaceSubContextDelegate &delegate,
333348
bool isTestableImport = false) = 0;
334349
};

include/swift/ClangImporter/ClangImporter.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class FuncDecl;
7575
class ImportDecl;
7676
class IRGenOptions;
7777
class ModuleDecl;
78+
struct ModuleDependencyID;
7879
class NominalTypeDecl;
7980
class StructDecl;
8081
class SwiftLookupTable;
@@ -433,32 +434,37 @@ class ClangImporter final : public ClangModuleLoader {
433434

434435
void verifyAllModules() override;
435436

436-
void recordModuleDependencies(
437-
ModuleDependenciesCache &cache,
438-
const clang::tooling::dependencies::ModuleDepsGraph &clangDependencies);
437+
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1> bridgeClangModuleDependencies(
438+
const clang::tooling::dependencies::ModuleDepsGraph &clangDependencies,
439+
StringRef moduleOutputPath);
440+
441+
llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>
442+
getModuleDependencies(StringRef moduleName, StringRef moduleOutputPath,
443+
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS,
444+
const llvm::DenseSet<clang::tooling::dependencies::ModuleID> &alreadySeenClangModules,
445+
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
446+
InterfaceSubContextDelegate &delegate,
447+
bool isTestableImport = false) override;
439448

440449
void recordBridgingHeaderOptions(
441450
ModuleDependencyInfo &MDI,
442451
const clang::tooling::dependencies::TranslationUnitDeps &deps);
443452

444-
llvm::Optional<const ModuleDependencyInfo *>
445-
getModuleDependencies(StringRef moduleName, ModuleDependenciesCache &cache,
446-
InterfaceSubContextDelegate &delegate,
447-
bool isTestableImport = false) override;
448-
449453
/// Add dependency information for the bridging header.
450454
///
451-
/// \param moduleName the name of the Swift module whose dependency
455+
/// \param moduleID the name of the Swift module whose dependency
452456
/// information will be augmented with information about the given
453457
/// bridging header.
454458
///
459+
/// \param clangScanningTool The clang dependency scanner.
460+
///
455461
/// \param cache The module dependencies cache to update, with information
456462
/// about new Clang modules discovered along the way.
457463
///
458464
/// \returns \c true if an error occurred, \c false otherwise
459465
bool addBridgingHeaderDependencies(
460-
StringRef moduleName,
461-
ModuleDependencyKind moduleKind,
466+
ModuleDependencyID moduleID,
467+
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
462468
ModuleDependenciesCache &cache);
463469
clang::TargetInfo &getModuleAvailabilityTarget() const override;
464470
clang::ASTContext &getClangASTContext() const override;

0 commit comments

Comments
 (0)