[llvm] CodeGen: Eliminate dynamic relocations in the register superclass tables. (PR #119122)

Owen Anderson via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 10 04:45:06 PST 2024


https://github.com/resistor updated https://github.com/llvm/llvm-project/pull/119122

>From 87babe71ed0116dd5e222bf2aa092cc6bbf35ee9 Mon Sep 17 00:00:00 2001
From: Owen Anderson <resistor at mac.com>
Date: Sun, 8 Dec 2024 22:57:55 +1300
Subject: [PATCH 1/5] CodeGen: Eliminate dynamic relocations in the register
 superclass tables.

---
 llvm/include/llvm/CodeGen/TargetRegisterInfo.h  |  6 ++----
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp     | 14 +++++++-------
 llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp |  5 +++--
 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp     | 15 ++++++++-------
 llvm/lib/Target/X86/X86RegisterInfo.cpp         |  3 ++-
 llvm/utils/TableGen/RegisterInfoEmitter.cpp     | 11 +++++------
 6 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 292fa3c94969be..becd335cfb4c2e 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -46,7 +46,7 @@ class TargetRegisterClass {
 public:
   using iterator = const MCPhysReg *;
   using const_iterator = const MCPhysReg *;
-  using sc_iterator = const TargetRegisterClass* const *;
+  using sc_iterator = const unsigned *;
 
   // Instance variables filled by tablegen, do not use!
   const MCRegisterClass *MC;
@@ -184,9 +184,7 @@ class TargetRegisterClass {
 
   /// Return true if this TargetRegisterClass is a subset
   /// class of at least one other TargetRegisterClass.
-  bool isASubClass() const {
-    return SuperClasses[0] != nullptr;
-  }
+  bool isASubClass() const { return SuperClasses[0] != ~0U; }
 
   /// Returns the preferred order for allocating registers from this register
   /// class in MF. The raw order comes directly from the .td file and may
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index a1f068f0e049bd..2df4ee3b84bc19 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -262,30 +262,30 @@ bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF,
 const TargetRegisterClass *
 ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
                                                const MachineFunction &MF) const {
-  const TargetRegisterClass *Super = RC;
+  unsigned SuperID = RC->getID();
   TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
   do {
-    switch (Super->getID()) {
+    switch (SuperID) {
     case ARM::GPRRegClassID:
     case ARM::SPRRegClassID:
     case ARM::DPRRegClassID:
     case ARM::GPRPairRegClassID:
-      return Super;
+      return getRegClass(SuperID);
     case ARM::QPRRegClassID:
     case ARM::QQPRRegClassID:
     case ARM::QQQQPRRegClassID:
       if (MF.getSubtarget<ARMSubtarget>().hasNEON())
-        return Super;
+        return getRegClass(SuperID);
       break;
     case ARM::MQPRRegClassID:
     case ARM::MQQPRRegClassID:
     case ARM::MQQQQPRRegClassID:
       if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps())
-        return Super;
+        return getRegClass(SuperID);
       break;
     }
-    Super = *I++;
-  } while (Super);
+    SuperID = *I++;
+  } while (SuperID != ~0U);
   return RC;
 }
 
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index d4d121e4380089..31840d9757f7e8 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -431,8 +431,9 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
       return WSub[GenIdx];
   }
 
-  if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
-    return getHexagonSubRegIndex(*SuperRC, GenIdx);
+  unsigned SuperID = *RC.getSuperClasses();
+  if (SuperID != ~0U)
+    return getHexagonSubRegIndex(*getRegClass(SuperID), GenIdx);
 
   llvm_unreachable("Invalid register class");
 }
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 43dfc4108f8384..bbefe380678441 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -692,21 +692,22 @@ PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
         InflateGPRC++;
     }
 
-    for (const auto *I = RC->getSuperClasses(); *I; ++I) {
-      if (getRegSizeInBits(**I) != getRegSizeInBits(*RC))
+    for (const unsigned *I = RC->getSuperClasses(); *I != ~0U; ++I) {
+      if (getRegSizeInBits(*getRegClass(*I)) != getRegSizeInBits(*RC))
         continue;
 
-      switch ((*I)->getID()) {
+      switch (*I) {
       case PPC::VSSRCRegClassID:
-        return Subtarget.hasP8Vector() ? *I : DefaultSuperclass;
+        return Subtarget.hasP8Vector() ? getRegClass(*I) : DefaultSuperclass;
       case PPC::VSFRCRegClassID:
       case PPC::VSRCRegClassID:
-        return *I;
+        return getRegClass(*I);
       case PPC::VSRpRCRegClassID:
-        return Subtarget.pairedVectorMemops() ? *I : DefaultSuperclass;
+        return Subtarget.pairedVectorMemops() ? getRegClass(*I)
+                                              : DefaultSuperclass;
       case PPC::ACCRCRegClassID:
       case PPC::UACCRCRegClassID:
-        return Subtarget.hasMMA() ? *I : DefaultSuperclass;
+        return Subtarget.hasMMA() ? getRegClass(*I) : DefaultSuperclass;
       }
     }
   }
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 50db211c99d882..96c42c559304cc 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -172,7 +172,8 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
       if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
         return Super;
     }
-    Super = *I++;
+    Super = (*I != ~0U) ? getRegClass(*I) : nullptr;
+    ++I;
   } while (Super);
   return RC;
 }
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index a6f87119aca5ba..a0b4668f152563 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1286,8 +1286,8 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
     }
     OS << "};\n";
 
-    OS << "\nstatic const TargetRegisterClass *const "
-       << "NullRegClasses[] = { nullptr };\n\n";
+    OS << "\nstatic const unsigned "
+       << "NullRegClasses[] = { ~0U };\n\n";
 
     // Emit register class bit mask tables. The first bit mask emitted for a
     // register class, RC, is the set of sub-classes, including RC itself.
@@ -1348,11 +1348,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
       if (Supers.empty())
         continue;
 
-      OS << "static const TargetRegisterClass *const " << RC.getName()
-         << "Superclasses[] = {\n";
+      OS << "static unsigned const " << RC.getName() << "Superclasses[] = {\n";
       for (const auto *Super : Supers)
-        OS << "  &" << Super->getQualifiedName() << "RegClass,\n";
-      OS << "  nullptr\n};\n\n";
+        OS << "  " << Super->getQualifiedIdName() << ",\n";
+      OS << "  ~0U\n};\n\n";
     }
 
     // Emit methods.

>From cd1602978c32da50ea1e8690b11c4a1ff23e6414 Mon Sep 17 00:00:00 2001
From: Owen Anderson <resistor at mac.com>
Date: Mon, 9 Dec 2024 05:30:34 +1300
Subject: [PATCH 2/5] Use iterator wrappers for superclasses

---
 .../include/llvm/CodeGen/TargetRegisterInfo.h | 24 +++++++++++++++----
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  2 +-
 .../Target/Hexagon/HexagonRegisterInfo.cpp    |  2 +-
 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp   | 15 ++++++------
 llvm/lib/Target/X86/X86RegisterInfo.cpp       |  4 ++--
 5 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index becd335cfb4c2e..b91f2edbfe38fe 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -42,11 +42,27 @@ class VirtRegMap;
 class LiveIntervals;
 class LiveInterval;
 
+/// TargetSuperClassIterator enumerates all super-registers of RegClass.
+class TargetSuperClassIterator
+    : public iterator_adaptor_base<TargetSuperClassIterator, const unsigned *> {
+public:
+  /// Constructs an end iterator.
+  TargetSuperClassIterator() = default;
+
+  TargetSuperClassIterator(const unsigned *V) { I = V; }
+
+  const unsigned &operator*() const { return *I; }
+
+  using iterator_adaptor_base::operator++;
+
+  /// Returns true if this iterator is not yet at the end.
+  bool isValid() const { return I && *I != ~0U; }
+};
+
 class TargetRegisterClass {
 public:
   using iterator = const MCPhysReg *;
   using const_iterator = const MCPhysReg *;
-  using sc_iterator = const unsigned *;
 
   // Instance variables filled by tablegen, do not use!
   const MCRegisterClass *MC;
@@ -67,7 +83,7 @@ class TargetRegisterClass {
   /// Whether a combination of subregisters can cover every register in the
   /// class. See also the CoveredBySubRegs description in Target.td.
   const bool CoveredBySubRegs;
-  const sc_iterator SuperClasses;
+  const unsigned *SuperClasses;
   ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
 
   /// Return the register class ID number.
@@ -178,8 +194,8 @@ class TargetRegisterClass {
   /// Returns a NULL-terminated list of super-classes.  The
   /// classes are ordered by ID which is also a topological ordering from large
   /// to small classes.  The list does NOT include the current class.
-  sc_iterator getSuperClasses() const {
-    return SuperClasses;
+  iterator_range<TargetSuperClassIterator> superclasses() const {
+    return make_range({SuperClasses}, TargetSuperClassIterator());
   }
 
   /// Return true if this TargetRegisterClass is a subset
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 2df4ee3b84bc19..ade447871545e9 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -263,7 +263,7 @@ const TargetRegisterClass *
 ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
                                                const MachineFunction &MF) const {
   unsigned SuperID = RC->getID();
-  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
+  auto I = RC->superclasses().begin();
   do {
     switch (SuperID) {
     case ARM::GPRRegClassID:
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index 31840d9757f7e8..d159d00201ad7a 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -431,7 +431,7 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
       return WSub[GenIdx];
   }
 
-  unsigned SuperID = *RC.getSuperClasses();
+  unsigned SuperID = *RC.superclasses().begin();
   if (SuperID != ~0U)
     return getHexagonSubRegIndex(*getRegClass(SuperID), GenIdx);
 
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index bbefe380678441..019d4cfa33fbaf 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -692,22 +692,23 @@ PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
         InflateGPRC++;
     }
 
-    for (const unsigned *I = RC->getSuperClasses(); *I != ~0U; ++I) {
-      if (getRegSizeInBits(*getRegClass(*I)) != getRegSizeInBits(*RC))
+    for (unsigned SuperID : RC->superclasses()) {
+      if (getRegSizeInBits(*getRegClass(SuperID)) != getRegSizeInBits(*RC))
         continue;
 
-      switch (*I) {
+      switch (SuperID) {
       case PPC::VSSRCRegClassID:
-        return Subtarget.hasP8Vector() ? getRegClass(*I) : DefaultSuperclass;
+        return Subtarget.hasP8Vector() ? getRegClass(SuperID)
+                                       : DefaultSuperclass;
       case PPC::VSFRCRegClassID:
       case PPC::VSRCRegClassID:
-        return getRegClass(*I);
+        return getRegClass(SuperID);
       case PPC::VSRpRCRegClassID:
-        return Subtarget.pairedVectorMemops() ? getRegClass(*I)
+        return Subtarget.pairedVectorMemops() ? getRegClass(SuperID)
                                               : DefaultSuperclass;
       case PPC::ACCRCRegClassID:
       case PPC::UACCRCRegClassID:
-        return Subtarget.hasMMA() ? getRegClass(*I) : DefaultSuperclass;
+        return Subtarget.hasMMA() ? getRegClass(SuperID) : DefaultSuperclass;
       }
     }
   }
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 96c42c559304cc..84b9310279fcb3 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -123,7 +123,7 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
   const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
 
   const TargetRegisterClass *Super = RC;
-  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
+  auto I = RC->superclasses().begin();
   do {
     switch (Super->getID()) {
     case X86::FR32RegClassID:
@@ -172,7 +172,7 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
       if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
         return Super;
     }
-    Super = (*I != ~0U) ? getRegClass(*I) : nullptr;
+    Super = I.isValid() ? getRegClass(*I) : nullptr;
     ++I;
   } while (Super);
   return RC;

>From cdcf4bd3a7f4a21cabde77bb580a2e272faa0236 Mon Sep 17 00:00:00 2001
From: Owen Anderson <resistor at mac.com>
Date: Mon, 9 Dec 2024 05:53:45 +1300
Subject: [PATCH 3/5] Fix PowerPC

---
 llvm/include/llvm/CodeGen/TargetRegisterInfo.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index b91f2edbfe38fe..00dac022563f32 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -55,6 +55,17 @@ class TargetSuperClassIterator
 
   using iterator_adaptor_base::operator++;
 
+  bool operator==(const TargetSuperClassIterator &Other) const {
+    // End can be represented either with a nullptr or with a ptr to
+    // a sentinel value of ~0U. They must compare equal.
+    bool SelfIsEnd = !I || *I == ~0U;
+    bool OtherIsEnd = !Other.I || *Other.I == ~0U;
+    if (SelfIsEnd && OtherIsEnd)
+      return true;
+
+    return I == Other.I;
+  }
+
   /// Returns true if this iterator is not yet at the end.
   bool isValid() const { return I && *I != ~0U; }
 };

>From bb2bc9140ce2a9ad9865a90ec451fcda30123539 Mon Sep 17 00:00:00 2001
From: Owen Anderson <resistor at mac.com>
Date: Tue, 10 Dec 2024 13:18:21 +1300
Subject: [PATCH 4/5] Simplify iterator by storing the superclass list size

---
 .../include/llvm/CodeGen/TargetRegisterInfo.h | 23 +++++--------------
 llvm/utils/TableGen/RegisterInfoEmitter.cpp   |  5 ++--
 2 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 00dac022563f32..fcc4bb9f1e809f 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -42,32 +42,19 @@ class VirtRegMap;
 class LiveIntervals;
 class LiveInterval;
 
-/// TargetSuperClassIterator enumerates all super-registers of RegClass.
+/// TargetSuperClassIterator enumerates all super-classes of RegClass.
 class TargetSuperClassIterator
     : public iterator_adaptor_base<TargetSuperClassIterator, const unsigned *> {
 public:
   /// Constructs an end iterator.
-  TargetSuperClassIterator() = default;
-
   TargetSuperClassIterator(const unsigned *V) { I = V; }
 
   const unsigned &operator*() const { return *I; }
 
   using iterator_adaptor_base::operator++;
 
-  bool operator==(const TargetSuperClassIterator &Other) const {
-    // End can be represented either with a nullptr or with a ptr to
-    // a sentinel value of ~0U. They must compare equal.
-    bool SelfIsEnd = !I || *I == ~0U;
-    bool OtherIsEnd = !Other.I || *Other.I == ~0U;
-    if (SelfIsEnd && OtherIsEnd)
-      return true;
-
-    return I == Other.I;
-  }
-
   /// Returns true if this iterator is not yet at the end.
-  bool isValid() const { return I && *I != ~0U; }
+  bool isValid() const { return *I != ~0U; }
 };
 
 class TargetRegisterClass {
@@ -95,6 +82,7 @@ class TargetRegisterClass {
   /// class. See also the CoveredBySubRegs description in Target.td.
   const bool CoveredBySubRegs;
   const unsigned *SuperClasses;
+  const uint16_t SuperClassesSize;
   ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
 
   /// Return the register class ID number.
@@ -202,11 +190,12 @@ class TargetRegisterClass {
     return SuperRegIndices;
   }
 
-  /// Returns a NULL-terminated list of super-classes.  The
+  /// Returns a ~0U-terminated list of super-classes.  The
   /// classes are ordered by ID which is also a topological ordering from large
   /// to small classes.  The list does NOT include the current class.
   iterator_range<TargetSuperClassIterator> superclasses() const {
-    return make_range({SuperClasses}, TargetSuperClassIterator());
+    return make_range(TargetSuperClassIterator(SuperClasses),
+                      {SuperClasses + SuperClassesSize});
   }
 
   /// Return true if this TargetRegisterClass is a subset
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index a0b4668f152563..cdb015efe24915 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1405,9 +1405,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
          << (RC.CoveredBySubRegs ? "true" : "false")
          << ", /* CoveredBySubRegs */\n    ";
       if (RC.getSuperClasses().empty())
-        OS << "NullRegClasses,\n    ";
+        OS << "NullRegClasses, ";
       else
-        OS << RC.getName() << "Superclasses,\n    ";
+        OS << RC.getName() << "Superclasses,  ";
+      OS << RC.getSuperClasses().size() << ",\n    ";
       if (RC.AltOrderSelect.empty())
         OS << "nullptr\n";
       else

>From cd31a25a839dee90e0cd66fb7330d800e514326d Mon Sep 17 00:00:00 2001
From: Owen Anderson <resistor at mac.com>
Date: Wed, 11 Dec 2024 01:44:25 +1300
Subject: [PATCH 5/5] Eliminate sentinel and remove sentinel. Fix test warning

---
 .../include/llvm/CodeGen/TargetRegisterInfo.h | 25 +++----------------
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   |  3 ++-
 llvm/lib/Target/X86/X86RegisterInfo.cpp       |  3 ++-
 llvm/unittests/CodeGen/MachineInstrTest.cpp   |  2 +-
 llvm/utils/TableGen/RegisterInfoEmitter.cpp   | 11 +++-----
 5 files changed, 13 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index fcc4bb9f1e809f..374f9f2e7f5696 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -41,22 +41,6 @@ class RegScavenger;
 class VirtRegMap;
 class LiveIntervals;
 class LiveInterval;
-
-/// TargetSuperClassIterator enumerates all super-classes of RegClass.
-class TargetSuperClassIterator
-    : public iterator_adaptor_base<TargetSuperClassIterator, const unsigned *> {
-public:
-  /// Constructs an end iterator.
-  TargetSuperClassIterator(const unsigned *V) { I = V; }
-
-  const unsigned &operator*() const { return *I; }
-
-  using iterator_adaptor_base::operator++;
-
-  /// Returns true if this iterator is not yet at the end.
-  bool isValid() const { return *I != ~0U; }
-};
-
 class TargetRegisterClass {
 public:
   using iterator = const MCPhysReg *;
@@ -190,17 +174,16 @@ class TargetRegisterClass {
     return SuperRegIndices;
   }
 
-  /// Returns a ~0U-terminated list of super-classes.  The
+  /// Returns a list of super-classes.  The
   /// classes are ordered by ID which is also a topological ordering from large
   /// to small classes.  The list does NOT include the current class.
-  iterator_range<TargetSuperClassIterator> superclasses() const {
-    return make_range(TargetSuperClassIterator(SuperClasses),
-                      {SuperClasses + SuperClassesSize});
+  ArrayRef<unsigned> superclasses() const {
+    return ArrayRef(SuperClasses, SuperClassesSize);
   }
 
   /// Return true if this TargetRegisterClass is a subset
   /// class of at least one other TargetRegisterClass.
-  bool isASubClass() const { return SuperClasses[0] != ~0U; }
+  bool isASubClass() const { return SuperClasses != nullptr; }
 
   /// Returns the preferred order for allocating registers from this register
   /// class in MF. The raw order comes directly from the .td file and may
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index ade447871545e9..291bfc0610f85d 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -264,6 +264,7 @@ ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
                                                const MachineFunction &MF) const {
   unsigned SuperID = RC->getID();
   auto I = RC->superclasses().begin();
+  auto E = RC->superclasses().end();
   do {
     switch (SuperID) {
     case ARM::GPRRegClassID:
@@ -284,7 +285,7 @@ ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
         return getRegClass(SuperID);
       break;
     }
-    SuperID = *I++;
+    SuperID = (I != E) ? *I++ : ~0U;
   } while (SuperID != ~0U);
   return RC;
 }
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 84b9310279fcb3..38096cd532fdf6 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -124,6 +124,7 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
 
   const TargetRegisterClass *Super = RC;
   auto I = RC->superclasses().begin();
+  auto E = RC->superclasses().end();
   do {
     switch (Super->getID()) {
     case X86::FR32RegClassID:
@@ -172,7 +173,7 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
       if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
         return Super;
     }
-    Super = I.isValid() ? getRegClass(*I) : nullptr;
+    Super = (I != E) ? getRegClass(*I) : nullptr;
     ++I;
   } while (Super);
   return RC;
diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp
index c32c2ce859af5d..ab28963b39311a 100644
--- a/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -584,7 +584,7 @@ TEST(MachineInstrTest, SpliceOperands) {
   // test tied operands
   MCRegisterClass MRC{
       0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true};
-  TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0};
+  TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0, 0};
   // MachineRegisterInfo will be very upset if these registers aren't
   // allocatable.
   assert(RC.isAllocatable() && "unusable TargetRegisterClass");
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index cdb015efe24915..bfcd52da1c39cb 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1286,9 +1286,6 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
     }
     OS << "};\n";
 
-    OS << "\nstatic const unsigned "
-       << "NullRegClasses[] = { ~0U };\n\n";
-
     // Emit register class bit mask tables. The first bit mask emitted for a
     // register class, RC, is the set of sub-classes, including RC itself.
     //
@@ -1340,18 +1337,18 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
     SuperRegIdxSeqs.emit(OS, printSubRegIndex);
     OS << "};\n\n";
 
-    // Emit NULL terminated super-class lists.
+    // Emit super-class lists.
     for (const auto &RC : RegisterClasses) {
       ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
 
-      // Skip classes without supers.  We can reuse NullRegClasses.
+      // Skip classes without supers.
       if (Supers.empty())
         continue;
 
       OS << "static unsigned const " << RC.getName() << "Superclasses[] = {\n";
       for (const auto *Super : Supers)
         OS << "  " << Super->getQualifiedIdName() << ",\n";
-      OS << "  ~0U\n};\n\n";
+      OS << "};\n\n";
     }
 
     // Emit methods.
@@ -1405,7 +1402,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
          << (RC.CoveredBySubRegs ? "true" : "false")
          << ", /* CoveredBySubRegs */\n    ";
       if (RC.getSuperClasses().empty())
-        OS << "NullRegClasses, ";
+        OS << "nullptr, ";
       else
         OS << RC.getName() << "Superclasses,  ";
       OS << RC.getSuperClasses().size() << ",\n    ";



More information about the llvm-commits mailing list