Skip to content

Commit 7426a4f

Browse files
committed
[Dependency Scanning] Re-use cached queried Clang dependency info in subsequent scanning stages
Dependency Scanning is recursive over discovered Swift module overlays and cross-import overlays. In the main 'resolveImportedModuleDependencies' routine, after all Swift and Clang dependencies of the main module are discovered, the scanner looks up Swift overlays for discovered Clang modules. For each such Swift overlay, the scanner will then proceed to call 'resolveImportedModuleDependencies' on the overlay module. On these subsequent recursive calls to 'resolveImportedModuleDependencies', Clang dependency resolution will re-query all imports of the overlay module which do not resolve to Swift modules, even if they had been queried previously in a parent invocation. This change adds the ability to re-use previously-queried-and-cached Clang module dependency information by having the dependency cache also store the set of visible modules which resulted from each by-name lookup.
1 parent 6628635 commit 7426a4f

File tree

7 files changed

+228
-145
lines changed

7 files changed

+228
-145
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class ModuleDependencyInfoStorageBase {
280280
/// A list of Clang modules that are visible to this Swift module. This
281281
/// includes both direct Clang modules as well as transitive Clang
282282
/// module dependencies when they are exported
283-
llvm::StringSet<> visibleClangModules;
283+
std::vector<std::string> bridgingHeaderVisibleClangModules;
284284

285285
/// ModuleDependencyInfo is finalized (with all transitive dependencies
286286
/// and inputs).
@@ -893,14 +893,12 @@ class ModuleDependencyInfo {
893893
llvm_unreachable("Unexpected module dependency kind");
894894
}
895895

896-
llvm::StringSet<> &getVisibleClangModules() const {
897-
return storage->visibleClangModules;
896+
ArrayRef<std::string> getHeaderVisibleClangModules() const {
897+
return storage->bridgingHeaderVisibleClangModules;
898898
}
899-
900-
void
901-
addVisibleClangModules(const std::vector<std::string> &moduleNames) const {
902-
storage->visibleClangModules.insert(moduleNames.begin(),
903-
moduleNames.end());
899+
void setHeaderVisibleClangModules(
900+
const std::vector<std::string> &moduleNames) const {
901+
storage->bridgingHeaderVisibleClangModules = moduleNames;
904902
}
905903

906904
/// Whether explicit input paths of all the module dependencies
@@ -1073,6 +1071,9 @@ class ModuleDependenciesCache {
10731071
private:
10741072
/// Discovered dependencies
10751073
ModuleDependenciesKindMap ModuleDependenciesMap;
1074+
/// A map from Clang module name to all visible modules to a client
1075+
/// of a by-name import of this Clang module
1076+
llvm::StringMap<std::vector<std::string>> clangModulesVisibleFromNamedLookup;
10761077
/// Set containing all of the Clang modules that have already been seen.
10771078
llvm::DenseSet<clang::tooling::dependencies::ModuleID> alreadySeenClangModules;
10781079
/// Name of the module under scan
@@ -1111,6 +1112,8 @@ class ModuleDependenciesCache {
11111112
bool hasDependency(StringRef moduleName) const;
11121113
/// Whether we have cached dependency information for the given Swift module.
11131114
bool hasSwiftDependency(StringRef moduleName) const;
1115+
/// Whether we have cached dependency information for the given Clang module.
1116+
bool hasClangDependency(StringRef moduleName) const;
11141117
/// Report the number of recorded Clang dependencies
11151118
int numberOfClangDependencies() const;
11161119
/// Report the number of recorded Swift dependencies
@@ -1152,9 +1155,20 @@ class ModuleDependenciesCache {
11521155
/// Query all cross-import overlay dependencies
11531156
llvm::ArrayRef<ModuleDependencyID>
11541157
getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const;
1158+
11551159
/// Query all visible Clang modules for a given Swift dependency
1156-
llvm::StringSet<>&
1157-
getVisibleClangModules(ModuleDependencyID moduleID) const;
1160+
llvm::StringSet<>
1161+
getAllVisibleClangModules(ModuleDependencyID moduleID) const;
1162+
/// Query all Clang modules visible via a by-name lookup of given
1163+
/// Clang dependency
1164+
llvm::ArrayRef<std::string>
1165+
getVisibleClangModulesFromLookup(StringRef moduleName) const;
1166+
bool hasVisibleClangModulesFromLookup(StringRef moduleName) const;
1167+
/// Query all Clang modules visible from a given Swift module's
1168+
/// bridging header
1169+
llvm::ArrayRef<std::string>
1170+
getVisibleClangModulesViaHeader(ModuleDependencyID moduleID) const;
1171+
bool hasVisibleClangModulesViaHeader(ModuleDependencyID moduleID) const;
11581172

11591173
/// Look for module dependencies for a module with the given ID
11601174
///
@@ -1230,8 +1244,8 @@ class ModuleDependenciesCache {
12301244
const ModuleDependencyIDCollectionView dependencyIDs);
12311245
/// Add to this module's set of visible Clang modules
12321246
void
1233-
addVisibleClangModules(ModuleDependencyID moduleID,
1234-
const std::vector<std::string> &moduleNames);
1247+
setVisibleClangModulesFromLookup(ModuleDependencyID clangModuleID,
1248+
const std::vector<std::string> &moduleNames);
12351249

12361250
StringRef getMainModuleName() const { return mainScanModuleName; }
12371251

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ using ImportStatementInfoMap =
3737
std::unordered_map<ModuleDependencyID,
3838
std::vector<ScannerImportStatementInfo>>;
3939

40+
/// A map from a module ID to a collection of module IDs.
41+
using ModuleIDToModuleIDSetVectorMap =
42+
std::unordered_map<ModuleDependencyID,
43+
ModuleDependencyIDSetVector>;
44+
45+
using ModuleIDImportInfoPair =
46+
std::pair<ModuleDependencyID, ScannerImportStatementInfo>;
47+
4048
struct ScannerMetrics {
4149
/// Number of performed queries for a Swift dependency with a given name
4250
std::atomic<uint32_t> SwiftModuleQueries;
@@ -306,7 +314,7 @@ class ModuleDependencyScanner {
306314
void resolveSwiftModuleDependencies(
307315
const ModuleDependencyID &rootModuleID,
308316
ModuleDependencyIDSetVector &discoveredSwiftModules);
309-
void resolveAllClangModuleDependencies(
317+
void resolveClangModuleDependencies(
310318
ArrayRef<ModuleDependencyID> swiftModules,
311319
ModuleDependencyIDSetVector &discoveredClangModules);
312320
void resolveHeaderDependencies(
@@ -391,25 +399,19 @@ class ModuleDependencyScanner {
391399
/// in \c failedToResolveImports.
392400
/// 4. Update the set of resolved Clang dependencies for each Swift
393401
/// module dependency in \c resolvedClangDependenciesMap.
394-
void cacheComputedClangModuleLookupResults(
402+
void processBatchClangModuleQueryResult(
395403
const BatchClangModuleLookupResult &lookupResult,
396404
const ImportStatementInfoMap &unresolvedImportsMap,
397405
const ImportStatementInfoMap &unresolvedOptionalImportsMap,
398-
ArrayRef<ModuleDependencyID> swiftModuleDependents,
399406
ModuleDependencyIDSetVector &allDiscoveredClangModules,
400-
std::vector<std::pair<ModuleDependencyID, ScannerImportStatementInfo>>
401-
&failedToResolveImports,
402-
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
403-
&resolvedClangDependenciesMap);
407+
std::vector<ModuleIDImportInfoPair> &failedToResolveImports,
408+
ModuleIDToModuleIDSetVectorMap &resolvedClangDependenciesMap);
404409

405410
/// Re-query some failed-to-resolve Clang imports from cache
406411
/// in chance they were brought in as transitive dependencies.
407412
void reQueryMissedModulesFromCache(
408-
const std::vector<
409-
std::pair<ModuleDependencyID, ScannerImportStatementInfo>>
410-
&failedToResolveImports,
411-
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
412-
&resolvedClangDependenciesMap);
413+
const std::vector<ModuleIDImportInfoPair> &failedToResolveImports,
414+
ModuleIDToModuleIDSetVectorMap &resolvedClangDependenciesMap);
413415

414416
/// Assuming the \c `moduleImport` failed to resolve,
415417
/// iterate over all binary Swift module dependencies with serialized

lib/AST/ModuleDependencies.cpp

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,9 @@ bool ModuleDependenciesCache::hasDependency(StringRef moduleName) const {
771771
bool ModuleDependenciesCache::hasSwiftDependency(StringRef moduleName) const {
772772
return findSwiftDependency(moduleName).has_value();
773773
}
774+
bool ModuleDependenciesCache::hasClangDependency(StringRef moduleName) const {
775+
return findDependency(moduleName, ModuleDependencyKind::Clang).has_value();
776+
}
774777

775778
int ModuleDependenciesCache::numberOfClangDependencies() const {
776779
return ModuleDependenciesMap.at(ModuleDependencyKind::Clang).size();
@@ -856,6 +859,16 @@ void ModuleDependenciesCache::recordClangDependency(
856859
}
857860
}
858861

862+
void ModuleDependenciesCache::setVisibleClangModulesFromLookup(
863+
ModuleDependencyID moduleID,
864+
const std::vector<std::string> &visibleModules) {
865+
ASSERT(moduleID.Kind == ModuleDependencyKind::Clang);
866+
if (visibleModules.empty())
867+
return;
868+
869+
clangModulesVisibleFromNamedLookup[moduleID.ModuleName] = visibleModules;
870+
}
871+
859872
void ModuleDependenciesCache::updateDependency(
860873
ModuleDependencyID moduleID, ModuleDependencyInfo dependencyInfo) {
861874
auto &map = getDependenciesMap(moduleID.Kind);
@@ -948,22 +961,55 @@ ModuleDependencyIDCollectionView ModuleDependenciesCache::getAllDependencies(
948961
moduleInfo.getImportedClangDependencies());
949962
}
950963

951-
void ModuleDependenciesCache::addVisibleClangModules(
952-
ModuleDependencyID moduleID, const std::vector<std::string> &moduleNames) {
953-
if (moduleNames.empty())
954-
return;
955-
auto dependencyInfo = findKnownDependency(moduleID);
956-
auto updatedDependencyInfo = dependencyInfo;
957-
updatedDependencyInfo.addVisibleClangModules(moduleNames);
958-
updateDependency(moduleID, updatedDependencyInfo);
964+
llvm::StringSet<> ModuleDependenciesCache::getAllVisibleClangModules(
965+
ModuleDependencyID moduleID) const {
966+
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
967+
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
968+
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
969+
llvm::StringSet<> result;
970+
if (hasVisibleClangModulesViaHeader(moduleID)) {
971+
auto headerVisibleModules = getVisibleClangModulesViaHeader(moduleID);
972+
result.insert(headerVisibleModules.begin(), headerVisibleModules.end());
973+
}
974+
for (const auto &clangDepID :
975+
findKnownDependency(moduleID).getImportedClangDependencies()) {
976+
// FIXME: This scenario should not occur
977+
// assert(hasVisibleClangModulesFrom(clangDepID.ModuleName));
978+
if (hasVisibleClangModulesFromLookup(clangDepID.ModuleName)) {
979+
auto visibleModulesViaImport =
980+
getVisibleClangModulesFromLookup(clangDepID.ModuleName);
981+
result.insert(visibleModulesViaImport.begin(),
982+
visibleModulesViaImport.end());
983+
}
984+
}
985+
return result;
959986
}
960987

961-
llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(
988+
ArrayRef<std::string> ModuleDependenciesCache::getVisibleClangModulesFromLookup(
989+
StringRef moduleName) const {
990+
ASSERT(hasVisibleClangModulesFromLookup(moduleName));
991+
return clangModulesVisibleFromNamedLookup.at(moduleName);
992+
}
993+
994+
bool ModuleDependenciesCache::hasVisibleClangModulesFromLookup(
995+
StringRef moduleName) const {
996+
return clangModulesVisibleFromNamedLookup.contains(moduleName);
997+
}
998+
999+
llvm::ArrayRef<std::string>
1000+
ModuleDependenciesCache::getVisibleClangModulesViaHeader(
1001+
ModuleDependencyID moduleID) const {
1002+
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
1003+
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
1004+
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
1005+
return findKnownDependency(moduleID).getHeaderVisibleClangModules();
1006+
}
1007+
bool ModuleDependenciesCache::hasVisibleClangModulesViaHeader(
9621008
ModuleDependencyID moduleID) const {
9631009
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
9641010
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
9651011
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
966-
return findKnownDependency(moduleID).getVisibleClangModules();
1012+
return !getVisibleClangModulesViaHeader(moduleID).empty();
9671013
}
9681014

9691015
ModuleDependencyIDCollectionView

0 commit comments

Comments
 (0)