[llvm] [ADT] Bitset: add shift operators, word accessors, and etc (PR #193400)
Jiachen Yuan via llvm-commits
llvm-commits at lists.llvm.org
Sun May 3 22:51:48 PDT 2026
================
@@ -194,6 +194,95 @@ template <unsigned NumBits> class Bitset {
}
return false;
}
+
+ constexpr Bitset &operator<<=(unsigned N) {
+ if (N == 0)
+ return *this;
+ if (N >= NumBits) {
+ return *this = Bitset();
+ }
+ const unsigned WordShift = N / BitwordBits;
+ const unsigned BitShift = N % BitwordBits;
+ if (BitShift == 0) {
+ for (unsigned I = NumWords; I-- > WordShift;)
+ Bits[I] = Bits[I - WordShift];
+ } else {
+ const unsigned CarryShift = BitwordBits - BitShift;
+ for (unsigned I = NumWords - 1; I > WordShift; --I) {
+ Bits[I] = (Bits[I - WordShift] << BitShift) |
+ (Bits[I - WordShift - 1] >> CarryShift);
+ }
+ Bits[WordShift] = Bits[0] << BitShift;
+ }
+ for (unsigned I = 0; I < WordShift; ++I)
+ Bits[I] = 0;
+ maskLastWord();
+ return *this;
+ }
+
+ constexpr Bitset operator<<(unsigned N) const {
+ Bitset Result(*this);
+ Result <<= N;
+ return Result;
+ }
+
+ constexpr Bitset &operator>>=(unsigned N) {
+ if (N == 0)
+ return *this;
+ if (N >= NumBits) {
+ return *this = Bitset();
+ }
+ const unsigned WordShift = N / BitwordBits;
+ const unsigned BitShift = N % BitwordBits;
+ if (BitShift == 0) {
+ for (unsigned I = 0; I < NumWords - WordShift; ++I)
+ Bits[I] = Bits[I + WordShift];
+ } else {
+ const unsigned CarryShift = BitwordBits - BitShift;
+ for (unsigned I = 0; I < NumWords - WordShift - 1; ++I) {
+ Bits[I] = (Bits[I + WordShift] >> BitShift) |
+ (Bits[I + WordShift + 1] << CarryShift);
+ }
+ Bits[NumWords - WordShift - 1] = Bits[NumWords - 1] >> BitShift;
+ }
+ for (unsigned I = NumWords - WordShift; I < NumWords; ++I)
+ Bits[I] = 0;
+ maskLastWord();
+ return *this;
+ }
+
+ constexpr Bitset operator>>(unsigned N) const {
+ Bitset Result(*this);
+ Result >>= N;
+ return Result;
+ }
+
+ /// Return the I-th 64-bit word of the bitset, from least significant to most.
+ constexpr uint64_t getWord64(unsigned I) const {
+ assert(I < getNumWords64() && "Word index out of range");
+ if constexpr (BitwordBits == 64) {
+ return Bits[I];
+ } else {
+ static_assert(BitwordBits == 32, "Unsupported word size");
+ // When Bitword is 32-bit, for a valid I, the first word is always
+ // present, but the second may not be present.
+ uint64_t Lo = Bits[2 * I];
+ uint64_t Hi = (2 * I + 1 < NumWords) ? Bits[2 * I + 1] : 0;
+ return Lo | (Hi << 32);
+ }
+ }
+
+ /// Return the index of the highest set bit, or -1 if no bits are set.
+ constexpr int findLastSet() const {
+ for (unsigned I = NumWords; I-- > 0;)
----------------
JiachenYuan wrote:
Sure, addressed!
https://github.com/llvm/llvm-project/pull/193400
More information about the llvm-commits
mailing list