File tree Expand file tree Collapse file tree 4 files changed +43
-6
lines changed Expand file tree Collapse file tree 4 files changed +43
-6
lines changed Original file line number Diff line number Diff line change 1414#include < utility>
1515
1616#include " llvm/ADT/STLForwardCompat.h"
17+ #include " llvm/ADT/bit.h"
1718#include " llvm/Support/MathExtras.h"
1819
1920// / LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can
@@ -138,10 +139,6 @@ template <typename E> constexpr std::underlying_type_t<E> Underlying(E Val) {
138139 return U;
139140}
140141
141- constexpr unsigned bitWidth (uint64_t Value) {
142- return Value ? 1 + bitWidth (Value >> 1 ) : 0 ;
143- }
144-
145142template <typename E, typename = std::enable_if_t <is_bitmask_enum<E>::value>>
146143constexpr bool operator !(E Val) {
147144 return Val == static_cast <E>(0 );
@@ -220,7 +217,7 @@ e &operator>>=(e &lhs, e rhs) {
220217// Enable bitmask enums in namespace ::llvm and all nested namespaces.
221218LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE ();
222219template <typename E, typename = std::enable_if_t <is_bitmask_enum<E>::value>>
223- constexpr unsigned BitWidth = BitmaskEnumDetail::bitWidth (
220+ constexpr unsigned BitWidth = llvm::bit_width_constexpr (
224221 uint64_t {llvm::to_underlying (E::LLVM_BITMASK_LARGEST_ENUMERATOR)});
225222
226223} // namespace llvm
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ namespace pointer_union_detail {
3131 // / Determine the number of bits required to store integers with values < n.
3232 // / This is ceil(log2(n)).
3333 constexpr int bitsRequired (unsigned n) {
34- return n > 1 ? 1 + bitsRequired ((n + 1 ) / 2 ) : 0 ;
34+ return n == 0 ? 0 : llvm::bit_width_constexpr (n - 1 );
3535 }
3636
3737 template <typename ... Ts> constexpr int lowBitsAvailable () {
Original file line number Diff line number Diff line change @@ -292,6 +292,23 @@ template <typename T> [[nodiscard]] int bit_width(T Value) {
292292 return std::numeric_limits<T>::digits - llvm::countl_zero (Value);
293293}
294294
295+ // / Returns the number of bits needed to represent Value if Value is nonzero.
296+ // / Returns 0 otherwise.
297+ // /
298+ // / A constexpr version of bit_width.
299+ // /
300+ // / Ex. bit_width_constexpr(5) == 3.
301+ template <typename T> [[nodiscard]] constexpr int bit_width_constexpr (T Value) {
302+ static_assert (std::is_unsigned_v<T>,
303+ " Only unsigned integral types are allowed." );
304+ int Width = 0 ;
305+ while (Value > 0 ) {
306+ Value >>= 1 ;
307+ ++Width;
308+ }
309+ return Width;
310+ }
311+
295312// / Returns the largest integral power of two no greater than Value if Value is
296313// / nonzero. Returns 0 otherwise.
297314// /
Original file line number Diff line number Diff line change @@ -247,6 +247,29 @@ TEST(BitTest, BitWidth) {
247247 EXPECT_EQ (64 , llvm::bit_width (uint64_t (0xffffffffffffffffull )));
248248}
249249
250+ TEST (BitTest, BitWidthConstexpr) {
251+ static_assert (llvm::bit_width_constexpr (0u ) == 0 );
252+ static_assert (llvm::bit_width_constexpr (1u ) == 1 );
253+ static_assert (llvm::bit_width_constexpr (2u ) == 2 );
254+ static_assert (llvm::bit_width_constexpr (3u ) == 2 );
255+ static_assert (llvm::bit_width_constexpr (4u ) == 3 );
256+ static_assert (llvm::bit_width_constexpr (5u ) == 3 );
257+ static_assert (llvm::bit_width_constexpr (6u ) == 3 );
258+ static_assert (llvm::bit_width_constexpr (7u ) == 3 );
259+ static_assert (llvm::bit_width_constexpr (8u ) == 4 );
260+
261+ static_assert (llvm::bit_width_constexpr (255u ) == 8 );
262+ static_assert (llvm::bit_width_constexpr (256u ) == 9 );
263+ static_assert (llvm::bit_width_constexpr (257u ) == 9 );
264+
265+ static_assert (
266+ llvm::bit_width_constexpr (std::numeric_limits<uint16_t >::max ()) == 16 );
267+ static_assert (
268+ llvm::bit_width_constexpr (std::numeric_limits<uint32_t >::max ()) == 32 );
269+ static_assert (
270+ llvm::bit_width_constexpr (std::numeric_limits<uint64_t >::max ()) == 64 );
271+ }
272+
250273TEST (BitTest, CountlZero) {
251274 uint8_t Z8 = 0 ;
252275 uint16_t Z16 = 0 ;
You can’t perform that action at this time.
0 commit comments