[llvm] [TRI] Remove reserved registers in getRegPressureSetLimit (PR #118787)

Pengcheng Wang via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 8 19:55:21 PST 2024


================
@@ -674,6 +674,49 @@ TargetRegisterInfo::prependOffsetExpression(const DIExpression *Expr,
                                       PrependFlags & DIExpression::EntryValue);
 }
 
+unsigned TargetRegisterInfo::getRegPressureSetLimit(const MachineFunction &MF,
+                                                    unsigned Idx) const {
+  const TargetRegisterClass *RC = nullptr;
+  unsigned NumRCUnits = 0;
+  for (const TargetRegisterClass *C : regclasses()) {
+    const int *PSetID = getRegClassPressureSets(C);
+    for (; *PSetID != -1; ++PSetID) {
+      if ((unsigned)*PSetID == Idx)
+        break;
+    }
+    if (*PSetID == -1)
+      continue;
+
+    // Found a register class that counts against this pressure set.
+    // For efficiency, only compute the set order for the largest set.
+    unsigned NUnits = getRegClassWeight(C).WeightLimit;
+    if (!RC || NUnits > NumRCUnits) {
+      RC = C;
+      NumRCUnits = NUnits;
+    }
+  }
+  assert(RC && "Failed to find register class");
+
----------------
wangpc-pp wrote:

The reason why we need a `compute` is because we need compute the number of allocatable register and then get the number of reserved registers (but actually I think we don't need call `compute` explicitly as `getNumAllocatableRegs` is cached, it will call `compute` in `get(RC)`):
```cpp
  // ...
  compute(RC);
  unsigned NAllocatableRegs = getNumAllocatableRegs(RC);
  // ...
  unsigned NReserved = RC->getNumRegs() - NAllocatableRegs;
```
```cpp
  unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const {
    return get(RC).NumRegs;
  }
```
The logic of calculating `NumRegs` in `compute` is:
```cpp
  // 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);
  for (unsigned PhysReg : RawOrder) {
    // Remove reserved registers from the allocation order.
    if (Reserved.test(PhysReg))
      continue;
    uint8_t Cost = RegCosts[PhysReg];
    MinCost = std::min(MinCost, Cost);

    if (getLastCalleeSavedAlias(PhysReg) &&
        !STI.ignoreCSRForAllocationOrder(*MF, PhysReg))
      // PhysReg aliases a CSR, save it for later.
      CSRAlias.push_back(PhysReg);
    else {
      if (Cost != LastCost)
        LastCostChange = N;
      RCI.Order[N++] = PhysReg;
      LastCost = Cost;
    }
  }
  RCI.NumRegs = N + CSRAlias.size();
```
`RCI.NumRegs` is the total number of register minus the number of reserved registers.
And in this patch, we change it to calculate the number of reserved registers first and calculate the allocatable register later. The effect should be the same I think.


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


More information about the llvm-commits mailing list