[llvm] [CodeGen] Use RegisterClassInfo for remaining allocation-order users (PR #216510)

Nikhil Kotikalapudi via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 15 14:45:42 PDT 2026


https://github.com/nkotikal created https://github.com/llvm/llvm-project/pull/216510

Greedy already uses RegisterClassInfo for the function-specific allocation order (reserved registers filtered, CSRs deferred). Remaining users still walked TRI's raw order or rebuilt RCI themselves.

Uses RCI.getOrder() everywhere that list is needed (PBQP, register scavenger scratch selection, Hexagon spill-slot search, ARM load/store opt, AMDGPU AGPR-copy MFMA rewrite). Takes the shared analysis when the pass can preserve it; otherwise keep a
local RCI after freezeReservedRegs().

Not NFC, as the scavenger now prefers caller-saved scratches (ARM test updated). Hexagon findPhysReg no longer considers reserved registers.

>From 5c3ec7294d7b6271da7f952b6d11aa21bda23e87 Mon Sep 17 00:00:00 2001
From: nkotikal <nak00001 at outlook.com>
Date: Sat, 15 Aug 2026 15:43:23 -0400
Subject: [PATCH 1/5] updated regalloc pbqp from tri to rci

---
 llvm/lib/CodeGen/RegAllocPBQP.cpp | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp
index 0650692962efa..ecb7a804bb057 100644
--- a/llvm/lib/CodeGen/RegAllocPBQP.cpp
+++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp
@@ -56,6 +56,7 @@
 #include "llvm/CodeGen/PBQP/Solution.h"
 #include "llvm/CodeGen/PBQPRAConstraint.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/Spiller.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -142,6 +143,7 @@ class RegAllocPBQP : public MachineFunctionPass {
 
   char *customPassID;
 
+  RegisterClassInfo RegClassInfo;
   RegSet VRegsToAlloc, EmptyIntervalVRegs;
 
   /// Inst which is a def of an original reg and whose defs are already all
@@ -611,11 +613,8 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
 
     // Compute an initial allowed set for the current vreg.
     std::vector<MCRegister> VRegAllowed;
-    ArrayRef<MCPhysReg> RawPRegOrder = TRI.getRawAllocationOrder(*TRC, MF);
-    for (MCPhysReg R : RawPRegOrder) {
+    for (MCPhysReg R : RegClassInfo.getOrder(TRC)) {
       MCRegister PReg(R);
-      if (MRI.isReserved(PReg))
-        continue;
 
       // vregLI crosses a regmask operand that clobbers preg.
       if (!RegMaskOverlaps.empty() && !RegMaskOverlaps.test(PReg))
@@ -744,7 +743,6 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
 void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
                                  LiveIntervals &LIS,
                                  VirtRegMap &VRM) const {
-  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
   MachineRegisterInfo &MRI = MF.getRegInfo();
 
   // First allocate registers for the empty intervals.
@@ -754,16 +752,11 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
     Register PReg = MRI.getSimpleHint(LI.reg());
 
     if (PReg == 0) {
-      const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg());
-      ArrayRef<MCPhysReg> RawPRegOrder = TRI.getRawAllocationOrder(RC, MF);
-      for (MCRegister CandidateReg : RawPRegOrder) {
-        if (!VRM.getRegInfo().isReserved(CandidateReg)) {
-          PReg = CandidateReg;
-          break;
-        }
-      }
-      assert(PReg &&
+      ArrayRef<MCPhysReg> Order =
+          RegClassInfo.getOrder(MRI.getRegClass(LI.reg()));
+      assert(!Order.empty() &&
              "No un-reserved physical registers in this register class");
+      PReg = Order.front();
     }
 
     VRM.assignVirt2Phys(LI.reg(), PReg);
@@ -804,6 +797,7 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
       createInlineSpiller({LIS, LiveStks, MDT, MBFI}, MF, VRM, DefaultVRAI));
 
   MF.getRegInfo().freezeReservedRegs();
+  RegClassInfo.runOnMachineFunction(MF);
 
   LLVM_DEBUG(dbgs() << "PBQP Register Allocating for " << MF.getName() << "\n");
 

>From 4f6b00424ef3986c0d50fd13b93f5a7ba61f4906 Mon Sep 17 00:00:00 2001
From: nkotikal <nak00001 at outlook.com>
Date: Sat, 15 Aug 2026 16:33:18 -0400
Subject: [PATCH 2/5] spread RCI to rest of passes that need it and replaced
 TRI where possible

---
 .../include/llvm/CodeGen/RegisterScavenging.h |  2 ++
 llvm/lib/CodeGen/RegAllocPBQP.cpp             |  8 ++---
 llvm/lib/CodeGen/RegisterScavenging.cpp       | 13 +++----
 .../AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp      | 19 +++++-----
 llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 35 ++++++++++---------
 .../Target/Hexagon/HexagonFrameLowering.cpp   |  9 +++--
 .../lib/Target/Hexagon/HexagonFrameLowering.h |  3 +-
 7 files changed, 51 insertions(+), 38 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/RegisterScavenging.h b/llvm/include/llvm/CodeGen/RegisterScavenging.h
index 3d8e9f5bdc122..1b55364602e9e 100644
--- a/llvm/include/llvm/CodeGen/RegisterScavenging.h
+++ b/llvm/include/llvm/CodeGen/RegisterScavenging.h
@@ -22,6 +22,7 @@
 #include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/MC/LaneBitmask.h"
 
 namespace llvm {
@@ -38,6 +39,7 @@ class RegScavenger {
   MachineRegisterInfo *MRI = nullptr;
   MachineBasicBlock *MBB = nullptr;
   MachineBasicBlock::iterator MBBI;
+  RegisterClassInfo RCI;
 
   /// Information on scavenged registers (held in a spill slot).
   struct ScavengedInfo {
diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp
index ecb7a804bb057..fbf2e8d7e3d99 100644
--- a/llvm/lib/CodeGen/RegAllocPBQP.cpp
+++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp
@@ -143,7 +143,7 @@ class RegAllocPBQP : public MachineFunctionPass {
 
   char *customPassID;
 
-  RegisterClassInfo RegClassInfo;
+  RegisterClassInfo RCI;
   RegSet VRegsToAlloc, EmptyIntervalVRegs;
 
   /// Inst which is a def of an original reg and whose defs are already all
@@ -613,7 +613,7 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
 
     // Compute an initial allowed set for the current vreg.
     std::vector<MCRegister> VRegAllowed;
-    for (MCPhysReg R : RegClassInfo.getOrder(TRC)) {
+    for (MCPhysReg R : RCI.getOrder(TRC)) {
       MCRegister PReg(R);
 
       // vregLI crosses a regmask operand that clobbers preg.
@@ -753,7 +753,7 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
 
     if (PReg == 0) {
       ArrayRef<MCPhysReg> Order =
-          RegClassInfo.getOrder(MRI.getRegClass(LI.reg()));
+          RCI.getOrder(MRI.getRegClass(LI.reg()));
       assert(!Order.empty() &&
              "No un-reserved physical registers in this register class");
       PReg = Order.front();
@@ -797,7 +797,7 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
       createInlineSpiller({LIS, LiveStks, MDT, MBFI}, MF, VRM, DefaultVRAI));
 
   MF.getRegInfo().freezeReservedRegs();
-  RegClassInfo.runOnMachineFunction(MF);
+  RCI.runOnMachineFunction(MF);
 
   LLVM_DEBUG(dbgs() << "PBQP Register Allocating for " << MF.getName() << "\n");
 
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index 8ef8906ef8086..119a2527028df 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -27,6 +27,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -57,7 +58,8 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
   TRI = MF.getSubtarget().getRegisterInfo();
   MRI = &MF.getRegInfo();
   LiveUnits.init(*TRI);
-
+  RCI.runOnMachineFunction(MF);
+  
   this->MBB = &MBB;
 
   for (ScavengedInfo &SI : Scavenged) {
@@ -99,7 +101,7 @@ bool RegScavenger::isRegUsed(Register Reg, bool includeReserved) const {
 }
 
 Register RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
-  for (Register Reg : *RC) {
+  for (MCPhysReg Reg : RCI.getOrder(RC)) {
     if (!isRegUsed(Reg)) {
       LLVM_DEBUG(dbgs() << "Scavenger found unused reg: " << printReg(Reg, TRI)
                         << "\n");
@@ -111,9 +113,9 @@ Register RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
 
 BitVector RegScavenger::getRegsAvailable(const TargetRegisterClass *RC) {
   BitVector Mask(TRI->getNumRegs());
-  for (Register Reg : *RC)
+  for (MCPhysReg Reg : RCI.getOrder(RC))
     if (!isRegUsed(Reg))
-      Mask.set(Reg.id());
+      Mask.set(Reg);
   return Mask;
 }
 
@@ -308,10 +310,9 @@ Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
                                                  bool RestoreAfter, int SPAdj,
                                                  bool AllowSpill) {
   const MachineBasicBlock &MBB = *To->getParent();
-  const MachineFunction &MF = *MBB.getParent();
 
   // Find the register whose use is furthest away.
-  ArrayRef<MCPhysReg> AllocationOrder = TRI->getRawAllocationOrder(RC, MF);
+  ArrayRef<MCPhysReg> AllocationOrder = RCI.getOrder(&RC);
   std::pair<MCPhysReg, MachineBasicBlock::iterator> P = findSurvivorBackwards(
       *MRI, std::prev(MBBI), To, LiveUnits, AllocationOrder, RestoreAfter);
   MCPhysReg Reg = P.first;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp
index 6510c07358e01..12945f288b2cf 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp
@@ -32,6 +32,7 @@
 #include "llvm/CodeGen/LiveStacks.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/VirtRegMap.h"
 #include "llvm/InitializePasses.h"
@@ -617,7 +618,6 @@ bool AMDGPURewriteAGPRCopyMFMAImpl::run(MachineFunction &MF) const {
 class AMDGPURewriteAGPRCopyMFMALegacy : public MachineFunctionPass {
 public:
   static char ID;
-  RegisterClassInfo RegClassInfo;
 
   AMDGPURewriteAGPRCopyMFMALegacy() : MachineFunctionPass(ID) {}
 
@@ -632,11 +632,13 @@ class AMDGPURewriteAGPRCopyMFMALegacy : public MachineFunctionPass {
     AU.addRequired<VirtRegMapWrapperLegacy>();
     AU.addRequired<LiveRegMatrixWrapperLegacy>();
     AU.addRequired<LiveStacksWrapperLegacy>();
+    AU.addRequired<MachineRegisterClassInfoWrapperPass>();
 
     AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreserved<VirtRegMapWrapperLegacy>();
     AU.addPreserved<LiveRegMatrixWrapperLegacy>();
     AU.addPreserved<LiveStacksWrapperLegacy>();
+    AU.addPreserved<MachineRegisterClassInfoWrapperPass>();
 
     AU.setPreservesAll();
     MachineFunctionPass::getAnalysisUsage(AU);
@@ -651,6 +653,7 @@ INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(VirtRegMapWrapperLegacy)
 INITIALIZE_PASS_DEPENDENCY(LiveRegMatrixWrapperLegacy)
 INITIALIZE_PASS_DEPENDENCY(LiveStacksWrapperLegacy)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
 INITIALIZE_PASS_END(AMDGPURewriteAGPRCopyMFMALegacy, DEBUG_TYPE,
                     "AMDGPU Rewrite AGPR-Copy-MFMA", false, false)
 
@@ -664,13 +667,12 @@ bool AMDGPURewriteAGPRCopyMFMALegacy::runOnMachineFunction(
   if (skipFunction(MF.getFunction()))
     return false;
 
-  RegClassInfo.runOnMachineFunction(MF);
-
   auto &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
   auto &LRM = getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
   auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
   auto &LSS = getAnalysis<LiveStacksWrapperLegacy>().getLS();
-  AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, LSS, RegClassInfo);
+  auto &RCI = getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
+  AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, LSS, RCI);
   return Impl.run(MF);
 }
 
@@ -681,10 +683,10 @@ AMDGPURewriteAGPRCopyMFMAPass::run(MachineFunction &MF,
   LiveRegMatrix &LRM = MFAM.getResult<LiveRegMatrixAnalysis>(MF);
   LiveIntervals &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
   LiveStacks &LSS = MFAM.getResult<LiveStacksAnalysis>(MF);
-  RegisterClassInfo RegClassInfo;
-  RegClassInfo.runOnMachineFunction(MF);
+  RegisterClassInfo &RCI =
+      MFAM.getResult<MachineRegisterClassAnalysis>(MF);
 
-  AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, LSS, RegClassInfo);
+  AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, LSS, RCI);
   if (!Impl.run(MF))
     return PreservedAnalyses::all();
   auto PA = getMachineFunctionPassPreservedAnalyses();
@@ -693,6 +695,7 @@ AMDGPURewriteAGPRCopyMFMAPass::run(MachineFunction &MF,
       .preserve<VirtRegMapAnalysis>()
       .preserve<SlotIndexesAnalysis>()
       .preserve<LiveIntervalsAnalysis>()
-      .preserve<LiveRegMatrixAnalysis>();
+      .preserve<LiveRegMatrixAnalysis>()
+      .preserve<MachineRegisterClassAnalysis>();
   return PA;
 }
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 058033bb7e942..9b119f32c5c77 100644
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -106,13 +106,13 @@ struct ARMLoadStoreOpt {
   const TargetLowering *TL;
   ARMFunctionInfo *AFI;
   LiveRegUnits LiveRegs;
-  RegisterClassInfo RegClassInfo;
+  const RegisterClassInfo *RCI = nullptr;
   MachineBasicBlock::const_iterator LiveRegPos;
   bool LiveRegsValid;
-  bool RegClassInfoValid;
   bool isThumb1, isThumb2;
 
-  bool runOnMachineFunction(MachineFunction &Fn);
+  bool runOnMachineFunction(MachineFunction &Fn,
+                            const RegisterClassInfo &RegClassInfo);
 
 private:
   /// A set of load/store MachineInstrs with same base register sorted by
@@ -200,6 +200,7 @@ struct ARMLoadStoreOptLegacy : public MachineFunctionPass {
   StringRef getPassName() const override { return ARM_LOAD_STORE_OPT_NAME; }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addRequired<MachineRegisterClassInfoWrapperPass>();
     AU.addPreserved<MachineRegisterClassInfoWrapperPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
   }
@@ -209,8 +210,11 @@ char ARMLoadStoreOptLegacy::ID = 0;
 
 } // end anonymous namespace
 
-INITIALIZE_PASS(ARMLoadStoreOptLegacy, "arm-ldst-opt", ARM_LOAD_STORE_OPT_NAME,
-                false, false)
+INITIALIZE_PASS_BEGIN(ARMLoadStoreOptLegacy, "arm-ldst-opt",
+                      ARM_LOAD_STORE_OPT_NAME, false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
+INITIALIZE_PASS_END(ARMLoadStoreOptLegacy, "arm-ldst-opt",
+                    ARM_LOAD_STORE_OPT_NAME, false, false)
 
 static bool definesCPSR(const MachineInstr &MI) {
   for (const auto &MO : MI.operands()) {
@@ -592,13 +596,8 @@ void ARMLoadStoreOpt::UpdateBaseRegUses(MachineBasicBlock &MBB,
 
 /// Return the first register of class \p RegClass that is not in \p Regs.
 unsigned ARMLoadStoreOpt::findFreeReg(const TargetRegisterClass &RegClass) {
-  if (!RegClassInfoValid) {
-    RegClassInfo.runOnMachineFunction(*MF);
-    RegClassInfoValid = true;
-  }
-
-  for (unsigned Reg : RegClassInfo.getOrder(&RegClass))
-    if (LiveRegs.available(Reg) && !MF->getRegInfo().isReserved(Reg))
+  for (unsigned Reg : RCI->getOrder(&RegClass))
+    if (LiveRegs.available(Reg))
       return Reg;
   return 0;
 }
@@ -2107,15 +2106,16 @@ bool ARMLoadStoreOpt::CombineMovBx(MachineBasicBlock &MBB) {
   llvm_unreachable("tMOVr doesn't kill a reg before tBX_RET?");
 }
 
-bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
+bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn,
+                                           const RegisterClassInfo &RegClassInfo) {
   MF = &Fn;
   STI = &Fn.getSubtarget<ARMSubtarget>();
   TL = STI->getTargetLowering();
   AFI = Fn.getInfo<ARMFunctionInfo>();
   TII = STI->getInstrInfo();
   TRI = STI->getRegisterInfo();
+  RCI = &RegClassInfo;
 
-  RegClassInfoValid = false;
   isThumb2 = AFI->isThumb2Function();
   isThumb1 = AFI->isThumbFunction() && !isThumb2;
 
@@ -2144,7 +2144,8 @@ bool ARMLoadStoreOptLegacy::runOnMachineFunction(MachineFunction &MF) {
   if (skipFunction(MF.getFunction()))
     return false;
   ARMLoadStoreOpt Impl;
-  return Impl.runOnMachineFunction(MF);
+  return Impl.runOnMachineFunction(
+      MF, getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI());
 }
 
 #define ARM_PREALLOC_LOAD_STORE_OPT_NAME                                       \
@@ -3344,11 +3345,13 @@ PreservedAnalyses
 ARMLoadStoreOptPass::run(MachineFunction &MF,
                          MachineFunctionAnalysisManager &MFAM) {
   ARMLoadStoreOpt Impl;
-  bool Changed = Impl.runOnMachineFunction(MF);
+  bool Changed = Impl.runOnMachineFunction(
+      MF, MFAM.getResult<MachineRegisterClassAnalysis>(MF));
   if (!Changed)
     return PreservedAnalyses::all();
   PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
   PA.preserveSet<CFGAnalyses>();
+  PA.preserve<MachineRegisterClassAnalysis>();
   return PA;
 }
 
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index b665ef98c5e44..22cec99e5e799 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -38,6 +38,7 @@
 #include "llvm/CodeGen/MachinePostDominators.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/IR/Attributes.h"
@@ -2419,7 +2420,7 @@ Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
       HexagonBlockRanges::IndexRange &FIR,
       HexagonBlockRanges::InstrIndexMap &IndexMap,
       HexagonBlockRanges::RegToRangeMap &DeadMap,
-      const TargetRegisterClass *RC) const {
+      const TargetRegisterClass *RC, const RegisterClassInfo &RCI) const {
   auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
   auto &MRI = MF.getRegInfo();
 
@@ -2433,7 +2434,7 @@ Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
     return false;
   };
 
-  for (Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
+  for (Register Reg : RCI.getOrder(RC)) {
     bool Dead = true;
     for (auto R : HexagonBlockRanges::expandToSubRegs({Reg,0}, MRI, HRI)) {
       if (isDead(R.Reg))
@@ -2453,6 +2454,8 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
   auto &HII = *HST.getInstrInfo();
   auto &HRI = *HST.getRegisterInfo();
   auto &MRI = MF.getRegInfo();
+  RegisterClassInfo RCI;
+  RCI.runOnMachineFunction(MF);
   HexagonBlockRanges HBR(MF);
 
   using BlockIndexMap =
@@ -2700,7 +2703,7 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
                                                   SrcOp.getSubReg() };
         auto *RC = HII.getRegClass(SI.getDesc(), 2);
         // The this-> is needed to unconfuse MSVC.
-        Register FoundR = this->findPhysReg(MF, Range, IM, DM, RC);
+        Register FoundR = this->findPhysReg(MF, Range, IM, DM, RC, RCI);
         LLVM_DEBUG(dbgs() << "Replacement reg:" << printReg(FoundR, &HRI)
                           << '\n');
         if (FoundR == 0)
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
index 0b93795f2b912..4fb69c338e85b 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -26,6 +26,7 @@ class HexagonRegisterInfo;
 class MachineFunction;
 class MachineInstr;
 class MachineRegisterInfo;
+class RegisterClassInfo;
 class MCRegisterClass;
 using TargetRegisterClass = MCRegisterClass;
 
@@ -173,7 +174,7 @@ class HexagonFrameLowering : public TargetFrameLowering {
   Register findPhysReg(MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR,
       HexagonBlockRanges::InstrIndexMap &IndexMap,
       HexagonBlockRanges::RegToRangeMap &DeadMap,
-      const TargetRegisterClass *RC) const;
+      const TargetRegisterClass *RC, const RegisterClassInfo &RCI) const;
   void optimizeSpillSlots(MachineFunction &MF,
       SmallVectorImpl<Register> &VRegs) const;
 

>From 17d3aa367e892f4132e5ae3f918a10254a543ae6 Mon Sep 17 00:00:00 2001
From: nkotikal <nak00001 at outlook.com>
Date: Sat, 15 Aug 2026 16:53:29 -0400
Subject: [PATCH 3/5] ARM register scavenger exceptions test regen

---
 .../ARM/register-scavenger-exceptions.mir     | 44 ++++++++++---------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/llvm/test/CodeGen/ARM/register-scavenger-exceptions.mir b/llvm/test/CodeGen/ARM/register-scavenger-exceptions.mir
index 98c80aeda31d0..2384657a8b649 100644
--- a/llvm/test/CodeGen/ARM/register-scavenger-exceptions.mir
+++ b/llvm/test/CodeGen/ARM/register-scavenger-exceptions.mir
@@ -16,9 +16,9 @@
 
 ...
 ---
-# Check that the register scavenger does pick r5 (not preserved in prolog) for
-# materialising a stack frame address when the function ends in throwing an
-# exception.
+# Check that the register scavenger picks r12 (caller-saved, not preserved in
+# the prolog) for materialising a stack frame address when the function ends
+# in throwing an exception.
 name:            _Z3foov
 stack:
   - { id: 0, name: V1, type: default, offset: 0, size: 5000, alignment: 8,
@@ -36,24 +36,26 @@ body:             |
   bb.0.entry:
 
     ; CHECK-LABEL: name: _Z3foov
-    ; CHECK: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $r10, killed $r11, killed $lr
-    ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 16
-    ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
-    ; CHECK: frame-setup CFI_INSTRUCTION offset $r11, -8
-    ; CHECK: frame-setup CFI_INSTRUCTION offset $r10, -12
-    ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -16
-    ; CHECK: $r11 = frame-setup ADDri killed $sp, 8, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: frame-setup CFI_INSTRUCTION def_cfa $r11, 8
-    ; CHECK: $sp = frame-setup SUBri killed $sp, 912, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $sp = frame-setup SUBri killed $sp, 4096, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $r0 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $r1 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $r2 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $r3 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $r4 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: $r10 = SUBri killed $r11, 4096, 14 /* CC::al */, $noreg, $noreg
-    ; CHECK: STRi12 killed $lr, killed $r10, -916, 14 /* CC::al */, $noreg :: (store (s32) into %stack.2)
-    ; CHECK: BL @_Z3barv, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r1, implicit killed $r2, implicit killed $r3, implicit killed $r4, implicit-def $sp
+    ; CHECK: liveins: $r4, $r10, $lr
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $r10, killed $r11, killed $lr
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r11, -8
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r10, -12
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -16
+    ; CHECK-NEXT: $r11 = frame-setup ADDri killed $sp, 8, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa $r11, 8
+    ; CHECK-NEXT: $sp = frame-setup SUBri killed $sp, 912, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $sp = frame-setup SUBri killed $sp, 4096, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r0 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r1 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r2 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r3 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r4 = MOVi 0, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: $r12 = SUBri killed $r11, 4096, 14 /* CC::al */, $noreg, $noreg
+    ; CHECK-NEXT: STRi12 killed $lr, killed $r12, -916, 14 /* CC::al */, $noreg :: (store (s32) into %stack.2)
+    ; CHECK-NEXT: BL @_Z3barv, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r1, implicit killed $r2, implicit killed $r3, implicit killed $r4, implicit-def $sp
     $r0 = MOVi 0, 14, $noreg, $noreg
     $r1 = MOVi 0, 14, $noreg, $noreg
     $r2 = MOVi 0, 14, $noreg, $noreg

>From 13bd9905074f3d0e1910f33c9f3c65f968b6e800 Mon Sep 17 00:00:00 2001
From: nkotikal <nak00001 at outlook.com>
Date: Sat, 15 Aug 2026 17:34:25 -0400
Subject: [PATCH 4/5] clang format

---
 llvm/lib/CodeGen/RegAllocPBQP.cpp                    |  6 ++----
 llvm/lib/CodeGen/RegisterScavenging.cpp              |  2 +-
 llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp |  3 +--
 llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp        |  4 ++--
 llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp     | 10 +++++-----
 llvm/lib/Target/Hexagon/HexagonFrameLowering.h       |  7 ++++---
 6 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp
index fbf2e8d7e3d99..1e624296cae63 100644
--- a/llvm/lib/CodeGen/RegAllocPBQP.cpp
+++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp
@@ -740,8 +740,7 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
   return !AnotherRoundNeeded;
 }
 
-void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
-                                 LiveIntervals &LIS,
+void RegAllocPBQP::finalizeAlloc(MachineFunction &MF, LiveIntervals &LIS,
                                  VirtRegMap &VRM) const {
   MachineRegisterInfo &MRI = MF.getRegInfo();
 
@@ -752,8 +751,7 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
     Register PReg = MRI.getSimpleHint(LI.reg());
 
     if (PReg == 0) {
-      ArrayRef<MCPhysReg> Order =
-          RCI.getOrder(MRI.getRegClass(LI.reg()));
+      ArrayRef<MCPhysReg> Order = RCI.getOrder(MRI.getRegClass(LI.reg()));
       assert(!Order.empty() &&
              "No un-reserved physical registers in this register class");
       PReg = Order.front();
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index 119a2527028df..edfdcef378052 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -59,7 +59,7 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
   MRI = &MF.getRegInfo();
   LiveUnits.init(*TRI);
   RCI.runOnMachineFunction(MF);
-  
+
   this->MBB = &MBB;
 
   for (ScavengedInfo &SI : Scavenged) {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp
index 12945f288b2cf..141639a47c89a 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteAGPRCopyMFMA.cpp
@@ -683,8 +683,7 @@ AMDGPURewriteAGPRCopyMFMAPass::run(MachineFunction &MF,
   LiveRegMatrix &LRM = MFAM.getResult<LiveRegMatrixAnalysis>(MF);
   LiveIntervals &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
   LiveStacks &LSS = MFAM.getResult<LiveStacksAnalysis>(MF);
-  RegisterClassInfo &RCI =
-      MFAM.getResult<MachineRegisterClassAnalysis>(MF);
+  RegisterClassInfo &RCI = MFAM.getResult<MachineRegisterClassAnalysis>(MF);
 
   AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, LSS, RCI);
   if (!Impl.run(MF))
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 9b119f32c5c77..27ba79d2cbda6 100644
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -2106,8 +2106,8 @@ bool ARMLoadStoreOpt::CombineMovBx(MachineBasicBlock &MBB) {
   llvm_unreachable("tMOVr doesn't kill a reg before tBX_RET?");
 }
 
-bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn,
-                                           const RegisterClassInfo &RegClassInfo) {
+bool ARMLoadStoreOpt::runOnMachineFunction(
+    MachineFunction &Fn, const RegisterClassInfo &RegClassInfo) {
   MF = &Fn;
   STI = &Fn.getSubtarget<ARMSubtarget>();
   TL = STI->getTargetLowering();
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 22cec99e5e799..57e611db15ca0 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -2416,11 +2416,11 @@ void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF,
   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
 }
 
-Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
-      HexagonBlockRanges::IndexRange &FIR,
-      HexagonBlockRanges::InstrIndexMap &IndexMap,
-      HexagonBlockRanges::RegToRangeMap &DeadMap,
-      const TargetRegisterClass *RC, const RegisterClassInfo &RCI) const {
+Register HexagonFrameLowering::findPhysReg(
+    MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR,
+    HexagonBlockRanges::InstrIndexMap &IndexMap,
+    HexagonBlockRanges::RegToRangeMap &DeadMap, const TargetRegisterClass *RC,
+    const RegisterClassInfo &RCI) const {
   auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
   auto &MRI = MF.getRegInfo();
 
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
index 4fb69c338e85b..bdb7b50791468 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -172,9 +172,10 @@ class HexagonFrameLowering : public TargetFrameLowering {
       SmallVectorImpl<Register> &NewRegs) const;
 
   Register findPhysReg(MachineFunction &MF, HexagonBlockRanges::IndexRange &FIR,
-      HexagonBlockRanges::InstrIndexMap &IndexMap,
-      HexagonBlockRanges::RegToRangeMap &DeadMap,
-      const TargetRegisterClass *RC, const RegisterClassInfo &RCI) const;
+                       HexagonBlockRanges::InstrIndexMap &IndexMap,
+                       HexagonBlockRanges::RegToRangeMap &DeadMap,
+                       const TargetRegisterClass *RC,
+                       const RegisterClassInfo &RCI) const;
   void optimizeSpillSlots(MachineFunction &MF,
       SmallVectorImpl<Register> &VRegs) const;
 

>From a47aa3cf8c88aa958e7924fb952e9fc77c8f299c Mon Sep 17 00:00:00 2001
From: nkotikal <nak00001 at outlook.com>
Date: Sat, 15 Aug 2026 17:42:36 -0400
Subject: [PATCH 5/5] reverted RC subset to *RC set in scavenger for
 getRegsAvailable

---
 llvm/lib/CodeGen/RegisterScavenging.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index edfdcef378052..b04a72e12f6e7 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -113,9 +113,9 @@ Register RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {
 
 BitVector RegScavenger::getRegsAvailable(const TargetRegisterClass *RC) {
   BitVector Mask(TRI->getNumRegs());
-  for (MCPhysReg Reg : RCI.getOrder(RC))
+  for (Register Reg : *RC)
     if (!isRegUsed(Reg))
-      Mask.set(Reg);
+      Mask.set(Reg.id());
   return Mask;
 }
 



More information about the llvm-commits mailing list