[libcxx-commits] [libcxx] [libcxx] Use a table for the offsets in __next_prime (PR #180651)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 11 11:46:20 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] [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;
More information about the libcxx-commits
mailing list