[llvm] [CodeGen] Merge TargetRegClass into MCRegClass (PR #207168)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 2 05:45:52 PDT 2026


https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/207168

>From b42a6544129104a833e21439b3cbb86b5cb7e0b9 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Thu, 2 Jul 2026 12:41:38 +0000
Subject: [PATCH 1/2] [spr] initial version

Created using spr 1.3.8-wip
---
 llvm/include/llvm/CodeGen/FastISel.h          |   3 +-
 .../include/llvm/CodeGen/GlobalISel/CSEInfo.h |   3 +-
 .../CodeGen/GlobalISel/MachineIRBuilder.h     |   3 +-
 llvm/include/llvm/CodeGen/GlobalISel/Utils.h  |   3 +-
 llvm/include/llvm/CodeGen/LiveStacks.h        |   3 +-
 .../include/llvm/CodeGen/MIRParser/MIParser.h |   3 +-
 llvm/include/llvm/CodeGen/MachineBasicBlock.h |   3 +-
 llvm/include/llvm/CodeGen/MachineFunction.h   |   3 +-
 llvm/include/llvm/CodeGen/MachineInstr.h      |   3 +-
 llvm/include/llvm/CodeGen/MachineSSAUpdater.h |   3 +-
 llvm/include/llvm/CodeGen/RegAllocCommon.h    |   3 +-
 llvm/include/llvm/CodeGen/RegisterBank.h      |   3 +-
 llvm/include/llvm/CodeGen/RegisterBankInfo.h  |   3 +-
 .../include/llvm/CodeGen/RegisterScavenging.h |   3 +-
 llvm/include/llvm/CodeGen/ScheduleDAG.h       |   3 +-
 llvm/include/llvm/CodeGen/TargetInstrInfo.h   |   3 +-
 llvm/include/llvm/CodeGen/TargetLowering.h    |   3 +-
 .../include/llvm/CodeGen/TargetRegisterInfo.h | 161 +----------
 .../llvm/CodeGen/TargetSubtargetInfo.h        |   3 +-
 llvm/include/llvm/MC/MCRegisterInfo.h         | 112 +++++++-
 llvm/lib/CodeGen/AggressiveAntiDepBreaker.h   |   3 +-
 llvm/lib/CodeGen/CriticalAntiDepBreaker.h     |   3 +-
 llvm/lib/CodeGen/RegisterCoalescer.h          |   3 +-
 .../AArch64/AArch64ExpandPseudoInsts.cpp      |   9 +-
 llvm/lib/Target/AArch64/AArch64RegisterInfo.h |   3 +-
 .../Target/AMDGPU/AMDGPUArgumentUsageInfo.h   |   3 +-
 .../Target/AMDGPU/AMDGPUInstructionSelector.h |   3 +-
 .../Target/AMDGPU/GCNPreRAOptimizations.cpp   |   2 +-
 llvm/lib/Target/AMDGPU/SIInstrInfo.h          |   3 +-
 .../lib/Target/AMDGPU/SIMachineFunctionInfo.h |   3 +-
 llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp     |  12 +-
 llvm/lib/Target/AMDGPU/SIRegisterInfo.h       |   5 -
 llvm/lib/Target/Hexagon/BitTracker.h          |   3 +-
 llvm/lib/Target/Hexagon/HexagonBitTracker.cpp |   8 +-
 .../lib/Target/Hexagon/HexagonFrameLowering.h |   3 +-
 .../Target/Hexagon/HexagonVLIWPacketizer.h    |   3 +-
 llvm/lib/Target/Mips/MipsISelLowering.h       |   3 +-
 llvm/lib/Target/Mips/MipsInstrInfo.h          |   3 +-
 llvm/lib/Target/Mips/MipsRegisterInfo.h       |   3 +-
 llvm/lib/Target/Mips/MipsSEISelLowering.h     |   3 +-
 .../WebAssembly/WebAssemblyRegisterInfo.h     |   3 +-
 .../Target/WebAssembly/WebAssemblyUtilities.h |   3 +-
 llvm/lib/Target/Xtensa/XtensaRegisterInfo.h   |   3 +-
 llvm/test/TableGen/RegisterClassCopyCost.td   |   6 +-
 .../RegisterInfoEmitter-inherit-properties.td |  19 +-
 .../TableGen/RegisterInfoEmitter-tsflags.td   |   8 +-
 llvm/unittests/CodeGen/MachineInstrTest.cpp   |   6 +-
 llvm/utils/TableGen/RegisterInfoEmitter.cpp   | 272 ++++++++++--------
 48 files changed, 361 insertions(+), 367 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h
index 454ed4126213f..02d2059d54785 100644
--- a/llvm/include/llvm/CodeGen/FastISel.h
+++ b/llvm/include/llvm/CodeGen/FastISel.h
@@ -54,7 +54,8 @@ class MCSymbol;
 class TargetInstrInfo;
 class TargetLibraryInfo;
 class TargetMachine;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 class Type;
 class User;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
index 39c7ad2cf34ca..f54cbafc0dc37 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -165,7 +165,8 @@ class LLVM_ABI GISelCSEInfo : public GISelChangeObserver {
   void changedInstr(MachineInstr &MI) override;
 };
 
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class RegisterBank;
 
 // Simple builder class to easily profile properties about MIs.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 511bc17161e03..ee533d2a8d8b8 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -34,7 +34,8 @@ class ConstantInt;
 class DataLayout;
 class GISelCSEInfo;
 class GlobalValue;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class MachineFunction;
 class MachineInstr;
 class TargetInstrInfo;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index bd97f7f4812f8..93fc33a61eb06 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -49,7 +49,8 @@ class TargetInstrInfo;
 class TargetLowering;
 class TargetPassConfig;
 class TargetRegisterInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class ConstantFP;
 class APFloat;
 
diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index f2ecdca257bb1..2e5455bc671a8 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -30,7 +30,8 @@ class AnalysisUsage;
 class MachineFunction;
 class Module;
 class raw_ostream;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 class LiveStacks {
diff --git a/llvm/include/llvm/CodeGen/MIRParser/MIParser.h b/llvm/include/llvm/CodeGen/MIRParser/MIParser.h
index d0604bbf59c5c..622862279cfdd 100644
--- a/llvm/include/llvm/CodeGen/MIRParser/MIParser.h
+++ b/llvm/include/llvm/CodeGen/MIRParser/MIParser.h
@@ -34,7 +34,8 @@ struct SlotMapping;
 class SMDiagnostic;
 class SourceMgr;
 class StringRef;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetSubtargetInfo;
 
 struct VRegInfo {
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 0aa2bc1bf6cbb..47430a100b3cc 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -47,7 +47,8 @@ class StringRef;
 class raw_ostream;
 class LiveIntervals;
 class LiveVariables;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 // This structure uniquely identifies a basic block section.
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index b3c814e1c3590..70b82bcd96b11 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -70,7 +70,8 @@ class PseudoSourceValueManager;
 class raw_ostream;
 class SlotIndexes;
 class StringRef;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetSubtargetInfo;
 struct WinEHFuncInfo;
 
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index f1f70f019a1b6..2efd3d4d6f095 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -58,7 +58,8 @@ template <typename T> class SmallVectorImpl;
 class SmallBitVector;
 class StringRef;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/CodeGen/MachineSSAUpdater.h b/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
index ee576cb872ee3..64980b8022829 100644
--- a/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -24,7 +24,8 @@ class MachineInstr;
 class MachineOperand;
 class MachineRegisterInfo;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 template<typename T> class SmallVectorImpl;
 template<typename T> class SSAUpdaterTraits;
 
diff --git a/llvm/include/llvm/CodeGen/RegAllocCommon.h b/llvm/include/llvm/CodeGen/RegAllocCommon.h
index 6c5cb295f5290..7ecf8bebd3fb2 100644
--- a/llvm/include/llvm/CodeGen/RegAllocCommon.h
+++ b/llvm/include/llvm/CodeGen/RegAllocCommon.h
@@ -14,7 +14,8 @@
 
 namespace llvm {
 
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 class MachineRegisterInfo;
 
diff --git a/llvm/include/llvm/CodeGen/RegisterBank.h b/llvm/include/llvm/CodeGen/RegisterBank.h
index 97f9c35a388f2..52b229c697acd 100644
--- a/llvm/include/llvm/CodeGen/RegisterBank.h
+++ b/llvm/include/llvm/CodeGen/RegisterBank.h
@@ -20,7 +20,8 @@ namespace llvm {
 // Forward declarations.
 class RegisterBankInfo;
 class raw_ostream;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 /// This class implements the register bank concept.
diff --git a/llvm/include/llvm/CodeGen/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
index 75153a4f840d2..825e06f429079 100644
--- a/llvm/include/llvm/CodeGen/RegisterBankInfo.h
+++ b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
@@ -33,7 +33,8 @@ class MachineIRBuilder;
 class MachineRegisterInfo;
 class raw_ostream;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 /// Holds all the information related to register banks.
diff --git a/llvm/include/llvm/CodeGen/RegisterScavenging.h b/llvm/include/llvm/CodeGen/RegisterScavenging.h
index 9b2c92adb0a6f..3d8e9f5bdc122 100644
--- a/llvm/include/llvm/CodeGen/RegisterScavenging.h
+++ b/llvm/include/llvm/CodeGen/RegisterScavenging.h
@@ -28,7 +28,8 @@ namespace llvm {
 
 class MachineInstr;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 class RegScavenger {
diff --git a/llvm/include/llvm/CodeGen/ScheduleDAG.h b/llvm/include/llvm/CodeGen/ScheduleDAG.h
index 902d6b83faadf..4638632815971 100644
--- a/llvm/include/llvm/CodeGen/ScheduleDAG.h
+++ b/llvm/include/llvm/CodeGen/ScheduleDAG.h
@@ -43,7 +43,8 @@ class SDNode;
 class SUnit;
 class ScheduleDAG;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
   /// Scheduling dependency. This represents one direction of an edge in the
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 03f3bf26d0608..8f381c5efe2e2 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -63,7 +63,8 @@ class SelectionDAG;
 class SMSchedule;
 class SwingSchedulerDAG;
 class RegScavenger;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 class TargetSchedModel;
 class TargetSubtargetInfo;
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 09f522742da4e..75b1ca2d2745f 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -93,7 +93,8 @@ class Module;
 class ProfileSummaryInfo;
 class TargetLibraryInfo;
 class TargetMachine;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 class TargetTransformInfo;
 class Value;
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 183848b36e800..736aa8a5cf35a 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -43,162 +43,9 @@ class RegScavenger;
 class VirtRegMap;
 class LiveIntervals;
 class LiveInterval;
-class TargetRegisterClass {
-public:
-  using iterator = const MCPhysReg *;
-  using const_iterator = const MCPhysReg *;
-
-  // Instance variables filled by tablegen, do not use!
-  const MCRegisterClass *MC;
-  const uint32_t *SubClassMask;
-  const uint16_t *SuperRegIndices;
-  const LaneBitmask LaneMask;
-  /// Classes with a higher priority value are assigned first by register
-  /// allocators using a greedy heuristic. The value is in the range [0,31].
-  const uint8_t AllocationPriority;
-
-  // Change allocation priority heuristic used by greedy.
-  const bool GlobalPriority;
-
-  /// Configurable target specific flags.
-  const uint8_t TSFlags;
-  const uint8_t SpillStackID;
-  /// Whether the class supports two (or more) disjunct subregister indices.
-  const bool HasDisjunctSubRegs;
-  /// Whether a combination of subregisters can cover every register in the
-  /// class. See also the CoveredBySubRegs description in Target.td.
-  const bool CoveredBySubRegs;
-  const unsigned *SuperClasses;
-  const uint16_t SuperClassesSize;
-
-  /// Return the register class ID number.
-  unsigned getID() const { return MC->getID(); }
-
-  /// begin/end - Return all of the registers in this class.
-  ///
-  iterator       begin() const { return MC->begin(); }
-  iterator         end() const { return MC->end(); }
-
-  /// Return the number of registers in this class.
-  unsigned getNumRegs() const { return MC->getNumRegs(); }
-
-  ArrayRef<MCPhysReg> getRegisters() const {
-    return ArrayRef(begin(), getNumRegs());
-  }
-
-  /// Return the specified register in the class.
-  MCRegister getRegister(unsigned i) const {
-    return MC->getRegister(i);
-  }
-
-  /// Return true if the specified register is included in this register class.
-  /// This does not include virtual registers.
-  bool contains(Register Reg) const {
-    /// FIXME: Historically this function has returned false when given vregs
-    ///        but it should probably only receive physical registers
-    if (!Reg.isPhysical())
-      return false;
-    return MC->contains(Reg.asMCReg());
-  }
-
-  /// Return true if both registers are in this class.
-  bool contains(Register Reg1, Register Reg2) const {
-    /// FIXME: Historically this function has returned false when given a vregs
-    ///        but it should probably only receive physical registers
-    if (!Reg1.isPhysical() || !Reg2.isPhysical())
-      return false;
-    return MC->contains(Reg1.asMCReg(), Reg2.asMCReg());
-  }
-
-  /// Return the cost of copying a value between two registers in this class. If
-  /// this is the maximum value, the register may be impossible to copy.
-  uint8_t getCopyCost() const { return MC->getCopyCost(); }
-
-  /// \return true if register class is very expensive to copy e.g. status flag
-  /// register classes.
-  bool expensiveOrImpossibleToCopy() const {
-    return MC->getCopyCost() == std::numeric_limits<uint8_t>::max();
-  }
-
-  /// Return true if this register class may be used to create virtual
-  /// registers.
-  bool isAllocatable() const { return MC->isAllocatable(); }
-
-  /// Return true if this register class has a defined BaseClassOrder.
-  bool isBaseClass() const { return MC->isBaseClass(); }
-
-  /// Return true if the specified TargetRegisterClass
-  /// is a proper sub-class of this TargetRegisterClass.
-  bool hasSubClass(const TargetRegisterClass *RC) const {
-    return RC != this && hasSubClassEq(RC);
-  }
 
-  /// Returns true if RC is a sub-class of or equal to this class.
-  bool hasSubClassEq(const TargetRegisterClass *RC) const {
-    unsigned ID = RC->getID();
-    return (SubClassMask[ID / 32] >> (ID % 32)) & 1;
-  }
-
-  /// Return true if the specified TargetRegisterClass is a
-  /// proper super-class of this TargetRegisterClass.
-  bool hasSuperClass(const TargetRegisterClass *RC) const {
-    return RC->hasSubClass(this);
-  }
-
-  /// Returns true if RC is a super-class of or equal to this class.
-  bool hasSuperClassEq(const TargetRegisterClass *RC) const {
-    return RC->hasSubClassEq(this);
-  }
-
-  /// Returns a bit vector of subclasses, including this one.
-  /// The vector is indexed by class IDs.
-  ///
-  /// To use it, consider the returned array as a chunk of memory that
-  /// contains an array of bits of size NumRegClasses. Each 32-bit chunk
-  /// contains a bitset of the ID of the subclasses in big-endian style.
-
-  /// I.e., the representation of the memory from left to right at the
-  /// bit level looks like:
-  /// [31 30 ... 1 0] [ 63 62 ... 33 32] ...
-  ///                     [ XXX NumRegClasses NumRegClasses - 1 ... ]
-  /// Where the number represents the class ID and XXX bits that
-  /// should be ignored.
-  ///
-  /// See the implementation of hasSubClassEq for an example of how it
-  /// can be used.
-  const uint32_t *getSubClassMask() const {
-    return SubClassMask;
-  }
-
-  /// Returns a 0-terminated list of sub-register indices that project some
-  /// super-register class into this register class. The list has an entry for
-  /// each Idx such that:
-  ///
-  ///   There exists SuperRC where:
-  ///     For all Reg in SuperRC:
-  ///       this->contains(Reg:Idx)
-  const uint16_t *getSuperRegIndices() const {
-    return SuperRegIndices;
-  }
-
-  /// 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.
-  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 != nullptr; }
-
-  /// Returns the combination of all lane masks of register in this class.
-  /// The lane masks of the registers are the combination of all lane masks
-  /// of their subregisters. Returns 1 if there are no subregisters.
-  LaneBitmask getLaneMask() const {
-    return LaneMask;
-  }
-};
+// TODO: Remove.
+using TargetRegisterClass = MCRegisterClass;
 
 /// Extra information, not in MCRegisterDesc, about registers.
 /// These are used by codegen, not by MC.
@@ -651,7 +498,7 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
   /// index \p SubIdx is \p Reg.
   MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx,
                                  const TargetRegisterClass *RC) const {
-    return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC);
+    return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC);
   }
 
   /// Return a subclass of the register class \p A so that each register in it
@@ -886,7 +733,7 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
 
   /// Returns the name of the register class.
   const char *getRegClassName(const TargetRegisterClass *Class) const {
-    return MCRegisterInfo::getRegClassName(Class->MC);
+    return MCRegisterInfo::getRegClassName(Class);
   }
 
   /// Find the largest common subclass of A and B.
diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
index fb0589e2c446e..8b8f64f49b595 100644
--- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
@@ -52,7 +52,8 @@ class SUnit;
 class TargetFrameLowering;
 class TargetInstrInfo;
 class TargetLowering;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 class TargetSchedModel;
 class Triple;
diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h
index 499dd6d6afda9..dac8f84119dc3 100644
--- a/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -39,6 +39,9 @@ class MCRegisterClass {
   using iterator = const MCPhysReg*;
   using const_iterator = const MCPhysReg*;
 
+  MCRegisterClass(const MCRegisterClass &) = delete;
+
+  // TODO: reorder fields to reduce memory usage.
   const uint32_t RegsOff;   ///< Relative offset to MCPhysReg array.
   const uint32_t RegSetOff; ///< Relative offset to uint8_t array.
   const uint32_t NameIdx;
@@ -50,6 +53,27 @@ class MCRegisterClass {
   const bool Allocatable;
   const bool BaseClass;
 
+  const uint32_t SubClassMaskOff;    ///< Relative offset to uin32t_t array.
+  const uint32_t SuperRegIndicesOff; ///< Relative offset to MCPhysReg array.
+  const LaneBitmask LaneMask;
+  /// Classes with a higher priority value are assigned first by register
+  /// allocators using a greedy heuristic. The value is in the range [0,31].
+  const uint8_t AllocationPriority;
+
+  // Change allocation priority heuristic used by greedy.
+  const bool GlobalPriority;
+
+  /// Configurable target specific flags.
+  const uint8_t TSFlags;
+  const uint8_t SpillStackID;
+  /// Whether the class supports two (or more) disjunct subregister indices.
+  const bool HasDisjunctSubRegs;
+  /// Whether a combination of subregisters can cover every register in the
+  /// class. See also the CoveredBySubRegs description in Target.td.
+  const bool CoveredBySubRegs;
+  const uint32_t SuperClassesOff; ///< Relative offset to unsigned array.
+  const uint16_t SuperClassesSize;
+
   /// getID() - Return the register class ID number.
   ///
   unsigned getID() const { return ID; }
@@ -73,6 +97,10 @@ class MCRegisterClass {
     return begin()[i];
   }
 
+  ArrayRef<MCPhysReg> getRegisters() const {
+    return ArrayRef(begin(), RegsSize);
+  }
+
   /// contains - Return true if the specified register is included in this
   /// register class.  This does not include virtual registers.
   bool contains(MCRegister Reg) const {
@@ -101,19 +129,101 @@ class MCRegisterClass {
   /// to copy e.g. status flag register classes.
   uint8_t getCopyCost() const { return CopyCost; }
 
+  /// \return true if register class is very expensive to copy e.g. status flag
+  /// register classes.
+  bool expensiveOrImpossibleToCopy() const {
+    return CopyCost == std::numeric_limits<uint8_t>::max();
+  }
+
   /// isAllocatable - Return true if this register class may be used to create
   /// virtual registers.
   bool isAllocatable() const { return Allocatable; }
 
   /// Return true if this register class has a defined BaseClassOrder.
   bool isBaseClass() const { return BaseClass; }
+
+  /// Return true if the specified TargetRegisterClass
+  /// is a proper sub-class of this TargetRegisterClass.
+  bool hasSubClass(const MCRegisterClass *RC) const {
+    return RC != this && hasSubClassEq(RC);
+  }
+
+  /// Returns true if RC is a sub-class of or equal to this class.
+  bool hasSubClassEq(const MCRegisterClass *RC) const {
+    unsigned ID = RC->getID();
+    return (getSubClassMask()[ID / 32] >> (ID % 32)) & 1;
+  }
+
+  /// Return true if the specified MCRegisterClass is a
+  /// proper super-class of this MCRegisterClass.
+  bool hasSuperClass(const MCRegisterClass *RC) const {
+    return RC->hasSubClass(this);
+  }
+
+  /// Returns true if RC is a super-class of or equal to this class.
+  bool hasSuperClassEq(const MCRegisterClass *RC) const {
+    return RC->hasSubClassEq(this);
+  }
+
+  /// Returns a bit vector of subclasses, including this one.
+  /// The vector is indexed by class IDs.
+  ///
+  /// To use it, consider the returned array as a chunk of memory that
+  /// contains an array of bits of size NumRegClasses. Each 32-bit chunk
+  /// contains a bitset of the ID of the subclasses in big-endian style.
+
+  /// I.e., the representation of the memory from left to right at the
+  /// bit level looks like:
+  /// [31 30 ... 1 0] [ 63 62 ... 33 32] ...
+  ///                     [ XXX NumRegClasses NumRegClasses - 1 ... ]
+  /// Where the number represents the class ID and XXX bits that
+  /// should be ignored.
+  ///
+  /// See the implementation of hasSubClassEq for an example of how it
+  /// can be used.
+  const uint32_t *getSubClassMask() const {
+    return reinterpret_cast<const uint32_t *>(
+        reinterpret_cast<const char *>(this) + SubClassMaskOff);
+  }
+
+  /// Returns a 0-terminated list of sub-register indices that project some
+  /// super-register class into this register class. The list has an entry for
+  /// each Idx such that:
+  ///
+  ///   There exists SuperRC where:
+  ///     For all Reg in SuperRC:
+  ///       this->contains(Reg:Idx)
+  const uint16_t *getSuperRegIndices() const {
+    return reinterpret_cast<const uint16_t *>(
+        reinterpret_cast<const char *>(this) + SuperRegIndicesOff);
+  }
+
+  /// 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.
+  ArrayRef<unsigned> superclasses() const {
+    const unsigned *SuperClasses = reinterpret_cast<const unsigned *>(
+        reinterpret_cast<const char *>(this) + SuperClassesOff);
+    return ArrayRef(SuperClasses, SuperClassesSize);
+  }
+
+  /// Returns the combination of all lane masks of register in this class.
+  /// The lane masks of the registers are the combination of all lane masks
+  /// of their subregisters. Returns 1 if there are no subregisters.
+  LaneBitmask getLaneMask() const { return LaneMask; }
 };
 
-template <unsigned RegClassCount, unsigned RegCount, unsigned BitSetSize>
+template <unsigned RegClassCount, unsigned RegCount, unsigned BitSetSize,
+          unsigned SubClassMaskSize, unsigned SuperRegIdxSeqSize,
+          unsigned SuperClassSize>
 struct MCRegisterClassStorage {
   MCRegisterClass Classes[RegClassCount];
   MCPhysReg Regs[RegCount];
   uint8_t BitSets[BitSetSize];
+  uint32_t SubClassMasks[SubClassMaskSize];
+  uint16_t SuperRegIdxSeqs[SuperRegIdxSeqSize];
+  // Avoid zero-sized arrays.
+  unsigned SuperClasses[SuperClassSize > 0 ? SuperClassSize : 1];
 };
 
 /// MCRegisterDesc - This record contains information about a particular
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
index 8726cdef2bfc4..4f474ebb6b89e 100644
--- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
+++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.h
@@ -33,7 +33,8 @@ class MachineOperand;
 class MachineRegisterInfo;
 class RegisterClassInfo;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
   /// Contains all the state necessary for anti-dep breaking.
diff --git a/llvm/lib/CodeGen/CriticalAntiDepBreaker.h b/llvm/lib/CodeGen/CriticalAntiDepBreaker.h
index a96e2ed8cf1a3..81deb80610938 100644
--- a/llvm/lib/CodeGen/CriticalAntiDepBreaker.h
+++ b/llvm/lib/CodeGen/CriticalAntiDepBreaker.h
@@ -30,7 +30,8 @@ class MachineOperand;
 class MachineRegisterInfo;
 class RegisterClassInfo;
 class TargetInstrInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 class LLVM_LIBRARY_VISIBILITY CriticalAntiDepBreaker : public AntiDepBreaker {
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.h b/llvm/lib/CodeGen/RegisterCoalescer.h
index ec1940805ea2e..c4aa6276c61b7 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.h
+++ b/llvm/lib/CodeGen/RegisterCoalescer.h
@@ -20,7 +20,8 @@
 namespace llvm {
 
 class MachineInstr;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 /// A helper class for register coalescers. When deciding if
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 5fa93da1544fc..944bbeac7bb9b 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -56,8 +56,8 @@ class AArch64ExpandPseudoImpl {
                 MachineBasicBlock::iterator &NextMBBI);
   bool expandMultiVecPseudo(MachineBasicBlock &MBB,
                             MachineBasicBlock::iterator MBBI,
-                            TargetRegisterClass ContiguousClass,
-                            TargetRegisterClass StridedClass,
+                            const TargetRegisterClass &ContiguousClass,
+                            const TargetRegisterClass &StridedClass,
                             unsigned ContiguousOpc, unsigned StridedOpc);
   bool expandFormTuplePseudo(MachineBasicBlock &MBB,
                              MachineBasicBlock::iterator MBBI,
@@ -1257,8 +1257,9 @@ AArch64ExpandPseudoImpl::expandCondSMToggle(MachineBasicBlock &MBB,
 
 bool AArch64ExpandPseudoImpl::expandMultiVecPseudo(
     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
-    TargetRegisterClass ContiguousClass, TargetRegisterClass StridedClass,
-    unsigned ContiguousOp, unsigned StridedOpc) {
+    const TargetRegisterClass &ContiguousClass,
+    const TargetRegisterClass &StridedClass, unsigned ContiguousOp,
+    unsigned StridedOpc) {
   MachineInstr &MI = *MBBI;
   Register Tuple = MI.getOperand(0).getReg();
 
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
index ac58d8d6b1cc7..b31104aac6551 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
@@ -20,7 +20,8 @@ namespace llvm {
 
 class MachineFunction;
 class RegScavenger;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class Triple;
 
 class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h b/llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h
index cbb3c6ce127a4..7f1589f778016 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h
@@ -17,7 +17,8 @@ namespace llvm {
 
 class LLT;
 class raw_ostream;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 struct ArgDescriptor {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h
index 1b6722f357080..19028ef58a166 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h
@@ -43,7 +43,8 @@ class MachineRegisterInfo;
 class RegisterBank;
 class SIInstrInfo;
 class SIRegisterInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
 class AMDGPUInstructionSelector final : public InstructionSelector {
 private:
diff --git a/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp b/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
index 825634d7af65b..50514e819f412 100644
--- a/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
@@ -312,7 +312,7 @@ bool GCNPreRAOptimizationsImpl::run(MachineFunction &MF) {
     if (!LIS->hasInterval(Reg))
       continue;
     const TargetRegisterClass *RC = MRI->getRegClass(Reg);
-    if ((RC->MC->getSizeInBits() != 64 || !TRI->isSGPRClass(RC)) &&
+    if ((RC->getSizeInBits() != 64 || !TRI->isSGPRClass(RC)) &&
         (ST.hasGFX90AInsts() || !TRI->isAGPRClass(RC)))
       continue;
 
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index 1d67c8664ff44..a1aa56741bb4f 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -34,7 +34,8 @@ class MachineDominatorTree;
 class MachineRegisterInfo;
 class RegScavenger;
 class SIMachineFunctionInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class ScheduleHazardRecognizer;
 
 constexpr unsigned DefaultMemoryClusterDWordsLimit = 8;
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index 1f43505650222..7374e996837a5 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -33,7 +33,8 @@ class MachineFrameInfo;
 class MachineFunction;
 class SIMachineFunctionInfo;
 class SIRegisterInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
 class AMDGPUPseudoSourceValue : public PseudoSourceValue {
 public:
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 9700720f0373a..903599cff67c0 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -3578,10 +3578,6 @@ unsigned SIRegisterInfo::getHWRegIndex(MCRegister Reg) const {
   return getEncodingValue(Reg) & AMDGPU::HWEncoding::REG_IDX_MASK;
 }
 
-unsigned AMDGPU::getRegBitWidth(const TargetRegisterClass &RC) {
-  return getRegBitWidth(RC.getID());
-}
-
 static const TargetRegisterClass *
 getAnyVGPRClassForBitWidth(unsigned BitWidth) {
   if (BitWidth == 64)
@@ -4257,10 +4253,10 @@ MachineInstr *SIRegisterInfo::findReachingDef(Register Reg, unsigned SubReg,
 MCPhysReg SIRegisterInfo::get32BitRegister(MCPhysReg Reg) const {
   assert(getRegSizeInBits(*getPhysRegBaseClass(Reg)) <= 32);
 
-  for (const TargetRegisterClass &RC : { AMDGPU::VGPR_32RegClass,
-                                         AMDGPU::SReg_32RegClass,
-                                         AMDGPU::AGPR_32RegClass } ) {
-    if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::lo16, &RC))
+  for (const TargetRegisterClass *RC :
+       {&AMDGPU::VGPR_32RegClass, &AMDGPU::SReg_32RegClass,
+        &AMDGPU::AGPR_32RegClass}) {
+    if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::lo16, RC))
       return Super;
   }
   if (MCPhysReg Super = getMatchingSuperReg(Reg, AMDGPU::hi16,
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index 5e08e47ad4d83..e464c9334ffea 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -508,11 +508,6 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
   }
 };
 
-namespace AMDGPU {
-/// Get the size in bits of a register from the register class \p RC.
-unsigned getRegBitWidth(const TargetRegisterClass &RC);
-} // namespace AMDGPU
-
 } // End namespace llvm
 
 #endif
diff --git a/llvm/lib/Target/Hexagon/BitTracker.h b/llvm/lib/Target/Hexagon/BitTracker.h
index 67ae29b21085d..509d5d4d7ddf0 100644
--- a/llvm/lib/Target/Hexagon/BitTracker.h
+++ b/llvm/lib/Target/Hexagon/BitTracker.h
@@ -26,7 +26,8 @@ class MachineRegisterInfo;
 class MachineBasicBlock;
 class MachineFunction;
 class raw_ostream;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 struct BitTracker {
diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
index 6f15011668e6c..360880a7afb19 100644
--- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
@@ -105,10 +105,10 @@ uint16_t HexagonEvaluator::getPhysRegBitWidth(MCRegister Reg) const {
   using namespace Hexagon;
   const auto &HST = MF.getSubtarget<HexagonSubtarget>();
   if (HST.useHVXOps()) {
-    for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass,
-                     HvxVQRRegClass})
-      if (RC.contains(Reg))
-        return TRI.getRegSizeInBits(RC);
+    for (auto *RC :
+         {&HvxVRRegClass, &HvxWRRegClass, &HvxQRRegClass, &HvxVQRRegClass})
+      if (RC->contains(Reg))
+        return TRI.getRegSizeInBits(*RC);
   }
   // Default treatment for other physical registers.
   if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg))
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
index 2e876ab034cbe..0b93795f2b912 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -26,7 +26,8 @@ class HexagonRegisterInfo;
 class MachineFunction;
 class MachineInstr;
 class MachineRegisterInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
 class HexagonFrameLowering : public TargetFrameLowering {
 public:
diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h
index 8eced652b2e32..33edcce995e1d 100644
--- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h
+++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h
@@ -22,7 +22,8 @@ class MachineBranchProbabilityInfo;
 class MachineFunction;
 class MachineInstr;
 class MachineLoopInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
 class HexagonPacketizerList : public VLIWPacketizerList {
   // Vector of instructions assigned to the packet that has just been created.
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 806fb59f5ff3e..93d90f23b362e 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -49,7 +49,8 @@ class MipsFunctionInfo;
 class MipsSubtarget;
 class MipsTargetMachine;
 class TargetLibraryInfo;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
   //===--------------------------------------------------------------------===//
   // TargetLowering Implementation
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.h b/llvm/lib/Target/Mips/MipsInstrInfo.h
index 29dfa0c41ad1d..a1d0496ff0c05 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.h
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.h
@@ -35,7 +35,8 @@ namespace llvm {
 class MachineInstr;
 class MachineOperand;
 class MipsSubtarget;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class TargetRegisterInfo;
 
 class MipsInstrInfo : public MipsGenInstrInfo {
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.h b/llvm/lib/Target/Mips/MipsRegisterInfo.h
index e2e81af4a8af1..9e6ef66163bd9 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.h
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.h
@@ -22,7 +22,8 @@
 
 namespace llvm {
 
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
 class MipsRegisterInfo : public MipsGenRegisterInfo {
 private:
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.h b/llvm/lib/Target/Mips/MipsSEISelLowering.h
index d75acbc9698f5..56b26b39f634d 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.h
@@ -24,7 +24,8 @@ class MachineInstr;
 class MipsSubtarget;
 class MipsTargetMachine;
 class SelectionDAG;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 
   class MipsSETargetLowering : public MipsTargetLowering  {
   public:
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
index 5b4293b9ec590..ffff5d1d96397 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.h
@@ -22,7 +22,8 @@ namespace llvm {
 
 class MachineFunction;
 class RegScavenger;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class Triple;
 
 class WebAssemblyRegisterInfo final : public WebAssemblyGenRegisterInfo {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h
index 0827791d93657..14ef9d142f36e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.h
@@ -25,7 +25,8 @@ class MachineInstr;
 class MachineOperand;
 class MCContext;
 class MCSymbolWasm;
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class WebAssemblyFunctionInfo;
 class WebAssemblySubtarget;
 class MachineSDNode;
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
index ede0eeb90b42d..7c2af4d978f6c 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.h
@@ -20,7 +20,8 @@
 #include "XtensaGenRegisterInfo.inc"
 
 namespace llvm {
-class TargetRegisterClass;
+class MCRegisterClass;
+using TargetRegisterClass = MCRegisterClass;
 class XtensaInstrInfo;
 class XtensaSubtarget;
 
diff --git a/llvm/test/TableGen/RegisterClassCopyCost.td b/llvm/test/TableGen/RegisterClassCopyCost.td
index bf785d4b1ae91..42cd29b00f325 100644
--- a/llvm/test/TableGen/RegisterClassCopyCost.td
+++ b/llvm/test/TableGen/RegisterClassCopyCost.td
@@ -8,10 +8,8 @@
 include "llvm/Target/Target.td"
 
 // CHECK: extern const MCRegisterClassStorage<{{[0-9, ]+}}> MyTargetMCRegisterClassStorage = {
-// CHECK-NEXT: {
-// CHECK-NEXT:   { {{[^,]+}}, {{[^,]+}}, 0, 32, 2, {{[0-9]+}}, MyTarget::GPR32RegClassID, 1, true, false },
-// CHECK-NEXT:   { {{[^,]+}}, {{[^,]+}}, 6, 32, 1, {{[0-9]+}}, MyTarget::SPECIAL_CLASSRegClassID, 255, true, false },
-// CHECK-NEXT: },
+// CHECK: 1, /* CopyCost */
+// CHECK: 255, /* CopyCost */
 
 def MyTargetISA : InstrInfo;
 def MyTarget : Target { let InstructionSet = MyTargetISA; }
diff --git a/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td b/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td
index 9ca3478662ce9..1707ded61c99c 100644
--- a/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td
+++ b/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td
@@ -68,20 +68,11 @@ def ABRC3 : MyClass<32, [untyped], (add ARC3, BRC3)> {
 
 def TestTarget : Target;
 
-// CHECK:      static unsigned const ARC3_with_sub0_sub1Superclasses[] = {
-// CHECK-NEXT:   Test::ABRC3RegClassID,
-// CHECK-NEXT:   Test::ARC3RegClassID,
-// CHECK-NEXT:   Test::ABRC3_with_sub0_sub1RegClassID,
-// CHECK-NEXT: };
-
-// CHECK:      static unsigned const ARC3_with_sub1_sub2Superclasses[] = {
-// CHECK-NEXT:   Test::ABRC3RegClassID,
-// CHECK-NEXT:   Test::ARC3RegClassID,
-// CHECK-NEXT:   Test::ABRC3_with_sub1_sub2RegClassID,
-// CHECK-NEXT: };
-
-// CHECK: extern const TargetRegisterClass ARC3_with_sub0_sub1RegClass = {
+// CHECK: ARC3_with_sub0_sub1RegClassID
 // CHECK:   0x01, /* TSFlags */
 
-// CHECK: extern const TargetRegisterClass ARC3_with_sub1_sub2RegClass = {
+// CHECK: ARC3_with_sub1_sub2RegClassID
 // CHECK:   0x01, /* TSFlags */
+
+// CHECK: ARC3_with_sub0_sub1 */ Test::ABRC3RegClassID, Test::ARC3RegClassID, Test::ABRC3_with_sub0_sub1RegClassID
+// CHECK: ARC3_with_sub1_sub2 */ Test::ABRC3RegClassID, Test::ARC3RegClassID, Test::ABRC3_with_sub1_sub2RegClassID
diff --git a/llvm/test/TableGen/RegisterInfoEmitter-tsflags.td b/llvm/test/TableGen/RegisterInfoEmitter-tsflags.td
index 55db3ddb1f27e..affdc0648fca9 100644
--- a/llvm/test/TableGen/RegisterInfoEmitter-tsflags.td
+++ b/llvm/test/TableGen/RegisterInfoEmitter-tsflags.td
@@ -38,11 +38,11 @@ def SDRegs : MyClass<32, [i32], (add D, S)>{
 
 def MyTarget : Target;
 
-// CHECK:  extern const TargetRegisterClass SDRegsRegClass = {
+// CHECK:  SDRegsRegClassID
 // CHECK:  0x07, /* TSFlags */
-// CHECK:  extern const TargetRegisterClass DRegsRegClass = {
+// CHECK:  DRegsRegClassID
 // CHECK:  0x06, /* TSFlags */
-// CHECK:  extern const TargetRegisterClass MyRegsRegClass = {
+// CHECK:  MyRegsRegClassID
 // CHECK:  0x00, /* TSFlags */
-// CHECK:  extern const TargetRegisterClass SRegsRegClass = {
+// CHECK:  SRegsRegClassID
 // CHECK:  0x01, /* TSFlags */
diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp
index 47e260104775f..9fd7b1980929c 100644
--- a/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -591,9 +591,9 @@ TEST(MachineInstrTest, SpliceOperands) {
   EXPECT_EQ(MI->getOperand(8).getImm(), MachineOperand::CreateImm(4).getImm());
 
   // 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, 0};
+  MCRegisterClass RC{
+      0, 0, 0,  0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true,
+      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 9eaee06143c64..0789e537e56bb 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1073,15 +1073,45 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
     OS << "};\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.
+  //
+  // If RC has super-registers, also create a list of subreg indices and bit
+  // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
+  // SuperRC, that satisfies:
+  //
+  //   For all SuperReg in SuperRC: SuperReg:Idx in RC
+  //
+  // The 0-terminated list of subreg indices starts at:
+  //
+  //   RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
+  //
+  // The corresponding bitmasks follow the sub-class mask in memory. Each
+  // mask has RCMaskWords uint32_t entries.
+  //
+  // Every bit mask present in the list has at least one bit set.
+
   const auto &RegisterClasses = RegBank.getRegClasses();
 
   OS << "// Register classes...\n";
 
   SequenceToOffsetTable<std::string> RegClassStrings;
-  SmallVector<unsigned> BitSetSizes;
-  BitSetSizes.reserve(RegisterClasses.size());
-  unsigned TotalRegCount = 0;
-  unsigned TotalBitSetSize = 0;
+  // Start indices for per-reg-class info in the respective arrays.
+  struct StartIndex {
+    unsigned RegIdx;
+    unsigned BitSetIdx;
+    unsigned SubClassMaskIdx;
+    unsigned SuperClassIdx;
+  };
+  SmallVector<StartIndex> StartIndices;
+  StartIndices.reserve(RegisterClasses.size() + 1);
+  StartIndices.push_back(StartIndex{0, 0, 0, 0});
+
+  // For compressing the sub-reg index lists.
+  using IdxList = std::vector<const CodeGenSubRegIndex *>;
+  SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
+  SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;
+  BitVector MaskBV(RegisterClasses.size());
   for (const auto &RC : RegisterClasses) {
     ArrayRef<const Record *> Order = RC.getOrder();
     RegClassStrings.add(RC.getName());
@@ -1089,77 +1119,155 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
     unsigned MaxRegVal = 0;
     for (const Record *Reg : Order)
       MaxRegVal = std::max(MaxRegVal, RegBank.getReg(Reg)->EnumValue);
-    // Round to next byte size.
-    BitSetSizes.push_back(Order.empty() ? 0 : (MaxRegVal / 8) + 1);
-    TotalRegCount += Order.size();
-    TotalBitSetSize += BitSetSizes.back();
+
+    unsigned SubClassMaskSize = (RC.getSubClasses().size() + 31) / 32;
+    IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
+    for (auto &Idx : SubRegIndices) {
+      MaskBV.reset();
+      RC.getSuperRegClasses(&Idx, MaskBV);
+      if (MaskBV.none())
+        continue;
+      SRIList.push_back(&Idx);
+      SubClassMaskSize += (MaskBV.size() + 31) / 32;
+    }
+    SuperRegIdxSeqs.add(SRIList);
+
+    const auto &Last = StartIndices.back();
+    StartIndices.push_back(StartIndex{
+        Last.RegIdx + unsigned(Order.size()),
+        // Round to next byte size.
+        Last.BitSetIdx + (Order.empty() ? 0 : (MaxRegVal / 8) + 1),
+        Last.SubClassMaskIdx + SubClassMaskSize,
+        Last.SuperClassIdx + unsigned(RC.getSuperClasses().size()),
+    });
   }
 
   RegClassStrings.layout();
   RegClassStrings.emitStringLiteralDef(
       OS, Twine("extern const char ") + TargetName + "RegClassStrings[]");
 
+  SuperRegIdxSeqs.layout();
+
+  const auto &Totals = StartIndices.back();
   raw_string_ostream(MCRegisterClassStorageType)
       << "MCRegisterClassStorage<" << RegisterClasses.size() << ", "
-      << TotalRegCount << ", " << TotalBitSetSize << ">";
+      << Totals.RegIdx << ", " << Totals.BitSetIdx << ", "
+      << Totals.SubClassMaskIdx << ", " << SuperRegIdxSeqs.size() << ", "
+      << Totals.SuperClassIdx << ">";
+  OS << "using " << TargetName
+     << "RegisterClassStorage = " << MCRegisterClassStorageType << ";\n";
   OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
      << "MCRegisterClassStorage = {\n"
      << "  {\n";
 
-  unsigned RegCount = 0;   // Number of entries in registers array.
-  unsigned BitSetSize = 0; // Number of entries in bitset array.
-  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
-    ArrayRef<const Record *> Order = RC.getOrder();
+  for (const auto &It : enumerate(RegisterClasses)) {
+    const auto &RC = It.value();
+    const auto &RCIndices = StartIndices[It.index()];
     uint32_t RegSize = 0;
     if (RC.RSI.isSimple())
       RegSize = RC.RSI.getSimple().RegSize;
-    OS << "    { " << (RegisterClasses.size() - Idx)
-       << " * sizeof(MCRegisterClass)"
-       << " + sizeof(MCPhysReg) * " << RegCount << ", "
-       << (RegisterClasses.size() - Idx) << " * sizeof(MCRegisterClass)"
-       << " + sizeof(MCPhysReg) * " << TotalRegCount << " + " << BitSetSize
-       << ", " << RegClassStrings.get(RC.getName()) << ", " << RegSize << ", "
-       << RC.getOrder().size() << ", " << BitSetSizes[Idx] << ", "
-       << RC.getQualifiedIdName() << ", " << static_cast<unsigned>(RC.CopyCost)
-       << ", " << (RC.Allocatable ? "true" : "false") << ", "
-       << (RC.getBaseClassOrder() ? "true" : "false") << " },\n";
 
-    RegCount += Order.size();
-    BitSetSize += BitSetSizes[Idx];
+    // Helper to generate offsetof macro for relative offset in storage.
+    auto GetOff = [&](std::string_view Member,
+                      unsigned DataIdx) -> std::string {
+      return ("offsetof(" + Twine(TargetName) + "RegisterClassStorage, " +
+              Member + "[" + Twine(DataIdx) + "]) - " + Twine(It.index()) +
+              " * sizeof(MCRegisterClass)")
+          .str();
+    };
+
+    unsigned BitSetSize =
+        StartIndices[It.index() + 1].BitSetIdx - RCIndices.BitSetIdx;
+    OS << "    {\n      " << GetOff("Regs", RCIndices.RegIdx) << ",\n      "
+       << GetOff("BitSets", RCIndices.BitSetIdx) << ",\n      "
+       << RegClassStrings.get(RC.getName()) << ",\n      " << RegSize
+       << ",\n      " << RC.getOrder().size() << ",\n      " << BitSetSize
+       << ",\n      " << RC.getQualifiedIdName() << ",\n      "
+       << static_cast<unsigned>(RC.CopyCost) << ", /* CopyCost */\n      "
+       << (RC.Allocatable ? "true" : "false") << ", /* Allocatable */\n      "
+       << (RC.getBaseClassOrder() ? "true" : "false") << ",\n      "
+       << GetOff("SubClassMasks", RCIndices.SubClassMaskIdx) << ",\n      "
+       << GetOff("SuperRegIdxSeqs",
+                 SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]))
+       << ",\n      ";
+    printMask(OS, RC.LaneMask);
+    OS << ",\n      " << (unsigned)RC.AllocationPriority << ",\n      "
+       << (RC.GlobalPriority ? "true" : "false") << ",\n      "
+       << format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n      "
+       << (unsigned)RC.SpillStackID << ", /* SpillStackID */\n      "
+       << (RC.HasDisjunctSubRegs ? "true" : "false")
+       << ", /* HasDisjunctSubRegs */\n      "
+       << (RC.CoveredBySubRegs ? "true" : "false")
+       << ", /* CoveredBySubRegs */\n      "
+       << GetOff("SuperClasses", RCIndices.SuperClassIdx) << ",\n      "
+       << RC.getSuperClasses().size() << "\n    },\n";
   }
 
   OS << "  },\n  {\n";
 
   // Emit registers.
   // TODO: these sequences often have overlaps which could be deduplicated.
-  RegCount = 0;
-  for (const auto &RC : RegisterClasses) {
+  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
     ArrayRef<const Record *> Order = RC.getOrder();
     if (Order.empty())
       continue;
-    OS << "    /* " << RegCount << " */ ";
+    OS << "    /* " << StartIndices[Idx].RegIdx << " */ ";
     for (const Record *Reg : Order)
       OS << getQualifiedName(Reg) << ", ";
     OS << "\n";
-    RegCount += Order.size();
   }
 
   OS << "  },\n  {\n";
 
   // Emit register bit sets.
-  BitSetSize = 0;
   for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
     ArrayRef<const Record *> Order = RC.getOrder();
     if (!Order.empty()) {
-      OS << "    /* " << BitSetSize << " */ ";
+      OS << "    /* " << StartIndices[Idx].BitSetIdx << " */ ";
       BitVectorEmitter BVE;
       for (const Record *Reg : Order)
         BVE.add(RegBank.getReg(Reg)->EnumValue);
       BVE.print(OS);
       OS << "\n";
-      BitSetSize += BitSetSizes[Idx];
     }
   }
+  OS << "  },\n  {\n";
+
+  // Emit subclass masks.
+  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
+    OS << "    // " << StartIndices[Idx].SubClassMaskIdx << " " << RC.getName()
+       << "\n    ";
+    printBitVectorAsHex(OS, RC.getSubClasses(), 32);
+
+    // Emit super-reg class masks for any relevant SubRegIndices that can
+    // project into RC.
+    for (auto &Idx : SubRegIndices) {
+      MaskBV.reset();
+      RC.getSuperRegClasses(&Idx, MaskBV);
+      if (MaskBV.none())
+        continue;
+      OS << "\n    ";
+      printBitVectorAsHex(OS, MaskBV, 32);
+      OS << "// " << Idx.getName();
+    }
+    OS << "\n";
+  }
+  OS << "  },\n  {\n";
+
+  // Emit SubRegIdxSeqs.
+  SuperRegIdxSeqs.emit(OS, printSubRegIndex);
+  OS << "  },\n  {\n";
+
+  // Emit super-class lists.
+  for (const auto &[Idx, RC] : enumerate(RegisterClasses)) {
+    ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
+    OS << "    /* " << StartIndices[Idx].SuperClassIdx << " " << RC.getName()
+       << " */ ";
+    for (const auto *Super : Supers)
+      OS << Super->getQualifiedIdName() << ", ";
+    OS << "\n";
+  }
+
   OS << "  }\n};\n\n";
   OS << "const MCRegisterClass &get" << Target.getName()
      << "MCRegisterClass(unsigned RC) {\n"
@@ -1250,6 +1358,9 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
 
   OS << "class " << TargetName << "FrameLowering;\n\n";
 
+  OS << "extern const " << MCRegisterClassStorageType << " " << TargetName
+     << "MCRegisterClassStorage;\n\n";
+
   OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
      << "  explicit " << ClassName
      << "(unsigned RA, unsigned D = 0, unsigned E = 0,\n"
@@ -1319,8 +1430,9 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
 
     for (const auto &RC : RegisterClasses) {
       // Output the extern for the instance.
-      OS << "  extern const TargetRegisterClass " << RC.getName()
-         << "RegClass;\n";
+      OS << "static constexpr const TargetRegisterClass &" << RC.getName()
+         << "RegClass = " << TargetName << "MCRegisterClassStorage.Classes["
+         << RC.EnumValue << "];\n";
     }
   }
 }
@@ -1446,71 +1558,6 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
     }
     OS << "};\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.
-    //
-    // If RC has super-registers, also create a list of subreg indices and bit
-    // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
-    // SuperRC, that satisfies:
-    //
-    //   For all SuperReg in SuperRC: SuperReg:Idx in RC
-    //
-    // The 0-terminated list of subreg indices starts at:
-    //
-    //   RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
-    //
-    // The corresponding bitmasks follow the sub-class mask in memory. Each
-    // mask has RCMaskWords uint32_t entries.
-    //
-    // Every bit mask present in the list has at least one bit set.
-
-    // Compress the sub-reg index lists.
-    using IdxList = std::vector<const CodeGenSubRegIndex *>;
-    SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
-    SequenceToOffsetTable<IdxList, deref<std::less<>>> SuperRegIdxSeqs;
-    BitVector MaskBV(RegisterClasses.size());
-
-    for (const auto &RC : RegisterClasses) {
-      OS << "static const uint32_t " << RC.getName()
-         << "SubClassMask[] = {\n  ";
-      printBitVectorAsHex(OS, RC.getSubClasses(), 32);
-
-      // Emit super-reg class masks for any relevant SubRegIndices that can
-      // project into RC.
-      IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
-      for (auto &Idx : SubRegIndices) {
-        MaskBV.reset();
-        RC.getSuperRegClasses(&Idx, MaskBV);
-        if (MaskBV.none())
-          continue;
-        SRIList.push_back(&Idx);
-        OS << "\n  ";
-        printBitVectorAsHex(OS, MaskBV, 32);
-        OS << "// " << Idx.getName();
-      }
-      SuperRegIdxSeqs.add(SRIList);
-      OS << "\n};\n\n";
-    }
-
-    OS << "static const uint16_t SuperRegIdxSeqs[] = {\n";
-    SuperRegIdxSeqs.layout();
-    SuperRegIdxSeqs.emit(OS, printSubRegIndex);
-    OS << "};\n\n";
-
-    // Emit super-class lists.
-    for (const auto &RC : RegisterClasses) {
-      ArrayRef<CodeGenRegisterClass *> Supers = RC.getSuperClasses();
-
-      // 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 << "};\n\n";
-    }
-
     // Emit methods.
     for (const auto &RC : RegisterClasses) {
       if (!RC.AltOrderSelect.empty()) {
@@ -1541,33 +1588,6 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
            << RC.getNumOrders() << ");\n  return Order[Select];\n}\n";
       }
     }
-
-    // Now emit the actual value-initialized register class instances.
-    NamespaceEmitter RegClassNS(OS, RegisterClasses.front().Namespace);
-    OS << "// Register class instances.\n";
-
-    for (const auto &RC : RegisterClasses) {
-      OS << "  extern const TargetRegisterClass " << RC.getName()
-         << "RegClass = {\n    " << "&" << Target.getName()
-         << "MCRegisterClassStorage.Classes[" << RC.getName() << "RegClassID],"
-         << "\n    " << RC.getName() << "SubClassMask,\n    SuperRegIdxSeqs + "
-         << SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n    ";
-      printMask(OS, RC.LaneMask);
-      OS << ",\n    " << (unsigned)RC.AllocationPriority << ",\n    "
-         << (RC.GlobalPriority ? "true" : "false") << ",\n    "
-         << format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n    "
-         << (unsigned)RC.SpillStackID << ", /* SpillStackID */\n    "
-         << (RC.HasDisjunctSubRegs ? "true" : "false")
-         << ", /* HasDisjunctSubRegs */\n    "
-         << (RC.CoveredBySubRegs ? "true" : "false")
-         << ", /* CoveredBySubRegs */\n    ";
-      if (RC.getSuperClasses().empty())
-        OS << "nullptr, ";
-      else
-        OS << RC.getName() << "Superclasses,  ";
-      OS << RC.getSuperClasses().size() << "\n";
-      OS << "  };\n\n";
-    }
   }
 
   OS << "static const TargetRegisterClass *const " << TargetName

>From 358e816346cd1ab3184c6f0dd0d543e23fce0ab4 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Thu, 2 Jul 2026 12:45:14 +0000
Subject: [PATCH 2/2] remove copy constructor (added for testing, valid in
 C++17, but breaks C++20...)

Created using spr 1.3.8-wip
---
 llvm/include/llvm/MC/MCRegisterInfo.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h
index dac8f84119dc3..88f93dfcdf91c 100644
--- a/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -39,8 +39,6 @@ class MCRegisterClass {
   using iterator = const MCPhysReg*;
   using const_iterator = const MCPhysReg*;
 
-  MCRegisterClass(const MCRegisterClass &) = delete;
-
   // TODO: reorder fields to reduce memory usage.
   const uint32_t RegsOff;   ///< Relative offset to MCPhysReg array.
   const uint32_t RegSetOff; ///< Relative offset to uint8_t array.



More information about the llvm-commits mailing list