[llvm] [CodeGen] Use SmallSetVector for getRegAllocationHints (PR #224472)
Nick Desaulniers via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 17:00:20 PDT 2026
https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/224472
>From 58df225acc35c256448fcfc8b183305363f99611 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 17 Sep 2026 14:53:57 -0700
Subject: [PATCH] [CodeGen] Use SmallSetVector for getRegAllocationHints
Change TargetRegisterInfo::getRegAllocationHints and all target overrides
to accept SmallSetVector<MCPhysReg, 16> &Hints instead of SmallVectorImpl,
structurally preventing duplicate register allocation hints while preserving
insertion order.
Assisted-by: Gemini
Link: #190139
Link: #193011
Link: #219007
Link: #224448
Link: #224451
Link: #224742
---
.../include/llvm/CodeGen/TargetRegisterInfo.h | 3 +-
llvm/lib/CodeGen/AllocationOrder.cpp | 10 ++--
llvm/lib/CodeGen/TargetRegisterInfo.cpp | 10 +---
.../Target/AArch64/AArch64RegisterInfo.cpp | 27 ++++++-----
llvm/lib/Target/AArch64/AArch64RegisterInfo.h | 2 +-
llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp | 8 ++--
llvm/lib/Target/AMDGPU/SIRegisterInfo.h | 2 +-
llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 8 ++--
llvm/lib/Target/ARM/ARMBaseRegisterInfo.h | 2 +-
llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 16 +++----
llvm/lib/Target/PowerPC/PPCRegisterInfo.h | 2 +-
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 10 ++--
llvm/lib/Target/RISCV/RISCVRegisterInfo.h | 2 +-
.../Target/SystemZ/SystemZRegisterInfo.cpp | 12 ++---
llvm/lib/Target/SystemZ/SystemZRegisterInfo.h | 2 +-
llvm/lib/Target/X86/X86RegisterInfo.cpp | 22 ++++-----
llvm/lib/Target/X86/X86RegisterInfo.h | 2 +-
.../AArch64/AArch64RegisterInfoTest.cpp | 46 +++++++++++++++++++
18 files changed, 111 insertions(+), 75 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 4678773607377..b18aaa7b05a6b 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -16,6 +16,7 @@
#define LLVM_CODEGEN_TARGETREGISTERINFO_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -837,7 +838,7 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
/// expect to see generic copy hints added.
virtual bool
getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF,
const VirtRegMap *VRM = nullptr,
const LiveRegMatrix *Matrix = nullptr) const;
diff --git a/llvm/lib/CodeGen/AllocationOrder.cpp b/llvm/lib/CodeGen/AllocationOrder.cpp
index 6294b86b27c44..4f04a25809430 100644
--- a/llvm/lib/CodeGen/AllocationOrder.cpp
+++ b/llvm/lib/CodeGen/AllocationOrder.cpp
@@ -53,14 +53,14 @@ AllocationOrder AllocationOrder::create(Register VirtReg, const VirtRegMap &VRM,
const TargetRegisterInfo *TRI = &VRM.getTargetRegInfo();
const MachineRegisterInfo &MRI = MF.getRegInfo();
auto Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
+ // Get Hints.
+ SmallSetVector<MCPhysReg, 16> Hints;
+ bool HardHints =
+ TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix);
// HintsAndCustomOrder holds Hints first followed by the custom order if the
// anti-hints reorders it.
- SmallVector<MCPhysReg, 16> HintsAndCustomOrder;
-
- // Get Hints.
- bool HardHints = TRI->getRegAllocationHints(
- VirtReg, Order, HintsAndCustomOrder, MF, &VRM, Matrix);
+ SmallVector<MCPhysReg, 16> HintsAndCustomOrder = Hints.takeVector();
const int NumHints = static_cast<int>(HintsAndCustomOrder.size());
// HintsAndCustomOrder only holds Hints (custom order is not added yet).
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index 79b01d27d91a5..fb86ca377e89e 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -14,7 +14,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LiveInterval.h"
@@ -399,7 +398,7 @@ float TargetRegisterInfo::getSpillWeightScaleFactor(
// Compute target-independent register allocator hints to help eliminate copies.
bool TargetRegisterInfo::getRegAllocationHints(
Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo &MRI = MF.getRegInfo();
const std::pair<unsigned, SmallVector<Register, 4>> *Hints_MRI =
@@ -408,7 +407,6 @@ bool TargetRegisterInfo::getRegAllocationHints(
if (!Hints_MRI)
return false;
- SmallSet<Register, 32> HintedRegs;
// First hint may be a target hint.
bool Skip = (Hints_MRI->first != 0);
for (auto Reg : Hints_MRI->second) {
@@ -422,10 +420,6 @@ bool TargetRegisterInfo::getRegAllocationHints(
if (VRM && Phys.isVirtual())
Phys = VRM->getPhys(Phys);
- // Don't add the same reg twice (Hints_MRI may contain multiple virtual
- // registers allocated to the same physreg).
- if (!HintedRegs.insert(Phys).second)
- continue;
// Check that Phys is a valid hint in VirtReg's register class.
if (!Phys.isPhysical())
continue;
@@ -438,7 +432,7 @@ bool TargetRegisterInfo::getRegAllocationHints(
continue;
// All clear, tell the register allocator to prefer this register.
- Hints.push_back(Phys.id());
+ Hints.insert(Phys);
}
return false;
}
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index 7f22038c206b7..672441c51286c 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -1111,7 +1111,7 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
static bool HandleDestructivePredicateHint(
Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints, const VirtRegMap *VRM,
+ SmallSetVector<MCPhysReg, 16> &Hints, const VirtRegMap *VRM,
const MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
const AArch64Subtarget &ST, const LiveRegMatrix *Matrix) {
const TargetRegisterClass *RegRC = MRI.getRegClass(VirtReg);
@@ -1150,15 +1150,17 @@ static bool HandleDestructivePredicateHint(
CSRs.insert(R);
}
- Hints.append(Order.begin(), Order.end());
+ Hints.insert_range(Order);
auto CanUseReg = [&](Register R) {
return !CSRs.contains(R) || !MRI.def_empty(R) || Matrix->isPhysRegUsed(R);
};
- llvm::stable_sort(Hints, [&](Register A, Register B) {
+ SmallVector<MCPhysReg, 16> SortedHints = Hints.takeVector();
+ llvm::stable_sort(SortedHints, [&](Register A, Register B) {
bool PrefA = (A != Op1Reg) && CanUseReg(A);
bool PrefB = (B != Op1Reg) && CanUseReg(B);
return PrefA && !PrefB;
});
+ Hints.insert_range(SortedHints);
return true;
}
@@ -1184,7 +1186,7 @@ static bool HandleDestructivePredicateHint(
// begins with $z24 (i.e. $z24_z25_z26_z27).
bool AArch64RegisterInfo::getRegAllocationHints(
Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
auto &ST = MF.getSubtarget<AArch64Subtarget>();
const AArch64InstrInfo *TII =
@@ -1219,7 +1221,7 @@ bool AArch64RegisterInfo::getRegAllocationHints(
PhysReg = getSubReg(PhysReg, MO.getSubReg());
if (PhysReg != R)
return false;
- Hints.push_back(R);
+ Hints.insert(R);
return true;
};
@@ -1260,8 +1262,7 @@ bool AArch64RegisterInfo::getRegAllocationHints(
return ConsiderOnlyHints;
if (!ST.hasSME() || !ST.isStreaming())
- return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF,
- VRM);
+ return ConsiderOnlyHints;
// The SVE calling convention preserves registers Z8-Z23. As a result, there
// are no ZPR2Strided or ZPR4Strided registers that do not overlap with the
@@ -1380,7 +1381,7 @@ bool AArch64RegisterInfo::getRegAllocationHints(
!Matrix->isPhysRegUsed(R);
};
if (all_of(seq(0U, TupleSize), IsFreeConsecutiveReg))
- Hints.push_back(Reg);
+ Hints.insert(Reg);
}
} else {
// At least copy already has a physical register assigned to its source.
@@ -1399,12 +1400,11 @@ bool AArch64RegisterInfo::getRegAllocationHints(
for (unsigned I = 0; I < StridedOrder.size(); ++I)
if (getSubReg(StridedOrder[I], AArch64::zsub0) == TargetStartReg)
- Hints.push_back(StridedOrder[I]);
+ Hints.insert(StridedOrder[I]);
}
if (!Hints.empty())
- return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints,
- MF, VRM);
+ return ConsiderOnlyHints;
}
}
@@ -1431,12 +1431,11 @@ bool AArch64RegisterInfo::getRegAllocationHints(
// Try to pick a tuple register for Dst with Src as a member.
for (MCPhysReg R : Order) {
if (getSubReg(R, Dst.getSubReg()) == SrcZPR)
- Hints.push_back(R);
+ Hints.insert(R);
}
}
- return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF,
- VRM);
+ return ConsiderOnlyHints;
}
unsigned AArch64RegisterInfo::getLocalAddressRegister(
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
index 5f6b0a2472b1a..4b577e7206f2f 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
@@ -138,7 +138,7 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
MachineFunction &MF) const override;
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 1aa423e1da647..8e620613aca9d 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -4239,7 +4239,7 @@ const int *SIRegisterInfo::getRegUnitPressureSets(MCRegUnit RegUnit) const {
bool SIRegisterInfo::getRegAllocationHints(Register VirtReg,
ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF,
const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const {
@@ -4266,7 +4266,7 @@ bool SIRegisterInfo::getRegAllocationHints(Register VirtReg,
if (PairedPhys)
// isLo(Paired) is implicitly true here from the API of
// getMatchingSuperReg.
- Hints.push_back(PairedPhys);
+ Hints.insert(PairedPhys);
return false;
}
case AMDGPURI::Size16: {
@@ -4281,7 +4281,7 @@ bool SIRegisterInfo::getRegAllocationHints(Register VirtReg,
// First prefer the paired physreg.
if (PairedPhys)
- Hints.push_back(PairedPhys);
+ Hints.insert(PairedPhys);
else {
// Add all the lo16 physregs.
// When the Paired operand has not yet been assigned a physreg it is
@@ -4293,7 +4293,7 @@ bool SIRegisterInfo::getRegAllocationHints(Register VirtReg,
continue;
if (AMDGPU::VGPR_16RegClass.contains(PhysReg) &&
!MRI.isReserved(PhysReg))
- Hints.push_back(PhysReg);
+ Hints.insert(PhysReg);
}
}
return false;
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index c5a4162fbb01c..72ffc3eaaa5d6 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -375,7 +375,7 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
unsigned Idx) const override;
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 5496729bcb2b3..b21e77be60f9a 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -358,7 +358,7 @@ static MCRegister getPairedGPR(MCRegister Reg, bool Odd,
// Resolve the RegPairEven / RegPairOdd register allocator hints.
bool ARMBaseRegisterInfo::getRegAllocationHints(
Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo &MRI = MF.getRegInfo();
std::pair<unsigned, Register> Hint = MRI.getRegAllocationHint(VirtReg);
@@ -374,7 +374,7 @@ bool ARMBaseRegisterInfo::getRegAllocationHints(
case ARMRI::RegLR:
TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
if (MRI.getRegClass(VirtReg)->contains(ARM::LR))
- Hints.push_back(ARM::LR);
+ Hints.insert(ARM::LR);
return false;
default:
return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM);
@@ -396,7 +396,7 @@ bool ARMBaseRegisterInfo::getRegAllocationHints(
// First prefer the paired physreg.
if (PairedPhys && is_contained(Order, PairedPhys))
- Hints.push_back(PairedPhys);
+ Hints.insert(PairedPhys);
// Then prefer even or odd registers.
for (MCPhysReg Reg : Order) {
@@ -406,7 +406,7 @@ bool ARMBaseRegisterInfo::getRegAllocationHints(
MCRegister Paired = getPairedGPR(Reg, !Odd, this);
if (!Paired || MRI.isReserved(Paired))
continue;
- Hints.push_back(Reg);
+ Hints.insert(Reg);
}
return false;
}
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
index 7a73680e637bc..cea598e302707 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -101,7 +101,7 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
MachineFunction &MF) const override;
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 80f678200f79a..c2908551402c7 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -534,12 +534,10 @@ bool PPCRegisterInfo::isCallerPreservedPhysReg(MCRegister PhysReg,
return false;
}
-bool PPCRegisterInfo::getRegAllocationHints(Register VirtReg,
- ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
- const MachineFunction &MF,
- const VirtRegMap *VRM,
- const LiveRegMatrix *Matrix) const {
+bool PPCRegisterInfo::getRegAllocationHints(
+ Register VirtReg, ArrayRef<MCPhysReg> Order,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
+ const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo *MRI = &MF.getRegInfo();
// Call the base implementation first to set any hints based on the usual
@@ -580,11 +578,11 @@ bool PPCRegisterInfo::getRegAllocationHints(Register VirtReg,
HintReg = getSubReg(UACCPhys, ResultOp->getSubReg());
// Ensure that the hint is a VSRp register.
if (HintReg >= PPC::VSRp0 && HintReg <= PPC::VSRp31)
- Hints.push_back(HintReg);
+ Hints.insert(HintReg);
} else if (RegClass->contains(PPC::ACC0)) {
HintReg = PPC::ACC0 + (UACCPhys - PPC::UACC0);
if (HintReg >= PPC::ACC0 && HintReg <= PPC::ACC7)
- Hints.push_back(HintReg);
+ Hints.insert(HintReg);
}
}
break;
@@ -598,7 +596,7 @@ bool PPCRegisterInfo::getRegAllocationHints(Register VirtReg,
assert((ACCPhys >= PPC::ACC0 && ACCPhys <= PPC::ACC7) &&
"Expecting an ACC register for BUILD_UACC.");
Register HintReg = PPC::UACC0 + (ACCPhys - PPC::ACC0);
- Hints.push_back(HintReg);
+ Hints.insert(HintReg);
}
break;
}
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.h b/llvm/lib/Target/PowerPC/PPCRegisterInfo.h
index 0c5b9d8b94233..ca0a700ac541e 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.h
@@ -106,7 +106,7 @@ class PPCRegisterInfo : public PPCGenRegisterInfo {
// Similarly if UACC5 is assigned, we want to assign VSRp10, VSRp11
// to its inputs.
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index adc6eadee2e35..33738a9661571 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -999,7 +999,7 @@ float RISCVRegisterInfo::getSpillWeightScaleFactor(
// instruction.
bool RISCVRegisterInfo::getRegAllocationHints(
Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo *MRI = &MF.getRegInfo();
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
@@ -1023,7 +1023,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
// Verify it's valid and available
if (RISCV::GPRRegClass.contains(TargetReg) &&
is_contained(Order, TargetReg))
- Hints.push_back(TargetReg.id());
+ Hints.insert(TargetReg.id());
}
// Second priority: Try to find consecutive register pairs in the allocation
@@ -1040,7 +1040,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
// Don't provide hints that are paired to a reserved register.
MCRegister Paired = PhysReg + (IsOdd ? -1 : 1);
if (WantOdd == IsOdd && !MRI->isReserved(Paired))
- Hints.push_back(PhysReg);
+ Hints.insert(PhysReg);
}
}
@@ -1062,7 +1062,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
// physical register is even (or vice versa), we should not add the hint.
if (PhysReg && (!NeedGPRC || RISCV::GPRCRegClass.contains(PhysReg)) &&
!MO.getSubReg() && !VRRegMO.getSubReg()) {
- if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
+ if (!MRI->isReserved(PhysReg) && !Hints.contains(PhysReg))
TwoAddrHints.insert(PhysReg);
}
};
@@ -1190,7 +1190,7 @@ bool RISCVRegisterInfo::getRegAllocationHints(
for (MCPhysReg OrderReg : Order)
if (TwoAddrHints.count(OrderReg))
- Hints.push_back(OrderReg);
+ Hints.insert(OrderReg);
return BaseImplRetVal;
}
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h
index e94f5f0b4b364..a0610f4446a29 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h
@@ -151,7 +151,7 @@ struct RISCVRegisterInfo : public RISCVGenRegisterInfo {
float getSpillWeightScaleFactor(const TargetRegisterClass *RC) const override;
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index 177f2c50e4f01..4cc20bbad6ee5 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -55,7 +55,7 @@ static const TargetRegisterClass *getRC32(MachineOperand &MO,
// registers are copy hints (and therefore already in Hints), hint them
// first.
static void addHints(ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const TargetRegisterClass *RC,
const MachineRegisterInfo *MRI) {
SmallSet<unsigned, 4> CopyHints(llvm::from_range, Hints);
@@ -63,16 +63,16 @@ static void addHints(ArrayRef<MCPhysReg> Order,
for (MCPhysReg Reg : Order)
if (CopyHints.count(Reg) &&
RC->contains(Reg) && !MRI->isReserved(Reg))
- Hints.push_back(Reg);
+ Hints.insert(Reg);
for (MCPhysReg Reg : Order)
if (!CopyHints.count(Reg) &&
RC->contains(Reg) && !MRI->isReserved(Reg))
- Hints.push_back(Reg);
+ Hints.insert(Reg);
}
bool SystemZRegisterInfo::getRegAllocationHints(
Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo *MRI = &MF.getRegInfo();
const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
@@ -114,7 +114,7 @@ bool SystemZRegisterInfo::getRegAllocationHints(
if (VRRegMO->getSubReg())
PhysReg = getMatchingSuperReg(PhysReg, VRRegMO->getSubReg(),
MRI->getRegClass(VirtReg));
- if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
+ if (!MRI->isReserved(PhysReg) && !Hints.contains(PhysReg))
TwoAddrHints.insert(PhysReg);
}
};
@@ -124,7 +124,7 @@ bool SystemZRegisterInfo::getRegAllocationHints(
}
for (MCPhysReg OrderReg : Order)
if (TwoAddrHints.count(OrderReg))
- Hints.push_back(OrderReg);
+ Hints.insert(OrderReg);
}
if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
index 7247736ff44e9..1182c408ac1e8 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
@@ -138,7 +138,7 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 7e1003c9b470b..864e93fd0c1bb 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -1163,12 +1163,10 @@ static ShapeT getTileShape(Register VirtReg, VirtRegMap *VRM,
}
}
-bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
- ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
- const MachineFunction &MF,
- const VirtRegMap *VRM,
- const LiveRegMatrix *Matrix) const {
+bool X86RegisterInfo::getRegAllocationHints(
+ Register VirtReg, ArrayRef<MCPhysReg> Order,
+ SmallSetVector<MCPhysReg, 16> &Hints, const MachineFunction &MF,
+ const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
const MachineRegisterInfo *MRI = &MF.getRegInfo();
const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
@@ -1192,7 +1190,7 @@ bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
auto TryAddNDDHint = [&](const MachineOperand &MO) {
Register Reg = MO.getReg();
Register PhysReg = Reg.isPhysical() ? Reg : Register(VRM->getPhys(Reg));
- if (PhysReg && !MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
+ if (PhysReg && !MRI->isReserved(PhysReg) && !Hints.contains(PhysReg))
TwoAddrHints.insert(PhysReg);
};
@@ -1219,7 +1217,7 @@ bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
for (MCPhysReg OrderReg : Order)
if (TwoAddrHints.count(OrderReg))
- Hints.push_back(OrderReg);
+ Hints.insert(OrderReg);
return BaseImplRetVal;
}
@@ -1228,22 +1226,22 @@ bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
auto AddHint = [&](MCPhysReg PhysReg) {
Register VReg = Matrix->getOneVReg(PhysReg);
if (VReg == MCRegister::NoRegister) { // Not allocated yet
- Hints.push_back(PhysReg);
+ Hints.insert(PhysReg);
return;
}
ShapeT PhysShape = getTileShape(VReg, const_cast<VirtRegMap *>(VRM), MRI);
if (PhysShape == VirtShape)
- Hints.push_back(PhysReg);
+ Hints.insert(PhysReg);
};
- SmallSet<MCPhysReg, 4> CopyHints(llvm::from_range, Hints);
+ SmallSetVector<MCPhysReg, 16> CopyHints(Hints);
Hints.clear();
for (auto Hint : CopyHints) {
if (RC.contains(Hint) && !MRI->isReserved(Hint))
AddHint(Hint);
}
for (MCPhysReg PhysReg : Order) {
- if (!CopyHints.count(PhysReg) && RC.contains(PhysReg) &&
+ if (!CopyHints.contains(PhysReg) && RC.contains(PhysReg) &&
!MRI->isReserved(PhysReg))
AddHint(PhysReg);
}
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h
index 399c6ab863705..5818675cc6829 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.h
+++ b/llvm/lib/Target/X86/X86RegisterInfo.h
@@ -165,7 +165,7 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
unsigned getSlotSize() const { return SlotSize; }
bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
+ SmallSetVector<MCPhysReg, 16> &Hints,
const MachineFunction &MF, const VirtRegMap *VRM,
const LiveRegMatrix *Matrix) const override;
diff --git a/llvm/unittests/Target/AArch64/AArch64RegisterInfoTest.cpp b/llvm/unittests/Target/AArch64/AArch64RegisterInfoTest.cpp
index 0f2cc69be42e5..0ec1554096587 100644
--- a/llvm/unittests/Target/AArch64/AArch64RegisterInfoTest.cpp
+++ b/llvm/unittests/Target/AArch64/AArch64RegisterInfoTest.cpp
@@ -4,6 +4,7 @@
#include "AArch64TargetMachine.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -187,4 +188,49 @@ TEST(AArch64ReservedRegs, ArtificialHIRegistersAreReserved) {
EXPECT_TRUE(Reserved.test(AArch64::Q31_HI));
}
+TEST(AArch64RegAllocationHints, NoDuplicates) {
+ std::unique_ptr<TargetMachine> TM = createTargetMachine("");
+ ASSERT_TRUE(TM);
+
+ std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
+ ASSERT_TRUE(II);
+
+ const AArch64RegisterInfo &TRI = II->getRegisterInfo();
+
+ LLVMContext Context;
+ Module M("", Context);
+ M.setDataLayout(TM->getTargetTriple().computeDataLayout());
+ Function *F = Function::Create(
+ FunctionType::get(Type::getVoidTy(Context), /*isVarArg=*/false),
+ GlobalValue::ExternalLinkage, "f", &M);
+
+ MachineModuleInfo MMI(TM.get());
+ const TargetSubtargetInfo *STI = TM->getSubtargetImpl(*F);
+ MachineFunction MF(*F, *TM, *STI, MMI.getContext(), /*FunctionNum=*/0);
+ MF.initTargetMachineFunctionInfo(*STI);
+
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ MRI.freezeReservedRegs();
+
+ Register VirtReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
+ MRI.addRegAllocationHint(VirtReg, AArch64::X0);
+
+ ArrayRef<MCPhysReg> Order = AArch64::GPR64RegClass.getRegisters();
+ SmallSetVector<MCPhysReg, 16> Hints;
+
+ // Calling getRegAllocationHints once should not produce duplicate hints
+ // from fallthrough to TargetRegisterInfo::getRegAllocationHints.
+ TRI.getRegAllocationHints(VirtReg, Order, Hints, MF, /*VRM=*/nullptr,
+ /*Matrix=*/nullptr);
+ EXPECT_EQ(Hints.size(), 1u);
+ EXPECT_EQ(Hints[0], MCPhysReg(AArch64::X0));
+
+ // Calling getRegAllocationHints a second time with Hints already populated
+ // should not append duplicate hints.
+ TRI.getRegAllocationHints(VirtReg, Order, Hints, MF, /*VRM=*/nullptr,
+ /*Matrix=*/nullptr);
+ EXPECT_EQ(Hints.size(), 1u);
+ EXPECT_EQ(Hints[0], MCPhysReg(AArch64::X0));
+}
+
} // namespace
More information about the llvm-commits
mailing list