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

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 27 07:26:20 PST 2025


https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/121357

>From d6b94214f928420007a81da78dcc3eddc340fd86 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 30 Dec 2024 15:28:49 -0500
Subject: [PATCH 1/3] Simplify __bitset::__init

---
 libcxx/include/bitset | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index f905b6f274e3f..d28355ab9fbc8 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -256,26 +256,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
@@ -618,7 +608,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,

>From 1a0e03c6e220ccf8bdfee8b670c3ea0fc1705c0d Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Mon, 24 Feb 2025 18:26:53 -0500
Subject: [PATCH 2/3] Add benchmark

---
 libcxx/test/benchmarks/bitset.bench.cpp | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 libcxx/test/benchmarks/bitset.bench.cpp

diff --git a/libcxx/test/benchmarks/bitset.bench.cpp b/libcxx/test/benchmarks/bitset.bench.cpp
new file mode 100644
index 0000000000000..55a36d0b566f0
--- /dev/null
+++ b/libcxx/test/benchmarks/bitset.bench.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <benchmark/benchmark.h>
+#include <bitset>
+
+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();

>From e95d2084f315b9c994e1727c47e9fb59636bef17 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Wed, 26 Feb 2025 23:09:04 -0500
Subject: [PATCH 3/3] Unify ULL ctor for C++03 and C++11

---
 libcxx/include/bitset | 60 ++++++++-----------------------------------
 1 file changed, 11 insertions(+), 49 deletions(-)

diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index d28355ab9fbc8..309e6dc77816a 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -229,10 +229,6 @@ protected:
   _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
 
 private:
-#  ifdef _LIBCPP_CXX03_LANG
-  void __init(unsigned long long __v, false_type) _NOEXCEPT;
-  _LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
-#  endif // _LIBCPP_CXX03_LANG
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
@@ -242,53 +238,20 @@ private:
 };
 
 template <size_t _N_words, size_t _Size>
-inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset() _NOEXCEPT
-#  ifndef _LIBCPP_CXX03_LANG
-    : __first_{0}
-#  endif
-{
-#  ifdef _LIBCPP_CXX03_LANG
-  std::fill_n(__first_, _N_words, __storage_type(0));
-#  endif
-}
-
-#  ifdef _LIBCPP_CXX03_LANG
+inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset() _NOEXCEPT : __first_() {}
 
 template <size_t _N_words, size_t _Size>
-void __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT {
-  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));
-}
+inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT : __first_() {
+  _LIBCPP_CONSTEXPR size_t __ull_words = (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1;
+  static_assert(__ull_words <= 4, "This constructor has not been ported to this platform");
 
-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;
-  std::fill(__first_ + 1, __first_ + _N_words, __storage_type(0));
-}
-
-#  endif // _LIBCPP_CXX03_LANG
-
-template <size_t _N_words, size_t _Size>
-inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
-#  ifndef _LIBCPP_CXX03_LANG
-#    if __SIZEOF_SIZE_T__ == 8
-    : __first_{__v}
-#    elif __SIZEOF_SIZE_T__ == 4
-    : __first_{static_cast<__storage_type>(__v),
-               _Size >= 2 * __bits_per_word
-                   ? static_cast<__storage_type>(__v >> __bits_per_word)
-                   : static_cast<__storage_type>((__v >> __bits_per_word) &
-                                                 (__storage_type(1) << (_Size - __bits_per_word)) - 1)}
-#    else
-#      error This constructor has not been ported to this platform
-#    endif
-#  endif
-{
-#  ifdef _LIBCPP_CXX03_LANG
-  __init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());
-#  endif
+  if _LIBCPP_CONSTEXPR (__ull_words >= 2)
+    __first_[1] = __v >> __bits_per_word;
+  if _LIBCPP_CONSTEXPR (__ull_words >= 3 && _N_words >= 3)
+    __first_[2] = __v >> (2 * __bits_per_word);
+  if _LIBCPP_CONSTEXPR (__ull_words >= 4 && _N_words >= 4)
+    __first_[3] = __v >> (3 * __bits_per_word);
 }
 
 template <size_t _N_words, size_t _Size>
@@ -480,8 +443,7 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
 
 template <size_t _Size>
 inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
-    : __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v)
-                                        : static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1)) {}
+    : __first_(static_cast<__storage_type>(__v)) {}
 
 template <size_t _Size>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void



More information about the libcxx-commits mailing list