LLVM 23.0.0git
Bitset.h
Go to the documentation of this file.
1//=== llvm/ADT/Bitset.h - constexpr std::bitset -----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Defines a std::bitset like container that can be used in constexprs.
10// That constructor and many of the methods are constexpr. std::bitset doesn't
11// get constexpr methods until C++23. This class also provides a constexpr
12// constructor that accepts an initializer_list of bits to set.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_ADT_BITSET_H
17#define LLVM_ADT_BITSET_H
18
19#include "llvm/ADT/bit.h"
20#include <array>
21#include <climits>
22#include <cstdint>
23
24namespace llvm {
25
26/// This is a constexpr reimplementation of a subset of std::bitset. It would be
27/// nice to use std::bitset directly, but it doesn't support constant
28/// initialization.
29template <unsigned NumBits> class Bitset {
30 using BitWord = uintptr_t;
31
32 static constexpr unsigned BitwordBits = sizeof(BitWord) * CHAR_BIT;
33 static constexpr unsigned RemainderNumBits = NumBits % BitwordBits;
34 static constexpr BitWord RemainderMask =
35 RemainderNumBits == 0 ? ~BitWord(0)
36 : ((BitWord(1) << RemainderNumBits) - 1);
37
38 static_assert(BitwordBits == 64 || BitwordBits == 32,
39 "Unsupported word size");
40
41 static constexpr unsigned NumWords =
42 (NumBits + BitwordBits - 1) / BitwordBits;
43
44 // Returns the index of the last word (0-based). The last word may be
45 // partially filled and requires masking to maintain the invariant that
46 // unused high bits are always zero.
47 static constexpr unsigned getLastWordIndex() { return NumWords - 1; }
48
49 using StorageType = std::array<BitWord, NumWords>;
50 StorageType Bits{};
51
52 constexpr void maskLastWord() { Bits[getLastWordIndex()] &= RemainderMask; }
53
54protected:
55 constexpr Bitset(const std::array<uint64_t, (NumBits + 63) / 64> &B) {
56 if constexpr (sizeof(BitWord) == sizeof(uint64_t)) {
57 for (size_t I = 0; I != B.size(); ++I)
58 Bits[I] = B[I];
59 } else {
60 unsigned BitsToAssign = NumBits;
61 for (size_t I = 0; I != B.size() && BitsToAssign; ++I) {
62 uint64_t Elt = B[I];
63 // On a 32-bit system the storage type will be 32-bit, so we may only
64 // need half of a uint64_t.
65 for (size_t Offset = 0; Offset != 2 && BitsToAssign; ++Offset) {
66 Bits[2 * I + Offset] = static_cast<uint32_t>(Elt >> (32 * Offset));
67 BitsToAssign = BitsToAssign >= 32 ? BitsToAssign - 32 : 0;
68 }
69 }
70 }
71 maskLastWord();
72 }
73
74public:
75 constexpr Bitset() = default;
76 constexpr Bitset(std::initializer_list<unsigned> Init) {
77 for (auto I : Init)
78 set(I);
79 }
80
81 constexpr Bitset &set() {
82 constexpr const BitWord AllOnes = ~BitWord(0);
83 for (BitWord &B : Bits)
84 B = AllOnes;
85 maskLastWord();
86 return *this;
87 }
88
89 constexpr Bitset &set(unsigned I) {
90 Bits[I / BitwordBits] |= BitWord(1) << (I % BitwordBits);
91 return *this;
92 }
93
94 constexpr Bitset &reset(unsigned I) {
95 Bits[I / BitwordBits] &= ~(BitWord(1) << (I % BitwordBits));
96 return *this;
97 }
98
99 constexpr Bitset &flip(unsigned I) {
100 Bits[I / BitwordBits] ^= BitWord(1) << (I % BitwordBits);
101 return *this;
102 }
103
104 constexpr bool operator[](unsigned I) const {
105 BitWord Mask = BitWord(1) << (I % BitwordBits);
106 return (Bits[I / BitwordBits] & Mask) != 0;
107 }
108
109 constexpr bool test(unsigned I) const { return (*this)[I]; }
110
111 constexpr size_t size() const { return NumBits; }
112
113 constexpr bool any() const {
114 for (BitWord B : Bits)
115 if (B != 0)
116 return true;
117 return false;
118 }
119
120 constexpr bool none() const { return !any(); }
121
122 constexpr bool all() const {
123 constexpr const BitWord AllOnes = ~BitWord(0);
124 for (unsigned I = 0; I < getLastWordIndex(); ++I)
125 if (Bits[I] != AllOnes)
126 return false;
127 return Bits[getLastWordIndex()] == RemainderMask;
128 }
129
130 constexpr size_t count() const {
131 size_t Count = 0;
132 for (BitWord Word : Bits)
133 Count += popcount(Word);
134 return Count;
135 }
136
137 constexpr Bitset &operator^=(const Bitset &RHS) {
138 for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
139 Bits[I] ^= RHS.Bits[I];
140 }
141 return *this;
142 }
143 constexpr Bitset operator^(const Bitset &RHS) const {
144 Bitset Result = *this;
145 Result ^= RHS;
146 return Result;
147 }
148
149 constexpr Bitset &operator&=(const Bitset &RHS) {
150 for (unsigned I = 0, E = Bits.size(); I != E; ++I)
151 Bits[I] &= RHS.Bits[I];
152 return *this;
153 }
154 constexpr Bitset operator&(const Bitset &RHS) const {
155 Bitset Result = *this;
156 Result &= RHS;
157 return Result;
158 }
159
160 constexpr Bitset &operator|=(const Bitset &RHS) {
161 for (unsigned I = 0, E = Bits.size(); I != E; ++I) {
162 Bits[I] |= RHS.Bits[I];
163 }
164 return *this;
165 }
166 constexpr Bitset operator|(const Bitset &RHS) const {
167 Bitset Result = *this;
168 Result |= RHS;
169 return Result;
170 }
171
172 constexpr Bitset operator~() const {
173 Bitset Result = *this;
174 for (BitWord &B : Result.Bits)
175 B = ~B;
176 Result.maskLastWord();
177 return Result;
178 }
179
180 constexpr bool operator==(const Bitset &RHS) const {
181 for (unsigned I = 0; I < NumWords; ++I)
182 if (Bits[I] != RHS.Bits[I])
183 return false;
184 return true;
185 }
186
187 constexpr bool operator!=(const Bitset &RHS) const { return !(*this == RHS); }
188
189 constexpr bool operator<(const Bitset &Other) const {
190 for (unsigned I = 0, E = size(); I != E; ++I) {
191 bool LHS = test(I), RHS = Other.test(I);
192 if (LHS != RHS)
193 return LHS < RHS;
194 }
195 return false;
196 }
197};
198
199} // end namespace llvm
200
201#endif
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define I(x, y, z)
Definition MD5.cpp:57
modulo schedule test
Value * RHS
Value * LHS
This file implements the C++20 <bit> header.
constexpr Bitset operator^(const Bitset &RHS) const
Definition Bitset.h:143
constexpr size_t count() const
Definition Bitset.h:130
constexpr Bitset & set(unsigned I)
Definition Bitset.h:89
constexpr Bitset & flip(unsigned I)
Definition Bitset.h:99
constexpr bool all() const
Definition Bitset.h:122
constexpr bool any() const
Definition Bitset.h:113
constexpr Bitset(const std::array< uint64_t,(NumBits+63)/64 > &B)
Definition Bitset.h:55
constexpr Bitset()=default
constexpr bool operator==(const Bitset &RHS) const
Definition Bitset.h:180
constexpr bool operator<(const Bitset &Other) const
Definition Bitset.h:189
constexpr Bitset & operator^=(const Bitset &RHS)
Definition Bitset.h:137
constexpr Bitset & set()
Definition Bitset.h:81
constexpr Bitset operator&(const Bitset &RHS) const
Definition Bitset.h:154
constexpr bool none() const
Definition Bitset.h:120
constexpr bool operator!=(const Bitset &RHS) const
Definition Bitset.h:187
constexpr bool operator[](unsigned I) const
Definition Bitset.h:104
constexpr size_t size() const
Definition Bitset.h:111
constexpr Bitset & operator|=(const Bitset &RHS)
Definition Bitset.h:160
constexpr Bitset(std::initializer_list< unsigned > Init)
Definition Bitset.h:76
constexpr Bitset & operator&=(const Bitset &RHS)
Definition Bitset.h:149
constexpr bool test(unsigned I) const
Definition Bitset.h:109
constexpr Bitset operator|(const Bitset &RHS) const
Definition Bitset.h:166
constexpr Bitset & reset(unsigned I)
Definition Bitset.h:94
constexpr Bitset operator~() const
Definition Bitset.h:172
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:154
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
@ Other
Any other memory.
Definition ModRef.h:68