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 |