Skip to content

Commit 41491c7

Browse files
authored
[CodeGen] Allocate RegAllocHints map lazily (#102186)
This hint map is not required whenever a new register is added, in fact, at -O0, it is not used at all. Growing this map is quite expensive, as SmallVectors are not trivially copyable. Grow this map only when hints are actually added to avoid multiple grows and grows when no hints are added at all.
1 parent 90e1c29 commit 41491c7

File tree

5 files changed

+22
-14
lines changed

5 files changed

+22
-14
lines changed

llvm/include/llvm/CodeGen/MachineRegisterInfo.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,7 @@ class MachineRegisterInfo {
801801
/// of an earlier hint it will be overwritten.
802802
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg) {
803803
assert(VReg.isVirtual());
804+
RegAllocHints.grow(Register::index2VirtReg(getNumVirtRegs()));
804805
RegAllocHints[VReg].first = Type;
805806
RegAllocHints[VReg].second.clear();
806807
RegAllocHints[VReg].second.push_back(PrefReg);
@@ -810,6 +811,7 @@ class MachineRegisterInfo {
810811
/// vector for VReg.
811812
void addRegAllocationHint(Register VReg, Register PrefReg) {
812813
assert(VReg.isVirtual());
814+
RegAllocHints.grow(Register::index2VirtReg(getNumVirtRegs()));
813815
RegAllocHints[VReg].second.push_back(PrefReg);
814816
}
815817

@@ -822,14 +824,17 @@ class MachineRegisterInfo {
822824
void clearSimpleHint(Register VReg) {
823825
assert (!RegAllocHints[VReg].first &&
824826
"Expected to clear a non-target hint!");
825-
RegAllocHints[VReg].second.clear();
827+
if (RegAllocHints.inBounds(VReg))
828+
RegAllocHints[VReg].second.clear();
826829
}
827830

828831
/// getRegAllocationHint - Return the register allocation hint for the
829832
/// specified virtual register. If there are many hints, this returns the
830833
/// one with the greatest weight.
831834
std::pair<unsigned, Register> getRegAllocationHint(Register VReg) const {
832835
assert(VReg.isVirtual());
836+
if (!RegAllocHints.inBounds(VReg))
837+
return {0, Register()};
833838
Register BestHint = (RegAllocHints[VReg.id()].second.size() ?
834839
RegAllocHints[VReg.id()].second[0] : Register());
835840
return {RegAllocHints[VReg.id()].first, BestHint};
@@ -845,10 +850,10 @@ class MachineRegisterInfo {
845850

846851
/// getRegAllocationHints - Return a reference to the vector of all
847852
/// register allocation hints for VReg.
848-
const std::pair<unsigned, SmallVector<Register, 4>> &
853+
const std::pair<unsigned, SmallVector<Register, 4>> *
849854
getRegAllocationHints(Register VReg) const {
850855
assert(VReg.isVirtual());
851-
return RegAllocHints[VReg];
856+
return RegAllocHints.inBounds(VReg) ? &RegAllocHints[VReg] : nullptr;
852857
}
853858

854859
/// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the

llvm/lib/CodeGen/MachineRegisterInfo.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
4747
: MF->getSubtarget().enableSubRegLiveness()) {
4848
unsigned NumRegs = getTargetRegisterInfo()->getNumRegs();
4949
VRegInfo.reserve(256);
50-
RegAllocHints.reserve(256);
5150
UsedPhysRegMask.resize(NumRegs);
5251
PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]());
5352
TheDelegates.clear();
@@ -147,7 +146,6 @@ MachineRegisterInfo::recomputeRegClass(Register Reg) {
147146
Register MachineRegisterInfo::createIncompleteVirtualRegister(StringRef Name) {
148147
Register Reg = Register::index2VirtReg(getNumVirtRegs());
149148
VRegInfo.grow(Reg);
150-
RegAllocHints.grow(Reg);
151149
insertVRegByName(Name, Reg);
152150
return Reg;
153151
}

llvm/lib/CodeGen/TargetRegisterInfo.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,16 @@ bool TargetRegisterInfo::getRegAllocationHints(
421421
SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,
422422
const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {
423423
const MachineRegisterInfo &MRI = MF.getRegInfo();
424-
const std::pair<unsigned, SmallVector<Register, 4>> &Hints_MRI =
424+
const std::pair<unsigned, SmallVector<Register, 4>> *Hints_MRI =
425425
MRI.getRegAllocationHints(VirtReg);
426426

427+
if (!Hints_MRI)
428+
return false;
429+
427430
SmallSet<Register, 32> HintedRegs;
428431
// First hint may be a target hint.
429-
bool Skip = (Hints_MRI.first != 0);
430-
for (auto Reg : Hints_MRI.second) {
432+
bool Skip = (Hints_MRI->first != 0);
433+
for (auto Reg : Hints_MRI->second) {
431434
if (Skip) {
432435
Skip = false;
433436
continue;

llvm/tools/llvm-reduce/ReducerWorkItem.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,10 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
306306
DstMRI->setType(NewReg, RegTy);
307307

308308
// Copy register allocation hints.
309-
const auto &Hints = SrcMRI->getRegAllocationHints(Reg);
310-
for (Register PrefReg : Hints.second)
311-
DstMRI->addRegAllocationHint(NewReg, PrefReg);
309+
const auto *Hints = SrcMRI->getRegAllocationHints(Reg);
310+
if (Hints)
311+
for (Register PrefReg : Hints->second)
312+
DstMRI->addRegAllocationHint(NewReg, PrefReg);
312313
}
313314

314315
const TargetSubtargetInfo &STI = DstMF->getSubtarget();
@@ -530,7 +531,8 @@ static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) {
530531
const MachineRegisterInfo &MRI = MF.getRegInfo();
531532
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
532533
Register Reg = Register::index2VirtReg(I);
533-
Score += MRI.getRegAllocationHints(Reg).second.size();
534+
if (const auto *Hints = MRI.getRegAllocationHints(Reg))
535+
Score += Hints->second.size();
534536
}
535537

536538
for (const MachineBasicBlock &MBB : MF) {

llvm/tools/llvm-reduce/deltas/ReduceVirtualRegisters.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ static void dropRegisterHintsFromFunction(Oracle &O, MachineFunction &MF) {
2323
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
2424
Register Reg = Register::index2VirtReg(I);
2525

26-
const std::pair<unsigned, SmallVector<Register, 4>> &Hints =
26+
const std::pair<unsigned, SmallVector<Register, 4>> *Hints =
2727
MRI.getRegAllocationHints(Reg);
28-
if (Hints.second.empty())
28+
if (!Hints || Hints->second.empty())
2929
continue;
3030

3131
if (!O.shouldKeep())

0 commit comments

Comments
 (0)