Skip to content

Commit fb1b9ae

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. 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 c64b470 commit fb1b9ae

File tree

4 files changed

+126
-42
lines changed

4 files changed

+126
-42
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ class ModuleDependencyInfo {
893893
llvm_unreachable("Unexpected module dependency kind");
894894
}
895895

896-
llvm::StringSet<> &getVisibleClangModules() const {
896+
llvm::StringSet<> getVisibleClangModules() const {
897897
return storage->visibleClangModules;
898898
}
899899

@@ -1076,6 +1076,11 @@ class ModuleDependenciesCache {
10761076
/// A set of module identifiers for which a scanning action failed
10771077
/// to discover a Swift module dependency
10781078
llvm::StringSet<> negativeSwiftDependencyCache;
1079+
1080+
/// A map from Clang module name to all visible modules to a client
1081+
/// of a by-name import of this Clang module
1082+
llvm::StringMap<std::vector<std::string>> clangModulesVisibleFrom;
1083+
10791084
/// Set containing all of the Clang modules that have already been seen.
10801085
llvm::DenseSet<clang::tooling::dependencies::ModuleID> alreadySeenClangModules;
10811086
/// Name of the module under scan
@@ -1153,8 +1158,12 @@ class ModuleDependenciesCache {
11531158
llvm::ArrayRef<ModuleDependencyID>
11541159
getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const;
11551160
/// Query all visible Clang modules for a given Swift dependency
1156-
llvm::StringSet<>&
1161+
llvm::StringSet<>
11571162
getVisibleClangModules(ModuleDependencyID moduleID) const;
1163+
/// Query all Clang modules visible via a by-name lookup of given
1164+
/// Clang dependency
1165+
std::vector<std::string>
1166+
getVisibleClangModulesFrom(ModuleDependencyID moduleID) const;
11581167

11591168
/// Look for module dependencies for a module with the given ID
11601169
///
@@ -1231,7 +1240,11 @@ class ModuleDependenciesCache {
12311240
/// Add to this module's set of visible Clang modules
12321241
void
12331242
addVisibleClangModules(ModuleDependencyID moduleID,
1243+
ModuleDependencyID clangDependencyID,
12341244
const std::vector<std::string> &moduleNames);
1245+
void
1246+
addHeaderVisibleClangModules(ModuleDependencyID moduleID,
1247+
const std::vector<std::string> &moduleNames);
12351248
/// Add an identifier to the set of failed Swift module queries
12361249
void cacheNegativeSwiftDependency(StringRef moduleIdentifier);
12371250

lib/AST/ModuleDependencies.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,34 @@ void ModuleDependenciesCache::recordClangDependency(
850850
}
851851
}
852852

853+
void ModuleDependenciesCache::addHeaderVisibleClangModules(
854+
ModuleDependencyID moduleID,
855+
const std::vector<std::string> &visibleModules) {
856+
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
857+
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
858+
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
859+
860+
if (visibleModules.empty())
861+
return;
862+
auto dependencyInfo = findKnownDependency(moduleID);
863+
auto updatedDependencyInfo = dependencyInfo;
864+
updatedDependencyInfo.addVisibleClangModules(visibleModules);
865+
updateDependency(moduleID, updatedDependencyInfo);
866+
}
867+
868+
void ModuleDependenciesCache::addVisibleClangModules(
869+
ModuleDependencyID moduleID,
870+
ModuleDependencyID clangDependencyID,
871+
const std::vector<std::string> &visibleModules) {
872+
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
873+
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
874+
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
875+
ASSERT(clangDependencyID.Kind == ModuleDependencyKind::Clang);
876+
877+
addHeaderVisibleClangModules(moduleID, visibleModules);
878+
clangModulesVisibleFrom[clangDependencyID.ModuleName] = visibleModules;
879+
}
880+
853881
void ModuleDependenciesCache::updateDependency(
854882
ModuleDependencyID moduleID, ModuleDependencyInfo dependencyInfo) {
855883
auto &map = getDependenciesMap(moduleID.Kind);
@@ -944,29 +972,26 @@ ModuleDependencyIDCollectionView ModuleDependenciesCache::getAllDependencies(
944972
moduleInfo.getImportedClangDependencies());
945973
}
946974

947-
void ModuleDependenciesCache::addVisibleClangModules(
948-
ModuleDependencyID moduleID, const std::vector<std::string> &moduleNames) {
949-
if (moduleNames.empty())
950-
return;
951-
auto dependencyInfo = findKnownDependency(moduleID);
952-
auto updatedDependencyInfo = dependencyInfo;
953-
updatedDependencyInfo.addVisibleClangModules(moduleNames);
954-
updateDependency(moduleID, updatedDependencyInfo);
955-
}
956-
957975
void ModuleDependenciesCache::cacheNegativeSwiftDependency(
958976
StringRef moduleIdentifier) {
959977
negativeSwiftDependencyCache.insert(moduleIdentifier);
960978
}
961979

962-
llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(
980+
llvm::StringSet<> ModuleDependenciesCache::getVisibleClangModules(
963981
ModuleDependencyID moduleID) const {
964982
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
965983
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
966984
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
967985
return findKnownDependency(moduleID).getVisibleClangModules();
968986
}
969987

988+
std::vector<std::string> ModuleDependenciesCache::getVisibleClangModulesFrom(
989+
ModuleDependencyID moduleID) const {
990+
ASSERT(moduleID.Kind == ModuleDependencyKind::Clang);
991+
return clangModulesVisibleFrom.contains(moduleID.ModuleName) ?
992+
clangModulesVisibleFrom.at(moduleID.ModuleName) : std::vector<std::string>() ;
993+
}
994+
970995
ModuleDependencyIDCollectionView
971996
ModuleDependenciesCache::getDirectImportedDependencies(
972997
const ModuleDependencyID &moduleID) const {

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,52 @@ void ModuleDependencyScanner::resolveSwiftModuleDependencies(
961961
return;
962962
}
963963

964-
static void
965-
gatherUnresolvedImports(ModuleDependenciesCache &cache,
966-
ASTContext &scanASTContext,
967-
ArrayRef<ModuleDependencyID> swiftModuleDependents,
968-
ModuleDependencyIDSetVector &allDiscoveredClangModules,
969-
ImportStatementInfoMap &unresolvedImportsMap,
970-
ImportStatementInfoMap &unresolvedOptionalImportsMap) {
964+
static void resolveClangDependenciesFromCache(ModuleDependenciesCache &cache, ASTContext &scanASTContext,
965+
ArrayRef<ModuleDependencyID> swiftModuleDependents,
966+
ModuleDependencyIDSetVector &allDiscoveredClangModules,
967+
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
968+
&resolvedClangDependenciesMap) {
969+
for (const auto &moduleID : swiftModuleDependents) {
970+
auto &moduleDependencyInfo = cache.findKnownDependency(moduleID);
971+
if (!moduleDependencyInfo.getImportedClangDependencies().empty())
972+
continue;
973+
974+
auto resolveImportIfCached = [&](const ScannerImportStatementInfo &importInfo) {
975+
auto dependencyID = ModuleDependencyID{importInfo.importIdentifier,
976+
ModuleDependencyKind::Clang};
977+
auto visibleFromDependencyID = cache.getVisibleClangModulesFrom(dependencyID);
978+
if (cache.hasDependency(dependencyID) &&
979+
!visibleFromDependencyID.empty()) {
980+
cache.addVisibleClangModules(
981+
moduleID, dependencyID, visibleFromDependencyID);
982+
resolvedClangDependenciesMap[moduleID].insert(dependencyID);
983+
}
984+
};
985+
986+
for (const auto &depImport : moduleDependencyInfo.getModuleImports())
987+
resolveImportIfCached(depImport);
988+
for (const auto &depImport : moduleDependencyInfo.getOptionalModuleImports())
989+
resolveImportIfCached(depImport);
990+
}
991+
}
992+
993+
static void findAllReachableClangModules(ModuleDependencyID moduleID,
994+
const ModuleDependenciesCache &cache,
995+
ModuleDependencyIDSetVector &reachableClangModules) {
996+
if (!reachableClangModules.insert(moduleID))
997+
return;
998+
for (const auto &depID : cache.getImportedClangDependencies(moduleID))
999+
findAllReachableClangModules(depID, cache, reachableClangModules);
1000+
}
1001+
1002+
static void gatherUnresolvedImports(
1003+
ModuleDependenciesCache &cache, ASTContext &scanASTContext,
1004+
ArrayRef<ModuleDependencyID> swiftModuleDependents,
1005+
ModuleDependencyIDSetVector &allDiscoveredClangModules,
1006+
ImportStatementInfoMap &unresolvedImportsMap,
1007+
ImportStatementInfoMap &unresolvedOptionalImportsMap,
1008+
const std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
1009+
&resolvedClangDependenciesMap) {
9711010
for (const auto &moduleID : swiftModuleDependents) {
9721011
auto moduleDependencyInfo = cache.findKnownDependency(moduleID);
9731012
auto unresolvedImports =
@@ -986,27 +1025,24 @@ gatherUnresolvedImports(ModuleDependenciesCache &cache,
9861025
if (!moduleDependencyInfo.getImportedClangDependencies().empty()) {
9871026
auto directClangDeps = cache.getImportedClangDependencies(moduleID);
9881027
ModuleDependencyIDSetVector reachableClangModules;
989-
reachableClangModules.insert(directClangDeps.begin(),
990-
directClangDeps.end());
991-
for (unsigned currentModuleIdx = 0;
992-
currentModuleIdx < reachableClangModules.size();
993-
++currentModuleIdx) {
994-
auto moduleID = reachableClangModules[currentModuleIdx];
995-
auto dependencies =
996-
cache.findKnownDependency(moduleID).getImportedClangDependencies();
997-
reachableClangModules.insert(dependencies.begin(), dependencies.end());
998-
}
999-
allDiscoveredClangModules.insert(reachableClangModules.begin(),
1000-
reachableClangModules.end());
1028+
for (const auto &depID : directClangDeps)
1029+
findAllReachableClangModules(depID, cache, reachableClangModules);
1030+
allDiscoveredClangModules.insert(reachableClangModules.getArrayRef().begin(),
1031+
reachableClangModules.getArrayRef().end());
10011032
continue;
10021033
} else {
10031034
// We need to query the Clang dependency scanner for this module's
1004-
// non-Swift imports
1035+
// unresolved imports
10051036
llvm::StringSet<> resolvedImportIdentifiers;
10061037
for (const auto &resolvedDep :
10071038
moduleDependencyInfo.getImportedSwiftDependencies())
10081039
resolvedImportIdentifiers.insert(resolvedDep.ModuleName);
10091040

1041+
if (resolvedClangDependenciesMap.find(moduleID) != resolvedClangDependenciesMap.end())
1042+
for (const auto &cacheResolvedDep :
1043+
resolvedClangDependenciesMap.at(moduleID))
1044+
resolvedImportIdentifiers.insert(cacheResolvedDep.ModuleName);
1045+
10101046
// When querying a *clang* module 'CxxStdlib' we must
10111047
// instead expect a module called 'std'...
10121048
auto addCanonicalClangModuleImport =
@@ -1074,7 +1110,8 @@ void ModuleDependencyScanner::reQueryMissedModulesFromCache(
10741110
resolvedClangDependenciesMap[unresolvedImport.first].insert(
10751111
unresolvedModuleID);
10761112
DependencyCache.addVisibleClangModules(
1077-
unresolvedImport.first, {unresolvedImport.second.importIdentifier});
1113+
unresolvedImport.first, unresolvedModuleID,
1114+
{unresolvedImport.second.importIdentifier});
10781115
} else {
10791116
// Failed to resolve module dependency.
10801117
IssueReporter.diagnoseModuleNotFoundFailure(
@@ -1156,7 +1193,8 @@ void ModuleDependencyScanner::cacheComputedClangModuleLookupResults(
11561193
// Swift module
11571194
if (lookupResult.visibleModules.contains(moduleIdentifier))
11581195
DependencyCache.addVisibleClangModules(
1159-
moduleID, lookupResult.visibleModules.at(moduleIdentifier));
1196+
moduleID, dependencyID,
1197+
lookupResult.visibleModules.at(moduleIdentifier));
11601198

11611199
// Add the resolved dependency ID
11621200
if (lookupResult.discoveredDependencyInfos.contains(
@@ -1204,13 +1242,21 @@ void ModuleDependencyScanner::cacheComputedClangModuleLookupResults(
12041242
void ModuleDependencyScanner::resolveAllClangModuleDependencies(
12051243
ArrayRef<ModuleDependencyID> swiftModuleDependents,
12061244
ModuleDependencyIDSetVector &allDiscoveredClangModules) {
1207-
// Gather all unresolved imports which must correspond to
1245+
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
1246+
resolvedClangDependenciesMap;
1247+
resolveClangDependenciesFromCache(DependencyCache, ScanASTContext,
1248+
swiftModuleDependents,
1249+
allDiscoveredClangModules,
1250+
resolvedClangDependenciesMap);
1251+
1252+
// Gather all remaining unresolved imports which must correspond to
12081253
// Clang modules (since no Swift module for them was found).
12091254
ImportStatementInfoMap unresolvedImportsMap;
12101255
ImportStatementInfoMap unresolvedOptionalImportsMap;
1211-
gatherUnresolvedImports(DependencyCache, ScanASTContext, swiftModuleDependents,
1212-
allDiscoveredClangModules, unresolvedImportsMap,
1213-
unresolvedOptionalImportsMap);
1256+
gatherUnresolvedImports(DependencyCache, ScanASTContext,
1257+
swiftModuleDependents, allDiscoveredClangModules,
1258+
unresolvedImportsMap, unresolvedOptionalImportsMap,
1259+
resolvedClangDependenciesMap);
12141260

12151261
// Execute parallel lookup of all unresolved import
12161262
// identifiers as Clang modules.
@@ -1222,8 +1268,6 @@ void ModuleDependencyScanner::resolveAllClangModuleDependencies(
12221268
// dependencies.
12231269
std::vector<std::pair<ModuleDependencyID, ScannerImportStatementInfo>>
12241270
failedToResolveImports;
1225-
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
1226-
resolvedClangDependenciesMap;
12271271
cacheComputedClangModuleLookupResults(
12281272
lookupResult, unresolvedImportsMap, unresolvedOptionalImportsMap,
12291273
swiftModuleDependents, allDiscoveredClangModules,
@@ -1506,6 +1550,8 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
15061550
// Update the set of visible Clang modules
15071551
moduleDependencyInfo.addVisibleClangModules(
15081552
headerScanResult->VisibleModules);
1553+
DependencyCache.addHeaderVisibleClangModules(moduleID,
1554+
headerScanResult->VisibleModules);
15091555
// Update the dependency in the cache
15101556
DependencyCache.updateDependency(moduleID, moduleDependencyInfo);
15111557
} else {

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ void swift::dependencies::incremental::validateInterModuleDependenciesCache(
15991599
emitRemarks, visited, modulesRequiringRescan);
16001600
for (const auto &outOfDateModID : modulesRequiringRescan)
16011601
cache.removeDependency(outOfDateModID);
1602-
1602+
// ACTODO: Invalidate visible modules
16031603
// Regardless of invalidation, always re-scan main module.
16041604
cache.removeDependency(rootModuleID);
16051605
}

0 commit comments

Comments
 (0)