[Dependency Scanning] Make GlobalModuleDependenciesCache aware of the current scanning action's target triple

And only resolve cached dependencies that came from scanning actions with the same target triple.

This change means that the `GlobalModuleDependenciesCache` must be configured with a specific target triple for every scannig action, and it will only resolve previously-found dependencies from previous scannig actions using the exact same triple.

Furthermore, the `GlobalModuleDependenciesCache` separately tracks source-file-based module dependencies as those represent main Swift modules of previous scanning actions, and we must be able to resolve those regardless of the target triple.

Resolves rdar://83105455
This commit is contained in:
Artem Chikin
2021-09-14 19:01:14 -07:00
parent e64a40451b
commit 709676c20c
8 changed files with 580 additions and 389 deletions

View File

@@ -151,8 +151,18 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
bool hasCurrentModule = false;
std::string currentModuleName;
unsigned currentTripleID;
llvm::Optional<std::vector<std::string>> currentModuleDependencies;
auto getTriple = [&]() {
assert(currentTripleID &&
"Expected target triple ID for a MODULE_DETAILS_NODE record");
auto triple = getIdentifier(currentTripleID);
if (!triple.hasValue())
llvm::report_fatal_error("Unexpected MODULE_DETAILS_NODE record");
return triple.getValue();
};
while (!Cursor.AtEndOfStream()) {
auto entry = cantFail(Cursor.advance(), "Advance bitstream cursor");
@@ -198,14 +208,14 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
case MODULE_NODE: {
hasCurrentModule = true;
unsigned moduleNameID, moduleDependenciesArrayID;
ModuleInfoLayout::readRecord(Scratch, moduleNameID,
unsigned moduleNameID, tripleID, moduleDependenciesArrayID;
ModuleInfoLayout::readRecord(Scratch, moduleNameID, tripleID,
moduleDependenciesArrayID);
auto moduleName = getIdentifier(moduleNameID);
if (!moduleName)
llvm::report_fatal_error("Bad module name");
currentModuleName = *moduleName;
currentTripleID = tripleID;
currentModuleDependencies = getArray(moduleDependenciesArrayID);
if (!currentModuleDependencies)
llvm::report_fatal_error("Bad direct dependencies");
@@ -216,6 +226,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_TEXTUAL_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned interfaceFileID, compiledModuleCandidatesArrayID,
buildCommandLineArrayID, extraPCMArgsArrayID, contextHashID,
isFramework, bridgingHeaderFileID, sourceFilesArrayID,
@@ -303,11 +314,17 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_SOURCE_MODULE_DETAILS_NODE record");
// Expected triple ID is 0
if (currentTripleID)
llvm::report_fatal_error(
"Unexpected target triple on MODULE_NODE corresponding to a "
"SWIFT_SOURCE_MODULE_DETAILS_NODE record");
unsigned extraPCMArgsArrayID, bridgingHeaderFileID, sourceFilesArrayID,
bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID;
SwiftSourceModuleDetailsLayout::readRecord(
Scratch, extraPCMArgsArrayID, bridgingHeaderFileID, sourceFilesArrayID,
bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID);
Scratch, extraPCMArgsArrayID, bridgingHeaderFileID,
sourceFilesArrayID, bridgingSourceFilesArrayID,
bridgingModuleDependenciesArrayID);
auto extraPCMArgs = getArray(extraPCMArgsArrayID);
if (!extraPCMArgs)
@@ -363,6 +380,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_BINARY_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID,
isFramework;
SwiftBinaryModuleDetailsLayout::readRecord(
@@ -396,6 +414,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_PLACEHOLDER_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID;
SwiftPlaceholderModuleDetailsLayout::readRecord(
Scratch, compiledModulePathID, moduleDocPathID,
@@ -426,6 +445,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
case CLANG_MODULE_DETAILS_NODE: {
if (!hasCurrentModule)
llvm::report_fatal_error("Unexpected CLANG_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned moduleMapPathID, contextHashID, commandLineArrayID,
fileDependenciesArrayID;
ClangModuleDetailsLayout::readRecord(Scratch, moduleMapPathID,
@@ -647,13 +667,15 @@ class Serializer {
void writeArraysOfIdentifiers();
void writeModuleInfo(ModuleDependencyID moduleID,
Optional<std::string> triple,
const ModuleDependencies &dependencyInfo);
public:
Serializer(llvm::BitstreamWriter &ExistingOut) : Out(ExistingOut) {}
public:
void writeInterModuleDependenciesCache(const GlobalModuleDependenciesCache &cache);
void
writeInterModuleDependenciesCache(const GlobalModuleDependenciesCache &cache);
};
} // end namespace
@@ -735,22 +757,27 @@ void Serializer::writeArraysOfIdentifiers() {
}
void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
Optional<std::string> triple,
const ModuleDependencies &dependencyInfo) {
using namespace graph_block;
auto tripleStrID = triple.hasValue() ? getIdentifier(triple.getValue()) : 0;
ModuleInfoLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[ModuleInfoLayout::Code],
getIdentifier(moduleID.first),
getIdentifier(moduleID.first), tripleStrID,
getArray(moduleID, ModuleIdentifierArrayKind::DirectDependencies));
switch (dependencyInfo.getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto swiftTextDeps = dependencyInfo.getAsSwiftInterfaceModule();
assert(swiftTextDeps);
unsigned swiftInterfaceFileId = getIdentifier(swiftTextDeps->swiftInterfaceFile);
unsigned swiftInterfaceFileId =
getIdentifier(swiftTextDeps->swiftInterfaceFile);
unsigned bridgingHeaderFileId =
swiftTextDeps->bridgingHeaderFile
? getIdentifier(swiftTextDeps->bridgingHeaderFile.getValue())
swiftTextDeps->textualModuleDetails.bridgingHeaderFile
? getIdentifier(swiftTextDeps->textualModuleDetails
.bridgingHeaderFile.getValue())
: 0;
SwiftInterfaceModuleDetailsLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[SwiftInterfaceModuleDetailsLayout::Code],
@@ -767,11 +794,14 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
assert(!triple.hasValue() &&
"Did not expecte triple for serializing MODULE_NODE");
auto swiftSourceDeps = dependencyInfo.getAsSwiftSourceModule();
assert(swiftSourceDeps);
unsigned bridgingHeaderFileId =
swiftSourceDeps->bridgingHeaderFile
? getIdentifier(swiftSourceDeps->bridgingHeaderFile.getValue())
swiftSourceDeps->textualModuleDetails.bridgingHeaderFile
? getIdentifier(swiftSourceDeps->textualModuleDetails
.bridgingHeaderFile.getValue())
: 0;
SwiftSourceModuleDetailsLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[SwiftSourceModuleDetailsLayout::Code],
@@ -784,6 +814,7 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::SwiftBinary: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto swiftBinDeps = dependencyInfo.getAsSwiftBinaryModule();
assert(swiftBinDeps);
SwiftBinaryModuleDetailsLayout::emitRecord(
@@ -795,6 +826,7 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::SwiftPlaceholder: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto swiftPHDeps = dependencyInfo.getAsPlaceholderDependencyModule();
assert(swiftPHDeps);
SwiftPlaceholderModuleDetailsLayout::emitRecord(
@@ -806,6 +838,7 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::Clang: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto clangDeps = dependencyInfo.getAsClangModule();
assert(clangDeps);
ClangModuleDetailsLayout::emitRecord(
@@ -889,87 +922,104 @@ unsigned Serializer::getArray(ModuleDependencyID moduleID,
return arrayIter->second;
}
void Serializer::collectStringsAndArrays(const GlobalModuleDependenciesCache &cache) {
for (auto &moduleID : cache.getAllModules()) {
auto dependencyInfos = cache.findAllDependenciesIrrespectiveOfSearchPaths(
moduleID.first, moduleID.second);
assert(dependencyInfos.hasValue() && "Expected dependency info.");
for (auto &dependencyInfo : *dependencyInfos) {
// Add the module's name
addIdentifier(moduleID.first);
// Add the module's dependencies
addArray(moduleID, ModuleIdentifierArrayKind::DirectDependencies,
dependencyInfo.getModuleDependencies());
void Serializer::collectStringsAndArrays(
const GlobalModuleDependenciesCache &cache) {
for (auto &moduleID : cache.getAllSourceModules()) {
assert(moduleID.second == ModuleDependenciesKind::SwiftSource &&
"Expected source-based dependency");
auto optionalDependencyInfo =
cache.findSourceModuleDependency(moduleID.first);
assert(optionalDependencyInfo.hasValue() && "Expected dependency info.");
auto dependencyInfo = optionalDependencyInfo.getValue();
// Add the module's name
addIdentifier(moduleID.first);
// Add the module's dependencies
addArray(moduleID, ModuleIdentifierArrayKind::DirectDependencies,
dependencyInfo.getModuleDependencies());
auto swiftSourceDeps = dependencyInfo.getAsSwiftSourceModule();
assert(swiftSourceDeps);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftSourceDeps->textualModuleDetails.extraPCMArgs);
if (swiftSourceDeps->textualModuleDetails.bridgingHeaderFile.hasValue())
addIdentifier(
swiftSourceDeps->textualModuleDetails.bridgingHeaderFile.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
swiftSourceDeps->sourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftSourceDeps->textualModuleDetails.bridgingSourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftSourceDeps->textualModuleDetails.bridgingModuleDependencies);
}
// Add the dependency-kind-specific data
switch (dependencyInfo.getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftTextDeps = dependencyInfo.getAsSwiftInterfaceModule();
assert(swiftTextDeps);
addIdentifier(swiftTextDeps->swiftInterfaceFile);
addArray(moduleID, ModuleIdentifierArrayKind::CompiledModuleCandidates,
swiftTextDeps->compiledModuleCandidates);
addArray(moduleID, ModuleIdentifierArrayKind::BuildCommandLine,
swiftTextDeps->buildCommandLine);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftTextDeps->extraPCMArgs);
addIdentifier(swiftTextDeps->contextHash);
if (swiftTextDeps->bridgingHeaderFile)
addIdentifier(swiftTextDeps->bridgingHeaderFile.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
swiftTextDeps->sourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftTextDeps->bridgingSourceFiles);
addArray(moduleID,
ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftTextDeps->bridgingModuleDependencies);
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceDeps = dependencyInfo.getAsSwiftSourceModule();
assert(swiftSourceDeps);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftSourceDeps->extraPCMArgs);
if (swiftSourceDeps->bridgingHeaderFile)
addIdentifier(swiftSourceDeps->bridgingHeaderFile.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
swiftSourceDeps->sourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftSourceDeps->bridgingSourceFiles);
addArray(moduleID,
ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftSourceDeps->bridgingModuleDependencies);
break;
}
case swift::ModuleDependenciesKind::SwiftBinary: {
auto swiftBinDeps = dependencyInfo.getAsSwiftBinaryModule();
assert(swiftBinDeps);
addIdentifier(swiftBinDeps->compiledModulePath);
addIdentifier(swiftBinDeps->moduleDocPath);
addIdentifier(swiftBinDeps->sourceInfoPath);
break;
}
case swift::ModuleDependenciesKind::SwiftPlaceholder: {
auto swiftPHDeps = dependencyInfo.getAsPlaceholderDependencyModule();
assert(swiftPHDeps);
addIdentifier(swiftPHDeps->compiledModulePath);
addIdentifier(swiftPHDeps->moduleDocPath);
addIdentifier(swiftPHDeps->sourceInfoPath);
break;
}
case swift::ModuleDependenciesKind::Clang: {
auto clangDeps = dependencyInfo.getAsClangModule();
assert(clangDeps);
addIdentifier(clangDeps->moduleMapFile);
addIdentifier(clangDeps->contextHash);
addArray(moduleID, ModuleIdentifierArrayKind::NonPathCommandLine,
clangDeps->nonPathCommandLine);
addArray(moduleID, ModuleIdentifierArrayKind::FileDependencies,
clangDeps->fileDependencies);
break;
}
default:
llvm_unreachable("Unhandled dependency kind.");
for (auto &triple : cache.getAllTriples()) {
addIdentifier(triple);
for (auto &moduleID : cache.getAllNonSourceModules(triple)) {
auto dependencyInfos = cache.findAllDependenciesIrrespectiveOfSearchPaths(
moduleID.first, moduleID.second);
assert(dependencyInfos.hasValue() && "Expected dependency info.");
for (auto &dependencyInfo : *dependencyInfos) {
// Add the module's name
addIdentifier(moduleID.first);
// Add the module's dependencies
addArray(moduleID, ModuleIdentifierArrayKind::DirectDependencies,
dependencyInfo.getModuleDependencies());
// Add the dependency-kind-specific data
switch (dependencyInfo.getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftTextDeps = dependencyInfo.getAsSwiftInterfaceModule();
assert(swiftTextDeps);
addIdentifier(swiftTextDeps->swiftInterfaceFile);
addArray(moduleID,
ModuleIdentifierArrayKind::CompiledModuleCandidates,
swiftTextDeps->compiledModuleCandidates);
addArray(moduleID, ModuleIdentifierArrayKind::BuildCommandLine,
swiftTextDeps->buildCommandLine);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftTextDeps->textualModuleDetails.extraPCMArgs);
addIdentifier(swiftTextDeps->contextHash);
if (swiftTextDeps->textualModuleDetails.bridgingHeaderFile.hasValue())
addIdentifier(swiftTextDeps->textualModuleDetails.bridgingHeaderFile
.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
std::vector<std::string>());
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftTextDeps->textualModuleDetails.bridgingSourceFiles);
addArray(
moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftTextDeps->textualModuleDetails.bridgingModuleDependencies);
break;
}
case swift::ModuleDependenciesKind::SwiftBinary: {
auto swiftBinDeps = dependencyInfo.getAsSwiftBinaryModule();
assert(swiftBinDeps);
addIdentifier(swiftBinDeps->compiledModulePath);
addIdentifier(swiftBinDeps->moduleDocPath);
addIdentifier(swiftBinDeps->sourceInfoPath);
break;
}
case swift::ModuleDependenciesKind::SwiftPlaceholder: {
auto swiftPHDeps = dependencyInfo.getAsPlaceholderDependencyModule();
assert(swiftPHDeps);
addIdentifier(swiftPHDeps->compiledModulePath);
addIdentifier(swiftPHDeps->moduleDocPath);
addIdentifier(swiftPHDeps->sourceInfoPath);
break;
}
case swift::ModuleDependenciesKind::Clang: {
auto clangDeps = dependencyInfo.getAsClangModule();
assert(clangDeps);
addIdentifier(clangDeps->moduleMapFile);
addIdentifier(clangDeps->contextHash);
addArray(moduleID, ModuleIdentifierArrayKind::NonPathCommandLine,
clangDeps->nonPathCommandLine);
addArray(moduleID, ModuleIdentifierArrayKind::FileDependencies,
clangDeps->fileDependencies);
break;
}
default:
llvm_unreachable("Unhandled dependency kind.");
}
}
}
}
@@ -1011,12 +1061,24 @@ void Serializer::writeInterModuleDependenciesCache(
writeArraysOfIdentifiers();
// Write the core graph
for (auto &moduleID : cache.getAllModules()) {
auto dependencyInfos = cache.findAllDependenciesIrrespectiveOfSearchPaths(
moduleID.first, moduleID.second);
assert(dependencyInfos.hasValue() && "Expected dependency info.");
for (auto &dependencyInfo : *dependencyInfos) {
writeModuleInfo(moduleID, dependencyInfo);
// First, write the source modules we've encountered
for (auto &moduleID : cache.getAllSourceModules()) {
auto dependencyInfo = cache.findSourceModuleDependency(moduleID.first);
assert(dependencyInfo.hasValue() && "Expected dependency info.");
writeModuleInfo(moduleID, llvm::Optional<std::string>(),
dependencyInfo.getValue());
}
// Write all non-source modules, for each of the target triples this scanner
// has been used with
for (auto &triple : cache.getAllTriples()) {
for (auto &moduleID : cache.getAllNonSourceModules(triple)) {
auto dependencyInfos = cache.findAllDependenciesIrrespectiveOfSearchPaths(
moduleID.first, moduleID.second);
assert(dependencyInfos.hasValue() && "Expected dependency info.");
for (auto &dependencyInfo : *dependencyInfos) {
writeModuleInfo(moduleID, triple, dependencyInfo);
}
}
}
@@ -1024,15 +1086,17 @@ void Serializer::writeInterModuleDependenciesCache(
}
void swift::dependencies::module_dependency_cache_serialization::
writeInterModuleDependenciesCache(llvm::BitstreamWriter &Out,
const GlobalModuleDependenciesCache &cache) {
writeInterModuleDependenciesCache(
llvm::BitstreamWriter &Out,
const GlobalModuleDependenciesCache &cache) {
Serializer serializer{Out};
serializer.writeInterModuleDependenciesCache(cache);
}
bool swift::dependencies::module_dependency_cache_serialization::
writeInterModuleDependenciesCache(DiagnosticEngine &diags, StringRef path,
const GlobalModuleDependenciesCache &cache) {
writeInterModuleDependenciesCache(
DiagnosticEngine &diags, StringRef path,
const GlobalModuleDependenciesCache &cache) {
PrettyStackTraceStringAction stackTrace(
"saving inter-module dependency graph", path);
return withOutputFile(diags, path, [&](llvm::raw_ostream &out) {