[llvm] [ADT] Inline PackedVectorBase into PackedVector (NFC) (PR #161122)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 28 21:11:34 PDT 2025


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/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.


>From ecf293bd0ac80683ab8c2f0526f413c9bdeadcac Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
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 <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
-class PackedVectorBase;
-
-// This won't be necessary if we can specialize members without specializing
-// the parent template.
-template <typename T, unsigned BitNum, typename BitVectorTy>
-class PackedVectorBase<T, BitNum, BitVectorTy, false> {
-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 <typename T, unsigned BitNum, typename BitVectorTy>
-class PackedVectorBase<T, BitNum, BitVectorTy, true> {
-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<T, BitNum, BitVectorTy, true> {
 /// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
 /// an assertion.
 template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
-class PackedVector
-    : public PackedVectorBase<T, BitNum, BitVectorTy,
-                              std::numeric_limits<T>::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<T, BitNum, BitVectorTy,
-                                std::numeric_limits<T>::is_signed>;
+
+  static T getValue(const BitVectorTy &Bits, unsigned Idx) {
+    if constexpr (std::numeric_limits<T>::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<T>::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; }
 



More information about the llvm-commits mailing list