Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: src/IceBitVector.h

Issue 1738443002: Subzero. Performance tweaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Undoes Makefile changes. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698