[llvm] [CodeGen][NFC] Move getRawAllocOrder to TargetRegInfo (PR #207124)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 1 23:24:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-tablegen
Author: Alexis Engelke (aengelke)
<details>
<summary>Changes</summary>
For most TargetRegisterClasses, the allocation order function is null
and we try to avoid pointer members in constants, so move the order
function to the TargetRegisterInfo to avoid the pointer member and
shrink the data structure.
---
Full diff: https://github.com/llvm/llvm-project/pull/207124.diff
8 Files Affected:
- (modified) llvm/include/llvm/CodeGen/TargetRegisterInfo.h (+19-19)
- (modified) llvm/lib/CodeGen/RegAllocPBQP.cpp (+3-2)
- (modified) llvm/lib/CodeGen/RegisterClassInfo.cpp (+1-1)
- (modified) llvm/lib/CodeGen/RegisterScavenging.cpp (+1-1)
- (modified) llvm/lib/CodeGen/TargetRegisterInfo.cpp (+2-1)
- (modified) llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp (+1-1)
- (modified) llvm/unittests/CodeGen/MachineInstrTest.cpp (+1-1)
- (modified) llvm/utils/TableGen/RegisterInfoEmitter.cpp (+31-10)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index ecf027d97cc15..183848b36e800 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -70,7 +70,6 @@ class TargetRegisterClass {
const bool CoveredBySubRegs;
const unsigned *SuperClasses;
const uint16_t SuperClassesSize;
- ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction &, bool Rev);
/// Return the register class ID number.
unsigned getID() const { return MC->getID(); }
@@ -193,24 +192,6 @@ class TargetRegisterClass {
/// class of at least one other TargetRegisterClass.
bool isASubClass() const { return SuperClasses != nullptr; }
- /// Returns the preferred order for allocating registers from this register
- /// class in MF. The raw order comes directly from the .td file and may
- /// include reserved registers that are not allocatable.
- /// Register allocators should also make sure to allocate
- /// callee-saved registers only after all the volatiles are used. The
- /// RegisterClassInfo class provides filtered allocation orders with
- /// callee-saved registers moved to the end.
- ///
- /// The MachineFunction argument can be used to tune the allocatable
- /// registers based on the characteristics of the function, subtarget, or
- /// other criteria.
- ///
- /// By default, this method returns all registers in the class.
- ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF,
- bool Rev = false) const {
- return OrderFunc ? OrderFunc(MF, Rev) : getRegisters();
- }
-
/// 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.
@@ -996,6 +977,25 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
/// Get the scale factor of spill weight for this register class.
virtual float getSpillWeightScaleFactor(const TargetRegisterClass *RC) const;
+ /// Returns the preferred order for allocating registers from this register
+ /// class in MF. The raw order comes directly from the .td file and may
+ /// include reserved registers that are not allocatable.
+ /// Register allocators should also make sure to allocate
+ /// callee-saved registers only after all the volatiles are used. The
+ /// RegisterClassInfo class provides filtered allocation orders with
+ /// callee-saved registers moved to the end.
+ ///
+ /// The MachineFunction argument can be used to tune the allocatable
+ /// registers based on the characteristics of the function, subtarget, or
+ /// other criteria.
+ ///
+ /// By default, this method returns all registers in the class.
+ virtual ArrayRef<MCPhysReg>
+ getRawAllocationOrder(const TargetRegisterClass &RC, const MachineFunction &,
+ bool /*Rev*/ = false) const {
+ return RC.getRegisters();
+ }
+
/// Get a list of 'hint' registers that the register allocator should try
/// first when allocating a physical register for the virtual register
/// VirtReg. These registers are effectively moved to the front of the
diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp
index 12bc63d172d0f..28c079c5dcbb7 100644
--- a/llvm/lib/CodeGen/RegAllocPBQP.cpp
+++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp
@@ -614,7 +614,7 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
// Compute an initial allowed set for the current vreg.
std::vector<MCRegister> VRegAllowed;
- ArrayRef<MCPhysReg> RawPRegOrder = TRC->getRawAllocationOrder(MF);
+ ArrayRef<MCPhysReg> RawPRegOrder = TRI.getRawAllocationOrder(*TRC, MF);
for (MCPhysReg R : RawPRegOrder) {
MCRegister PReg(R);
if (MRI.isReserved(PReg))
@@ -747,6 +747,7 @@ 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.
@@ -757,7 +758,7 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
if (PReg == 0) {
const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg());
- const ArrayRef<MCPhysReg> RawPRegOrder = RC.getRawAllocationOrder(MF);
+ ArrayRef<MCPhysReg> RawPRegOrder = TRI.getRawAllocationOrder(RC, MF);
for (MCRegister CandidateReg : RawPRegOrder) {
if (!VRM.getRegInfo().isReserved(CandidateReg)) {
PReg = CandidateReg;
diff --git a/llvm/lib/CodeGen/RegisterClassInfo.cpp b/llvm/lib/CodeGen/RegisterClassInfo.cpp
index acf306f32dd1d..50b2085fe688a 100644
--- a/llvm/lib/CodeGen/RegisterClassInfo.cpp
+++ b/llvm/lib/CodeGen/RegisterClassInfo.cpp
@@ -144,7 +144,7 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
// FIXME: Once targets reserve registers instead of removing them from the
// allocation order, we can simply use begin/end here.
- ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF, Reverse);
+ ArrayRef<MCPhysReg> RawOrder = TRI->getRawAllocationOrder(*RC, *MF, Reverse);
for (unsigned PhysReg : reverse_conditionally(RawOrder, Reverse)) {
// Remove reserved registers from the allocation order.
if (Reserved.test(PhysReg))
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index 1b6a0880eac9f..8ef8906ef8086 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -311,7 +311,7 @@ Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
const MachineFunction &MF = *MBB.getParent();
// Find the register whose use is furthest away.
- ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF);
+ ArrayRef<MCPhysReg> AllocationOrder = TRI->getRawAllocationOrder(RC, MF);
std::pair<MCPhysReg, MachineBasicBlock::iterator> P = findSurvivorBackwards(
*MRI, std::prev(MBBI), To, LiveUnits, AllocationOrder, RestoreAfter);
MCPhysReg Reg = P.first;
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index b97e3afd9da1e..b7cd250d2730b 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -232,7 +232,8 @@ TargetRegisterInfo::getCommonMinimalPhysRegClass(MCRegister Reg1,
static void getAllocatableSetForRC(const MachineFunction &MF,
const TargetRegisterClass *RC, BitVector &R){
assert(RC->isAllocatable() && "invalid for nonallocatable sets");
- ArrayRef<MCPhysReg> Order = RC->getRawAllocationOrder(MF);
+ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
+ ArrayRef<MCPhysReg> Order = TRI.getRawAllocationOrder(*RC, MF);
for (MCPhysReg PR : Order)
R.set(PR);
}
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 9a02bfda4b4a9..6adbe5c160c8c 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -2422,7 +2422,7 @@ Register HexagonFrameLowering::findPhysReg(MachineFunction &MF,
return false;
};
- for (Register Reg : RC->getRawAllocationOrder(MF)) {
+ for (Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
bool Dead = true;
for (auto R : HexagonBlockRanges::expandToSubRegs({Reg,0}, MRI, HRI)) {
if (isDead(R.Reg))
diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp
index 7e1fd091fa1c3..47e260104775f 100644
--- a/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -593,7 +593,7 @@ TEST(MachineInstrTest, SpliceOperands) {
// test tied operands
MCRegisterClass MRC{
0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true};
- TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0, 0};
// MachineRegisterInfo will be very upset if these registers aren't
// allocatable.
assert(RC.isAllocatable() && "unusable TargetRegisterClass");
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 72a256aa330c4..9eaee06143c64 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1295,6 +1295,12 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
<< " const MachineFunction &MF);\n";
const auto &RegisterClasses = RegBank.getRegClasses();
+ if (llvm::any_of(RegisterClasses,
+ [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
+ OS << " ArrayRef<MCPhysReg> getRawAllocationOrder("
+ "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
+ "const override;\n";
+ }
if (llvm::any_of(RegisterClasses,
[](const auto &RC) { return RC.getBaseClassOrder(); })) {
OS << " const TargetRegisterClass *getPhysRegBaseClass(MCRegister Reg) "
@@ -1512,7 +1518,8 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
<< "AltOrderSelect(const MachineFunction &MF, bool Rev) {"
<< RC.AltOrderSelect << "}\n\n"
<< "static ArrayRef<MCPhysReg> " << RC.getName()
- << "GetRawAllocationOrder(const MachineFunction &MF, bool Rev) {\n";
+ << "GetRawAllocationOrder(const TargetRegisterClass &RC, "
+ << "const MachineFunction &MF, bool Rev) {\n";
for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) {
ArrayRef<const Record *> Elems = RC.getOrder(oi);
if (!Elems.empty()) {
@@ -1522,10 +1529,8 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
OS << " };\n";
}
}
- OS << " const MCRegisterClass &MCR = get" << Target.getName()
- << "MCRegisterClass(" << RC.getQualifiedName() + "RegClassID);\n"
- << " const ArrayRef<MCPhysReg> Order[] = {\n"
- << " ArrayRef(MCR.begin(), MCR.getNumRegs()";
+ OS << " const ArrayRef<MCPhysReg> Order[] = {\n"
+ << " RC.getRegisters(";
for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
if (RC.getOrder(oi).empty())
OS << "),\n ArrayRef<MCPhysReg>(";
@@ -1560,11 +1565,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
OS << "nullptr, ";
else
OS << RC.getName() << "Superclasses, ";
- OS << RC.getSuperClasses().size() << ",\n ";
- if (RC.AltOrderSelect.empty())
- OS << "nullptr\n";
- else
- OS << RC.getName() << "GetRawAllocationOrder\n";
+ OS << RC.getSuperClasses().size() << "\n";
OS << " };\n\n";
}
}
@@ -1705,6 +1706,26 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
EmitRegUnitPressure(OS, ClassName);
+ if (llvm::any_of(RegisterClasses,
+ [](const auto &RC) { return !RC.AltOrderSelect.empty(); })) {
+ OS << "ArrayRef<MCPhysReg> " << ClassName
+ << "::getRawAllocationOrder("
+ "const TargetRegisterClass &RC, const MachineFunction &MF, bool Rev) "
+ "const {\n";
+ OS << " switch (RC.getID()) {\n";
+ for (const auto &RC : RegisterClasses) {
+ if (RC.AltOrderSelect.empty())
+ continue;
+ OS << " case " << RC.getQualifiedIdName() << ":\n"
+ << " return " << RC.getName()
+ << "GetRawAllocationOrder(RC, MF, Rev);\n";
+ ;
+ }
+ OS << " }\n";
+ OS << " return RC.getRegisters();\n";
+ OS << "}\n\n";
+ }
+
// Emit register base class mapper
if (!RegisterClasses.empty()) {
// Collect base classes
``````````
</details>
https://github.com/llvm/llvm-project/pull/207124
More information about the llvm-commits
mailing list