Skip to content

Commit bc30953

Browse files
committed
[Dependency Scanning] Fix optional import statement serialization logic
Previously, serialization of optional import statement node arrays erroneously used the node layout of a non-optional import node array while maintaining a separate index for these arrays which got serialized into each module's info node. This meant it got serialized out in a sequence of non-optional import arrays, and as a result, the consumer deserialized them as such, which broke ordering of which arrays of import nodes belong which module, causing mismatches between a module's actual import set and the import which got deserialized for it. This change fixes the optional import serialization routine to use the purpose-made separate layout which gets read out according to the separate optional import array index.
1 parent 030564b commit bc30953

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

lib/DependencyScan/ModuleDependencyCacheSerialization.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class ModuleDependenciesCacheDeserializer {
4949
std::vector<std::vector<uint64_t>> ArraysOfMacroDependenciesIDs;
5050
std::vector<ScannerImportStatementInfo> ImportStatements;
5151
std::vector<std::vector<uint64_t>> ArraysOfImportStatementIDs;
52-
std::vector<std::vector<uint64_t>> ArraysOfSearchPathIDs;
5352
std::vector<std::vector<uint64_t>> ArraysOfOptionalImportStatementIDs;
53+
std::vector<std::vector<uint64_t>> ArraysOfSearchPathIDs;
5454

5555
llvm::BitstreamCursor Cursor;
5656
SmallVector<uint64_t, 64> Scratch;
@@ -1170,6 +1170,7 @@ class ModuleDependenciesCacheSerializer {
11701170
unsigned writeImportStatementInfos(const ModuleDependencyInfo &dependencyInfo,
11711171
bool optional);
11721172
void writeImportStatementInfosArray(unsigned startIndex, unsigned count);
1173+
void writeOptionalImportStatementInfosArray(unsigned startIndex, unsigned count);
11731174

11741175
void writeModuleInfo(ModuleDependencyID moduleID,
11751176
const ModuleDependencyInfo &dependencyInfo);
@@ -1478,7 +1479,7 @@ void ModuleDependenciesCacheSerializer::writeImportStatementInfos(
14781479
}
14791480
auto optionalEntries = optionalImportInfoArrayMap.at(moduleID);
14801481
if (optionalEntries.second != 0) {
1481-
writeImportStatementInfosArray(optionalEntries.first, optionalEntries.second);
1482+
writeOptionalImportStatementInfosArray(optionalEntries.first, optionalEntries.second);
14821483
OptionalImportInfosArrayIDsMap.insert({moduleID, lastOptionalImportInfoArrayIndex++});
14831484
}
14841485
}
@@ -1530,6 +1531,15 @@ void ModuleDependenciesCacheSerializer::writeImportStatementInfosArray(
15301531
Out, ScratchRecord, AbbrCodes[ImportStatementArrayLayout::Code], vec);
15311532
}
15321533

1534+
void ModuleDependenciesCacheSerializer::writeOptionalImportStatementInfosArray(
1535+
unsigned startIndex, unsigned count) {
1536+
using namespace graph_block;
1537+
std::vector<unsigned> vec(count);
1538+
std::iota(vec.begin(), vec.end(), startIndex);
1539+
OptionalImportStatementArrayLayout::emitRecord(
1540+
Out, ScratchRecord, AbbrCodes[OptionalImportStatementArrayLayout::Code], vec);
1541+
}
1542+
15331543
void ModuleDependenciesCacheSerializer::writeModuleInfo(
15341544
ModuleDependencyID moduleID, const ModuleDependencyInfo &dependencyInfo) {
15351545
using namespace graph_block;
@@ -1965,6 +1975,7 @@ void ModuleDependenciesCacheSerializer::writeInterModuleDependenciesCache(
19651975
registerRecordAbbr<SearchPathArrayLayout>();
19661976
registerRecordAbbr<ImportStatementLayout>();
19671977
registerRecordAbbr<ImportStatementArrayLayout>();
1978+
registerRecordAbbr<OptionalImportStatementArrayLayout>();
19681979
registerRecordAbbr<ModuleInfoLayout>();
19691980
registerRecordAbbr<SwiftSourceModuleDetailsLayout>();
19701981
registerRecordAbbr<SwiftInterfaceModuleDetailsLayout>();

test/ScanDependencies/serialized_imports.swift

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
// RUN: %empty-directory(%t/module-cache)
44

55
// Run the scanner once, emitting the serialized scanner cache
6-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE
6+
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays -module-name deps 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE
77
// RUN: llvm-bcanalyzer --dump %t/cache.moddepcache > %t/cache.moddepcache.initial.dump.txt
8+
// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix CHECK-IMPORTS
89

910
// Run the scanner again, but now re-using previously-serialized cache
10-
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD
11+
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/module-cache %s -o %t/deps_incremental.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -enable-cross-import-overlays -module-name deps 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD
1112
// RUN: llvm-bcanalyzer --dump %t/cache.moddepcache > %t/cache.moddepcache.dump.txt
13+
// RUN: %validate-json %t/deps_incremental.json | %FileCheck %s -check-prefix CHECK-IMPORTS
1214

1315
// Ensure that the initial scan, and the secondary scan which just re-used the initial scan's results report
1416
// the same number of import statement nodes, ensuring that serialization-deserialization did not affect
@@ -22,8 +24,26 @@
2224
// CHECK-REMARK-SAVE: remark: Incremental module scan: Serializing module scanning dependency cache to:
2325
// CHECK-REMARK-LOAD: remark: Incremental module scan: Re-using serialized module scanning dependency cache from:
2426

25-
import E
26-
27-
28-
27+
// CHECK-IMPORTS: "modulePath": "deps.swiftmodule",
28+
// CHECK-IMPORTS: "imports": [
29+
// CHECK-IMPORTS-NEXT: {
30+
// CHECK-IMPORTS-NEXT: "identifier": "Swift",
31+
// CHECK-IMPORTS-NEXT: "accessLevel": "public"
32+
// CHECK-IMPORTS-NEXT: },
33+
// CHECK-IMPORTS-NEXT: {
34+
// CHECK-IMPORTS-NEXT: "identifier": "SwiftOnoneSupport",
35+
// CHECK-IMPORTS-NEXT: "accessLevel": "public"
36+
// CHECK-IMPORTS-NEXT: },
37+
// CHECK-IMPORTS-NEXT: {
38+
// CHECK-IMPORTS-NEXT: "identifier": "E",
39+
// CHECK-IMPORTS-NEXT: "accessLevel": "public",
40+
// CHECK-IMPORTS-NEXT: "importLocations": [
41+
// CHECK-IMPORTS-NEXT: {
42+
// CHECK-IMPORTS-NEXT: "bufferIdentifier": "{{.*}}serialized_imports.swift",
43+
// CHECK-IMPORTS-NEXT: "linuNumber": 49,
44+
// CHECK-IMPORTS-NEXT: "columnNumber": 8
45+
// CHECK-IMPORTS-NEXT: }
46+
// CHECK-IMPORTS-NEXT: ]
47+
// CHECK-IMPORTS-NEXT: }
2948

49+
import E

0 commit comments

Comments
 (0)