Skip to content

Commit 7ec791b

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 7ec791b

File tree

4 files changed

+131
-42
lines changed

4 files changed

+131
-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: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,57 @@ 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(
965+
ModuleDependenciesCache &cache, ASTContext &scanASTContext,
966+
ArrayRef<ModuleDependencyID> swiftModuleDependents,
967+
ModuleDependencyIDSetVector &allDiscoveredClangModules,
968+
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
969+
&resolvedClangDependenciesMap) {
970+
for (const auto &moduleID : swiftModuleDependents) {
971+
ModuleDependencyInfo moduleDependencyInfo =
972+
cache.findKnownDependency(moduleID);
973+
if (!moduleDependencyInfo.getImportedClangDependencies().empty())
974+
continue;
975+
976+
auto resolveImportIfCached =
977+
[&](const ScannerImportStatementInfo &importInfo) {
978+
auto dependencyID = ModuleDependencyID{importInfo.importIdentifier,
979+
ModuleDependencyKind::Clang};
980+
auto visibleFromDependencyID =
981+
cache.getVisibleClangModulesFrom(dependencyID);
982+
if (cache.hasDependency(dependencyID) &&
983+
!visibleFromDependencyID.empty()) {
984+
cache.addVisibleClangModules(moduleID, dependencyID,
985+
visibleFromDependencyID);
986+
resolvedClangDependenciesMap[moduleID].insert(dependencyID);
987+
}
988+
};
989+
990+
for (const auto &depImport : moduleDependencyInfo.getModuleImports())
991+
resolveImportIfCached(depImport);
992+
for (const auto &depImport :
993+
moduleDependencyInfo.getOptionalModuleImports())
994+
resolveImportIfCached(depImport);
995+
}
996+
}
997+
998+
static void findAllReachableClangModules(ModuleDependencyID moduleID,
999+
const ModuleDependenciesCache &cache,
1000+
ModuleDependencyIDSetVector &reachableClangModules) {
1001+
if (!reachableClangModules.insert(moduleID))
1002+
return;
1003+
for (const auto &depID : cache.getImportedClangDependencies(moduleID))
1004+
findAllReachableClangModules(depID, cache, reachableClangModules);
1005+
}
1006+
1007+
static void gatherUnresolvedImports(
1008+
ModuleDependenciesCache &cache, ASTContext &scanASTContext,
1009+
ArrayRef<ModuleDependencyID> swiftModuleDependents,
1010+
ModuleDependencyIDSetVector &allDiscoveredClangModules,
1011+
ImportStatementInfoMap &unresolvedImportsMap,
1012+
ImportStatementInfoMap &unresolvedOptionalImportsMap,
1013+
const std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
1014+
&resolvedClangDependenciesMap) {
9711015
for (const auto &moduleID : swiftModuleDependents) {
9721016
auto moduleDependencyInfo = cache.findKnownDependency(moduleID);
9731017
auto unresolvedImports =
@@ -986,27 +1030,24 @@ gatherUnresolvedImports(ModuleDependenciesCache &cache,
9861030
if (!moduleDependencyInfo.getImportedClangDependencies().empty()) {
9871031
auto directClangDeps = cache.getImportedClangDependencies(moduleID);
9881032
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());
1033+
for (const auto &depID : directClangDeps)
1034+
findAllReachableClangModules(depID, cache, reachableClangModules);
1035+
allDiscoveredClangModules.insert(reachableClangModules.getArrayRef().begin(),
1036+
reachableClangModules.getArrayRef().end());
10011037
continue;
10021038
} else {
10031039
// We need to query the Clang dependency scanner for this module's
1004-
// non-Swift imports
1040+
// unresolved imports
10051041
llvm::StringSet<> resolvedImportIdentifiers;
10061042
for (const auto &resolvedDep :
10071043
moduleDependencyInfo.getImportedSwiftDependencies())
10081044
resolvedImportIdentifiers.insert(resolvedDep.ModuleName);
10091045

1046+
if (resolvedClangDependenciesMap.find(moduleID) != resolvedClangDependenciesMap.end())
1047+
for (const auto &cacheResolvedDep :
1048+
resolvedClangDependenciesMap.at(moduleID))
1049+
resolvedImportIdentifiers.insert(cacheResolvedDep.ModuleName);
1050+
10101051
// When querying a *clang* module 'CxxStdlib' we must
10111052
// instead expect a module called 'std'...
10121053
auto addCanonicalClangModuleImport =
@@ -1074,7 +1115,8 @@ void ModuleDependencyScanner::reQueryMissedModulesFromCache(
10741115
resolvedClangDependenciesMap[unresolvedImport.first].insert(
10751116
unresolvedModuleID);
10761117
DependencyCache.addVisibleClangModules(
1077-
unresolvedImport.first, {unresolvedImport.second.importIdentifier});
1118+
unresolvedImport.first, unresolvedModuleID,
1119+
{unresolvedImport.second.importIdentifier});
10781120
} else {
10791121
// Failed to resolve module dependency.
10801122
IssueReporter.diagnoseModuleNotFoundFailure(
@@ -1156,7 +1198,8 @@ void ModuleDependencyScanner::cacheComputedClangModuleLookupResults(
11561198
// Swift module
11571199
if (lookupResult.visibleModules.contains(moduleIdentifier))
11581200
DependencyCache.addVisibleClangModules(
1159-
moduleID, lookupResult.visibleModules.at(moduleIdentifier));
1201+
moduleID, dependencyID,
1202+
lookupResult.visibleModules.at(moduleIdentifier));
11601203

11611204
// Add the resolved dependency ID
11621205
if (lookupResult.discoveredDependencyInfos.contains(
@@ -1204,13 +1247,21 @@ void ModuleDependencyScanner::cacheComputedClangModuleLookupResults(
12041247
void ModuleDependencyScanner::resolveAllClangModuleDependencies(
12051248
ArrayRef<ModuleDependencyID> swiftModuleDependents,
12061249
ModuleDependencyIDSetVector &allDiscoveredClangModules) {
1207-
// Gather all unresolved imports which must correspond to
1250+
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
1251+
resolvedClangDependenciesMap;
1252+
resolveClangDependenciesFromCache(DependencyCache, ScanASTContext,
1253+
swiftModuleDependents,
1254+
allDiscoveredClangModules,
1255+
resolvedClangDependenciesMap);
1256+
1257+
// Gather all remaining unresolved imports which must correspond to
12081258
// Clang modules (since no Swift module for them was found).
12091259
ImportStatementInfoMap unresolvedImportsMap;
12101260
ImportStatementInfoMap unresolvedOptionalImportsMap;
1211-
gatherUnresolvedImports(DependencyCache, ScanASTContext, swiftModuleDependents,
1212-
allDiscoveredClangModules, unresolvedImportsMap,
1213-
unresolvedOptionalImportsMap);
1261+
gatherUnresolvedImports(DependencyCache, ScanASTContext,
1262+
swiftModuleDependents, allDiscoveredClangModules,
1263+
unresolvedImportsMap, unresolvedOptionalImportsMap,
1264+
resolvedClangDependenciesMap);
12141265

12151266
// Execute parallel lookup of all unresolved import
12161267
// identifiers as Clang modules.
@@ -1222,8 +1273,6 @@ void ModuleDependencyScanner::resolveAllClangModuleDependencies(
12221273
// dependencies.
12231274
std::vector<std::pair<ModuleDependencyID, ScannerImportStatementInfo>>
12241275
failedToResolveImports;
1225-
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
1226-
resolvedClangDependenciesMap;
12271276
cacheComputedClangModuleLookupResults(
12281277
lookupResult, unresolvedImportsMap, unresolvedOptionalImportsMap,
12291278
swiftModuleDependents, allDiscoveredClangModules,
@@ -1506,6 +1555,8 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
15061555
// Update the set of visible Clang modules
15071556
moduleDependencyInfo.addVisibleClangModules(
15081557
headerScanResult->VisibleModules);
1558+
DependencyCache.addHeaderVisibleClangModules(moduleID,
1559+
headerScanResult->VisibleModules);
15091560
// Update the dependency in the cache
15101561
DependencyCache.updateDependency(moduleID, moduleDependencyInfo);
15111562
} 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)