[clang] [Clang] Cache the most recent diagnostic source file (NFC) (PR #223029)

Mehdi Amini via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 16 03:23:00 PDT 2026


https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/223029

>From 7839d33136743d80b8f3129d285c12e4ebdb3f0f Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Thu, 10 Sep 2026 05:30:30 -0700
Subject: [PATCH] Cache the most recent diagnostic source file

Avoid repeated ordered-map lookups while diagnostics remain in the same
source file. Clear the cached map node whenever the map is reset.

CTMark O0 (3 samples, CPU 6): 29.439800 s -> 29.312967 s (-0.431%).

Impact on significant TUs in MLIR build time:
- `mlir/lib/RegisterAllDialects.cpp`: 1.0930% fewer retired
  instructions.
- `mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp`: 0.5034% fewer retired
  instructions.

Assisted-by: Codex
---
 clang/include/clang/Basic/Diagnostic.h |  6 ++++++
 clang/lib/Basic/Diagnostic.cpp         | 12 +++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index 834f026aff62d..06e1f454d058d 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -439,6 +439,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
     void clear(bool Soft) {
       // Just clear the cache when in soft mode.
       Files.clear();
+      LastFile = nullptr;
       if (!Soft) {
         FirstDiagState = CurDiagState = nullptr;
         CurDiagStateLoc = SourceLocation();
@@ -497,6 +498,11 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
     /// The diagnostic states for each file.
     mutable std::map<FileID, File> Files;
 
+    /// Cache the most recently accessed file. Diagnostic lookups commonly
+    /// stay within one source file for long runs.
+    mutable FileID LastFileID;
+    mutable File *LastFile = nullptr;
+
     /// The initial diagnostic state.
     DiagState *FirstDiagState;
 
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 48dd9559ab8e6..d7795297ceff4 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -218,10 +218,15 @@ DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
 DiagnosticsEngine::DiagStateMap::File *
 DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
                                          FileID ID) const {
+  if (LastFile && LastFileID == ID)
+    return LastFile;
+
   // Get or insert the File for this ID.
   auto Range = Files.equal_range(ID);
-  if (Range.first != Range.second)
-    return &Range.first->second;
+  if (Range.first != Range.second) {
+    LastFileID = ID;
+    return LastFile = &Range.first->second;
+  }
   auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
 
   // We created a new File; look up the diagnostic state at the start of it and
@@ -241,7 +246,8 @@ DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
     // end of isBeforeInTranslationUnit for the quirks it deals with.
     F.StateTransitions.push_back({FirstDiagState, 0});
   }
-  return &F;
+  LastFileID = ID;
+  return LastFile = &F;
 }
 
 void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr,



More information about the cfe-commits mailing list