Use a fast path when initializing LineOffsetMapping
authorserge-sans-paille <sguelton@redhat.com>
Tue, 23 Feb 2021 19:46:35 +0000 (20:46 +0100)
committerserge-sans-paille <sguelton@redhat.com>
Mon, 1 Mar 2021 09:18:36 +0000 (10:18 +0100)
Use the fact that the number of line break is lower than printable characters to
guide the optimization process. Also use a fuzzy test that catches both \n and
\r in a single check to speedup the computation.

Differential Revision: https://reviews.llvm.org/D97320

clang/lib/Basic/SourceManager.cpp

index c0b2283..cc275d4 100644 (file)
@@ -1270,13 +1270,16 @@ LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer,
   const std::size_t BufLen = End - Buf;
   unsigned I = 0;
   while (I < BufLen) {
-    if (Buf[I] == '\n') {
-      LineOffsets.push_back(I + 1);
-    } else if (Buf[I] == '\r') {
-      // If this is \r\n, skip both characters.
-      if (I + 1 < BufLen && Buf[I + 1] == '\n')
-        ++I;
-      LineOffsets.push_back(I + 1);
+    // Use a fast check to catch both newlines
+    if (LLVM_UNLIKELY(Buf[I] <= std::max('\n', '\r'))) {
+      if (Buf[I] == '\n') {
+        LineOffsets.push_back(I + 1);
+      } else if (Buf[I] == '\r') {
+        // If this is \r\n, skip both characters.
+        if (I + 1 < BufLen && Buf[I + 1] == '\n')
+          ++I;
+        LineOffsets.push_back(I + 1);
+      }
     }
     ++I;
   }