Skip to content

Commit 18798b6

Browse files
authored
Merge pull request #66556 from artemcm/TransitivePCHDepsOfBinaryModules
[Dependency Scanning] Record header dependencies of binary Swift module dependencies
2 parents 185820a + 92d9e61 commit 18798b6

File tree

15 files changed

+240
-76
lines changed

15 files changed

+240
-76
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ SWIFTSCAN_PUBLIC swiftscan_string_ref_t
180180
swiftscan_swift_binary_detail_get_module_source_info_path(
181181
swiftscan_module_details_t details);
182182

183+
SWIFTSCAN_PUBLIC swiftscan_string_set_t *
184+
swiftscan_swift_binary_detail_get_header_dependencies(
185+
swiftscan_module_details_t details);
186+
183187
SWIFTSCAN_PUBLIC bool
184188
swiftscan_swift_binary_detail_get_is_framework(
185189
swiftscan_module_details_t details);

include/swift/AST/ModuleDependencies.h

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,15 @@ class ModuleDependencyInfoStorageBase {
106106
const ModuleDependencyKind dependencyKind;
107107

108108
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind,
109-
StringRef moduleCacheKey = "",
110-
bool resolved = false)
109+
StringRef moduleCacheKey = "")
111110
: dependencyKind(dependencyKind), moduleCacheKey(moduleCacheKey.str()),
112-
resolved(resolved) {}
111+
resolved(false) { }
112+
113+
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind,
114+
const std::vector<std::string> &moduleImports,
115+
StringRef moduleCacheKey = "")
116+
: dependencyKind(dependencyKind), moduleImports(moduleImports),
117+
moduleCacheKey(moduleCacheKey.str()), resolved(false) {}
113118

114119
virtual ModuleDependencyInfoStorageBase *clone() const = 0;
115120

@@ -282,12 +287,15 @@ class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBas
282287
SwiftBinaryModuleDependencyStorage(const std::string &compiledModulePath,
283288
const std::string &moduleDocPath,
284289
const std::string &sourceInfoPath,
290+
const std::vector<std::string> &moduleImports,
291+
const std::vector<std::string> &headerImports,
285292
const bool isFramework,
286293
const std::string &moduleCacheKey)
287294
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftBinary,
288-
moduleCacheKey),
295+
moduleImports, moduleCacheKey),
289296
compiledModulePath(compiledModulePath), moduleDocPath(moduleDocPath),
290-
sourceInfoPath(sourceInfoPath), isFramework(isFramework) {}
297+
sourceInfoPath(sourceInfoPath), preCompiledBridgingHeaderPaths(headerImports),
298+
isFramework(isFramework) {}
291299

292300
ModuleDependencyInfoStorageBase *clone() const override {
293301
return new SwiftBinaryModuleDependencyStorage(*this);
@@ -302,6 +310,9 @@ class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBas
302310
/// The path to the .swiftSourceInfo file.
303311
const std::string sourceInfoPath;
304312

313+
/// The paths of all the .pch dependencies of this module.
314+
const std::vector<std::string> preCompiledBridgingHeaderPaths;
315+
305316
/// A flag that indicates this dependency is a framework
306317
const bool isFramework;
307318

@@ -447,15 +458,17 @@ class ModuleDependencyInfo {
447458
}
448459

449460
/// Describe the module dependencies for a serialized or parsed Swift module.
450-
static ModuleDependencyInfo
451-
forSwiftBinaryModule(const std::string &compiledModulePath,
452-
const std::string &moduleDocPath,
453-
const std::string &sourceInfoPath, bool isFramework,
454-
const std::string &moduleCacheKey) {
461+
static ModuleDependencyInfo forSwiftBinaryModule(
462+
const std::string &compiledModulePath,
463+
const std::string &moduleDocPath,
464+
const std::string &sourceInfoPath,
465+
const std::vector<std::string> &moduleImports,
466+
const std::vector<std::string> &headerImports,
467+
bool isFramework, const std::string &moduleCacheKey) {
455468
return ModuleDependencyInfo(
456469
std::make_unique<SwiftBinaryModuleDependencyStorage>(
457-
compiledModulePath, moduleDocPath, sourceInfoPath, isFramework,
458-
moduleCacheKey));
470+
compiledModulePath, moduleDocPath, sourceInfoPath,
471+
moduleImports, headerImports, isFramework, moduleCacheKey));
459472
}
460473

461474
/// Describe the main Swift module.

include/swift/DependencyScan/DependencyScanImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ typedef struct {
121121
/// The path to the .swiftSourceInfo file.
122122
swiftscan_string_ref_t module_source_info_path;
123123

124+
/// (Clang) header dependencies of this binary module.
125+
/// Typically pre-compiled bridging header.
126+
swiftscan_string_set_t *header_dependencies;
127+
124128
/// A flag to indicate whether or not this module is a framework.
125129
bool is_framework;
126130

include/swift/DependencyScan/SerializedModuleDependencyCacheFormat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ using SwiftBinaryModuleDetailsLayout =
165165
FileIDField, // compiledModulePath
166166
FileIDField, // moduleDocPath
167167
FileIDField, // moduleSourceInfoPath
168+
ImportArrayIDField, // headerImports
168169
IsFrameworkField, // isFramework
169170
IdentifierIDField // moduleCacheKey
170171
>;

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,14 @@ struct ExplicitSwiftModuleInputInfo {
241241
ExplicitSwiftModuleInputInfo(std::string modulePath,
242242
llvm::Optional<std::string> moduleDocPath,
243243
llvm::Optional<std::string> moduleSourceInfoPath,
244+
llvm::Optional<std::vector<std::string>> headerDependencyPaths,
244245
bool isFramework = false,
245246
bool isSystem = false,
246247
llvm::Optional<std::string> moduleCacheKey = None)
247248
: modulePath(modulePath),
248249
moduleDocPath(moduleDocPath),
249250
moduleSourceInfoPath(moduleSourceInfoPath),
251+
headerDependencyPaths(headerDependencyPaths),
250252
isFramework(isFramework),
251253
isSystem(isSystem),
252254
moduleCacheKey(moduleCacheKey) {}
@@ -256,6 +258,8 @@ struct ExplicitSwiftModuleInputInfo {
256258
llvm::Optional<std::string> moduleDocPath;
257259
// Path of the .swiftsourceinfo file.
258260
llvm::Optional<std::string> moduleSourceInfoPath;
261+
// Paths of the precompiled header dependencies of this module.
262+
llvm::Optional<std::vector<std::string>> headerDependencyPaths;
259263
// A flag that indicates whether this module is a framework
260264
bool isFramework = false;
261265
// A flag that indicates whether this module is a system module
@@ -369,34 +373,39 @@ class ExplicitModuleMapParser {
369373
llvm::Optional<std::string> swiftModulePath, swiftModuleDocPath,
370374
swiftModuleSourceInfoPath, swiftModuleCacheKey,
371375
clangModuleCacheKey;
376+
llvm::Optional<std::vector<std::string>> headerDependencyPaths;
372377
std::string clangModuleMapPath = "", clangModulePath = "";
373378
bool isFramework = false, isSystem = false;
374379
for (auto &entry : *mapNode) {
375380
auto key = getScalaNodeText(entry.getKey());
376-
auto val = getScalaNodeText(entry.getValue());
377-
if (key == "moduleName") {
378-
moduleName = val;
379-
} else if (key == "modulePath") {
380-
swiftModulePath = val.str();
381-
} else if (key == "docPath") {
382-
swiftModuleDocPath = val.str();
383-
} else if (key == "sourceInfoPath") {
384-
swiftModuleSourceInfoPath = val.str();
385-
} else if (key == "isFramework") {
386-
isFramework = parseBoolValue(val);
387-
} else if (key == "isSystem") {
388-
isSystem = parseBoolValue(val);
389-
} else if (key == "clangModuleMapPath") {
390-
clangModuleMapPath = val.str();
391-
} else if (key == "clangModulePath") {
392-
clangModulePath = val.str();
393-
} else if (key == "moduleCacheKey") {
394-
swiftModuleCacheKey = val.str();
395-
} else if (key == "clangModuleCacheKey") {
396-
clangModuleCacheKey = val.str();
397-
} else {
398-
// Being forgiving for future fields.
381+
if (key == "prebuiltHeaderDependencyPaths") {
399382
continue;
383+
} else {
384+
auto val = getScalaNodeText(entry.getValue());
385+
if (key == "moduleName") {
386+
moduleName = val;
387+
} else if (key == "modulePath") {
388+
swiftModulePath = val.str();
389+
} else if (key == "docPath") {
390+
swiftModuleDocPath = val.str();
391+
} else if (key == "sourceInfoPath") {
392+
swiftModuleSourceInfoPath = val.str();
393+
} else if (key == "isFramework") {
394+
isFramework = parseBoolValue(val);
395+
} else if (key == "isSystem") {
396+
isSystem = parseBoolValue(val);
397+
} else if (key == "clangModuleMapPath") {
398+
clangModuleMapPath = val.str();
399+
} else if (key == "clangModulePath") {
400+
clangModulePath = val.str();
401+
} else if (key == "moduleCacheKey") {
402+
swiftModuleCacheKey = val.str();
403+
} else if (key == "clangModuleCacheKey") {
404+
clangModuleCacheKey = val.str();
405+
} else {
406+
// Being forgiving for future fields.
407+
continue;
408+
}
400409
}
401410
}
402411
if (moduleName.empty())
@@ -409,6 +418,7 @@ class ExplicitModuleMapParser {
409418
ExplicitSwiftModuleInputInfo entry(swiftModulePath.value(),
410419
swiftModuleDocPath,
411420
swiftModuleSourceInfoPath,
421+
headerDependencyPaths,
412422
isFramework,
413423
isSystem,
414424
swiftModuleCacheKey);

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,20 @@ class SerializedModuleLoaderBase : public ModuleLoader {
150150
/// Scan the given serialized module file to determine dependencies.
151151
llvm::ErrorOr<ModuleDependencyInfo> scanModuleFile(Twine modulePath, bool isFramework);
152152

153-
static llvm::ErrorOr<llvm::StringSet<>>
154-
getModuleImportsOfModule(Twine modulePath,
155-
ModuleLoadingBehavior transitiveBehavior,
156-
bool isFramework,
157-
bool isRequiredOSSAModules,
158-
StringRef SDKName,
159-
StringRef packageName,
160-
llvm::vfs::FileSystem *fileSystem,
161-
PathObfuscator &recoverer);
153+
struct BinaryModuleImports {
154+
llvm::StringSet<> moduleImports;
155+
llvm::StringSet<> headerImports;
156+
};
157+
158+
static llvm::ErrorOr<BinaryModuleImports>
159+
getImportsOfModule(Twine modulePath,
160+
ModuleLoadingBehavior transitiveBehavior,
161+
bool isFramework,
162+
bool isRequiredOSSAModules,
163+
StringRef SDKName,
164+
StringRef packageName,
165+
llvm::vfs::FileSystem *fileSystem,
166+
PathObfuscator &recoverer);
162167

163168
/// Load the module file into a buffer and also collect its module name.
164169
static std::unique_ptr<llvm::MemoryBuffer>

lib/DependencyScan/ModuleDependencyCacheSerialization.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,11 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
462462
"Unexpected SWIFT_BINARY_MODULE_DETAILS_NODE record");
463463
cache.configureForContextHash(getContextHash());
464464
unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID,
465-
isFramework, moduleCacheKeyID;
465+
headerImportsArrayID, isFramework, moduleCacheKeyID;
466466
SwiftBinaryModuleDetailsLayout::readRecord(
467467
Scratch, compiledModulePathID, moduleDocPathID,
468-
moduleSourceInfoPathID, isFramework, moduleCacheKeyID);
468+
moduleSourceInfoPathID, headerImportsArrayID, isFramework,
469+
moduleCacheKeyID);
469470

470471
auto compiledModulePath = getIdentifier(compiledModulePathID);
471472
if (!compiledModulePath)
@@ -477,16 +478,18 @@ bool ModuleDependenciesCacheDeserializer::readGraph(SwiftDependencyScanningServi
477478
if (!moduleSourceInfoPath)
478479
llvm::report_fatal_error("Bad module source info path");
479480
auto moduleCacheKey = getIdentifier(moduleCacheKeyID);
480-
if (!moduleCacheKeyID)
481+
if (!moduleCacheKey)
481482
llvm::report_fatal_error("Bad moduleCacheKey");
482483

484+
auto headerImports = getStringArray(headerImportsArrayID);
485+
if (!headerImports)
486+
llvm::report_fatal_error("Bad binary direct dependencies: no header imports");
487+
483488
// Form the dependencies storage object
484489
auto moduleDep = ModuleDependencyInfo::forSwiftBinaryModule(
485-
*compiledModulePath, *moduleDocPath, *moduleSourceInfoPath,
486-
isFramework, *moduleCacheKey);
487-
// Add dependencies of this module
488-
for (const auto &moduleName : *currentModuleImports)
489-
moduleDep.addModuleImport(moduleName);
490+
*compiledModulePath, *moduleDocPath, *moduleSourceInfoPath,
491+
*currentModuleImports, *headerImports, isFramework,
492+
*moduleCacheKey);
490493

491494
cache.recordDependency(currentModuleName, std::move(moduleDep),
492495
getContextHash());
@@ -704,6 +707,7 @@ bool swift::dependencies::module_dependency_cache_serialization::
704707
enum ModuleIdentifierArrayKind : uint8_t {
705708
Empty = 0,
706709
DependencyImports,
710+
DependencyHeaders,
707711
QualifiedModuleDependencyIDs,
708712
CompiledModuleCandidates,
709713
BuildCommandLine,
@@ -975,6 +979,7 @@ void ModuleDependenciesCacheSerializer::writeModuleInfo(ModuleDependencyID modul
975979
getIdentifier(swiftBinDeps->compiledModulePath),
976980
getIdentifier(swiftBinDeps->moduleDocPath),
977981
getIdentifier(swiftBinDeps->sourceInfoPath),
982+
getArrayID(moduleID, ModuleIdentifierArrayKind::DependencyHeaders),
978983
swiftBinDeps->isFramework,
979984
getIdentifier(swiftBinDeps->moduleCacheKey));
980985

@@ -1152,6 +1157,8 @@ void ModuleDependenciesCacheSerializer::collectStringsAndArrays(
11521157
addIdentifier(swiftBinDeps->moduleDocPath);
11531158
addIdentifier(swiftBinDeps->sourceInfoPath);
11541159
addIdentifier(swiftBinDeps->moduleCacheKey);
1160+
addStringArray(moduleID, ModuleIdentifierArrayKind::DependencyHeaders,
1161+
swiftBinDeps->preCompiledBridgingHeaderPaths);
11551162
break;
11561163
}
11571164
case swift::ModuleDependencyKind::SwiftPlaceholder: {

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ computeTransitiveClosureOfExplicitDependencies(
254254
llvm::set_union(modReachableSet, succReachableSet);
255255
}
256256
}
257+
// For ease of use down-the-line, remove the node's self from its set of reachable nodes
258+
for (const auto &modID : topologicallySortedModuleList)
259+
result[modID].erase(modID);
260+
257261
return result;
258262
}
259263

@@ -330,6 +334,12 @@ static llvm::Error resolveExplicitModuleInputs(
330334
: binaryDepDetails->moduleCacheKey;
331335
commandLine.push_back("-swift-module-file=" + depModuleID.first + "=" +
332336
path);
337+
for (const auto &headerDep : binaryDepDetails->preCompiledBridgingHeaderPaths) {
338+
commandLine.push_back("-Xcc");
339+
commandLine.push_back("-include-pch");
340+
commandLine.push_back("-Xcc");
341+
commandLine.push_back(headerDep);
342+
}
333343
} break;
334344
case swift::ModuleDependencyKind::SwiftPlaceholder: {
335345
auto placeholderDetails = depInfo->getAsPlaceholderDependencyModule();
@@ -1163,6 +1173,13 @@ static void writeJSON(llvm::raw_ostream &out,
11631173
swiftBinaryDeps->module_cache_key, 5,
11641174
/*trailingComma=*/true);
11651175
}
1176+
1177+
// Module Header Dependencies
1178+
if (swiftBinaryDeps->header_dependencies->count != 0)
1179+
writeJSONSingleField(out, "headerDependencies",
1180+
swiftBinaryDeps->header_dependencies, 5,
1181+
/*trailingComma=*/true);
1182+
11661183
writeJSONSingleField(out, "isFramework", swiftBinaryDeps->is_framework,
11671184
5, /*trailingComma=*/false);
11681185
} else {
@@ -1399,6 +1416,7 @@ generateFullDependencyGraph(CompilerInstance &instance,
13991416
create_clone(swiftBinaryDeps->compiledModulePath.c_str()),
14001417
create_clone(swiftBinaryDeps->moduleDocPath.c_str()),
14011418
create_clone(swiftBinaryDeps->sourceInfoPath.c_str()),
1419+
create_set(swiftBinaryDeps->preCompiledBridgingHeaderPaths),
14021420
swiftBinaryDeps->isFramework,
14031421
create_clone(swiftBinaryDeps->moduleCacheKey.c_str())};
14041422
} else {

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,7 +2004,7 @@ struct ExplicitSwiftModuleLoader::Implementation {
20042004
const std::vector<std::pair<std::string, std::string>>
20052005
&commandLineExplicitInputs) {
20062006
for (const auto &moduleInput : commandLineExplicitInputs) {
2007-
ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {});
2007+
ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}, {});
20082008
ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry));
20092009
}
20102010
}
@@ -2270,7 +2270,7 @@ struct ExplicitCASModuleLoader::Implementation {
22702270
const std::vector<std::pair<std::string, std::string>>
22712271
&commandLineExplicitInputs) {
22722272
for (const auto &moduleInput : commandLineExplicitInputs) {
2273-
ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {});
2273+
ExplicitSwiftModuleInputInfo entry(moduleInput.second, {}, {}, {});
22742274
ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry));
22752275
}
22762276
}

0 commit comments

Comments
 (0)