Skip to content

Commit 8ed4121

Browse files
committed
Serialize explicit module dependencies in swift module files
For clients, such as the debugger, who do not have access the full output of the dependency scanner, it is a huger performance and correctness improvement if each explicitly built Swift module not just serialized all its Clang .pcm dependencies (via the serialized Clang compiler invocation) but also its direct Swift module dependencies. This patch changes the Swift module format to store the absolute path or cas cache key for each dependency in the INPUT block, and makes sure the deserialization makes these available to the ESML. rdar://150969755
1 parent a867ff8 commit 8ed4121

20 files changed

+149
-63
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,9 @@ class ASTContext final {
10741074
/// Does any proper bookkeeping to keep all module loaders up to date as well.
10751075
void addSearchPath(StringRef searchPath, bool isFramework, bool isSystem);
10761076

1077+
/// Adds the path to the explicitly built module \c name.
1078+
void addExplicitModulePath(StringRef name, std::string path);
1079+
10771080
/// Adds a module loader to this AST context.
10781081
///
10791082
/// \param loader The new module loader, which will be added after any
@@ -1087,7 +1090,7 @@ class ASTContext final {
10871090
/// interface.
10881091
void addModuleLoader(std::unique_ptr<ModuleLoader> loader,
10891092
bool isClang = false, bool isDWARF = false,
1090-
bool IsInterface = false);
1093+
bool IsInterface = false, bool IsExplicit = false);
10911094

10921095
/// Add a module interface checker to use for this AST context.
10931096
void addModuleInterfaceChecker(std::unique_ptr<ModuleInterfaceChecker> checker);

include/swift/AST/Module.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,13 @@ class ModuleDecl
858858
/// returns true.
859859
bool isSubmoduleOf(const ModuleDecl *M) const;
860860

861+
private:
862+
std::string CacheKey;
863+
864+
public:
865+
void setCacheKey(const std::string &key) { CacheKey = key; }
866+
StringRef getCacheKey() const { return CacheKey; }
867+
861868
bool isResilient() const {
862869
return getResilienceStrategy() != ResilienceStrategy::Default;
863870
}

include/swift/AST/SearchPathOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ enum class ModuleLoadingMode {
4545
PreferInterface,
4646
PreferSerialized,
4747
OnlyInterface,
48-
OnlySerialized
48+
OnlySerialized,
4949
};
5050

5151
/// A single module search path that can come from different sources, e.g.

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,9 @@ namespace swift {
459459
bool EnableDeserializationSafety =
460460
::getenv("SWIFT_ENABLE_DESERIALIZATION_SAFETY");
461461

462+
/// Disable injecting deserializes module paths into the explict module map.
463+
bool DisableDeserializationOfExplicitPaths = false;
464+
462465
/// Attempt to recover for imported modules with broken modularization
463466
/// in an unsafe way. Currently applies only to xrefs where the target
464467
/// decl moved to a different module that is already loaded.

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
152152
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
153153
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
154154
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
155-
bool isCanImportLookup, bool isTestableDependencyLookup,
156-
bool &isFramework, bool &isSystemModule) override;
155+
std::string *cacheKey, bool isCanImportLookup,
156+
bool isTestableDependencyLookup, bool &isFramework,
157+
bool &isSystemModule) override;
157158

158159
std::error_code findModuleFilesInDirectory(
159160
ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName,
@@ -181,6 +182,7 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
181182
const llvm::StringMap<std::string> &ExplicitSwiftModuleInputs,
182183
bool IgnoreSwiftSourceInfoFile);
183184

185+
void addExplicitModulePath(StringRef name, std::string path) override;
184186
/// Append visible module names to \p names. Note that names are possibly
185187
/// duplicated, and not guaranteed to be ordered in any way.
186188
void collectVisibleTopLevelModuleNames(
@@ -201,8 +203,9 @@ class ExplicitCASModuleLoader : public SerializedModuleLoaderBase {
201203
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
202204
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
203205
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
204-
bool isCanImportLookup, bool isTestableDependencyLookup,
205-
bool &isFramework, bool &isSystemModule) override;
206+
std::string *cacheKey, bool isCanImportLookup,
207+
bool isTestableDependencyLookup, bool &isFramework,
208+
bool &isSystemModule) override;
206209

207210
std::error_code findModuleFilesInDirectory(
208211
ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName,

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
103103
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
104104
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
105105
std::unique_ptr<llvm::MemoryBuffer> *moduleSourceInfoBuffer,
106-
bool isCanImportLookup, bool isTestableDependencyLookup,
107-
bool &isFramework, bool &isSystemModule);
106+
std::string *CacheKey, bool isCanImportLookup,
107+
bool isTestableDependencyLookup, bool &isFramework, bool &isSystemModule);
108108

109109
/// Attempts to search the provided directory for a loadable serialized
110110
/// .swiftmodule with the provided `ModuleFilename`. Subclasses must
@@ -268,6 +268,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
268268
/// A textual reason why the compiler rejected a binary module load
269269
/// attempt with a given status, to be used for diagnostic output.
270270
static std::optional<std::string> invalidModuleReason(serialization::Status status);
271+
272+
virtual void addExplicitModulePath(StringRef name, std::string path) {};
271273
};
272274

273275
/// Imports serialized Swift modules into an ASTContext.

lib/AST/ASTContext.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#include "ClangTypeConverter.h"
2020
#include "ForeignRepresentationInfo.h"
2121
#include "SubstitutionMapStorage.h"
22-
#include "swift/AST/ASTContextGlobalCache.h"
2322
#include "swift/ABI/MetadataValues.h"
23+
#include "swift/AST/ASTContextGlobalCache.h"
2424
#include "swift/AST/AvailabilityContextStorage.h"
2525
#include "swift/AST/ClangModuleLoader.h"
2626
#include "swift/AST/ConcreteDeclRef.h"
@@ -67,6 +67,8 @@
6767
#include "swift/Basic/Statistic.h"
6868
#include "swift/Basic/StringExtras.h"
6969
#include "swift/ClangImporter/ClangModule.h"
70+
#include "swift/Frontend/ModuleInterfaceLoader.h"
71+
#include "swift/Serialization/SerializedModuleLoader.h"
7072
#include "swift/Strings.h"
7173
#include "swift/Subsystems.h"
7274
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
@@ -445,6 +447,9 @@ struct ASTContext::Implementation {
445447
/// Singleton used to cache the import graph.
446448
swift::namelookup::ImportCache TheImportCache;
447449

450+
/// The module loader used to load explicit Swift modules.
451+
SerializedModuleLoaderBase *TheExplicitSwiftModuleLoader = nullptr;
452+
448453
/// The module loader used to load Clang modules.
449454
ClangModuleLoader *TheClangModuleLoader = nullptr;
450455

@@ -2159,14 +2164,23 @@ void ASTContext::addSearchPath(StringRef searchPath, bool isFramework,
21592164
clangLoader->addSearchPath(searchPath, isFramework, isSystem);
21602165
}
21612166

2167+
void ASTContext::addExplicitModulePath(StringRef name, std::string path) {
2168+
if (getImpl().TheExplicitSwiftModuleLoader)
2169+
getImpl().TheExplicitSwiftModuleLoader->addExplicitModulePath(name, path);
2170+
}
2171+
21622172
void ASTContext::addModuleLoader(std::unique_ptr<ModuleLoader> loader,
2163-
bool IsClang, bool IsDwarf, bool IsInterface) {
2173+
bool IsClang, bool IsDwarf, bool IsInterface,
2174+
bool IsExplicit) {
21642175
if (IsClang && !IsDwarf && !getImpl().TheClangModuleLoader)
21652176
getImpl().TheClangModuleLoader =
21662177
static_cast<ClangModuleLoader *>(loader.get());
21672178
if (IsClang && IsDwarf && !getImpl().TheDWARFModuleLoader)
21682179
getImpl().TheDWARFModuleLoader =
21692180
static_cast<ClangModuleLoader *>(loader.get());
2181+
if (IsExplicit && !getImpl().TheExplicitSwiftModuleLoader)
2182+
getImpl().TheExplicitSwiftModuleLoader =
2183+
static_cast<SerializedModuleLoaderBase *>(loader.get());
21702184
getImpl().ModuleLoaders.push_back(std::move(loader));
21712185
}
21722186

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,6 @@ bool swift::dependencies::scanDependencies(CompilerInstance &CI) {
14761476
ctx.Allocate<SwiftDependencyScanningService>();
14771477
ModuleDependenciesCache cache(CI.getMainModule()->getNameStr().str(),
14781478
CI.getInvocation().getModuleScanningHash());
1479-
14801479
if (service->setupCachingDependencyScanningService(CI))
14811480
return true;
14821481

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ bool CompilerInstance::setUpModuleLoaders() {
870870
// Install an explicit module loader if it was created earlier.
871871
if (ESML) {
872872
this->DefaultSerializedLoader = ESML.get();
873-
Context->addModuleLoader(std::move(ESML));
873+
Context->addModuleLoader(std::move(ESML), false, false, false, true);
874874
}
875875

876876
if (!ExplicitModuleBuild) {

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,8 +2304,8 @@ bool ExplicitSwiftModuleLoader::findModule(
23042304
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
23052305
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
23062306
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
2307-
bool IsCanImportLookup, bool isTestableDependencyLookup,
2308-
bool &IsFramework, bool &IsSystemModule) {
2307+
std::string *cacheKey, bool IsCanImportLookup,
2308+
bool isTestableDependencyLookup, bool &IsFramework, bool &IsSystemModule) {
23092309
// Find a module with an actual, physical name on disk, in case
23102310
// -module-alias is used (otherwise same).
23112311
//
@@ -2473,6 +2473,12 @@ ExplicitSwiftModuleLoader::create(ASTContext &ctx,
24732473
return result;
24742474
}
24752475

2476+
void ExplicitSwiftModuleLoader::addExplicitModulePath(StringRef name,
2477+
std::string path) {
2478+
ExplicitSwiftModuleInputInfo entry(path, {}, {}, {});
2479+
Impl.ExplicitModuleMap.try_emplace(name, std::move(entry));
2480+
}
2481+
24762482
struct ExplicitCASModuleLoader::Implementation {
24772483
ASTContext &Ctx;
24782484
llvm::BumpPtrAllocator Allocator;
@@ -2660,8 +2666,8 @@ bool ExplicitCASModuleLoader::findModule(
26602666
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
26612667
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
26622668
std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
2663-
bool IsCanImportLookup, bool IsTestableDependencyLookup,
2664-
bool &IsFramework, bool &IsSystemModule) {
2669+
std::string *CacheKey, bool IsCanImportLookup,
2670+
bool IsTestableDependencyLookup, bool &IsFramework, bool &IsSystemModule) {
26652671
// Find a module with an actual, physical name on disk, in case
26662672
// -module-alias is used (otherwise same).
26672673
//
@@ -2681,6 +2687,8 @@ bool ExplicitCASModuleLoader::findModule(
26812687
// Set IsFramework bit according to the moduleInfo
26822688
IsFramework = moduleInfo.isFramework;
26832689
IsSystemModule = moduleInfo.isSystem;
2690+
if (CacheKey && moduleInfo.moduleCacheKey)
2691+
*CacheKey = *moduleInfo.moduleCacheKey;
26842692

26852693
// Fallback check for module cache key passed on command-line as module path.
26862694
std::string moduleCASID = moduleInfo.moduleCacheKey

0 commit comments

Comments
 (0)