Skip to content

Commit af5e0aa

Browse files
committed
Cache parsed source files in the PrintingDiagnosticConsumer
We were re-parsing each source file for each top-level diagnostic emitted, which is... rather inefficient. Cache the parsed source files until the PrintingDiagnosticConsumer goes away.
1 parent 06d4d8c commit af5e0aa

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

include/swift/Frontend/PrintingDiagnosticConsumer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
5151
void *queuedDiagnostics = nullptr;
5252
llvm::DenseMap<unsigned, QueuedBuffer> queuedBuffers;
5353

54+
/// Source file syntax nodes cached by { source manager, buffer ID }.
55+
llvm::DenseMap<std::pair<SourceManager *, unsigned>, void *> sourceFileSyntax;
56+
5457
public:
5558
PrintingDiagnosticConsumer(llvm::raw_ostream &stream = llvm::errs());
5659
~PrintingDiagnosticConsumer();
@@ -90,6 +93,9 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
9093
}
9194

9295
private:
96+
/// Retrieve the SourceFileSyntax for the given buffer.
97+
void *getSourceFileSyntax(SourceManager &SM, unsigned bufferID);
98+
9399
void queueBuffer(SourceManager &sourceMgr, unsigned bufferID);
94100
void printDiagnostic(SourceManager &SM, const DiagnosticInfo &Info);
95101
};

lib/Frontend/PrintingDiagnosticConsumer.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -304,17 +304,27 @@ static SmallVector<unsigned, 1> getSourceBufferStack(
304304
}
305305
}
306306

307-
void PrintingDiagnosticConsumer::queueBuffer(
307+
void *PrintingDiagnosticConsumer::getSourceFileSyntax(
308308
SourceManager &sourceMgr, unsigned bufferID) {
309-
QueuedBuffer knownSourceFile = queuedBuffers[bufferID];
310-
if (knownSourceFile)
311-
return;
309+
auto known = sourceFileSyntax.find({&sourceMgr, bufferID});
310+
if (known != sourceFileSyntax.end())
311+
return known->second;
312312

313313
auto bufferContents = sourceMgr.getEntireTextForBuffer(bufferID);
314314
auto sourceFile = swift_ASTGen_parseSourceFile(
315315
bufferContents.data(), bufferContents.size(),
316316
"module", "file.swift", /*ctx*/ nullptr);
317317

318+
sourceFileSyntax[{&sourceMgr, bufferID}] = sourceFile;
319+
return sourceFile;
320+
}
321+
322+
void PrintingDiagnosticConsumer::queueBuffer(
323+
SourceManager &sourceMgr, unsigned bufferID) {
324+
QueuedBuffer knownSourceFile = queuedBuffers[bufferID];
325+
if (knownSourceFile)
326+
return;
327+
318328
// Find the parent and position in parent, if there is one.
319329
int parentID = -1;
320330
int positionInParent = 0;
@@ -345,6 +355,7 @@ void PrintingDiagnosticConsumer::queueBuffer(
345355
sourceMgr.getLocForBufferStart(bufferID)).str();
346356
}
347357

358+
auto sourceFile = getSourceFileSyntax(sourceMgr, bufferID);
348359
swift_ASTGen_addQueuedSourceFile(
349360
queuedDiagnostics, bufferID, sourceFile,
350361
(const uint8_t*)displayName.data(), displayName.size(),
@@ -423,9 +434,6 @@ void PrintingDiagnosticConsumer::flush(bool includeTrailingBreak) {
423434
}
424435
swift_ASTGen_destroyQueuedDiagnostics(queuedDiagnostics);
425436
queuedDiagnostics = nullptr;
426-
for (const auto &buffer : queuedBuffers) {
427-
swift_ASTGen_destroySourceFile(buffer.second);
428-
}
429437
queuedBuffers.clear();
430438

431439
if (includeTrailingBreak)
@@ -566,4 +574,9 @@ SourceManager::GetMessage(SourceLoc Loc, llvm::SourceMgr::DiagKind Kind,
566574
PrintingDiagnosticConsumer::PrintingDiagnosticConsumer(
567575
llvm::raw_ostream &stream)
568576
: Stream(stream) {}
569-
PrintingDiagnosticConsumer::~PrintingDiagnosticConsumer() = default;
577+
578+
PrintingDiagnosticConsumer::~PrintingDiagnosticConsumer() {
579+
for (const auto &sourceFileSyntax : sourceFileSyntax) {
580+
swift_ASTGen_destroySourceFile(sourceFileSyntax.second);
581+
}
582+
}

0 commit comments

Comments
 (0)