[llvm] [llvm] Improve implementation of StringRef::find_last_of and cie (PR #71865)

via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 12 23:54:49 PST 2023


https://github.com/serge-sans-paille updated https://github.com/llvm/llvm-project/pull/71865

>From fd5224f266bd131db9a1a6f1638198e9e570e158 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Thu, 9 Nov 2023 20:41:40 +0100
Subject: [PATCH] [llvm] Improve implementation of StringRef::find_last_of for
 the usual case of 2 chars

Almost all usage of StringRef::find_last_of in Clang/LLVM use a Needle
of 2 elements, which can easily be optimized in SSE2. The IPC of the
improved version is significantly better as shown in

        https://godbolt.org/z/h1dsdcMd8

And it does not require an extra structure.
---
 llvm/lib/Support/StringRef.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/llvm/lib/Support/StringRef.cpp b/llvm/lib/Support/StringRef.cpp
index feee47ca693b251..715730e4c1112c8 100644
--- a/llvm/lib/Support/StringRef.cpp
+++ b/llvm/lib/Support/StringRef.cpp
@@ -274,6 +274,23 @@ StringRef::size_type StringRef::find_first_not_of(StringRef Chars,
 /// Note: O(size() + Chars.size())
 StringRef::size_type StringRef::find_last_of(StringRef Chars,
                                              size_t From) const {
+#ifdef __SSE2__
+  if (Chars.size() == 2) {
+    __m128i Needle0 = _mm_set1_epi8(Chars[0]);
+    __m128i Needle1 = _mm_set1_epi8(Chars[1]);
+    size_type Sz = Size();
+    do {
+      Sz = Sz < 16 ? 0 : Sz - 16;
+      __m128i Buffer = _mm_loadu_si128((__m128i *)(Data() + sz));
+      int Mask = _mm_movemask_epi8(_mm_or_si128(
+          _mm_cmpeq_epi8(Buffer, Needle0), _mm_cmpeq_epi8(Buffer, Needle1)));
+      if (Mask != 0) {
+        return Sz + sizeof(Mask) * CHAR_BIT - llvm::countl_zero(Mask);
+      }
+    } while (sz);
+    return npso;
+  }
+#endif
   std::bitset<1 << CHAR_BIT> CharBits;
   for (char C : Chars)
     CharBits.set((unsigned char)C);



More information about the llvm-commits mailing list