[llvm-branch-commits] [llvm] TableGen: Store super-register class sets as bit vectors (PR #234798)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Oct 22 16:47:09 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tablegen

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

extendSuperRegClasses adds the super-register classes of each register
class's super-classes to its own, by merging their sets. The sets were
DenseSets, so most of the time went to hashing classes that were already
present.

Store the sets as bit vectors instead, so merging is a bitwise or. They
are indexed by a new CreationIndex, since EnumValue isn't assigned until
all classes have been inferred.

AMDGPU tablegen runs that build the register bank:

            Gigainstructions  Gigacycles     CPU seconds
  Before    700               435            135
  After     622 (-11.1%)      381 (-12.5%)   120 (-11.2%)

Co-authored-by: Claude Opus 5.5 <noreply@<!-- -->anthropic.com>

---

<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

---
Full diff: https://github.com/llvm/llvm-project/pull/234798.diff


3 Files Affected:

- (modified) llvm/utils/TableGen/Common/CodeGenRegisters.cpp (+20-12) 
- (modified) llvm/utils/TableGen/Common/CodeGenRegisters.h (+24-5) 
- (modified) llvm/utils/TableGen/RegisterInfoEmitter.cpp (+1-1) 


``````````diff
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 0af3a5a3c7d3a..3b5451e0d32b5 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -1174,23 +1174,29 @@ bool CodeGenRegisterClass::hasAnySuperRegClasses(
 bool CodeGenRegisterClass::hasSuperRegClass(
     const CodeGenSubRegIndex *SubIdx, const CodeGenRegisterClass *RC) const {
   auto FindI = SuperRegClasses.find(SubIdx);
+  if (FindI == SuperRegClasses.end())
+    return false;
 
-  return FindI != SuperRegClasses.end() && FindI->second.contains(RC);
+  const BitVector &Supers = FindI->second;
+  return RC->CreationIndex < Supers.size() && Supers.test(RC->CreationIndex);
 }
 
 bool CodeGenRegisterClass::hasSuperRegClass(
     const CodeGenRegisterClass *RC) const {
-  return any_of(SuperRegClasses,
-                [RC](const auto &Entry) { return Entry.second.contains(RC); });
+  return any_of(SuperRegClasses, [RC](const auto &Entry) {
+    const BitVector &Supers = Entry.second;
+    return RC->CreationIndex < Supers.size() && Supers.test(RC->CreationIndex);
+  });
 }
 
 void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
+                                              const CodeGenRegBank &RegBank,
                                               BitVector &Out) const {
   auto FindI = SuperRegClasses.find(SubIdx);
   if (FindI == SuperRegClasses.end())
     return;
-  for (CodeGenRegisterClass *RC : FindI->second)
-    Out.set(RC->EnumValue);
+  for (unsigned I : FindI->second.set_bits())
+    Out.set(RegBank.getRegClassByCreationIndex(I)->EnumValue);
 }
 
 // Populate a unique sorted list of units from a register set.
@@ -1211,21 +1217,21 @@ void CodeGenRegisterClass::buildRegUnitSet(
 
 // Combine our super classes of the given sub-register index with all of their
 // super classes in turn.
-void CodeGenRegisterClass::extendSuperRegClasses(CodeGenSubRegIndex *SubIdx) {
+void CodeGenRegisterClass::extendSuperRegClasses(
+    CodeGenSubRegIndex *SubIdx, const CodeGenRegBank &RegBank) {
   auto It = SuperRegClasses.find(SubIdx);
   if (It == SuperRegClasses.end())
     return;
 
-  SmallVector<CodeGenRegisterClass *> MidRCs;
-  llvm::append_range(MidRCs, It->second);
-
-  for (CodeGenRegisterClass *MidRC : MidRCs) {
+  BitVector MidRCs = It->second;
+  for (unsigned I : MidRCs.set_bits()) {
+    const CodeGenRegisterClass *MidRC = RegBank.getRegClassByCreationIndex(I);
     for (auto &Pair : MidRC->SuperRegClasses) {
       CodeGenSubRegIndex *ComposedSubIdx = Pair.first->compose(SubIdx);
       if (!ComposedSubIdx)
         continue;
 
-      SuperRegClasses[ComposedSubIdx].insert_range(Pair.second);
+      SuperRegClasses[ComposedSubIdx] |= Pair.second;
     }
   }
 }
@@ -1364,6 +1370,7 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
   for (const Record *R : RCs) {
     RegClasses.emplace_back(*this, R);
     CodeGenRegisterClass &RC = RegClasses.back();
+    setCreationIndex(RC);
     RegClassNames.insert(RC.getName());
     if (!RC.Artificial)
       addToMaps(&RC);
@@ -1442,6 +1449,7 @@ CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
 
   // Sub-class doesn't exist, create a new one.
   RegClasses.emplace_back(*this, Name, K);
+  setCreationIndex(RegClasses.back());
   RegClassNames.insert(Name);
   addToMaps(&RegClasses.back());
   return {&RegClasses.back(), true};
@@ -2777,7 +2785,7 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
   // pass.
   for (CodeGenSubRegIndex *SubIdx : SubRegIndicesRPOT) {
     for (CodeGenRegisterClass &SubRC : RegClasses)
-      SubRC.extendSuperRegClasses(SubIdx);
+      SubRC.extendSuperRegClasses(SubIdx, *this);
   }
 
   Records.getTimer().stopTimer();
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index 6f30e517c758a..4b58b8d844169 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -405,8 +405,8 @@ class CodeGenRegisterClass {
   //
   //   R:SubRegIndex in this RC for all R in SuperRC.
   //
-  DenseMap<CodeGenSubRegIndex *, DenseSet<CodeGenRegisterClass *>>
-      SuperRegClasses;
+  // The sets are indexed by CreationIndex.
+  DenseMap<CodeGenSubRegIndex *, BitVector> SuperRegClasses;
 
   // Bit vector of TopoSigs for the registers with super registers in this
   // class. This will be very sparse on regular architectures.
@@ -420,6 +420,9 @@ class CodeGenRegisterClass {
 
 public:
   unsigned EnumValue;
+  // Position in creation order, see CodeGenRegBank::getRegClassByCreationIndex.
+  // Unlike EnumValue, this is known while classes are being inferred.
+  unsigned CreationIndex = ~0u;
   StringRef Namespace;
   SmallVector<ValueTypeByHwMode, 4> VTs;
   RegSizeInfoByHwMode RSI;
@@ -518,15 +521,19 @@ class CodeGenRegisterClass {
   // getSuperRegClasses - Returns a bit vector of all register classes
   // containing only SubIdx super-registers of this class.
   void getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
-                          BitVector &Out) const;
+                          const CodeGenRegBank &RegBank, BitVector &Out) const;
 
   // addSuperRegClass - Add a class containing only SubIdx super-registers.
   void addSuperRegClass(CodeGenSubRegIndex *SubIdx,
                         CodeGenRegisterClass *SuperRC) {
-    SuperRegClasses[SubIdx].insert(SuperRC);
+    BitVector &Supers = SuperRegClasses[SubIdx];
+    if (Supers.size() <= SuperRC->CreationIndex)
+      Supers.resize(SuperRC->CreationIndex + 1);
+    Supers.set(SuperRC->CreationIndex);
   }
 
-  void extendSuperRegClasses(CodeGenSubRegIndex *SubIdx);
+  void extendSuperRegClasses(CodeGenSubRegIndex *SubIdx,
+                             const CodeGenRegBank &RegBank);
 
   // getSubClasses - Returns a constant BitVector of subclasses indexed by
   // EnumValue.
@@ -727,6 +734,8 @@ class CodeGenRegBank {
 
   // Register classes.
   std::list<CodeGenRegisterClass> RegClasses;
+  // RegClasses in creation order, indexed by CreationIndex.
+  std::vector<CodeGenRegisterClass *> RegClassesByCreationIndex;
   StringSet<> RegClassNames;
   DenseMap<const Record *, CodeGenRegisterClass *> Def2RC;
   using RCKeyMap = std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass *>;
@@ -760,6 +769,12 @@ class CodeGenRegBank {
   // Add RC to *2RC maps.
   void addToMaps(CodeGenRegisterClass *);
 
+  // Set the CreationIndex of the newest register class.
+  void setCreationIndex(CodeGenRegisterClass &RC) {
+    RC.CreationIndex = RegClassesByCreationIndex.size();
+    RegClassesByCreationIndex.push_back(&RC);
+  }
+
   // Create a synthetic sub-class if it is missing. Returns (RC, inserted).
   std::pair<CodeGenRegisterClass *, bool>
   getOrCreateSubClass(const CodeGenRegisterClass *RC,
@@ -901,6 +916,10 @@ class CodeGenRegBank {
     return RegClasses;
   }
 
+  CodeGenRegisterClass *getRegClassByCreationIndex(unsigned Idx) const {
+    return RegClassesByCreationIndex[Idx];
+  }
+
   std::list<CodeGenRegisterCategory> &getRegCategories() {
     return RegCategories;
   }
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 05a7ff8b77c2d..9a3b78244f4ea 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1207,7 +1207,7 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
     SmallVector<unsigned, 8> &MaskIndices = SuperRegMaskIndices[RC.EnumValue];
     for (auto &Idx : SubRegIndices) {
       MaskBV.reset();
-      RC.getSuperRegClasses(&Idx, MaskBV);
+      RC.getSuperRegClasses(&Idx, RegBank, MaskBV);
       if (MaskBV.none())
         continue;
       SRIList.push_back(&Idx);

``````````

</details>


https://github.com/llvm/llvm-project/pull/234798


More information about the llvm-branch-commits mailing list