Skip to content

Commit d2e7bdc

Browse files
committed
Teach SwiftModules To Embed Incremental Information
Take advantage of the binary swiftdeps serialization utliities built during #32131. Add a new optional information block to swiftdeps files. For now, don't actually serialize swiftdeps information. Frontends will use this information to determine whether to write incremental dependencies across modules into their swiftdeps files. We will then teach the driver to deserialize the data from this section and integrate it into its incremental decision making.
1 parent 8e73d21 commit d2e7bdc

11 files changed

+112
-31
lines changed

include/swift/AST/FineGrainedDependencyFormat.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ bool readFineGrainedDependencyGraph(llvm::StringRef path,
124124

125125
/// Tries to write the dependency graph to the given path name.
126126
/// Returns true if there was an error.
127-
bool writeFineGrainedDependencyGraph(DiagnosticEngine &diags, llvm::StringRef path,
127+
bool writeFineGrainedDependencyGraphToPath(DiagnosticEngine &diags,
128+
llvm::StringRef path,
129+
const SourceFileDepGraph &g);
130+
131+
void writeFineGrainedDependencyGraph(llvm::BitstreamWriter &Out,
128132
const SourceFileDepGraph &g);
129133

130134
} // namespace fine_grained_dependencies

include/swift/Subsystems.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ namespace swift {
7575
class TypeConverter;
7676
}
7777

78+
namespace fine_grained_dependencies {
79+
class SourceFileDepGraph;
80+
}
81+
7882
/// @{
7983

8084
/// \returns true if the declaration should be verified. This can return
@@ -174,8 +178,10 @@ namespace swift {
174178
using ModuleOrSourceFile = PointerUnion<ModuleDecl *, SourceFile *>;
175179

176180
/// Serializes a module or single source file to the given output file.
177-
void serialize(ModuleOrSourceFile DC, const SerializationOptions &options,
178-
const SILModule *M = nullptr);
181+
void
182+
serialize(ModuleOrSourceFile DC, const SerializationOptions &options,
183+
const SILModule *M = nullptr,
184+
const fine_grained_dependencies::SourceFileDepGraph *DG = nullptr);
179185

180186
/// Serializes a module or single source file to the given output file and
181187
/// returns back the file's contents as a memory buffer.

lib/AST/FineGrainedDependencyFormat.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,13 @@ class Serializer {
289289
unsigned LastIdentifierID = 0;
290290
std::vector<StringRef> IdentifiersToWrite;
291291

292-
SmallVector<char, 0> Buffer;
293-
llvm::BitstreamWriter Out{Buffer};
292+
llvm::BitstreamWriter &Out;
294293

295294
/// A reusable buffer for emitting records.
296295
SmallVector<uint64_t, 64> ScratchRecord;
297296

298297
std::array<unsigned, 256> AbbrCodes;
299298

300-
void writeFineGrainedDependencyGraph(const SourceFileDepGraph &g);
301-
302299
void addIdentifier(StringRef str);
303300
unsigned getIdentifier(StringRef str);
304301

@@ -321,8 +318,10 @@ class Serializer {
321318
void writeMetadata();
322319

323320
public:
324-
void writeFineGrainedDependencyGraph(llvm::raw_ostream &os,
325-
const SourceFileDepGraph &g);
321+
Serializer(llvm::BitstreamWriter &ExistingOut) : Out(ExistingOut) {}
322+
323+
public:
324+
void writeFineGrainedDependencyGraph(const SourceFileDepGraph &g);
326325
};
327326

328327
} // end namespace
@@ -467,20 +466,22 @@ unsigned Serializer::getIdentifier(StringRef str) {
467466
return iter->second;
468467
}
469468

470-
void Serializer::writeFineGrainedDependencyGraph(llvm::raw_ostream &os,
471-
const SourceFileDepGraph &g) {
472-
writeFineGrainedDependencyGraph(g);
473-
os.write(Buffer.data(), Buffer.size());
474-
os.flush();
469+
void swift::fine_grained_dependencies::writeFineGrainedDependencyGraph(
470+
llvm::BitstreamWriter &Out, const SourceFileDepGraph &g) {
471+
Serializer serializer{Out};
472+
serializer.writeFineGrainedDependencyGraph(g);
475473
}
476474

477-
bool swift::fine_grained_dependencies::writeFineGrainedDependencyGraph(
475+
bool swift::fine_grained_dependencies::writeFineGrainedDependencyGraphToPath(
478476
DiagnosticEngine &diags, StringRef path,
479477
const SourceFileDepGraph &g) {
480478
PrettyStackTraceStringAction stackTrace("saving fine-grained dependency graph", path);
481479
return withOutputFile(diags, path, [&](llvm::raw_ostream &out) {
482-
Serializer serializer;
483-
serializer.writeFineGrainedDependencyGraph(out, g);
480+
SmallVector<char, 0> Buffer;
481+
llvm::BitstreamWriter Writer{Buffer};
482+
writeFineGrainedDependencyGraph(Writer, g);
483+
out.write(Buffer.data(), Buffer.size());
484+
out.flush();
484485
return false;
485486
});
486-
}
487+
}

lib/AST/FrontendSourceFileDepGraphFactory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ bool fine_grained_dependencies::emitReferenceDependencies(
251251
SF, outputPath, depTracker, alsoEmitDotFile)
252252
.construct();
253253

254-
bool hadError = writeFineGrainedDependencyGraph(diags, outputPath, g);
254+
bool hadError = writeFineGrainedDependencyGraphToPath(diags, outputPath, g);
255255

256256
// If path is stdout, cannot read it back, so check for "-"
257257
assert(outputPath == "-" || g.verifyReadsWhatIsWritten(outputPath));

lib/Serialization/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_swift_host_library(swiftSerialization STATIC
88
SerializedModuleLoader.cpp
99
SerializedSILLoader.cpp
1010
SerializeDoc.cpp
11+
SerializeIncremental.cpp
1112
SerializeSIL.cpp
1213

1314
LLVM_LINK_COMPONENTS

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,17 @@ ModuleFileSharedCore::ModuleFileSharedCore(
14271427
break;
14281428
}
14291429

1430+
case INCREMENTAL_INFORMATION_BLOCK_ID: {
1431+
HasIncrementalInfo = true;
1432+
// Skip incremental info if present. The Frontend currently doesn't do
1433+
// anything with this.
1434+
if (cursor.SkipBlock()) {
1435+
info.status = error(Status::Malformed);
1436+
return;
1437+
}
1438+
break;
1439+
}
1440+
14301441
default:
14311442
// Unknown top-level block, possibly for use by a future version of the
14321443
// module format.

lib/Serialization/ModuleFormat.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t SWIFTMODULE_VERSION_MINOR = 578; // Remove hasNonPatternBindingInit
58+
const uint16_t SWIFTMODULE_VERSION_MINOR = 579; // incremental deps info block
5959

6060
/// A standard hash seed used for all string hashes in a serialized module.
6161
///
@@ -729,6 +729,11 @@ enum BlockID {
729729
///
730730
/// \sa decl_locs_block
731731
DECL_LOCS_BLOCK_ID,
732+
733+
/// The incremental dependency information block.
734+
///
735+
/// This is part of a stable format and should not be renumbered.
736+
INCREMENTAL_INFORMATION_BLOCK_ID = 196,
732737
};
733738

734739
/// The record types within the control block.

lib/Serialization/Serialization.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5212,9 +5212,11 @@ SerializerBase::SerializerBase(ArrayRef<unsigned char> signature,
52125212
this->SF = DC.dyn_cast<SourceFile *>();
52135213
}
52145214

5215-
void Serializer::writeToStream(raw_ostream &os, ModuleOrSourceFile DC,
5216-
const SILModule *SILMod,
5217-
const SerializationOptions &options) {
5215+
void Serializer::writeToStream(
5216+
raw_ostream &os, ModuleOrSourceFile DC,
5217+
const SILModule *SILMod,
5218+
const SerializationOptions &options,
5219+
const fine_grained_dependencies::SourceFileDepGraph *DepGraph) {
52185220
Serializer S{SWIFTMODULE_SIGNATURE, DC};
52195221

52205222
// FIXME: This is only really needed for debugging. We don't actually use it.
@@ -5226,6 +5228,9 @@ void Serializer::writeToStream(raw_ostream &os, ModuleOrSourceFile DC,
52265228
S.writeInputBlock(options);
52275229
S.writeSIL(SILMod, options.SerializeAllSIL);
52285230
S.writeAST(DC);
5231+
if (options.ExperimentalCrossModuleIncrementalInfo) {
5232+
S.writeIncrementalInfo(DepGraph);
5233+
}
52295234
}
52305235

52315236
S.writeToStream(os);
@@ -5244,7 +5249,8 @@ void swift::serializeToBuffers(
52445249
"Serialization, swiftmodule, to buffer");
52455250
llvm::SmallString<1024> buf;
52465251
llvm::raw_svector_ostream stream(buf);
5247-
Serializer::writeToStream(stream, DC, M, options);
5252+
Serializer::writeToStream(stream, DC, M, options,
5253+
/*dependency info*/ nullptr);
52485254
bool hadError = withOutputFile(getContext(DC).Diags,
52495255
options.OutputPath,
52505256
[&](raw_ostream &out) {
@@ -5295,12 +5301,13 @@ void swift::serializeToBuffers(
52955301

52965302
void swift::serialize(ModuleOrSourceFile DC,
52975303
const SerializationOptions &options,
5298-
const SILModule *M) {
5304+
const SILModule *M,
5305+
const fine_grained_dependencies::SourceFileDepGraph *DG) {
52995306
assert(!StringRef::withNullAsEmpty(options.OutputPath).empty());
53005307

53015308
if (StringRef(options.OutputPath) == "-") {
53025309
// Special-case writing to stdout.
5303-
Serializer::writeToStream(llvm::outs(), DC, M, options);
5310+
Serializer::writeToStream(llvm::outs(), DC, M, options, DG);
53045311
assert(StringRef::withNullAsEmpty(options.DocOutputPath).empty());
53055312
return;
53065313
}
@@ -5310,7 +5317,7 @@ void swift::serialize(ModuleOrSourceFile DC,
53105317
[&](raw_ostream &out) {
53115318
FrontendStatsTracer tracer(getContext(DC).Stats,
53125319
"Serialization, swiftmodule");
5313-
Serializer::writeToStream(out, DC, M, options);
5320+
Serializer::writeToStream(out, DC, M, options, DG);
53145321
return false;
53155322
});
53165323
if (hadError)

lib/Serialization/Serialization.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ namespace clang {
3434
namespace swift {
3535
class SILModule;
3636

37+
namespace fine_grained_dependencies {
38+
class SourceFileDepGraph;
39+
}
40+
3741
namespace serialization {
3842

3943
using FilenamesTy = ArrayRef<std::string>;
@@ -389,14 +393,21 @@ class Serializer : public SerializerBase {
389393
/// Top-level entry point for serializing a module.
390394
void writeAST(ModuleOrSourceFile DC);
391395

396+
/// Serializes the given dependnecy graph into the incremental information
397+
/// section of this swift module.
398+
void writeIncrementalInfo(
399+
const fine_grained_dependencies::SourceFileDepGraph *DepGraph);
400+
392401
using SerializerBase::SerializerBase;
393402
using SerializerBase::writeToStream;
394403

395404
public:
396405
/// Serialize a module to the given stream.
397-
static void writeToStream(raw_ostream &os, ModuleOrSourceFile DC,
398-
const SILModule *M,
399-
const SerializationOptions &options);
406+
static void
407+
writeToStream(raw_ostream &os, ModuleOrSourceFile DC,
408+
const SILModule *M,
409+
const SerializationOptions &options,
410+
const fine_grained_dependencies::SourceFileDepGraph *DepGraph);
400411

401412
/// Records the use of the given Type.
402413
///
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===--- SerializeIncremental.cpp - Write incremental swiftdeps -----------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#define DEBUG_TYPE "serialize-incremental"
14+
#include "Serialization.h"
15+
#include "swift/AST/FineGrainedDependencyFormat.h"
16+
17+
#include <type_traits>
18+
19+
using namespace swift;
20+
using namespace swift::serialization;
21+
using namespace llvm::support;
22+
using llvm::BCBlockRAII;
23+
24+
void Serializer::writeIncrementalInfo(
25+
const fine_grained_dependencies::SourceFileDepGraph *DepGraph) {
26+
if (!DepGraph)
27+
return;
28+
29+
{
30+
BCBlockRAII restoreBlock(Out, INCREMENTAL_INFORMATION_BLOCK_ID, 5);
31+
swift::fine_grained_dependencies::writeFineGrainedDependencyGraph(
32+
Out, *DepGraph);
33+
}
34+
}

0 commit comments

Comments
 (0)