[PATCH] D28207: Add second fast path for DiagnosticsEngine::GetDiagStatePointForLoc

Daniel Jasper via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 1 00:43:51 PST 2017


djasper created this revision.
djasper added a reviewer: rsmith.
djasper added a subscriber: cfe-commits.
Herald added a subscriber: sanjoy.

In many translation units I have tested, many of the calls to DiagnosticsEngine::GetDiagStatePointForLoc are for source locations before the first diag state point. AFAICT, this happens frequently for locations in the STL and other base libraries. This patch adds a fast path for this case to avoid the costly binary search. This binary search is costly, because the relatively slow SourceManager::isBeforeInTranslationUnit() is used to compare DiagStatePoints.


https://reviews.llvm.org/D28207

Files:
  lib/Basic/Diagnostic.cpp


Index: lib/Basic/Diagnostic.cpp
===================================================================
--- lib/Basic/Diagnostic.cpp
+++ lib/Basic/Diagnostic.cpp
@@ -163,21 +163,28 @@
   assert(DiagStatePoints.front().Loc.isInvalid() &&
          "Should have created a DiagStatePoint for command-line");
 
-  if (!SourceMgr)
+  if (!SourceMgr || DiagStatePoints.size() == 1)
     return DiagStatePoints.end() - 1;
 
   FullSourceLoc Loc(L, *SourceMgr);
   if (Loc.isInvalid())
     return DiagStatePoints.end() - 1;
 
-  DiagStatePointsTy::iterator Pos = DiagStatePoints.end();
+  // Most frequent case: L is after the last diag state change.
   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
-  if (LastStateChangePos.isValid() &&
-      Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
-    Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
-                           DiagStatePoint(nullptr, Loc));
-  --Pos;
-  return Pos;
+  assert(LastStateChangePos.isValid());
+  if (!Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
+    return DiagStatePoints.end() - 1;
+
+  // 2nd most frequent case: L is before the first diag state change.
+  FullSourceLoc FirstStateChangePos = DiagStatePoints[1].Loc;
+  assert(FirstStateChangePos.isValid());
+  if (Loc.isBeforeInTranslationUnitThan(FirstStateChangePos))
+    return DiagStatePoints.begin();
+
+  // Fall back to binary search.
+  return std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
+                          DiagStatePoint(nullptr, Loc)) - 1;
 }
 
 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28207.82782.patch
Type: text/x-patch
Size: 1640 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170101/156b622a/attachment.bin>


More information about the cfe-commits mailing list