Skip to content

Commit 07de483

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 512ef2e commit 07de483

File tree

8 files changed

+241
-144
lines changed

8 files changed

+241
-144
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,9 @@ class ModuleDependencyInfoStorageBase {
277277
/// The macro dependencies.
278278
std::map<std::string, MacroPluginDependency> macroDependencies;
279279

280-
/// A list of Clang modules that are visible to this Swift module. This
281-
/// includes both direct Clang modules as well as transitive Clang
282-
/// module dependencies when they are exported
283-
llvm::StringSet<> visibleClangModules;
280+
/// A list of Clang modules that are visible to this Swift module
281+
/// as re-exported modular includes of its bridging header.
282+
std::vector<std::string> bridgingHeaderVisibleClangModules;
284283

285284
/// ModuleDependencyInfo is finalized (with all transitive dependencies
286285
/// and inputs).
@@ -893,14 +892,12 @@ class ModuleDependencyInfo {
893892
llvm_unreachable("Unexpected module dependency kind");
894893
}
895894

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

906903
/// Whether explicit input paths of all the module dependencies
@@ -1073,6 +1070,9 @@ class ModuleDependenciesCache {
10731070
private:
10741071
/// Discovered dependencies
10751072
ModuleDependenciesKindMap ModuleDependenciesMap;
1073+
/// A map from Clang module name to all visible modules to a client
1074+
/// of a by-name import of this Clang module
1075+
llvm::StringMap<std::vector<std::string>> clangModulesVisibleFromNamedLookup;
10761076
/// Set containing all of the Clang modules that have already been seen.
10771077
llvm::DenseSet<clang::tooling::dependencies::ModuleID> alreadySeenClangModules;
10781078
/// Name of the module under scan
@@ -1111,6 +1111,8 @@ class ModuleDependenciesCache {
11111111
bool hasDependency(StringRef moduleName) const;
11121112
/// Whether we have cached dependency information for the given Swift module.
11131113
bool hasSwiftDependency(StringRef moduleName) const;
1114+
/// Whether we have cached dependency information for the given Clang module.
1115+
bool hasClangDependency(StringRef moduleName) const;
11141116
/// Report the number of recorded Clang dependencies
11151117
int numberOfClangDependencies() const;
11161118
/// Report the number of recorded Swift dependencies
@@ -1152,9 +1154,20 @@ class ModuleDependenciesCache {
11521154
/// Query all cross-import overlay dependencies
11531155
llvm::ArrayRef<ModuleDependencyID>
11541156
getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const;
1157+
11551158
/// Query all visible Clang modules for a given Swift dependency
1156-
llvm::StringSet<>&
1157-
getVisibleClangModules(ModuleDependencyID moduleID) const;
1159+
llvm::StringSet<>
1160+
getAllVisibleClangModules(ModuleDependencyID moduleID) const;
1161+
/// Query all Clang modules visible via a by-name lookup of given
1162+
/// Clang dependency
1163+
llvm::ArrayRef<std::string>
1164+
getVisibleClangModulesFromLookup(StringRef moduleName) const;
1165+
bool hasVisibleClangModulesFromLookup(StringRef moduleName) const;
1166+
/// Query all Clang modules visible from a given Swift module's
1167+
/// bridging header
1168+
llvm::ArrayRef<std::string>
1169+
getVisibleClangModulesViaHeader(ModuleDependencyID moduleID) const;
1170+
bool hasVisibleClangModulesViaHeader(ModuleDependencyID moduleID) const;
11581171

11591172
/// Look for module dependencies for a module with the given ID
11601173
///
@@ -1230,8 +1243,8 @@ class ModuleDependenciesCache {
12301243
const ModuleDependencyIDCollectionView dependencyIDs);
12311244
/// Add to this module's set of visible Clang modules
12321245
void
1233-
addVisibleClangModules(ModuleDependencyID moduleID,
1234-
const std::vector<std::string> &moduleNames);
1246+
setVisibleClangModulesFromLookup(ModuleDependencyID clangModuleID,
1247+
const std::vector<std::string> &moduleNames);
12351248

12361249
StringRef getMainModuleName() const { return mainScanModuleName; }
12371250

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(
@@ -390,25 +398,19 @@ class ModuleDependencyScanner {
390398
/// in \c failedToResolveImports.
391399
/// 4. Update the set of resolved Clang dependencies for each Swift
392400
/// module dependency in \c resolvedClangDependenciesMap.
393-
void cacheComputedClangModuleLookupResults(
401+
void processBatchClangModuleQueryResult(
394402
const BatchClangModuleLookupResult &lookupResult,
395403
const ImportStatementInfoMap &unresolvedImportsMap,
396404
const ImportStatementInfoMap &unresolvedOptionalImportsMap,
397-
ArrayRef<ModuleDependencyID> swiftModuleDependents,
398405
ModuleDependencyIDSetVector &allDiscoveredClangModules,
399-
std::vector<std::pair<ModuleDependencyID, ScannerImportStatementInfo>>
400-
&failedToResolveImports,
401-
std::unordered_map<ModuleDependencyID, ModuleDependencyIDSetVector>
402-
&resolvedClangDependenciesMap);
406+
std::vector<ModuleIDImportInfoPair> &failedToResolveImports,
407+
ModuleIDToModuleIDSetVectorMap &resolvedClangDependenciesMap);
403408

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

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

lib/AST/ModuleDependencies.cpp

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,9 @@ bool ModuleDependenciesCache::hasDependency(StringRef moduleName) const {
759759
bool ModuleDependenciesCache::hasSwiftDependency(StringRef moduleName) const {
760760
return findSwiftDependency(moduleName).has_value();
761761
}
762+
bool ModuleDependenciesCache::hasClangDependency(StringRef moduleName) const {
763+
return findDependency(moduleName, ModuleDependencyKind::Clang).has_value();
764+
}
762765

763766
int ModuleDependenciesCache::numberOfClangDependencies() const {
764767
return ModuleDependenciesMap.at(ModuleDependencyKind::Clang).size();
@@ -844,6 +847,16 @@ void ModuleDependenciesCache::recordClangDependency(
844847
}
845848
}
846849

850+
void ModuleDependenciesCache::setVisibleClangModulesFromLookup(
851+
ModuleDependencyID moduleID,
852+
const std::vector<std::string> &visibleModules) {
853+
ASSERT(moduleID.Kind == ModuleDependencyKind::Clang);
854+
if (visibleModules.empty())
855+
return;
856+
857+
clangModulesVisibleFromNamedLookup[moduleID.ModuleName] = visibleModules;
858+
}
859+
847860
void ModuleDependenciesCache::updateDependency(
848861
ModuleDependencyID moduleID, ModuleDependencyInfo dependencyInfo) {
849862
auto &map = getDependenciesMap(moduleID.Kind);
@@ -854,6 +867,10 @@ void ModuleDependenciesCache::updateDependency(
854867
void ModuleDependenciesCache::removeDependency(ModuleDependencyID moduleID) {
855868
auto &map = getDependenciesMap(moduleID.Kind);
856869
map.erase(moduleID.ModuleName);
870+
// If we are removing a Clang module which was queried by-name
871+
// in a prior scan, we must re-compute its set of visible modules.
872+
if (moduleID.Kind == ModuleDependencyKind::Clang)
873+
clangModulesVisibleFromNamedLookup.erase(moduleID.ModuleName);
857874
}
858875

859876
void ModuleDependenciesCache::setImportedSwiftDependencies(
@@ -936,22 +953,52 @@ ModuleDependencyIDCollectionView ModuleDependenciesCache::getAllDependencies(
936953
moduleInfo.getImportedClangDependencies());
937954
}
938955

939-
void ModuleDependenciesCache::addVisibleClangModules(
940-
ModuleDependencyID moduleID, const std::vector<std::string> &moduleNames) {
941-
if (moduleNames.empty())
942-
return;
943-
auto dependencyInfo = findKnownDependency(moduleID);
944-
auto updatedDependencyInfo = dependencyInfo;
945-
updatedDependencyInfo.addVisibleClangModules(moduleNames);
946-
updateDependency(moduleID, updatedDependencyInfo);
956+
llvm::StringSet<> ModuleDependenciesCache::getAllVisibleClangModules(
957+
ModuleDependencyID moduleID) const {
958+
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
959+
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
960+
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
961+
llvm::StringSet<> result;
962+
if (hasVisibleClangModulesViaHeader(moduleID)) {
963+
auto headerVisibleModules = getVisibleClangModulesViaHeader(moduleID);
964+
result.insert(headerVisibleModules.begin(), headerVisibleModules.end());
965+
}
966+
for (const auto &clangDepID :
967+
findKnownDependency(moduleID).getImportedClangDependencies()) {
968+
assert(hasVisibleClangModulesFromLookup(clangDepID.ModuleName));
969+
auto visibleModulesViaImport =
970+
getVisibleClangModulesFromLookup(clangDepID.ModuleName);
971+
result.insert(visibleModulesViaImport.begin(),
972+
visibleModulesViaImport.end());
973+
}
974+
return result;
975+
}
976+
977+
ArrayRef<std::string> ModuleDependenciesCache::getVisibleClangModulesFromLookup(
978+
StringRef moduleName) const {
979+
ASSERT(hasVisibleClangModulesFromLookup(moduleName));
980+
return clangModulesVisibleFromNamedLookup.at(moduleName);
981+
}
982+
983+
bool ModuleDependenciesCache::hasVisibleClangModulesFromLookup(
984+
StringRef moduleName) const {
985+
return clangModulesVisibleFromNamedLookup.contains(moduleName);
947986
}
948987

949-
llvm::StringSet<> &ModuleDependenciesCache::getVisibleClangModules(
988+
llvm::ArrayRef<std::string>
989+
ModuleDependenciesCache::getVisibleClangModulesViaHeader(
990+
ModuleDependencyID moduleID) const {
991+
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
992+
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
993+
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
994+
return findKnownDependency(moduleID).getHeaderVisibleClangModules();
995+
}
996+
bool ModuleDependenciesCache::hasVisibleClangModulesViaHeader(
950997
ModuleDependencyID moduleID) const {
951998
ASSERT(moduleID.Kind == ModuleDependencyKind::SwiftSource ||
952999
moduleID.Kind == ModuleDependencyKind::SwiftInterface ||
9531000
moduleID.Kind == ModuleDependencyKind::SwiftBinary);
954-
return findKnownDependency(moduleID).getVisibleClangModules();
1001+
return !getVisibleClangModulesViaHeader(moduleID).empty();
9551002
}
9561003

9571004
ModuleDependencyIDCollectionView

0 commit comments

Comments
 (0)