Index: src/IceBitVector.h |
diff --git a/src/IceBitVector.h b/src/IceBitVector.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..37dbc663e11f3ca418c9a42b59e0e5c58cebdf72 |
--- /dev/null |
+++ b/src/IceBitVector.h |
@@ -0,0 +1,251 @@ |
+ |
Jim Stichnoth
2016/02/24 23:11:39
remove leading blank line
John
2016/02/24 23:46:05
Done.
|
+//===- subzero/src/IceBitVector.h - Inline bit vector. ----------*- C++ -*-===// |
+// |
+// The Subzero Code Generator |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+/// |
+/// \file |
+/// \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.
|
+/// 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.
|
+/// all of |
+/// llvm::SmallSmallBitVector interface is implemented. |
+/// |
+//===----------------------------------------------------------------------===// |
+ |
+#ifndef SUBZERO_SRC_ICEBITVECTOR_H |
+#define SUBZERO_SRC_ICEBITVECTOR_H |
+ |
+#include "IceDefs.h" |
+#include "IceOperand.h" |
+ |
+#include "llvm/Support/MathExtras.h" |
+ |
+#include <algorithm> |
+#include <climits> |
+#include <memory> |
+#include <type_traits> |
+ |
+namespace Ice { |
+class SmallBitVector { |
+public: |
+ using ElementType = uint64_t; |
+ static constexpr SizeT NumBitsPerPos = sizeof(ElementType) * CHAR_BIT; |
+ |
+ SmallBitVector(const SmallBitVector &BV) { *this = BV; } |
+ |
+ SmallBitVector &operator=(const SmallBitVector &BV) { |
+ if (&BV != this) { |
+ resize(BV.size()); |
+ memcpy(Bits, BV.Bits, sizeof(Bits)); |
+ } |
+ return *this; |
+ } |
+ |
+ SmallBitVector() { |
+ 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.
|
+ memset(Bits, 0, sizeof(Bits)); |
+ } |
+ |
+ explicit SmallBitVector(SizeT S) : SmallBitVector() { |
+ resize(S); |
+ assert(Size <= sizeof(Bits) * CHAR_BIT); |
Jim Stichnoth
2016/02/24 23:11:39
constexpr
John
2016/02/24 23:46:05
Done.
|
+ } |
+ |
+ class Reference { |
+ Reference() = delete; |
+ |
+ public: |
+ Reference(const Reference &) = default; |
+ Reference &operator=(const Reference &Rhs) { return *this = (bool)Rhs; } |
+ Reference &operator=(bool t) { |
+ if (t) { |
+ *Data |= 1ull << Bit; |
+ } else { |
+ *Data &= ~(1ull << Bit); |
+ } |
+ return *this; |
+ } |
+ operator bool() const { return (*Data & (1ull << Bit)) != 0; } |
+ |
+ private: |
+ friend class SmallBitVector; |
+ 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.
|
+ assert(B < CHAR_BIT * sizeof(*D)); |
+ } |
+ |
+ uint64_t *const Data; |
+ const SizeT Bit; |
+ }; |
+ |
+ Reference operator[](unsigned Idx) { |
+ assert(Idx < size()); |
+ // 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.
|
+ // Idx & ((1ull << llvm::Log2_64(NumBitsPerPos))-1)); |
+ 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.
|
+ } |
+ |
+ bool operator[](unsigned Idx) const { |
+ assert(Idx < size()); |
+ 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.
|
+ } |
+ |
+ int find_first() const { return find_first<0>(); } |
+ |
+ int find_next(unsigned Prev) const { return find_next<0>(Prev); } |
+ |
+ 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.
|
+ |
+ SizeT size() const { return Size; } |
+ |
+ void resize(SizeT Size) { |
+ assert(Size <= sizeof(Bits) * CHAR_BIT); |
+ this->Size = Size; |
+ } |
+ |
+ void reserve(SizeT Size) { |
+ assert(Size <= sizeof(Bits) * CHAR_BIT); |
+ (void)Size; |
+ } |
+ |
+ void set(unsigned Idx) { |
+ // TODO(jpp): improve. |
+ (*this)[Idx] = true; |
+ } |
+ |
+ void set() { |
+ // TODO(jpp): improve. |
+ for (SizeT ii = 0; ii < size(); ++ii) { |
+ (*this)[ii] = true; |
+ } |
+ // set_all<0>(); |
Jim Stichnoth
2016/02/24 23:11:38
remove comment
John
2016/02/24 23:46:05
Done.
|
+ } |
+ |
+ SizeT count() const { |
+ 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.
|
+ } |
+ |
+ SmallBitVector operator&(const SmallBitVector &Rhs) const { |
+ assert(size() == Rhs.size()); |
+ SmallBitVector Ret(std::max(size(), Rhs.size())); |
+ Ret.Bits[0] = Bits[0] & Rhs.Bits[0]; |
+ Ret.Bits[1] = Bits[1] & Rhs.Bits[1]; |
+ return Ret; |
+ } |
+ |
+ SmallBitVector operator~() const { |
+ SmallBitVector Ret = *this; |
+ Ret.invert<0>(); |
+ return Ret; |
+ } |
+ |
+ SmallBitVector &operator|=(const SmallBitVector &Rhs) { |
+ assert(size() == Rhs.size()); |
+ resize(std::max(size(), Rhs.size())); |
+ Bits[0] |= Rhs.Bits[0]; |
+ Bits[1] |= Rhs.Bits[1]; |
+ return *this; |
+ } |
+ |
+ SmallBitVector operator|(const SmallBitVector &Rhs) const { |
+ assert(size() == Rhs.size()); |
+ SmallBitVector Ret(std::max(size(), Rhs.size())); |
+ Ret.Bits[0] = Bits[0] | Rhs.Bits[0]; |
+ Ret.Bits[1] = Bits[1] | Rhs.Bits[1]; |
+ return Ret; |
+ } |
+ |
+ void reset() { memset(Bits, 0, sizeof(Bits)); } |
+ |
+ void reset(const SmallBitVector &Mask) { |
+ for (const auto V : RegNumBVIter(Mask)) { |
+ (*this)[unsigned(V)] = false; |
+ } |
+ } |
+ |
+private: |
+ ElementType Bits[2]; |
+ static_assert(sizeof(Bits) == 16, "Bits must be 16 bytes wide."); |
+ SizeT Size = 0; |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), int>::type |
+ find_first() const { |
+ return -1; |
+ } |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if < |
+ Pos<sizeof(Bits) / sizeof(Bits[0]), int>::type find_first() const { |
+ if (Bits[Pos] != 0) { |
+ return NumBitsPerPos * Pos + llvm::countTrailingZeros(Bits[Pos]); |
+ } |
+ return find_first<Pos + 1>(); |
+ } |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), int>::type |
+ find_next(unsigned) const { |
+ return -1; |
+ } |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if < Pos<sizeof(Bits) / sizeof(Bits[0]), int>::type |
+ find_next(unsigned Prev) const { |
+ if (Prev + 1 < (Pos + 1) * NumBitsPerPos) { |
+ const ElementType Mask = |
+ (ElementType(1) << ((Prev + 1) - Pos * NumBitsPerPos)) - 1; |
+ const ElementType B = Bits[Pos] & ~Mask; |
+ if (B != 0) { |
+ return NumBitsPerPos * Pos + llvm::countTrailingZeros(B); |
+ } |
+ Prev = (1 + Pos) * NumBitsPerPos - 1; |
+ } |
+ return find_next<Pos + 1>(Prev); |
+ } |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), void>::type |
+ invert() {} |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if < |
+ Pos<sizeof(Bits) / sizeof(Bits[0]), void>::type invert() { |
+ if (size() < Pos * NumBitsPerPos) { |
+ Bits[Pos] = 0; |
+ } else if ((Pos + 1) * NumBitsPerPos < size()) { |
+ Bits[Pos] ^= ~ElementType(0); |
+ } else { |
+ const ElementType Mask = |
+ (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1; |
+ Bits[Pos] ^= Mask; |
+ } |
+ invert<Pos + 1>(); |
+ } |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if<Pos == sizeof(Bits) / sizeof(Bits[0]), void>::type |
+ set_all() {} |
+ |
+ template <SizeT Pos> |
+ typename std::enable_if < |
+ Pos<sizeof(Bits) / sizeof(Bits[0]), void>::type set_all() { |
+ if (size() < Pos * NumBitsPerPos) { |
+ Bits[Pos] = 0; |
+ } else if ((Pos + 1) * NumBitsPerPos < size()) { |
+ Bits[Pos] = ~ElementType(0); |
+ } else { |
+ const ElementType Mask = |
+ (ElementType(1) << (size() - (Pos * NumBitsPerPos))) - 1; |
+ Bits[Pos] = Mask; |
+ } |
+ set_all<Pos + 1>(); |
+ } |
+}; |
+ |
+} // end of namespace Ice |
+ |
+#endif // SUBZERO_SRC_ICEBITVECTOR_H |