Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 | |
|
Jim Stichnoth
2016/02/24 23:11:39
remove leading blank line
John
2016/02/24 23:46:05
Done.
| |
| 2 //===- subzero/src/IceBitVector.h - Inline bit vector. ----------*- C++ -*-===// | |
| 3 // | |
| 4 // The Subzero Code Generator | |
| 5 // | |
| 6 // This file is distributed under the University of Illinois Open Source | |
| 7 // License. See LICENSE.TXT for details. | |
| 8 // | |
| 9 //===----------------------------------------------------------------------===// | |
| 10 /// | |
| 11 /// \file | |
| 12 /// \brief Defines and implements a bit vector with inline storage. It is a | |
|
Jim Stichnoth
2016/02/24 23:11:38
reflow comment
John
2016/02/24 23:46:05
Done.
| |
| 13 /// drop in replacement for llvm::SmallSmallBitVector in subzero -- i.e., not | |
|
Jim Stichnoth
2016/02/24 23:11:39
SmallSmall
here and below
John
2016/02/24 23:46:05
Done.
| |
| 14 /// all of | |
| 15 /// llvm::SmallSmallBitVector interface is implemented. | |
| 16 /// | |
| 17 //===----------------------------------------------------------------------===// | |
| 18 | |
| 19 #ifndef SUBZERO_SRC_ICEBITVECTOR_H | |
| 20 #define SUBZERO_SRC_ICEBITVECTOR_H | |
| 21 | |
| 22 #include "IceDefs.h" | |
| 23 #include "IceOperand.h" | |
| 24 | |
| 25 #include "llvm/Support/MathExtras.h" | |
| 26 | |
| 27 #include <algorithm> | |
| 28 #include <climits> | |
| 29 #include <memory> | |
| 30 #include <type_traits> | |
| 31 | |
| 32 namespace Ice { | |
| 33 class SmallBitVector { | |
| 34 public: | |
| 35 using ElementType = uint64_t; | |
| 36 static constexpr SizeT NumBitsPerPos = sizeof(ElementType) * CHAR_BIT; | |
| 37 | |
| 38 SmallBitVector(const SmallBitVector &BV) { *this = BV; } | |
| 39 | |
| 40 SmallBitVector &operator=(const SmallBitVector &BV) { | |
| 41 if (&BV != this) { | |
| 42 resize(BV.size()); | |
| 43 memcpy(Bits, BV.Bits, sizeof(Bits)); | |
| 44 } | |
| 45 return *this; | |
| 46 } | |
| 47 | |
| 48 SmallBitVector() { | |
| 49 static_assert(sizeof(Bits) == 16, ""); | |
|
Jim Stichnoth
2016/02/24 23:11:38
Can you remove this? Seems to be also tested belo
John
2016/02/24 23:46:05
Done.
| |
| 50 memset(Bits, 0, sizeof(Bits)); | |
| 51 } | |
| 52 | |
| 53 explicit SmallBitVector(SizeT S) : SmallBitVector() { | |
| 54 resize(S); | |
| 55 assert(Size <= sizeof(Bits) * CHAR_BIT); | |
|
Jim Stichnoth
2016/02/24 23:11:39
constexpr
John
2016/02/24 23:46:05
Done.
| |
| 56 } | |
| 57 | |
| 58 class Reference { | |
| 59 Reference() = delete; | |
| 60 | |
| 61 public: | |
| 62 Reference(const Reference &) = default; | |
| 63 Reference &operator=(const Reference &Rhs) { return *this = (bool)Rhs; } | |
| 64 Reference &operator=(bool t) { | |
| 65 if (t) { | |
| 66 *Data |= 1ull << Bit; | |
| 67 } else { | |
| 68 *Data &= ~(1ull << Bit); | |
| 69 } | |
| 70 return *this; | |
| 71 } | |
| 72 operator bool() const { return (*Data & (1ull << Bit)) != 0; } | |
| 73 | |
| 74 private: | |
| 75 friend class SmallBitVector; | |
| 76 Reference(uint64_t *D, SizeT B) : Data(D), Bit(B) { | |
|
Jim Stichnoth
2016/02/24 23:11:38
ElementType instead of uint64_t ?
John
2016/02/24 23:46:05
Done.
| |
| 77 assert(B < CHAR_BIT * sizeof(*D)); | |
| 78 } | |
| 79 | |
| 80 uint64_t *const Data; | |
| 81 const SizeT Bit; | |
| 82 }; | |
| 83 | |
| 84 Reference operator[](unsigned Idx) { | |
| 85 assert(Idx < size()); | |
| 86 // return Reference(Bits + (Idx >> llvm::Log2_64(NumBitsPerPos)), | |
|
Jim Stichnoth
2016/02/24 23:11:39
remove commented code
John
2016/02/24 23:46:05
Done.
| |
| 87 // Idx & ((1ull << llvm::Log2_64(NumBitsPerPos))-1)); | |
| 88 return Reference(Bits + (Idx >> 6), Idx & ((1ull << 6) - 1)); | |
|
Jim Stichnoth
2016/02/24 23:11:39
All these "6" should be constexpr, with a static_a
John
2016/02/24 23:46:05
Done.
| |
| 89 } | |
| 90 | |
| 91 bool operator[](unsigned Idx) const { | |
| 92 assert(Idx < size()); | |
| 93 return Bits[Idx >> 6] & (1ull << (Idx & ((1ull << 6) - 1))); | |
|
Jim Stichnoth
2016/02/24 23:11:39
I think it would be nicer for the 1ull to be a con
John
2016/02/24 23:46:05
Done.
| |
| 94 } | |
| 95 | |
| 96 int find_first() const { return find_first<0>(); } | |
| 97 | |
| 98 int find_next(unsigned Prev) const { return find_next<0>(Prev); } | |
| 99 | |
| 100 bool any() const { return Bits[0] != 0 || Bits[1] != 0; } | |
|
Jim Stichnoth
2016/02/24 23:11:39
Either unroll this automatically like above, or st
John
2016/02/24 23:46:05
Done.
| |
| 101 | |
| 102 SizeT size() const { return Size; } | |
| 103 | |
| 104 void resize(SizeT Size) { | |
| 105 assert(Size <= sizeof(Bits) * CHAR_BIT); | |
| 106 this->Size = Size; | |
| 107 } | |
| 108 | |
| 109 void reserve(SizeT Size) { | |
| 110 assert(Size <= sizeof(Bits) * CHAR_BIT); | |
| 111 (void)Size; | |
| 112 } | |
| 113 | |
| 114 void set(unsigned Idx) { | |
| 115 // TODO(jpp): improve. | |
| 116 (*this)[Idx] = true; | |
| 117 } | |
| 118 | |
| 119 void set() { | |
| 120 // TODO(jpp): improve. | |
| 121 for (SizeT ii = 0; ii < size(); ++ii) { | |
| 122 (*this)[ii] = true; | |
| 123 } | |
| 124 // set_all<0>(); | |
|
Jim Stichnoth
2016/02/24 23:11:38
remove comment
John
2016/02/24 23:46:05
Done.
| |
| 125 } | |
| 126 | |
| 127 SizeT count() const { | |
| 128 return llvm::countPopulation(Bits[0]) + llvm::countPopulation(Bits[1]); | |
|
Jim Stichnoth
2016/02/24 23:11:39
inline/static_assert
here and below
John
2016/02/24 23:46:05
Done.
| |
| 129 } | |
| 130 | |
| 131 SmallBitVector operator&(const SmallBitVector &Rhs) const { | |
| 132 assert(size() == Rhs.size()); | |
| 133 SmallBitVector Ret(std::max(size(), Rhs.size())); | |
| 134 Ret.Bits[0] = Bits[0] & Rhs.Bits[0]; | |
| 135 Ret.Bits[1] = Bits[1] & Rhs.Bits[1]; | |
| 136 return Ret; | |
| 137 } | |
| 138 | |
| 139 SmallBitVector operator~() const { | |
| 140 SmallBitVector Ret = *this; | |
| 141 Ret.invert<0>(); | |
| 142 return Ret; | |
| 143 } | |
| 144 | |
| 145 SmallBitVector &operator|=(const SmallBitVector &Rhs) { | |
| 146 assert(size() == Rhs.size()); | |
| 147 resize(std::max(size(), Rhs.size())); | |
| 148 Bits[0] |= Rhs.Bits[0]; | |
| 149 Bits[1] |= Rhs.Bits[1]; | |
| 150 return *this; | |
| 151 } | |
| 152 | |
| 153 SmallBitVector operator|(const SmallBitVector &Rhs) const { | |
| 154 assert(size() == Rhs.size()); | |
| 155 SmallBitVector Ret(std::max(size(), Rhs.size())); | |
| 156 Ret.Bits[0] = Bits[0] | Rhs.Bits[0]; | |
| 157 Ret.Bits[1] = Bits[1] | Rhs.Bits[1]; | |
| 158 return Ret; | |
| 159 } | |
| 160 | |
| 161 void reset() { memset(Bits, 0, sizeof(Bits)); } | |
| 162 | |
| 163 void reset(const SmallBitVector &Mask) { | |
| 164 for (const auto V : RegNumBVIter(Mask)) { | |
| 165 (*this)[unsigned(V)] = false; | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 private: | |
| 170 ElementType Bits[2]; | |
| 171 static_assert(sizeof(Bits) == 16, "Bits must be 16 bytes wide."); | |
| 172 SizeT Size = 0; | |
| 173 | |
| 174 template <SizeT Pos> | |
| 175 typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), int>::type | |
| 176 find_first() const { | |
| 177 return -1; | |
| 178 } | |
| 179 | |
| 180 template <SizeT Pos> | |
| 181 typename std::enable_if < | |
| 182 Pos<sizeof(Bits) / sizeof(Bits[0]), int>::type find_first() const { | |
| 183 if (Bits[Pos] != 0) { | |
| 184 return NumBitsPerPos * Pos + llvm::countTrailingZeros(Bits[Pos]); | |
| 185 } | |
| 186 return find_first<Pos + 1>(); | |
| 187 } | |
| 188 | |
| 189 template <SizeT Pos> | |
| 190 typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), int>::type | |
| 191 find_next(unsigned) const { | |
| 192 return -1; | |
| 193 } | |
| 194 | |
| 195 template <SizeT Pos> | |
| 196 typename std::enable_if < Pos<sizeof(Bits) / sizeof(Bits[0]), int>::type | |
| 197 find_next(unsigned Prev) const { | |
| 198 if (Prev + 1 < (Pos + 1) * NumBitsPerPos) { | |
| 199 const ElementType Mask = | |
| 200 (ElementType(1) << ((Prev + 1) - Pos * NumBitsPerPos)) - 1; | |
| 201 const ElementType B = Bits[Pos] & ~Mask; | |
| 202 if (B != 0) { | |
| 203 return NumBitsPerPos * Pos + llvm::countTrailingZeros(B); | |
| 204 } | |
| 205 Prev = (1 + Pos) * NumBitsPerPos - 1; | |
| 206 } | |
| 207 return find_next<Pos + 1>(Prev); | |
| 208 } | |
| 209 | |
| 210 template <SizeT Pos> | |
| 211 typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), void>::type | |
| 212 invert() {} | |
| 213 | |
| 214 template <SizeT Pos> | |
| 215 typename std::enable_if < | |
| 216 Pos<sizeof(Bits) / sizeof(Bits[0]), void>::type invert() { | |
| 217 if (size() < Pos * NumBitsPerPos) { | |
| 218 Bits[Pos] = 0; | |
| 219 } else if ((Pos + 1) * NumBitsPerPos < size()) { | |
| 220 Bits[Pos] ^= ~ElementType(0); | |
| 221 } else { | |
| 222 const ElementType Mask = | |
| 223 (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1; | |
| 224 Bits[Pos] ^= Mask; | |
| 225 } | |
| 226 invert<Pos + 1>(); | |
| 227 } | |
| 228 | |
| 229 template <SizeT Pos> | |
| 230 typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), void>::type | |
| 231 set_all() {} | |
| 232 | |
| 233 template <SizeT Pos> | |
| 234 typename std::enable_if < | |
| 235 Pos<sizeof(Bits) / sizeof(Bits[0]), void>::type set_all() { | |
| 236 if (size() < Pos * NumBitsPerPos) { | |
| 237 Bits[Pos] = 0; | |
| 238 } else if ((Pos + 1) * NumBitsPerPos < size()) { | |
| 239 Bits[Pos] = ~ElementType(0); | |
| 240 } else { | |
| 241 const ElementType Mask = | |
| 242 (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1; | |
| 243 Bits[Pos] = Mask; | |
| 244 } | |
| 245 set_all<Pos + 1>(); | |
| 246 } | |
| 247 }; | |
| 248 | |
| 249 } // end of namespace Ice | |
| 250 | |
| 251 #endif // SUBZERO_SRC_ICEBITVECTOR_H | |
| OLD | NEW |