Skip to content

Commit ba9e560

Browse files
committed
[Dependency Scanning] Parallelize Clang module queries
This change refactors the top-level dependency scanning flow to follow the following procedure: Scan(): 1. From the source target under scan, query all imported module identifiers for a *Swift* module. Leave unresolved identifiers unresolved. Proceed transitively to build a *Swift* module dependency graph. 2. Take every unresolved import identifier in the graph from (1) and, assuming that it must be a Clang module, dispatch all of them to be queried in-parallel by the scanner's worker pool. 3. Resolve bridging header Clang module dpendencies 4. Resolve all Swift overlay dependencies, relying on all Clang modules collected in (2) and (3) 5. For the source target under scan, use all of the above discovered module dependencies to resolve all cross-import overlay dependencies
1 parent d6e8eb2 commit ba9e560

File tree

12 files changed

+1110
-648
lines changed

12 files changed

+1110
-648
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 143 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class ModuleDependencyInfoStorageBase {
180180
ArrayRef<LinkLibrary> linkLibraries,
181181
StringRef moduleCacheKey = "")
182182
: dependencyKind(dependencyKind), linkLibraries(linkLibraries),
183-
moduleCacheKey(moduleCacheKey.str()), resolved(false),
183+
moduleCacheKey(moduleCacheKey.str()),
184184
finalized(false) {}
185185

186186
ModuleDependencyInfoStorageBase(
@@ -191,7 +191,7 @@ class ModuleDependencyInfoStorageBase {
191191
: dependencyKind(dependencyKind), moduleImports(moduleImports),
192192
optionalModuleImports(optionalModuleImports),
193193
linkLibraries(linkLibraries), moduleCacheKey(moduleCacheKey.str()),
194-
resolved(false), finalized(false) {}
194+
finalized(false) {}
195195

196196
virtual ModuleDependencyInfoStorageBase *clone() const = 0;
197197

@@ -209,11 +209,13 @@ class ModuleDependencyInfoStorageBase {
209209
/// use this module.
210210
std::vector<LinkLibrary> linkLibraries;
211211

212-
/// The set of modules on which this module depends, resolved
213-
/// to Module IDs, qualified by module kind: Swift, Clang, etc.
214-
std::vector<ModuleDependencyID> resolvedDirectModuleDependencies;
215-
216-
/// Dependencies comprised of Swift overlay modules of direct and
212+
/// All directly-imported Swift module dependencies.
213+
std::vector<ModuleDependencyID> importedSwiftModules;
214+
/// All directly-imported Clang module dependencies.
215+
std::vector<ModuleDependencyID> importedClangModules;
216+
/// All cross-import overlay module dependencies.
217+
std::vector<ModuleDependencyID> crossImportOverlayModules;
218+
/// All dependencies comprised of Swift overlay modules of direct and
217219
/// transitive Clang dependencies.
218220
std::vector<ModuleDependencyID> swiftOverlayDependencies;
219221

@@ -227,8 +229,6 @@ class ModuleDependencyInfoStorageBase {
227229
/// The macro dependencies.
228230
std::map<std::string, MacroPluginDependency> macroDependencies;
229231

230-
/// The direct dependency of the module is resolved by scanner.
231-
bool resolved;
232232
/// ModuleDependencyInfo is finalized (with all transitive dependencies
233233
/// and inputs).
234234
bool finalized;
@@ -253,8 +253,11 @@ struct CommonSwiftTextualModuleDependencyDetails {
253253
/// Source files on which the bridging header depends.
254254
std::vector<std::string> bridgingSourceFiles;
255255

256+
/// The macro dependencies.
257+
std::map<std::string, MacroPluginDependency> macroDependencies;
258+
256259
/// (Clang) modules on which the bridging header depends.
257-
std::vector<std::string> bridgingModuleDependencies;
260+
std::vector<ModuleDependencyID> bridgingModuleDependencies;
258261

259262
/// The Swift frontend invocation arguments to build the Swift module from the
260263
/// interface.
@@ -426,7 +429,7 @@ class SwiftBinaryModuleDependencyStorage
426429
std::vector<std::string> headerSourceFiles;
427430

428431
/// (Clang) modules on which the header inputs depend.
429-
std::vector<std::string> headerModuleDependencies;
432+
std::vector<ModuleDependencyID> headerModuleDependencies;
430433

431434
/// A flag that indicates this dependency is a framework
432435
const bool isFramework;
@@ -660,42 +663,105 @@ class ModuleDependencyInfo {
660663
return storage->optionalModuleImports;
661664
}
662665

663-
/// Retreive the module-level dependencies.
664-
const ArrayRef<ModuleDependencyID> getDirectModuleDependencies() const {
665-
assert(storage->resolved);
666-
return storage->resolvedDirectModuleDependencies;
667-
}
668-
669666
std::string getModuleCacheKey() const {
670-
assert(storage->resolved);
671667
return storage->moduleCacheKey;
672668
}
673669

674670
void updateModuleCacheKey(const std::string &key) {
675671
storage->moduleCacheKey = key;
676672
}
677673

678-
/// Resolve a dependency's set of `imports` with qualified Module IDs
679674
void
680-
resolveDirectDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
681-
assert(!storage->resolved && "Resolving an already-resolved dependency");
682-
storage->resolved = true;
683-
storage->resolvedDirectModuleDependencies.assign(dependencyIDs.begin(),
684-
dependencyIDs.end());
675+
setImportedSwiftDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
676+
assert(isSwiftModule());
677+
storage->importedSwiftModules.assign(dependencyIDs.begin(),
678+
dependencyIDs.end());
679+
}
680+
const ArrayRef<ModuleDependencyID> getImportedSwiftDependencies() const {
681+
return storage->importedSwiftModules;
682+
}
683+
684+
void
685+
setImportedClangDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
686+
storage->importedClangModules.assign(dependencyIDs.begin(),
687+
dependencyIDs.end());
688+
}
689+
const ArrayRef<ModuleDependencyID> getImportedClangDependencies() const {
690+
return storage->importedClangModules;
691+
}
692+
693+
void
694+
setHeaderClangDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
695+
assert(isSwiftModule());
696+
switch (getKind()) {
697+
case swift::ModuleDependencyKind::SwiftInterface: {
698+
auto swiftInterfaceStorage =
699+
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
700+
swiftInterfaceStorage->textualModuleDetails.bridgingModuleDependencies.assign(dependencyIDs.begin(),
701+
dependencyIDs.end());
702+
break;
703+
}
704+
case swift::ModuleDependencyKind::SwiftSource: {
705+
auto swiftSourceStorage =
706+
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
707+
swiftSourceStorage->textualModuleDetails.bridgingModuleDependencies.assign(dependencyIDs.begin(),
708+
dependencyIDs.end());
709+
break;
710+
}
711+
case swift::ModuleDependencyKind::SwiftBinary: {
712+
auto swiftBinaryStorage =
713+
cast<SwiftBinaryModuleDependencyStorage>(storage.get());
714+
swiftBinaryStorage->headerModuleDependencies.assign(dependencyIDs.begin(),
715+
dependencyIDs.end());
716+
break;
717+
}
718+
default: {
719+
llvm_unreachable("Unexpected dependency kind");
720+
}
721+
}
722+
}
723+
const ArrayRef<ModuleDependencyID> getHeaderClangDependencies() const {
724+
switch (getKind()) {
725+
case swift::ModuleDependencyKind::SwiftInterface: {
726+
auto swiftInterfaceStorage =
727+
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
728+
return swiftInterfaceStorage->textualModuleDetails.bridgingModuleDependencies;
729+
}
730+
case swift::ModuleDependencyKind::SwiftSource: {
731+
auto swiftSourceStorage =
732+
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
733+
return swiftSourceStorage->textualModuleDetails.bridgingModuleDependencies;
734+
}
735+
case swift::ModuleDependencyKind::SwiftBinary: {
736+
auto swiftBinaryStorage =
737+
cast<SwiftBinaryModuleDependencyStorage>(storage.get());
738+
return swiftBinaryStorage->headerModuleDependencies;
739+
}
740+
default:
741+
return {};
742+
}
685743
}
686744

687-
/// Set this module's set of Swift Overlay dependencies
688745
void
689-
setOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
746+
setSwiftOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
690747
assert(isSwiftModule());
691748
storage->swiftOverlayDependencies.assign(dependencyIDs.begin(),
692749
dependencyIDs.end());
693750
}
694-
695751
const ArrayRef<ModuleDependencyID> getSwiftOverlayDependencies() const {
696752
return storage->swiftOverlayDependencies;
697753
}
698754

755+
void
756+
setCrossImportOverlayDependencies(const ArrayRef<ModuleDependencyID> dependencyIDs) {
757+
assert(isSwiftModule());
758+
storage->crossImportOverlayModules.assign(dependencyIDs.begin(),
759+
dependencyIDs.end());
760+
}
761+
const ArrayRef<ModuleDependencyID> getCrossImportOverlayDependencies() const {
762+
return storage->crossImportOverlayModules;
763+
}
764+
699765
const ArrayRef<LinkLibrary> getLinkLibraries() const {
700766
return storage->linkLibraries;
701767
}
@@ -723,16 +789,6 @@ class ModuleDependencyInfo {
723789
return {};
724790
}
725791

726-
const ArrayRef<std::string> getHeaderDependencies() const {
727-
if (auto *detail = getAsSwiftInterfaceModule())
728-
return detail->textualModuleDetails.bridgingModuleDependencies;
729-
if (auto *detail = getAsSwiftSourceModule())
730-
return detail->textualModuleDetails.bridgingModuleDependencies;
731-
if (auto *detail = getAsSwiftBinaryModule())
732-
return detail->headerModuleDependencies;
733-
return {};
734-
}
735-
736792
std::vector<std::string> getCommandline() const {
737793
if (auto *detail = getAsClangModule())
738794
return detail->buildCommandLine;
@@ -798,9 +854,8 @@ class ModuleDependencyInfo {
798854
llvm_unreachable("Unexpected type");
799855
}
800856

801-
bool isResolved() const { return storage->resolved; }
802-
void setIsResolved(bool isResolved) { storage->resolved = isResolved; }
803-
857+
/// Whether explicit input paths of all the module dependencies
858+
/// have been specified on the command-line recipe for this module.
804859
bool isFinalized() const { return storage->finalized; }
805860
void setIsFinalized(bool isFinalized) { storage->finalized = isFinalized; }
806861

@@ -876,10 +931,6 @@ class ModuleDependencyInfo {
876931
const SourceManager *sourceManager = nullptr,
877932
SourceLoc sourceLocation = SourceLoc());
878933

879-
/// Add a kind-qualified module dependency ID to the set of
880-
/// module dependencies.
881-
void addModuleDependency(ModuleDependencyID dependencyID);
882-
883934
/// Get the bridging header.
884935
std::optional<std::string> getBridgingHeader() const;
885936

@@ -904,10 +955,6 @@ class ModuleDependencyInfo {
904955
/// Add source files that the header input depends on.
905956
void addHeaderSourceFile(StringRef bridgingSourceFile);
906957

907-
/// Add (Clang) modules on which a non-bridging header input depends.
908-
void addHeaderInputModuleDependency(StringRef module,
909-
llvm::StringSet<> &alreadyAddedModules);
910-
911958
/// Add bridging header include tree.
912959
void addBridgingHeaderIncludeTree(StringRef ID);
913960

@@ -1175,6 +1222,8 @@ class ModuleDependenciesCache {
11751222
std::optional<ModuleDependencyKind> kind) const;
11761223
/// Whether we have cached dependency information for the given module Name.
11771224
bool hasDependency(StringRef moduleName) const;
1225+
/// Whether we have cached dependency information for the given Swift module.
1226+
bool hasSwiftDependency(StringRef moduleName) const;
11781227

11791228
SwiftDependencyScanningService &getScanService() {
11801229
return globalScanningService;
@@ -1191,17 +1240,29 @@ class ModuleDependenciesCache {
11911240
}
11921241
std::string getModuleOutputPath() const { return moduleOutputPath; }
11931242

1194-
/// Query all dependencies, direct and Swift overlay.
1195-
std::vector<ModuleDependencyID>
1243+
/// Query all dependencies
1244+
ModuleDependencyIDSetVector
11961245
getAllDependencies(const ModuleDependencyID &moduleID) const;
1197-
1198-
/// Query only direct import dependencies
1246+
1247+
/// Query all Clang module dependencies.
1248+
ModuleDependencyIDSetVector
1249+
getClangDependencies(const ModuleDependencyID &moduleID) const;
1250+
1251+
/// Query all directly-imported Swift dependencies
11991252
llvm::ArrayRef<ModuleDependencyID>
1200-
getOnlyDirectDependencies(const ModuleDependencyID &moduleID) const;
1201-
1202-
/// Query only Swift overlay dependencies
1253+
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;
1254+
/// Query all directly-imported Clang dependencies
1255+
llvm::ArrayRef<ModuleDependencyID>
1256+
getImportedClangDependencies(const ModuleDependencyID &moduleID) const;
1257+
/// Query all Clang module dependencies of this module's imported (bridging) header
12031258
llvm::ArrayRef<ModuleDependencyID>
1204-
getOnlyOverlayDependencies(const ModuleDependencyID &moduleID) const;
1259+
getHeaderClangDependencies(const ModuleDependencyID &moduleID) const;
1260+
/// Query Swift overlay dependencies
1261+
llvm::ArrayRef<ModuleDependencyID>
1262+
getSwiftOverlayDependencies(const ModuleDependencyID &moduleID) const;
1263+
/// Query all cross-import overlay dependencies
1264+
llvm::ArrayRef<ModuleDependencyID>
1265+
getCrossImportOverlayDependencies(const ModuleDependencyID &moduleID) const;
12051266

12061267
/// Look for module dependencies for a module with the given ID
12071268
///
@@ -1222,6 +1283,12 @@ class ModuleDependenciesCache {
12221283
std::optional<const ModuleDependencyInfo *>
12231284
findDependency(StringRef moduleName) const;
12241285

1286+
/// Look for Swift module dependencies for a module with the given name
1287+
///
1288+
/// \returns the cached result, or \c None if there is no cached entry.
1289+
std::optional<const ModuleDependencyInfo *>
1290+
findSwiftDependency(StringRef moduleName) const;
1291+
12251292
/// Look for known existing dependencies.
12261293
///
12271294
/// \returns the cached result.
@@ -1237,19 +1304,32 @@ class ModuleDependenciesCache {
12371304

12381305
/// Update stored dependencies for the given module.
12391306
void updateDependency(ModuleDependencyID moduleID,
1240-
ModuleDependencyInfo dependencies);
1307+
ModuleDependencyInfo dependencyInfo);
12411308

1242-
/// Resolve a dependency module's set of imports
1243-
/// to a kind-qualified set of module IDs.
1309+
/// Resolve this module's set of directly-imported Swift module
1310+
/// dependencies
12441311
void
1245-
resolveDependencyImports(ModuleDependencyID moduleID,
1246-
const ArrayRef<ModuleDependencyID> dependencyIDs);
1247-
1248-
/// Resolve a dependency module's set of Swift module dependencies
1312+
setImportedSwiftDependencies(ModuleDependencyID moduleID,
1313+
const ArrayRef<ModuleDependencyID> dependencyIDs);
1314+
/// Resolve this module's set of directly-imported Clang module
1315+
/// dependencies
1316+
void
1317+
setImportedClangDependencies(ModuleDependencyID moduleID,
1318+
const ArrayRef<ModuleDependencyID> dependencyIDs);
1319+
/// Resolve this module's set of Swift module dependencies
12491320
/// that are Swift overlays of Clang module dependencies.
12501321
void
12511322
setSwiftOverlayDependencies(ModuleDependencyID moduleID,
12521323
const ArrayRef<ModuleDependencyID> dependencyIDs);
1324+
/// Resolve this Swift module's imported (bridging) header's
1325+
/// Clang module dependencies
1326+
void
1327+
setHeaderClangDependencies(ModuleDependencyID moduleID,
1328+
const ArrayRef<ModuleDependencyID> dependencyIDs);
1329+
/// Resolve this module's cross-import overlay dependencies
1330+
void
1331+
setCrossImportOverlayDependencies(ModuleDependencyID moduleID,
1332+
const ArrayRef<ModuleDependencyID> dependencyIDs);
12531333

12541334
StringRef getMainModuleName() const { return mainScanModuleName; }
12551335
};

include/swift/ClangImporter/ClangImporter.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class SwiftLookupTable;
9090
class TypeDecl;
9191
class ValueDecl;
9292
class VisibleDeclConsumer;
93+
using ModuleDependencyIDSetVector =
94+
llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
95+
std::set<ModuleDependencyID>>;
9396
enum class SelectorSplitKind;
9497

9598
/// Kinds of optional types.
@@ -492,7 +495,11 @@ class ClangImporter final : public ClangModuleLoader {
492495
ModuleDependencyInfo &MDI,
493496
const clang::tooling::dependencies::TranslationUnitDeps &deps);
494497

495-
/// Add dependency information for header dependencies
498+
void getBridgingHeaderOptions(
499+
const clang::tooling::dependencies::TranslationUnitDeps &deps,
500+
std::vector<std::string> &swiftArgs);
501+
502+
/// Query dependency information for header dependencies
496503
/// of a binary Swift module.
497504
///
498505
/// \param moduleID the name of the Swift module whose dependency
@@ -505,10 +512,14 @@ class ClangImporter final : public ClangModuleLoader {
505512
/// about new Clang modules discovered along the way.
506513
///
507514
/// \returns \c true if an error occurred, \c false otherwise
508-
bool addHeaderDependencies(
515+
bool getHeaderDependencies(
509516
ModuleDependencyID moduleID,
510517
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
511-
ModuleDependenciesCache &cache);
518+
ModuleDependenciesCache &cache,
519+
ModuleDependencyIDSetVector &headerClangModuleDependencies,
520+
std::vector<std::string> &headerFileInputs,
521+
std::vector<std::string> &bridgingHeaderCommandLine,
522+
std::optional<std::string> &includeTreeID);
512523

513524
clang::TargetInfo &getModuleAvailabilityTarget() const override;
514525
clang::ASTContext &getClangASTContext() const override;

0 commit comments

Comments
 (0)