Skip to content

Commit a8f0def

Browse files
[Caching] Support CrossImport modules for caching build
Add support for cross import modules by ingesting swiftoverlay files for the cross import into CAS file system. The long-term better fix will be just passing the cross import information from scanner to swift-frontend so frontend doesn't need to read overlay files again to figure out the cross import module. rdar://123839248
1 parent 52ad460 commit a8f0def

File tree

8 files changed

+161
-81
lines changed

8 files changed

+161
-81
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ class ModuleDependencyInfoStorageBase {
172172
/// The cache key for the produced module.
173173
std::string moduleCacheKey;
174174

175+
/// Auxiliary files that help to construct other dependencies (e.g.
176+
/// command-line), no need to be saved to reconstruct from cache.
177+
std::vector<std::string> auxiliaryFiles;
178+
175179
/// The direct dependency of the module is resolved by scanner.
176180
bool resolved;
177181
/// ModuleDependencyInfo is finalized (with all transitive dependencies
@@ -635,6 +639,24 @@ class ModuleDependencyInfo {
635639
llvm_unreachable("Unexpected type");
636640
}
637641

642+
void addAuxiliaryFile(const std::string &file) {
643+
storage->auxiliaryFiles.emplace_back(file);
644+
}
645+
646+
void updateCASFileSystemRootID(const std::string &rootID) {
647+
if (isSwiftInterfaceModule())
648+
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())
649+
->textualModuleDetails.CASFileSystemRootID = rootID;
650+
else if (isSwiftSourceModule())
651+
cast<SwiftSourceModuleDependenciesStorage>(storage.get())
652+
->textualModuleDetails.CASFileSystemRootID = rootID;
653+
else if (isClangModule())
654+
cast<ClangModuleDependencyStorage>(storage.get())->CASFileSystemRootID =
655+
rootID;
656+
else
657+
llvm_unreachable("Unexpected type");
658+
}
659+
638660
bool isResolved() const {
639661
return storage->resolved;
640662
}
@@ -764,7 +786,8 @@ class ModuleDependencyInfo {
764786
/// Collect a map from a secondary module name to a list of cross-import
765787
/// overlays, when this current module serves as the primary module.
766788
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
767-
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName) const;
789+
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName,
790+
std::vector<std::string> &overlayFiles) const;
768791
};
769792

770793
using ModuleDependencyVector = llvm::SmallVector<std::pair<ModuleDependencyID, ModuleDependencyInfo>, 1>;

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,8 @@ class ModuleDependencyScanner {
7272
DiagnosticEngine &diags, bool ParallelScan);
7373

7474
/// Identify the scanner invocation's main module's dependencies
75-
llvm::ErrorOr<ModuleDependencyInfo> getMainModuleDependencyInfo(
76-
ModuleDecl *mainModule,
77-
std::optional<SwiftDependencyTracker> tracker = std::nullopt);
75+
llvm::ErrorOr<ModuleDependencyInfo>
76+
getMainModuleDependencyInfo(ModuleDecl *mainModule);
7877

7978
/// Resolve module dependencies of the given module, computing a full
8079
/// transitive closure dependency graph.

include/swift/Serialization/ScanningLoaders.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,17 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase {
4141
/// Location where pre-built moduels are to be built into.
4242
std::string moduleOutputPath;
4343

44-
std::optional<SwiftDependencyTracker> dependencyTracker;
45-
4644
public:
4745
std::optional<ModuleDependencyInfo> dependencies;
4846

49-
SwiftModuleScanner(
50-
ASTContext &ctx, ModuleLoadingMode LoadMode, Identifier moduleName,
51-
InterfaceSubContextDelegate &astDelegate, StringRef moduleOutputPath,
52-
ScannerKind kind = MDS_plain,
53-
std::optional<SwiftDependencyTracker> tracker = std::nullopt)
47+
SwiftModuleScanner(ASTContext &ctx, ModuleLoadingMode LoadMode,
48+
Identifier moduleName,
49+
InterfaceSubContextDelegate &astDelegate,
50+
StringRef moduleOutputPath, ScannerKind kind = MDS_plain)
5451
: SerializedModuleLoaderBase(ctx, nullptr, LoadMode,
5552
/*IgnoreSwiftSourceInfoFile=*/true),
5653
kind(kind), moduleName(moduleName), astDelegate(astDelegate),
57-
moduleOutputPath(moduleOutputPath), dependencyTracker(tracker) {}
54+
moduleOutputPath(moduleOutputPath) {}
5855

5956
std::error_code findModuleFilesInDirectory(
6057
ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName,
@@ -91,13 +88,13 @@ class PlaceholderSwiftModuleScanner : public SwiftModuleScanner {
9188
llvm::BumpPtrAllocator Allocator;
9289

9390
public:
94-
PlaceholderSwiftModuleScanner(
95-
ASTContext &ctx, ModuleLoadingMode LoadMode, Identifier moduleName,
96-
StringRef PlaceholderDependencyModuleMap,
97-
InterfaceSubContextDelegate &astDelegate, StringRef moduleOutputPath,
98-
std::optional<SwiftDependencyTracker> tracker = std::nullopt)
91+
PlaceholderSwiftModuleScanner(ASTContext &ctx, ModuleLoadingMode LoadMode,
92+
Identifier moduleName,
93+
StringRef PlaceholderDependencyModuleMap,
94+
InterfaceSubContextDelegate &astDelegate,
95+
StringRef moduleOutputPath)
9996
: SwiftModuleScanner(ctx, LoadMode, moduleName, astDelegate,
100-
moduleOutputPath, MDS_placeholder, tracker) {
97+
moduleOutputPath, MDS_placeholder) {
10198

10299
// FIXME: Find a better place for this map to live, to avoid
103100
// doing the parsing on every module.

lib/AST/ModuleLoader.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,9 @@ void ModuleLoader::findOverlayFiles(SourceLoc diagLoc, ModuleDecl *module,
186186
}
187187

188188
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
189-
ModuleDependencyInfo::collectCrossImportOverlayNames(ASTContext &ctx,
190-
StringRef moduleName) const {
189+
ModuleDependencyInfo::collectCrossImportOverlayNames(
190+
ASTContext &ctx, StringRef moduleName,
191+
std::vector<std::string> &overlayFiles) const {
191192
using namespace llvm::sys;
192193
using namespace file_types;
193194
std::optional<std::string> modulePath;
@@ -239,6 +240,7 @@ ModuleDependencyInfo::collectCrossImportOverlayNames(ASTContext &ctx,
239240
ModuleDecl::collectCrossImportOverlay(ctx, file, moduleName,
240241
bystandingModule);
241242
result[bystandingModule] = std::move(overlayNames);
243+
overlayFiles.push_back(file.str());
242244
});
243245
return result;
244246
}

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,7 @@ static void findAllImportedClangModules(StringRef moduleName,
326326
}
327327

328328
llvm::ErrorOr<ModuleDependencyInfo>
329-
ModuleDependencyScanner::getMainModuleDependencyInfo(
330-
ModuleDecl *mainModule, std::optional<SwiftDependencyTracker> tracker) {
329+
ModuleDependencyScanner::getMainModuleDependencyInfo(ModuleDecl *mainModule) {
331330
// Main module file name.
332331
auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
333332
llvm::SmallString<32> mainModulePath = mainModule->getName().str();
@@ -345,37 +344,19 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(
345344
ExtraPCMArgs.begin(),
346345
{"-Xcc", "-target", "-Xcc", ScanASTContext.LangOpts.Target.str()});
347346

348-
std::string rootID;
349-
if (tracker) {
350-
tracker->startTracking();
351-
for (auto fileUnit : mainModule->getFiles()) {
352-
auto sf = dyn_cast<SourceFile>(fileUnit);
353-
if (!sf)
354-
continue;
355-
tracker->trackFile(sf->getFilename());
356-
}
357-
tracker->addCommonSearchPathDeps(
358-
ScanCompilerInvocation.getSearchPathOptions());
359-
// Fetch some dependency files from clang importer.
360-
std::vector<std::string> clangDependencyFiles;
347+
auto mainDependencies = ModuleDependencyInfo::forSwiftSourceModule(
348+
{}, buildCommands, {}, ExtraPCMArgs);
349+
350+
if (ScanASTContext.CASOpts.EnableCaching) {
361351
auto clangImporter =
362352
static_cast<ClangImporter *>(ScanASTContext.getClangModuleLoader());
353+
std::vector<std::string> clangDependencyFiles;
363354
clangImporter->addClangInvovcationDependencies(clangDependencyFiles);
364-
llvm::for_each(clangDependencyFiles,
365-
[&](std::string &file) { tracker->trackFile(file); });
366-
367-
auto root = tracker->createTreeFromDependencies();
368-
if (!root) {
369-
Diagnostics.diagnose(SourceLoc(), diag::error_cas,
370-
toString(root.takeError()));
371-
return std::make_error_code(std::errc::io_error);
372-
}
373-
rootID = root->getID().toString();
355+
llvm::for_each(clangDependencyFiles, [&](std::string &file) {
356+
mainDependencies.addAuxiliaryFile(file);
357+
});
374358
}
375359

376-
auto mainDependencies =
377-
ModuleDependencyInfo::forSwiftSourceModule(rootID, {}, {}, ExtraPCMArgs);
378-
379360
llvm::StringSet<> alreadyAddedModules;
380361
// Compute Implicit dependencies of the main module
381362
{
@@ -801,6 +782,7 @@ void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(
801782
llvm::function_ref<void(ModuleDependencyID)> action) {
802783
// Modules explicitly imported. Only these can be secondary module.
803784
llvm::SetVector<Identifier> newOverlays;
785+
std::vector<std::string> overlayFiles;
804786
for (auto dep : allDependencies) {
805787
auto moduleName = dep.ModuleName;
806788
// Do not look for overlays of main module under scan
@@ -810,7 +792,7 @@ void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(
810792
auto dependencies = cache.findDependency(moduleName, dep.Kind).value();
811793
// Collect a map from secondary module name to cross-import overlay names.
812794
auto overlayMap = dependencies->collectCrossImportOverlayNames(
813-
ScanASTContext, moduleName);
795+
ScanASTContext, moduleName, overlayFiles);
814796
if (overlayMap.empty())
815797
continue;
816798
for (const auto &dependencyId : allDependencies) {
@@ -872,11 +854,9 @@ void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(
872854

873855
// Update main module's dependencies to include these new overlays.
874856
auto resolvedDummyDep =
875-
*(cache.findDependency(dummyMainName, ModuleDependencyKind::SwiftSource)
876-
.value());
857+
**cache.findDependency(dummyMainName, ModuleDependencyKind::SwiftSource);
877858
auto mainDep =
878-
*(cache.findDependency(mainModuleName, ModuleDependencyKind::SwiftSource)
879-
.value());
859+
**cache.findDependency(mainModuleName, ModuleDependencyKind::SwiftSource);
880860
auto newOverlayDeps = resolvedDummyDep.getDirectModuleDependencies();
881861
auto existingMainDeps = mainDep.getDirectModuleDependencies();
882862
ModuleDependencyIDSet existingMainDepsSet(existingMainDeps.begin(),
@@ -888,6 +868,11 @@ void ModuleDependencyScanner::discoverCrossImportOverlayDependencies(
888868
if (!existingMainDepsSet.count(crossImportOverlayModID))
889869
mainDep.addModuleDependency(crossImportOverlayModID);
890870
});
871+
872+
llvm::for_each(overlayFiles, [&mainDep](const std::string &file) {
873+
mainDep.addAuxiliaryFile(file);
874+
});
875+
891876
cache.updateDependency(
892877
{mainModuleName.str(), ModuleDependencyKind::SwiftSource}, mainDep);
893878

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,11 @@ static llvm::Error resolveExplicitModuleInputs(
207207
auto &service = cache.getScanService();
208208
auto remapPath = [&](StringRef path) { return service.remapPath(path); };
209209
std::vector<std::string> rootIDs;
210-
if (auto ID = resolvingDepInfo.getCASFSRootID())
211-
rootIDs.push_back(*ID);
212-
213210
std::vector<std::string> includeTrees;
214211
if (auto ID = resolvingDepInfo.getClangIncludeTree())
215212
includeTrees.push_back(*ID);
216213

214+
auto tracker = cache.getScanService().createSwiftDependencyTracker();
217215
auto addBridgingHeaderDeps =
218216
[&](const ModuleDependencyInfo &depInfo) -> llvm::Error {
219217
auto sourceDepDetails = depInfo.getAsSwiftSourceModule();
@@ -223,8 +221,7 @@ static llvm::Error resolveExplicitModuleInputs(
223221
if (sourceDepDetails->textualModuleDetails
224222
.CASBridgingHeaderIncludeTreeRootID.empty()) {
225223
if (!sourceDepDetails->textualModuleDetails.bridgingSourceFiles.empty()) {
226-
if (auto tracker =
227-
cache.getScanService().createSwiftDependencyTracker()) {
224+
if (tracker) {
228225
tracker->startTracking();
229226
for (auto &file :
230227
sourceDepDetails->textualModuleDetails.bridgingSourceFiles)
@@ -342,10 +339,32 @@ static llvm::Error resolveExplicitModuleInputs(
342339
// Merge CASFS from clang dependency.
343340
auto &CASFS = cache.getScanService().getSharedCachingFS();
344341
auto &CAS = CASFS.getCAS();
342+
assert(tracker && "no caching tracker is available");
345343

346344
// Update build command line.
347345
if (resolvingDepInfo.isSwiftInterfaceModule() ||
348346
resolvingDepInfo.isSwiftSourceModule()) {
347+
// Compute the CASFS root ID for the resolving dependency.
348+
tracker->startTracking();
349+
tracker->addCommonSearchPathDeps(
350+
instance.getInvocation().getSearchPathOptions());
351+
if (auto *sourceDep = resolvingDepInfo.getAsSwiftSourceModule())
352+
llvm::for_each(
353+
sourceDep->sourceFiles,
354+
[&tracker](const std::string &file) { tracker->trackFile(file); });
355+
else if (auto *textualDep = resolvingDepInfo.getAsSwiftInterfaceModule())
356+
tracker->trackFile(textualDep->swiftInterfaceFile);
357+
358+
llvm::for_each(
359+
textualDep->auxiliaryFiles,
360+
[&tracker](const std::string &file) { tracker->trackFile(file); });
361+
auto root = tracker->createTreeFromDependencies();
362+
if (!root)
363+
return root.takeError();
364+
auto rootID = root->getID().toString();
365+
dependencyInfoCopy.updateCASFileSystemRootID(rootID);
366+
rootIDs.push_back(rootID);
367+
349368
// Update with casfs option.
350369
std::vector<std::string> newCommandLine =
351370
dependencyInfoCopy.getCommandline();
@@ -1898,9 +1917,8 @@ swift::dependencies::performModuleScan(CompilerInstance &instance,
18981917

18991918
// Identify imports of the main module and add an entry for it
19001919
// to the dependency graph.
1901-
auto mainModuleDepInfo = scanner.getMainModuleDependencyInfo(
1902-
instance.getMainModule(),
1903-
cache.getScanService().createSwiftDependencyTracker());
1920+
auto mainModuleDepInfo =
1921+
scanner.getMainModuleDependencyInfo(instance.getMainModule());
19041922
auto mainModuleName = instance.getMainModule()->getNameStr();
19051923
auto mainModuleID = ModuleDependencyID{mainModuleName.str(),
19061924
ModuleDependencyKind::SwiftSource};

lib/Serialization/ScanningLoaders.cpp

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -192,29 +192,21 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath,
192192
*moduleDecl, SourceFileKind::Interface, bufferID, parsingOpts);
193193
moduleDecl->addAuxiliaryFile(*sourceFile);
194194

195-
std::string RootID;
196-
if (dependencyTracker) {
197-
dependencyTracker->startTracking();
198-
dependencyTracker->addCommonSearchPathDeps(Ctx.SearchPathOpts);
195+
std::vector<StringRef> ArgsRefs(Args.begin(), Args.end());
196+
Result = ModuleDependencyInfo::forSwiftInterfaceModule(
197+
outputPathBase.str().str(), InPath, compiledCandidates, ArgsRefs,
198+
PCMArgs, Hash, isFramework, {}, /*module-cache-key*/ "");
199+
200+
if (Ctx.CASOpts.EnableCaching) {
199201
std::vector<std::string> clangDependencyFiles;
200202
auto clangImporter =
201203
static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
202204
clangImporter->addClangInvovcationDependencies(clangDependencyFiles);
203205
llvm::for_each(clangDependencyFiles, [&](std::string &file) {
204-
dependencyTracker->trackFile(file);
206+
Result->addAuxiliaryFile(file);
205207
});
206-
dependencyTracker->trackFile(moduleInterfacePath);
207-
auto RootOrError = dependencyTracker->createTreeFromDependencies();
208-
if (!RootOrError)
209-
return llvm::errorToErrorCode(RootOrError.takeError());
210-
RootID = RootOrError->getID().toString();
211208
}
212209

213-
std::vector<StringRef> ArgsRefs(Args.begin(), Args.end());
214-
Result = ModuleDependencyInfo::forSwiftInterfaceModule(
215-
outputPathBase.str().str(), InPath, compiledCandidates, ArgsRefs,
216-
PCMArgs, Hash, isFramework, RootID, /*module-cache-key*/ "");
217-
218210
// Walk the source file to find the import declarations.
219211
llvm::StringSet<> alreadyAddedModules;
220212
Result->addModuleImport(*sourceFile, alreadyAddedModules);
@@ -247,9 +239,6 @@ ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
247239
ImportPath::Module::Builder builder(moduleName);
248240
auto modulePath = builder.get();
249241
auto moduleId = modulePath.front().Item;
250-
std::optional<SwiftDependencyTracker> tracker = std::nullopt;
251-
if (CacheFS)
252-
tracker = SwiftDependencyTracker(*CacheFS, mapper);
253242

254243
// Do not load interface module if it is testable import.
255244
ModuleLoadingMode MLM =
@@ -264,10 +253,10 @@ ModuleDependencyVector SerializedModuleLoaderBase::getModuleDependencies(
264253
// FIXME: submodules?
265254
scanners.push_back(std::make_unique<PlaceholderSwiftModuleScanner>(
266255
Ctx, MLM, moduleId, Ctx.SearchPathOpts.PlaceholderDependencyModuleMap,
267-
delegate, moduleOutputPath, tracker));
256+
delegate, moduleOutputPath));
268257
scanners.push_back(std::make_unique<SwiftModuleScanner>(
269258
Ctx, MLM, moduleId, delegate, moduleOutputPath,
270-
SwiftModuleScanner::MDS_plain, tracker));
259+
SwiftModuleScanner::MDS_plain));
271260

272261
// Check whether there is a module with this name that we can import.
273262
assert(isa<PlaceholderSwiftModuleScanner>(scanners[0].get()) &&

0 commit comments

Comments
 (0)