Skip to content

Commit 7917d72

Browse files
committed
Teach the Driver to Read Fine-Grained Dependency Graphs in Swiftdeps Files
1 parent 485467e commit 7917d72

File tree

7 files changed

+154
-5
lines changed

7 files changed

+154
-5
lines changed

include/swift/AST/FineGrainedDependencies.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,8 @@ class SourceFileDepGraph {
851851
/// Read a swiftdeps file from \p buffer and return a SourceFileDepGraph if
852852
/// successful.
853853
Optional<SourceFileDepGraph> static loadFromBuffer(llvm::MemoryBuffer &);
854+
Optional<SourceFileDepGraph> static loadFromSwiftModuleBuffer(
855+
llvm::MemoryBuffer &);
854856

855857
void verifySame(const SourceFileDepGraph &other) const;
856858

include/swift/AST/FineGrainedDependencyFormat.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ using NodeKindField = BCFixed<3>;
4848
using DeclAspectField = BCFixed<1>;
4949

5050
const unsigned RECORD_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID;
51+
const unsigned INCREMENTAL_INFORMATION_BLOCK_ID = 196;
5152

5253
/// The swiftdeps file format consists of a METADATA record, followed by zero or more
5354
/// IDENTIFIER_NODE records.
@@ -113,10 +114,16 @@ namespace record_block {
113114
}
114115

115116
/// Tries to read the dependency graph from the given buffer.
116-
/// Returns true if there was an error.
117+
/// Returns \c true if there was an error.
117118
bool readFineGrainedDependencyGraph(llvm::MemoryBuffer &buffer,
118119
SourceFileDepGraph &g);
119120

121+
/// Tries to read the dependency graph from the given buffer, assuming that it
122+
/// is in the format of a swiftmodule file.
123+
/// Returns \c true if there was an error.
124+
bool readFineGrainedDependencyGraphFromSwiftModule(llvm::MemoryBuffer &buffer,
125+
SourceFileDepGraph &g);
126+
120127
/// Tries to read the dependency graph from the given path name.
121128
/// Returns true if there was an error.
122129
bool readFineGrainedDependencyGraph(llvm::StringRef path,

include/swift/Driver/FineGrainedDependencyDriverGraph.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ class ModuleDepGraph {
336336
const SourceFileDepGraph &,
337337
DiagnosticEngine &);
338338

339+
Changes loadFromSwiftModuleBuffer(const driver::Job *, llvm::MemoryBuffer &,
340+
DiagnosticEngine &);
339341

340342
private:
341343
/// Read a SourceFileDepGraph belonging to \p job from \p buffer

lib/AST/FineGrainedDependencies.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ SourceFileDepGraph::loadFromBuffer(llvm::MemoryBuffer &buffer) {
5858
return Optional<SourceFileDepGraph>(std::move(fg));
5959
}
6060

61+
Optional<SourceFileDepGraph>
62+
SourceFileDepGraph::loadFromSwiftModuleBuffer(llvm::MemoryBuffer &buffer) {
63+
SourceFileDepGraph fg;
64+
if (swift::fine_grained_dependencies::
65+
readFineGrainedDependencyGraphFromSwiftModule(buffer, fg))
66+
return None;
67+
return Optional<SourceFileDepGraph>(std::move(fg));
68+
}
69+
6170
//==============================================================================
6271
// MARK: SourceFileDepGraph access
6372
//==============================================================================

lib/AST/FineGrainedDependencyFormat.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class Deserializer {
4545
public:
4646
Deserializer(llvm::MemoryBufferRef Data) : Cursor(Data) {}
4747
bool readFineGrainedDependencyGraph(SourceFileDepGraph &g);
48+
bool readFineGrainedDependencyGraphFromSwiftModule(SourceFileDepGraph &g);
4849
};
4950

5051
} // end namespace
@@ -485,3 +486,106 @@ bool swift::fine_grained_dependencies::writeFineGrainedDependencyGraphToPath(
485486
return false;
486487
});
487488
}
489+
490+
static bool checkModuleSignature(llvm::BitstreamCursor &cursor,
491+
ArrayRef<unsigned char> signature) {
492+
for (unsigned char byte : signature) {
493+
if (cursor.AtEndOfStream())
494+
return false;
495+
if (llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead =
496+
cursor.Read(8)) {
497+
if (maybeRead.get() != byte)
498+
return false;
499+
} else {
500+
consumeError(maybeRead.takeError());
501+
return false;
502+
}
503+
}
504+
return true;
505+
}
506+
507+
static bool enterTopLevelModuleBlock(llvm::BitstreamCursor &cursor, unsigned ID,
508+
bool shouldReadBlockInfo = true) {
509+
llvm::Expected<llvm::BitstreamEntry> maybeNext = cursor.advance();
510+
if (!maybeNext) {
511+
consumeError(maybeNext.takeError());
512+
return false;
513+
}
514+
llvm::BitstreamEntry next = maybeNext.get();
515+
516+
if (next.Kind != llvm::BitstreamEntry::SubBlock)
517+
return false;
518+
519+
if (next.ID == RECORD_BLOCK_ID) {
520+
if (shouldReadBlockInfo) {
521+
if (!cursor.ReadBlockInfoBlock())
522+
return false;
523+
} else {
524+
if (cursor.SkipBlock())
525+
return false;
526+
}
527+
return enterTopLevelModuleBlock(cursor, ID, false);
528+
}
529+
530+
if (next.ID != ID)
531+
return false;
532+
533+
if (llvm::Error Err = cursor.EnterSubBlock(ID)) {
534+
// FIXME this drops the error on the floor.
535+
consumeError(std::move(Err));
536+
return false;
537+
}
538+
539+
return true;
540+
}
541+
542+
bool swift::fine_grained_dependencies::
543+
readFineGrainedDependencyGraphFromSwiftModule(llvm::MemoryBuffer &buffer,
544+
SourceFileDepGraph &g) {
545+
Deserializer deserializer(buffer.getMemBufferRef());
546+
return deserializer.readFineGrainedDependencyGraphFromSwiftModule(g);
547+
}
548+
549+
bool Deserializer::readFineGrainedDependencyGraphFromSwiftModule(
550+
SourceFileDepGraph &g) {
551+
if (!checkModuleSignature(Cursor, {0xE2, 0x9C, 0xA8, 0x0E}) ||
552+
!enterTopLevelModuleBlock(Cursor, RECORD_BLOCK_ID, false)) {
553+
return false;
554+
}
555+
556+
llvm::BitstreamEntry topLevelEntry;
557+
558+
while (!Cursor.AtEndOfStream()) {
559+
llvm::Expected<llvm::BitstreamEntry> maybeEntry =
560+
Cursor.advance(llvm::BitstreamCursor::AF_DontPopBlockAtEnd);
561+
if (!maybeEntry) {
562+
consumeError(maybeEntry.takeError());
563+
return false;
564+
}
565+
topLevelEntry = maybeEntry.get();
566+
if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
567+
break;
568+
569+
switch (topLevelEntry.ID) {
570+
case INCREMENTAL_INFORMATION_BLOCK_ID: {
571+
if (llvm::Error Err =
572+
Cursor.EnterSubBlock(INCREMENTAL_INFORMATION_BLOCK_ID)) {
573+
consumeError(std::move(Err));
574+
return false;
575+
}
576+
readFineGrainedDependencyGraph(g);
577+
break;
578+
}
579+
580+
default:
581+
// Unknown top-level block, possibly for use by a future version of the
582+
// module format.
583+
if (Cursor.SkipBlock()) {
584+
return false;
585+
}
586+
break;
587+
}
588+
}
589+
590+
return false;
591+
}

lib/Driver/FineGrainedDependencyDriverGraph.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,27 @@ ModuleDepGraph::Changes ModuleDepGraph::loadFromSourceFileDepGraph(
108108
return changes;
109109
}
110110

111+
ModuleDepGraph::Changes ModuleDepGraph::loadFromSwiftModuleBuffer(
112+
const Job *Cmd, llvm::MemoryBuffer &buffer, DiagnosticEngine &diags) {
113+
FrontendStatsTracer tracer(
114+
stats, "fine-grained-dependencies-loadFromSwiftModuleBuffer");
115+
PrettyStackTraceStringAction stackTrace(
116+
"loading fine-grained dependency graph from swiftmodule",
117+
buffer.getBufferIdentifier());
118+
119+
Optional<SourceFileDepGraph> sourceFileDepGraph =
120+
SourceFileDepGraph::loadFromSwiftModuleBuffer(buffer);
121+
if (!sourceFileDepGraph)
122+
return None;
123+
registerJob(Cmd);
124+
auto changes = integrate(*sourceFileDepGraph, buffer.getBufferIdentifier());
125+
if (verifyFineGrainedDependencyGraphAfterEveryImport)
126+
verify();
127+
if (emitFineGrainedDependencyDotFileAfterEveryImport)
128+
emitDotFileForJob(diags, Cmd);
129+
return changes;
130+
}
131+
111132
bool ModuleDepGraph::haveAnyNodesBeenTraversedIn(const Job *cmd) const {
112133
std::string swiftDeps = getSwiftDeps(cmd).str();
113134

lib/Serialization/ModuleFormat.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
#define SWIFT_SERIALIZATION_MODULEFORMAT_H
2121

2222
#include "swift/AST/Decl.h"
23+
#include "swift/AST/FineGrainedDependencyFormat.h"
2324
#include "swift/AST/Types.h"
25+
#include "llvm/ADT/PointerEmbeddedInt.h"
2426
#include "llvm/Bitcode/RecordLayout.h"
2527
#include "llvm/Bitstream/BitCodes.h"
26-
#include "llvm/ADT/PointerEmbeddedInt.h"
2728

2829
namespace swift {
2930
namespace serialization {
@@ -724,16 +725,19 @@ enum BlockID {
724725
/// This is part of a stable format and should not be renumbered.
725726
///
726727
/// Though we strive to keep the format stable, breaking the format of
727-
/// .swiftsourceinfo doesn't have consequences as serious as breaking the format
728-
/// of .swiftdoc because .swiftsourceinfo file is for local development use only.
728+
/// .swiftsourceinfo doesn't have consequences as serious as breaking the
729+
/// format
730+
/// of .swiftdoc because .swiftsourceinfo file is for local development use
731+
/// only.
729732
///
730733
/// \sa decl_locs_block
731734
DECL_LOCS_BLOCK_ID,
732735

733736
/// The incremental dependency information block.
734737
///
735738
/// This is part of a stable format and should not be renumbered.
736-
INCREMENTAL_INFORMATION_BLOCK_ID = 196,
739+
INCREMENTAL_INFORMATION_BLOCK_ID =
740+
fine_grained_dependencies::INCREMENTAL_INFORMATION_BLOCK_ID,
737741
};
738742

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

0 commit comments

Comments
 (0)