Repository: llvm/llvm-project
File: llvm/lib/Target/AMDGPU/GCNRegPressure.cpp (C++)

Code before:
bool GCNRPTarget::isSaveBeneficial(Register Reg) const {
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
  const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
  const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(TRI);

  RegExcess Excess(MF, RP, *this);

  if (SRI->isSGPRClass(RC))
    return Excess.SGPR;

  if (SRI->isAGPRClass(RC))
    return (UnifiedRF && Excess.VGPR) || Excess.AGPR;

  return (UnifiedRF && Excess.VGPR) || Excess.ArchVGPR;
}

unsigned GCNRPTarget::getNumRegsBenefit(const GCNRegPressure &SaveRP) const {
  RegExcess Excess(MF, RP, *this);
  unsigned NumRegsSaved = 0;
  unsigned NumVGPRAboveAddrLimit = 0;

  if (Excess.SGPR)
    NumRegsSaved += std::min(Excess.SGPR, SaveRP.getSGPRNum());
  if (Excess.ArchVGPR)
    NumVGPRAboveAddrLimit += std::min(Excess.ArchVGPR, SaveRP.getArchVGPRNum());
  if (Excess.AGPR)
    NumVGPRAboveAddrLimit += std::min(Excess.AGPR, SaveRP.getAGPRNum());
  NumRegsSaved += NumVGPRAboveAddrLimit;

  if (UnifiedRF && Excess.VGPR) {
    // Do not double-count VGPRs that are both above the addressable limit in
    // their respective class and contribute to an overall excess in VGPR.
    const unsigned VGPRSave = SaveRP.getVGPRNum(true);
    if (NumVGPRAboveAddrLimit < VGPRSave)
      NumRegsSaved += std::min(Excess.VGPR, VGPRSave - NumVGPRAboveAddrLimit);
  }

  return NumRegsSaved;
}

bool GCNRPTarget::satisfied(const GCNRegPressure &TestRP) const {
  if (TestRP.getSGPRNum() > MaxSGPRs || TestRP.getVGPRNum(false) > MaxVGPRs)
    return false;
  if (UnifiedRF && TestRP.getVGPRNum(true) > MaxUnifiedVGPRs)
    return false;
  return true;
}

bool GCNRPTarget::hasVectorRegisterExcess() const {
  RegExcess Excess(MF, RP, *this);

Review comment (suggestion):
I think the special case for `UnifiedRF` would benefit a quick reminder of why we're doing this.
I feel the code work because you know the implementation of getVGPRNum(true), but for me who's not familiar with all that, this just looks like black magic.

Code after:
bool GCNRPTarget::isSaveBeneficial(Register Reg) const {
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
  const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
  const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(TRI);

  RegExcess Excess(MF, RP, *this);

  if (SRI->isSGPRClass(RC))
    return Excess.SGPR;

  if (SRI->isAGPRClass(RC))
    return (UnifiedRF && Excess.VGPR) || Excess.AGPR;

  return (UnifiedRF && Excess.VGPR) || Excess.ArchVGPR;
}

unsigned GCNRPTarget::getNumRegsBenefit(const GCNRegPressure &SaveRP) const {
  RegExcess Excess(MF, RP, *this);
  const unsigned NumVGPRAboveAddrLimit =
      std::min(Excess.ArchVGPR, SaveRP.getArchVGPRNum()) +
      std::min(Excess.AGPR, SaveRP.getAGPRNum());
  unsigned NumRegsSaved =
      std::min(Excess.SGPR, SaveRP.getSGPRNum()) + NumVGPRAboveAddrLimit;

  if (UnifiedRF && Excess.VGPR) {
    // We have already accounted for excess pressure above addressive limits for
    // the individual VGPR classes. However for targets with unified RFs there
    // is also a unified VGPR pressure (ArchVGPR + AGPR combination) limit to
    // honor that may be more restrictive that the per-VGPR-class limits. We
    // must also be careful not to double-count VGPR saves that may contribute
    // to lowering pressure both above the addressable limit in their respective
    // class as well as in the unified VGPR limit.
    const unsigned VGPRSave = SaveRP.getArchVGPRNum() + SaveRP.getAGPRNum();
    if (NumVGPRAboveAddrLimit < VGPRSave)
      NumRegsSaved += std::min(Excess.VGPR, VGPRSave - NumVGPRAboveAddrLimit);
  }

  return NumRegsSaved;
}

bool GCNRPTarget::satisfied(const GCNRegPressure &TestRP) const {
  if (TestRP.getSGPRNum() > MaxSGPRs || TestRP.getVGPRNum(false) > MaxVGPRs)
    return false;
  if (UnifiedRF && TestRP.getVGPRNum(true) > MaxUnifiedVGPRs)
    return false;
  return true;
}

bool GCNRPTarget::hasVectorRegisterExcess() const {
  RegExcess Excess(MF, RP, *this);