[libcxx-commits] [libcxx] 1b0553c - [libc++] Use _BitInt and __builtin_popcountg in bitset::count() (#160679)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Sep 25 11:16:30 PDT 2025


Author: Nikolas Klauser
Date: 2025-09-25T20:16:27+02:00
New Revision: 1b0553c9fa8d61010a43b1a2dcb649d1aab7d8ae

URL: https://github.com/llvm/llvm-project/commit/1b0553c9fa8d61010a43b1a2dcb649d1aab7d8ae
DIFF: https://github.com/llvm/llvm-project/commit/1b0553c9fa8d61010a43b1a2dcb649d1aab7d8ae.diff

LOG: [libc++] Use _BitInt and __builtin_popcountg in bitset::count() (#160679)

This has multiple benefits:
1) The compiler has to do way less work to figure out things fold into a
simple `popcount`, improving compile times quite a bit
2) The compiler inlines better, since the compile doesn't have to do
complicated optimizations to get to the same point. Looking at the
pipeline, it seems that without this, LLVM has to go all the way to GVN
to get to the same code as there is after the first InstCombine pass
with this change.

Currently this applies only to `bitset`s with at most 64 bits, but that
is by far the most common case.

Added: 
    

Modified: 
    libcxx/include/bitset

Removed: 
    


################################################################################
diff  --git a/libcxx/include/bitset b/libcxx/include/bitset
index e2b46154ae730..3453c2fcde71e 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -867,7 +867,16 @@ bitset<_Size>::to_string(char __zero, char __one) const {
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t bitset<_Size>::count() const _NOEXCEPT {
-  return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
+#  if defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
+  if constexpr (_Size == 0) {
+    return 0;
+  } else if constexpr (_Size <= __base::__bits_per_word) {
+    return __builtin_popcountg(static_cast<unsigned _BitInt(_Size)>(__base::__first_));
+  } else
+#  endif
+  {
+    return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
+  }
 }
 
 template <size_t _Size>


        


More information about the libcxx-commits mailing list