Skip to content

Commit 8c21ee7

Browse files
kazutakahiratamahesh-attarde
authored andcommitted
[ADT] Inline PackedVectorBase into PackedVector (NFC) (llvm#161122)
This patch "inlines" PackedVectorBase into its sole user PackedVector. The two variants of PackedVectorBase are dispatched with "if constexpr". getValue and setValue are now non-static methods of PackedVector. We could further simplify getValue and setValue by storing signed integers as two's complement, but that's a change for another day. This patch focuses on the code organization, like removing the template trick and inheritance and making the two methods non-static.
1 parent 8bfd053 commit 8c21ee7

File tree

1 file changed

+36
-53
lines changed

1 file changed

+36
-53
lines changed

llvm/include/llvm/ADT/PackedVector.h

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,53 +20,6 @@
2020

2121
namespace llvm {
2222

23-
template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
24-
class PackedVectorBase;
25-
26-
// This won't be necessary if we can specialize members without specializing
27-
// the parent template.
28-
template <typename T, unsigned BitNum, typename BitVectorTy>
29-
class PackedVectorBase<T, BitNum, BitVectorTy, false> {
30-
protected:
31-
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
32-
T val = T();
33-
for (unsigned i = 0; i != BitNum; ++i)
34-
val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i));
35-
return val;
36-
}
37-
38-
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
39-
assert((val >> BitNum) == 0 && "value is too big");
40-
for (unsigned i = 0; i != BitNum; ++i)
41-
Bits[(Idx * BitNum) + i] = val & (T(1) << i);
42-
}
43-
};
44-
45-
template <typename T, unsigned BitNum, typename BitVectorTy>
46-
class PackedVectorBase<T, BitNum, BitVectorTy, true> {
47-
protected:
48-
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
49-
T val = T();
50-
for (unsigned i = 0; i != BitNum - 1; ++i)
51-
val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i));
52-
if (Bits[(Idx * BitNum) + BitNum - 1])
53-
val = ~val;
54-
return val;
55-
}
56-
57-
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
58-
if (val < 0) {
59-
val = ~val;
60-
Bits.set((Idx * BitNum) + BitNum - 1);
61-
} else {
62-
Bits.reset((Idx * BitNum) + BitNum - 1);
63-
}
64-
assert((val >> (BitNum - 1)) == 0 && "value is too big");
65-
for (unsigned i = 0; i != BitNum - 1; ++i)
66-
Bits[(Idx * BitNum) + i] = val & (T(1) << i);
67-
}
68-
};
69-
7023
/// Store a vector of values using a specific number of bits for each
7124
/// value. Both signed and unsigned types can be used, e.g
7225
/// @code
@@ -75,16 +28,46 @@ class PackedVectorBase<T, BitNum, BitVectorTy, true> {
7528
/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
7629
/// an assertion.
7730
template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
78-
class PackedVector
79-
: public PackedVectorBase<T, BitNum, BitVectorTy,
80-
std::numeric_limits<T>::is_signed> {
31+
class PackedVector {
8132
BitVectorTy Bits;
8233
// Keep track of the number of elements on our own.
8334
// We always maintain Bits.size() == NumElements * BitNum.
8435
// Used to avoid an integer division in size().
8536
unsigned NumElements = 0;
86-
using base = PackedVectorBase<T, BitNum, BitVectorTy,
87-
std::numeric_limits<T>::is_signed>;
37+
38+
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
39+
if constexpr (std::numeric_limits<T>::is_signed) {
40+
T val = T();
41+
for (unsigned i = 0; i != BitNum - 1; ++i)
42+
val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i));
43+
if (Bits[(Idx * BitNum) + BitNum - 1])
44+
val = ~val;
45+
return val;
46+
} else {
47+
T val = T();
48+
for (unsigned i = 0; i != BitNum; ++i)
49+
val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i));
50+
return val;
51+
}
52+
}
53+
54+
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
55+
if constexpr (std::numeric_limits<T>::is_signed) {
56+
if (val < 0) {
57+
val = ~val;
58+
Bits.set((Idx * BitNum) + BitNum - 1);
59+
} else {
60+
Bits.reset((Idx * BitNum) + BitNum - 1);
61+
}
62+
assert((val >> (BitNum - 1)) == 0 && "value is too big");
63+
for (unsigned i = 0; i != BitNum - 1; ++i)
64+
Bits[(Idx * BitNum) + i] = val & (T(1) << i);
65+
} else {
66+
assert((val >> BitNum) == 0 && "value is too big");
67+
for (unsigned i = 0; i != BitNum; ++i)
68+
Bits[(Idx * BitNum) + i] = val & (T(1) << i);
69+
}
70+
}
8871

8972
public:
9073
class reference {
@@ -135,7 +118,7 @@ class PackedVector
135118

136119
reference operator[](unsigned Idx) { return reference(*this, Idx); }
137120

138-
T operator[](unsigned Idx) const { return base::getValue(Bits, Idx); }
121+
T operator[](unsigned Idx) const { return getValue(Bits, Idx); }
139122

140123
bool operator==(const PackedVector &RHS) const { return Bits == RHS.Bits; }
141124

0 commit comments

Comments
 (0)