Skip to content

Commit cb94753

Browse files
authored
Merge pull request #24503 from jrose-apple/artiodactyla
[Serialization] Reduce file size by splitting dep dirnames from basenames
2 parents 81e5cdb + 6720a7c commit cb94753

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

include/swift/Serialization/ModuleFormat.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 489; // backing variables
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 490; // dependency directories
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -644,6 +644,7 @@ namespace input_block {
644644
MODULE_FLAGS, // [unused]
645645
SEARCH_PATH,
646646
FILE_DEPENDENCY,
647+
DEPENDENCY_DIRECTORY,
647648
PARSEABLE_INTERFACE_PATH
648649
};
649650

@@ -689,9 +690,15 @@ namespace input_block {
689690
FileModTimeOrContentHashField, // mtime or content hash (for validation)
690691
BCFixed<1>, // are we reading mtime (0) or hash (1)?
691692
BCFixed<1>, // SDK-relative?
693+
BCVBR<8>, // subpath-relative index (0=none)
692694
BCBlob // path
693695
>;
694696

697+
using DependencyDirectoryLayout = BCRecordLayout<
698+
DEPENDENCY_DIRECTORY,
699+
BCBlob
700+
>;
701+
695702
using ParseableInterfaceLayout = BCRecordLayout<
696703
PARSEABLE_INTERFACE_PATH,
697704
BCBlob // file path

lib/Serialization/ModuleFile.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ validateControlBlock(llvm::BitstreamCursor &cursor,
239239
static bool validateInputBlock(
240240
llvm::BitstreamCursor &cursor, SmallVectorImpl<uint64_t> &scratch,
241241
SmallVectorImpl<SerializationOptions::FileDependency> &dependencies) {
242+
SmallVector<StringRef, 4> dependencyDirectories;
243+
SmallString<256> dependencyFullPathBuffer;
244+
242245
while (!cursor.AtEndOfStream()) {
243246
auto entry = cursor.advance();
244247
if (entry.Kind == llvm::BitstreamEntry::EndBlock)
@@ -255,17 +258,30 @@ static bool validateInputBlock(
255258
bool isHashBased = scratch[2] != 0;
256259
bool isSDKRelative = scratch[3] != 0;
257260

261+
StringRef path = blobData;
262+
size_t directoryIndex = scratch[4];
263+
if (directoryIndex != 0) {
264+
if (directoryIndex > dependencyDirectories.size())
265+
return true;
266+
dependencyFullPathBuffer = dependencyDirectories[directoryIndex-1];
267+
llvm::sys::path::append(dependencyFullPathBuffer, blobData);
268+
path = dependencyFullPathBuffer;
269+
}
270+
258271
if (isHashBased) {
259272
dependencies.push_back(
260273
SerializationOptions::FileDependency::hashBased(
261-
blobData, isSDKRelative, scratch[0], scratch[1]));
274+
path, isSDKRelative, scratch[0], scratch[1]));
262275
} else {
263276
dependencies.push_back(
264277
SerializationOptions::FileDependency::modTimeBased(
265-
blobData, isSDKRelative, scratch[0], scratch[1]));
278+
path, isSDKRelative, scratch[0], scratch[1]));
266279
}
267280
break;
268281
}
282+
case input_block::DEPENDENCY_DIRECTORY:
283+
dependencyDirectories.push_back(blobData);
284+
break;
269285
default:
270286
// Unknown metadata record, possibly for use by a future version of the
271287
// module format.

lib/Serialization/Serialization.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,7 @@ void Serializer::writeBlockInfoBlock() {
835835
BLOCK_RECORD(input_block, MODULE_FLAGS);
836836
BLOCK_RECORD(input_block, SEARCH_PATH);
837837
BLOCK_RECORD(input_block, FILE_DEPENDENCY);
838+
BLOCK_RECORD(input_block, DEPENDENCY_DIRECTORY);
838839
BLOCK_RECORD(input_block, PARSEABLE_INTERFACE_PATH);
839840

840841
BLOCK(DECLS_AND_TYPES_BLOCK);
@@ -1062,6 +1063,7 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
10621063
input_block::ImportedHeaderContentsLayout ImportedHeaderContents(Out);
10631064
input_block::SearchPathLayout SearchPath(Out);
10641065
input_block::FileDependencyLayout FileDependency(Out);
1066+
input_block::DependencyDirectoryLayout DependencyDirectory(Out);
10651067
input_block::ParseableInterfaceLayout ParseableInterface(Out);
10661068

10671069
if (options.SerializeOptionsForDebugging) {
@@ -1075,13 +1077,24 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
10751077
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false, path);
10761078
}
10771079

1080+
// Note: We're not using StringMap here because we don't need to own the
1081+
// strings.
1082+
llvm::DenseMap<StringRef, unsigned> dependencyDirectories;
10781083
for (auto const &dep : options.Dependencies) {
1084+
StringRef directoryName = llvm::sys::path::parent_path(dep.getPath());
1085+
unsigned &dependencyDirectoryIndex = dependencyDirectories[directoryName];
1086+
if (!dependencyDirectoryIndex) {
1087+
// This name must be newly-added. Give it a new ID (and skip 0).
1088+
dependencyDirectoryIndex = dependencyDirectories.size();
1089+
DependencyDirectory.emit(ScratchRecord, directoryName);
1090+
}
10791091
FileDependency.emit(ScratchRecord,
10801092
dep.getSize(),
10811093
getRawModTimeOrHash(dep),
10821094
dep.isHashBased(),
10831095
dep.isSDKRelative(),
1084-
dep.getPath());
1096+
dependencyDirectoryIndex,
1097+
llvm::sys::path::filename(dep.getPath()));
10851098
}
10861099

10871100
if (!options.ParseableInterface.empty())

test/ParseableInterface/ModuleCache/SystemDependencies.swiftinterface

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
// RUN: echo 'import SystemDependencies' | %target-swift-frontend -typecheck - -I %S -sdk %t/mock-sdk -module-cache-path %t/MCP-system -emit-dependencies-path %t/dummy.d -track-system-dependencies
2323
// RUN: test -f %t/MCP-system/SystemDependencies*.swiftmodule
2424
// RUN: %FileCheck -check-prefix CHECK %s < %t/dummy.d
25+
// RUN: llvm-bcanalyzer -dump %t/MCP-system/SystemDependencies*.swiftmodule | %FileCheck -check-prefix CHECK-DUMP %s
2526
// RUN: %{python} %S/Inputs/make-old.py %t/MCP-system/SystemDependencies*.swiftmodule
2627

2728
// Baseline: running the same command again doesn't rebuild the cached module.
@@ -41,6 +42,13 @@
4142

4243
// NEGATIVE-NOT: SomeCModule.h
4344
// CHECK: SomeCModule.h
45+
46+
// CHECK-DUMP-NOT: usr/include
47+
// CHECK-DUMP: DEPENDENCY_DIRECTORY{{.+}}'usr/include'
48+
// CHECK-DUMP-NEXT: FILE_DEPENDENCY{{.+}}'module.modulemap'
49+
// CHECK-DUMP-NEXT: FILE_DEPENDENCY{{.+}}'SomeCModule.h'
50+
// CHECK-DUMP-NOT: usr/include
51+
4452
// MODULECACHE-COUNT-2: SystemDependencies-{{[^ ]+}}.swiftmodule
4553

4654
import SomeCModule

0 commit comments

Comments
 (0)