[libcxx-commits] [libcxx] [libcxx] Use a table for the offsets in __next_prime (PR #180651)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 12 10:53:59 PST 2026


https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/180651

>From a3ea7193958fc6690575d2dd0e5abb120e5fe6cf Mon Sep 17 00:00:00 2001
From: Leonard Chan <leonardchan at google.com>
Date: Mon, 9 Feb 2026 16:16:10 -0800
Subject: [PATCH 1/2] [libcxx] Use a table for the offsets in __next_prime

This reduces the size of __next_prime on armv8m baremetal from 1.4KB to
about 276B. Ideally there would be something that rolls up the if chain
into a single loop but there doesn't seem to be anything that does that
in llvm. Conversely, we should expect an unroller to be able to unroll
this loop in something like a -O3 build, but we unfortunately don't see
that either. I suspect perf might not be as much of a concern here since
this function is already called in a slow path when rehashing might be
done.
---
 libcxx/src/hash.cpp | 349 ++------------------------------------------
 1 file changed, 15 insertions(+), 334 deletions(-)

diff --git a/libcxx/src/hash.cpp b/libcxx/src/hash.cpp
index e1e6d2b4c2bdb..6d4ebacb6cca0 100644
--- a/libcxx/src/hash.cpp
+++ b/libcxx/src/hash.cpp
@@ -30,6 +30,13 @@ const unsigned indices[] = {
     71,  73,  79,  83,  89,  97,  101, 103, 107, 109, 113, 121, 127, 131, 137, 139,
     143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209};
 
+// These are the amount we increment by when checking for potential
+// primes in the  loop in __next_prime.
+const size_t increments[] = {
+    0, 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2,
+    4, 2,  4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10,
+};
+
 } // namespace
 
 // Returns:  If n == 0, returns 0.  Else returns the lowest prime number that
@@ -97,340 +104,14 @@ size_t __next_prime(size_t n) {
     {
       size_t i = 211;
       while (true) {
-        std::size_t q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 10;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 8;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 8;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 6;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 4;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 2;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
-
-        i += 10;
-        q = n / i;
-        if (q < i)
-          return n;
-        if (n == q * i)
-          break;
+        for (auto inc : increments) {
+          i += inc;
+          std::size_t q = n / i;
+          if (q < i)
+            return n;
+          if (n == q * i)
+            goto next;
+        }
 
         // This will loop i to the next "plane" of potential primes
         i += 2;

>From 699e16609f09919ba7a664d54efcfff185e053fc Mon Sep 17 00:00:00 2001
From: PiJoules <6019989+PiJoules at users.noreply.github.com>
Date: Thu, 12 Feb 2026 10:53:31 -0800
Subject: [PATCH 2/2] Update libcxx/src/hash.cpp

Co-authored-by: Nikolas Klauser <nikolasklauser at berlin.de>
---
 libcxx/src/hash.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/src/hash.cpp b/libcxx/src/hash.cpp
index 6d4ebacb6cca0..b04cf0a8948c3 100644
--- a/libcxx/src/hash.cpp
+++ b/libcxx/src/hash.cpp
@@ -32,7 +32,7 @@ const unsigned indices[] = {
 
 // These are the amount we increment by when checking for potential
 // primes in the  loop in __next_prime.
-const size_t increments[] = {
+const uint8_t increments[] = {
     0, 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2,
     4, 2,  4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10,
 };



More information about the libcxx-commits mailing list