|
| 1 | +From eaabc1bbeaa057bac3fe699bebda1472dc2ae03b Mon Sep 17 00:00:00 2001 |
| 2 | +From: Kazu Hirata < [email protected]> |
| 3 | +Date: Fri, 20 Jan 2023 19:34:42 -0800 |
| 4 | +Subject: [PATCH] [ADT] Add bit_floor, bit_ceil, and bit_width to bit.h |
| 5 | + |
| 6 | +This patch adds C++20-style bit_floor, bit_ceil, and bit_width. |
| 7 | + |
| 8 | +In a subsequent patch, I'm going to define PowerOf2Floor in |
| 9 | +MathExtras.h in terms of bit_floor. |
| 10 | + |
| 11 | +Unfortunately, PowerOf2Ceil isn't quite the same as bit_ceil because |
| 12 | +PowerOf2Ceil(0) == 0, whereas bit_ceil(0) == 1. |
| 13 | + |
| 14 | +MathExtras.h does not have a function directly corresponding to |
| 15 | +bit_width, but Log2_32(X) + 1, which occurs in a few places, can be |
| 16 | +replaced with bit_width(X). |
| 17 | + |
| 18 | +Differential Revision: https://reviews.llvm.org/D142179 |
| 19 | + |
| 20 | +diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h |
| 21 | +index 442f3795841a..04105bf942c4 100644 |
| 22 | +--- a/llvm/include/llvm/ADT/bit.h |
| 23 | ++++ b/llvm/include/llvm/ADT/bit.h |
| 24 | +@@ -79,6 +79,42 @@ inline int popcount(T Value) noexcept { |
| 25 | + return detail::PopulationCounter<T, sizeof(T)>::count(Value); |
| 26 | + } |
| 27 | + |
| 28 | ++/// Returns the number of bits needed to represent Value if Value is nonzero. |
| 29 | ++ /// Returns 0 otherwise. |
| 30 | ++ /// |
| 31 | ++ /// Ex. bit_width(5) == 3. |
| 32 | ++ template <typename T> int bit_width(T Value) { |
| 33 | ++ static_assert(std::is_unsigned_v<T>, |
| 34 | ++ "Only unsigned integral types are allowed."); |
| 35 | ++ return std::numeric_limits<T>::digits - llvm::countl_zero(Value); |
| 36 | ++} |
| 37 | ++ |
| 38 | ++/// Returns the largest integral power of two no greater than Value if Value is |
| 39 | ++/// nonzero. Returns 0 otherwise. |
| 40 | ++/// |
| 41 | ++/// Ex. bit_floor(5) == 4. |
| 42 | ++template <typename T> T bit_floor(T Value) { |
| 43 | ++ static_assert(std::is_unsigned_v<T>, |
| 44 | ++ "Only unsigned integral types are allowed."); |
| 45 | ++ if (!Value) |
| 46 | ++ return 0; |
| 47 | ++ return T(1) << (llvm::bit_width(Value) - 1); |
| 48 | ++} |
| 49 | ++ |
| 50 | ++/// Returns the smallest integral power of two no smaller than Value if Value is |
| 51 | ++/// nonzero. Returns 0 otherwise. |
| 52 | ++/// |
| 53 | ++/// Ex. bit_ceil(5) == 8. |
| 54 | ++/// |
| 55 | ++/// The return value is undefined if the input is larger than the largest power |
| 56 | ++/// of two representable in T. |
| 57 | ++template <typename T> T bit_ceil(T Value) { |
| 58 | ++ static_assert(std::is_unsigned_v<T>, |
| 59 | ++ "Only unsigned integral types are allowed."); |
| 60 | ++ if (Value < 2) |
| 61 | ++ return 1; |
| 62 | ++ return T(1) << llvm::bit_width<T>(Value - 1u); |
| 63 | ++} |
| 64 | + } // namespace llvm |
| 65 | + |
| 66 | + #endif |
0 commit comments