From ecf293bd0ac80683ab8c2f0526f413c9bdeadcac Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Tue, 16 Sep 2025 09:31:00 -0700 Subject: [PATCH] [ADT] Inline PackedVectorBase into PackedVector (NFC) 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. --- llvm/include/llvm/ADT/PackedVector.h | 89 +++++++++++----------------- 1 file changed, 36 insertions(+), 53 deletions(-) diff --git a/llvm/include/llvm/ADT/PackedVector.h b/llvm/include/llvm/ADT/PackedVector.h index 77fcbf24b2861..09c20e39d1552 100644 --- a/llvm/include/llvm/ADT/PackedVector.h +++ b/llvm/include/llvm/ADT/PackedVector.h @@ -20,53 +20,6 @@ namespace llvm { -template -class PackedVectorBase; - -// This won't be necessary if we can specialize members without specializing -// the parent template. -template -class PackedVectorBase { -protected: - static T getValue(const BitVectorTy &Bits, unsigned Idx) { - T val = T(); - for (unsigned i = 0; i != BitNum; ++i) - val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); - return val; - } - - static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { - assert((val >> BitNum) == 0 && "value is too big"); - for (unsigned i = 0; i != BitNum; ++i) - Bits[(Idx * BitNum) + i] = val & (T(1) << i); - } -}; - -template -class PackedVectorBase { -protected: - static T getValue(const BitVectorTy &Bits, unsigned Idx) { - T val = T(); - for (unsigned i = 0; i != BitNum - 1; ++i) - val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); - if (Bits[(Idx * BitNum) + BitNum - 1]) - val = ~val; - return val; - } - - static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { - if (val < 0) { - val = ~val; - Bits.set((Idx * BitNum) + BitNum - 1); - } else { - Bits.reset((Idx * BitNum) + BitNum - 1); - } - assert((val >> (BitNum - 1)) == 0 && "value is too big"); - for (unsigned i = 0; i != BitNum - 1; ++i) - Bits[(Idx * BitNum) + i] = val & (T(1) << i); - } -}; - /// Store a vector of values using a specific number of bits for each /// value. Both signed and unsigned types can be used, e.g /// @code @@ -75,16 +28,46 @@ class PackedVectorBase { /// will create a vector accepting values -2, -1, 0, 1. Any other value will hit /// an assertion. template -class PackedVector - : public PackedVectorBase::is_signed> { +class PackedVector { BitVectorTy Bits; // Keep track of the number of elements on our own. // We always maintain Bits.size() == NumElements * BitNum. // Used to avoid an integer division in size(). unsigned NumElements = 0; - using base = PackedVectorBase::is_signed>; + + static T getValue(const BitVectorTy &Bits, unsigned Idx) { + if constexpr (std::numeric_limits::is_signed) { + T val = T(); + for (unsigned i = 0; i != BitNum - 1; ++i) + val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); + if (Bits[(Idx * BitNum) + BitNum - 1]) + val = ~val; + return val; + } else { + T val = T(); + for (unsigned i = 0; i != BitNum; ++i) + val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); + return val; + } + } + + static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { + if constexpr (std::numeric_limits::is_signed) { + if (val < 0) { + val = ~val; + Bits.set((Idx * BitNum) + BitNum - 1); + } else { + Bits.reset((Idx * BitNum) + BitNum - 1); + } + assert((val >> (BitNum - 1)) == 0 && "value is too big"); + for (unsigned i = 0; i != BitNum - 1; ++i) + Bits[(Idx * BitNum) + i] = val & (T(1) << i); + } else { + assert((val >> BitNum) == 0 && "value is too big"); + for (unsigned i = 0; i != BitNum; ++i) + Bits[(Idx * BitNum) + i] = val & (T(1) << i); + } + } public: class reference { @@ -135,7 +118,7 @@ class PackedVector reference operator[](unsigned Idx) { return reference(*this, Idx); } - T operator[](unsigned Idx) const { return base::getValue(Bits, Idx); } + T operator[](unsigned Idx) const { return getValue(Bits, Idx); } bool operator==(const PackedVector &RHS) const { return Bits == RHS.Bits; }