[libcxx-commits] [libcxx] 4608df5 - [libc++] Simplify __bitset::__init (#121357)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed May 28 09:09:54 PDT 2025


Author: Peng Liu
Date: 2025-05-28T12:09:50-04:00
New Revision: 4608df5b9fea7322714fc5fe7e6bcc5e5e3a666a

URL: https://github.com/llvm/llvm-project/commit/4608df5b9fea7322714fc5fe7e6bcc5e5e3a666a
DIFF: https://github.com/llvm/llvm-project/commit/4608df5b9fea7322714fc5fe7e6bcc5e5e3a666a.diff

LOG: [libc++] Simplify __bitset::__init (#121357)

This PR simplifies `__bitset::__init` into a more compact and readable
form, which avoids redundant computations of a `size_t` value and
eliminates the overhead of a local array.

Added: 
    

Modified: 
    libcxx/include/bitset
    libcxx/test/benchmarks/bitset.bench.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/bitset b/libcxx/include/bitset
index eee5a51a39e24..13ad31f5f924f 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -273,26 +273,16 @@ inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset() _NOEXCEPT
 
 template <size_t _N_words, size_t _Size>
 void __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT {
-  __storage_type __t[sizeof(unsigned long long) / sizeof(__storage_type)];
-  size_t __sz = _Size;
-  for (size_t __i = 0; __i < sizeof(__t) / sizeof(__t[0]); ++__i, __v >>= __bits_per_word, __sz -= __bits_per_word)
-    if (__sz < __bits_per_word)
-      __t[__i] = static_cast<__storage_type>(__v) & (1ULL << __sz) - 1;
-    else
-      __t[__i] = static_cast<__storage_type>(__v);
-
-  std::copy(__t, __t + sizeof(__t) / sizeof(__t[0]), __first_);
-  std::fill(
-      __first_ + sizeof(__t) / sizeof(__t[0]), __first_ + sizeof(__first_) / sizeof(__first_[0]), __storage_type(0));
+  const size_t __n_words = std::min((sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1, _N_words);
+  for (size_t __i = 0; __i < __n_words; ++__i, __v >>= __bits_per_word)
+    __first_[__i] = static_cast<__storage_type>(__v);
+  std::fill(__first_ + __n_words, __first_ + _N_words, __storage_type(0));
 }
 
 template <size_t _N_words, size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT {
   __first_[0] = __v;
-  if (_Size < __bits_per_word)
-    __first_[0] &= (1ULL << _Size) - 1;
-
-  std::fill(__first_ + 1, __first_ + sizeof(__first_) / sizeof(__first_[0]), __storage_type(0));
+  std::fill(__first_ + 1, __first_ + _N_words, __storage_type(0));
 }
 
 #  endif // _LIBCPP_CXX03_LANG
@@ -314,7 +304,7 @@ inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long
 #  endif
 {
 #  ifdef _LIBCPP_CXX03_LANG
-  __init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());
+  __init(__v, integral_constant<bool, sizeof(unsigned long long) <= sizeof(__storage_type)>());
 #  endif
 }
 
@@ -658,7 +648,8 @@ public:
 
   // 23.3.5.1 constructors:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : __base(__v) {}
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT
+      : __base(sizeof(unsigned long long) * CHAR_BIT <= _Size ? __v : __v & ((1ULL << _Size) - 1)) {}
   template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
       const _CharT* __str,

diff  --git a/libcxx/test/benchmarks/bitset.bench.cpp b/libcxx/test/benchmarks/bitset.bench.cpp
index 5e95d3aad1cb2..8fcf52e9425ce 100644
--- a/libcxx/test/benchmarks/bitset.bench.cpp
+++ b/libcxx/test/benchmarks/bitset.bench.cpp
@@ -103,4 +103,14 @@ BENCHMARK(BM_BitsetToString<262144>)->Arg(50)->Name("BM_BitsetToString<262144>/U
 BENCHMARK(BM_BitsetToString<524288>)->Arg(50)->Name("BM_BitsetToString<524288>/Uniform (50%)");
 BENCHMARK(BM_BitsetToString<1048576>)->Arg(50)->Name("BM_BitsetToString<1048576>/Uniform (50%)"); // 1 << 20
 
+static void BM_ctor_ull(benchmark::State& state) {
+  unsigned long long val = (1ULL << state.range(0)) - 1;
+  for (auto _ : state) {
+    std::bitset<128> b(val);
+    benchmark::DoNotOptimize(b);
+  }
+}
+
+BENCHMARK(BM_ctor_ull)->DenseRange(1, 63);
+
 BENCHMARK_MAIN();


        


More information about the libcxx-commits mailing list