aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegAllocPBQP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocPBQP.cpp')
-rw-r--r--llvm/lib/CodeGen/RegAllocPBQP.cpp117
1 files changed, 62 insertions, 55 deletions
diff --git a/llvm/lib/CodeGen/RegAllocPBQP.cpp b/llvm/lib/CodeGen/RegAllocPBQP.cpp
index 7590dbf1b977..7c5af1a0c56e 100644
--- a/llvm/lib/CodeGen/RegAllocPBQP.cpp
+++ b/llvm/lib/CodeGen/RegAllocPBQP.cpp
@@ -140,14 +140,13 @@ public:
MachineFunctionProperties::Property::NoPHIs);
}
+ MachineFunctionProperties getClearedProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
private:
- using LI2NodeMap = std::map<const LiveInterval *, unsigned>;
- using Node2LIMap = std::vector<const LiveInterval *>;
- using AllowedSet = std::vector<unsigned>;
- using AllowedSetMap = std::vector<AllowedSet>;
- using RegPair = std::pair<unsigned, unsigned>;
- using CoalesceMap = std::map<RegPair, PBQP::PBQPNum>;
- using RegSet = std::set<unsigned>;
+ using RegSet = std::set<Register>;
char *customPassID;
@@ -199,7 +198,7 @@ public:
for (auto NId : G.nodeIds()) {
PBQP::PBQPNum SpillCost =
- LIS.getInterval(G.getNodeMetadata(NId).getVReg()).weight;
+ LIS.getInterval(G.getNodeMetadata(NId).getVReg()).weight();
if (SpillCost == 0.0)
SpillCost = std::numeric_limits<PBQP::PBQPNum>::min();
else
@@ -231,9 +230,9 @@ private:
return false;
if (NRegs < MRegs)
- return D.count(IKey(NRegs, MRegs)) > 0;
+ return D.contains(IKey(NRegs, MRegs));
- return D.count(IKey(MRegs, NRegs)) > 0;
+ return D.contains(IKey(MRegs, NRegs));
}
void setDisjointAllowedRegs(const PBQPRAGraph &G, PBQPRAGraph::NodeId NId,
@@ -290,7 +289,7 @@ private:
// If two intervals end at the same point, we need a way to break the tie or
// the set will assume they're actually equal and refuse to insert a
// "duplicate". Just compare the vregs - fast and guaranteed unique.
- return std::get<0>(I1)->reg < std::get<0>(I2)->reg;
+ return std::get<0>(I1)->reg() < std::get<0>(I2)->reg();
}
static bool isAtLastSegment(const IntervalInfo &I) {
@@ -331,7 +330,7 @@ public:
// Start by building the inactive set.
for (auto NId : G.nodeIds()) {
- unsigned VReg = G.getNodeMetadata(NId).getVReg();
+ Register VReg = G.getNodeMetadata(NId).getVReg();
LiveInterval &LI = LIS.getInterval(VReg);
assert(!LI.empty() && "PBQP graph contains node for empty interval");
Inactive.push(std::make_tuple(&LI, 0, NId));
@@ -413,9 +412,9 @@ private:
PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0);
bool NodesInterfere = false;
for (unsigned I = 0; I != NRegs.size(); ++I) {
- unsigned PRegN = NRegs[I];
+ MCRegister PRegN = NRegs[I];
for (unsigned J = 0; J != MRegs.size(); ++J) {
- unsigned PRegM = MRegs[J];
+ MCRegister PRegM = MRegs[J];
if (TRI.regsOverlap(PRegN, PRegM)) {
M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
NodesInterfere = true;
@@ -448,11 +447,10 @@ public:
if (!CP.setRegisters(&MI) || CP.getSrcReg() == CP.getDstReg())
continue;
- unsigned DstReg = CP.getDstReg();
- unsigned SrcReg = CP.getSrcReg();
+ Register DstReg = CP.getDstReg();
+ Register SrcReg = CP.getSrcReg();
- const float Scale = 1.0f / MBFI.getEntryFreq();
- PBQP::PBQPNum CBenefit = MBFI.getBlockFreq(&MBB).getFrequency() * Scale;
+ PBQP::PBQPNum CBenefit = MBFI.getBlockFreqRelativeToEntryBlock(&MBB);
if (CP.isPhys()) {
if (!MF.getRegInfo().isAllocatable(DstReg))
@@ -464,7 +462,7 @@ public:
G.getNodeMetadata(NId).getAllowedRegs();
unsigned PRegOpt = 0;
- while (PRegOpt < Allowed.size() && Allowed[PRegOpt] != DstReg)
+ while (PRegOpt < Allowed.size() && Allowed[PRegOpt].id() != DstReg)
++PRegOpt;
if (PRegOpt < Allowed.size()) {
@@ -509,9 +507,9 @@ private:
assert(CostMat.getRows() == Allowed1.size() + 1 && "Size mismatch.");
assert(CostMat.getCols() == Allowed2.size() + 1 && "Size mismatch.");
for (unsigned I = 0; I != Allowed1.size(); ++I) {
- unsigned PReg1 = Allowed1[I];
+ MCRegister PReg1 = Allowed1[I];
for (unsigned J = 0; J != Allowed2.size(); ++J) {
- unsigned PReg2 = Allowed2[J];
+ MCRegister PReg2 = Allowed2[J];
if (PReg1 == PReg2)
CostMat[I + 1][J + 1] -= Benefit;
}
@@ -519,6 +517,20 @@ private:
}
};
+/// PBQP-specific implementation of weight normalization.
+class PBQPVirtRegAuxInfo final : public VirtRegAuxInfo {
+ float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr) override {
+ // All intervals have a spill weight that is mostly proportional to the
+ // number of uses, with uses in loops having a bigger weight.
+ return NumInstr * VirtRegAuxInfo::normalize(UseDefFreq, Size, 1);
+ }
+
+public:
+ PBQPVirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,
+ const MachineLoopInfo &Loops,
+ const MachineBlockFrequencyInfo &MBFI)
+ : VirtRegAuxInfo(MF, LIS, VRM, Loops, MBFI) {}
+};
} // end anonymous namespace
// Out-of-line destructor/anchor for PBQPRAConstraint.
@@ -558,18 +570,19 @@ void RegAllocPBQP::findVRegIntervalsToAlloc(const MachineFunction &MF,
// Iterate over all live ranges.
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- unsigned Reg = Register::index2VirtReg(I);
+ Register Reg = Register::index2VirtReg(I);
if (MRI.reg_nodbg_empty(Reg))
continue;
VRegsToAlloc.insert(Reg);
}
}
-static bool isACalleeSavedRegister(unsigned reg, const TargetRegisterInfo &TRI,
+static bool isACalleeSavedRegister(MCRegister Reg,
+ const TargetRegisterInfo &TRI,
const MachineFunction &MF) {
const MCPhysReg *CSR = MF.getRegInfo().getCalleeSavedRegs();
for (unsigned i = 0; CSR[i] != 0; ++i)
- if (TRI.regsOverlap(reg, CSR[i]))
+ if (TRI.regsOverlap(Reg, CSR[i]))
return true;
return false;
}
@@ -583,12 +596,12 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
const TargetRegisterInfo &TRI =
*G.getMetadata().MF.getSubtarget().getRegisterInfo();
- std::vector<unsigned> Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end());
+ std::vector<Register> Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end());
- std::map<unsigned, std::vector<unsigned>> VRegAllowedMap;
+ std::map<Register, std::vector<MCRegister>> VRegAllowedMap;
while (!Worklist.empty()) {
- unsigned VReg = Worklist.back();
+ Register VReg = Worklist.back();
Worklist.pop_back();
LiveInterval &VRegLI = LIS.getInterval(VReg);
@@ -596,8 +609,8 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
// If this is an empty interval move it to the EmptyIntervalVRegs set then
// continue.
if (VRegLI.empty()) {
- EmptyIntervalVRegs.insert(VRegLI.reg);
- VRegsToAlloc.erase(VRegLI.reg);
+ EmptyIntervalVRegs.insert(VRegLI.reg());
+ VRegsToAlloc.erase(VRegLI.reg());
continue;
}
@@ -608,10 +621,10 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
LIS.checkRegMaskInterference(VRegLI, RegMaskOverlaps);
// Compute an initial allowed set for the current vreg.
- std::vector<unsigned> VRegAllowed;
+ std::vector<MCRegister> VRegAllowed;
ArrayRef<MCPhysReg> RawPRegOrder = TRC->getRawAllocationOrder(MF);
for (unsigned I = 0; I != RawPRegOrder.size(); ++I) {
- unsigned PReg = RawPRegOrder[I];
+ MCRegister PReg(RawPRegOrder[I]);
if (MRI.isReserved(PReg))
continue;
@@ -639,10 +652,11 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G, VirtRegMap &VRM,
if (VRegAllowed.empty()) {
SmallVector<Register, 8> NewVRegs;
spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);
- Worklist.insert(Worklist.end(), NewVRegs.begin(), NewVRegs.end());
+ llvm::append_range(Worklist, NewVRegs);
continue;
- } else
- VRegAllowedMap[VReg] = std::move(VRegAllowed);
+ }
+
+ VRegAllowedMap[VReg.id()] = std::move(VRegAllowed);
}
for (auto &KV : VRegAllowedMap) {
@@ -685,7 +699,7 @@ void RegAllocPBQP::spillVReg(Register VReg,
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
(void)TRI;
LLVM_DEBUG(dbgs() << "VREG " << printReg(VReg, &TRI) << " -> SPILLED (Cost: "
- << LRE.getParent().weight << ", New vregs: ");
+ << LRE.getParent().weight() << ", New vregs: ");
// Copy any newly inserted live intervals into the list of regs to
// allocate.
@@ -693,8 +707,8 @@ void RegAllocPBQP::spillVReg(Register VReg,
I != E; ++I) {
const LiveInterval &LI = LIS.getInterval(*I);
assert(!LI.empty() && "Empty spill range.");
- LLVM_DEBUG(dbgs() << printReg(LI.reg, &TRI) << " ");
- VRegsToAlloc.insert(LI.reg);
+ LLVM_DEBUG(dbgs() << printReg(LI.reg(), &TRI) << " ");
+ VRegsToAlloc.insert(LI.reg());
}
LLVM_DEBUG(dbgs() << ")\n");
@@ -718,11 +732,11 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
// Iterate over the nodes mapping the PBQP solution to a register
// assignment.
for (auto NId : G.nodeIds()) {
- unsigned VReg = G.getNodeMetadata(NId).getVReg();
- unsigned AllocOption = Solution.getSelection(NId);
+ Register VReg = G.getNodeMetadata(NId).getVReg();
+ unsigned AllocOpt = Solution.getSelection(NId);
- if (AllocOption != PBQP::RegAlloc::getSpillOptionIdx()) {
- unsigned PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOption - 1];
+ if (AllocOpt != PBQP::RegAlloc::getSpillOptionIdx()) {
+ MCRegister PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOpt - 1];
LLVM_DEBUG(dbgs() << "VREG " << printReg(VReg, &TRI) << " -> "
<< TRI.getName(PReg) << "\n");
assert(PReg != 0 && "Invalid preg selected.");
@@ -750,12 +764,12 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
I != E; ++I) {
LiveInterval &LI = LIS.getInterval(*I);
- unsigned PReg = MRI.getSimpleHint(LI.reg);
+ Register PReg = MRI.getSimpleHint(LI.reg());
if (PReg == 0) {
- const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg);
+ const TargetRegisterClass &RC = *MRI.getRegClass(LI.reg());
const ArrayRef<MCPhysReg> RawPRegOrder = RC.getRawAllocationOrder(MF);
- for (unsigned CandidateReg : RawPRegOrder) {
+ for (MCRegister CandidateReg : RawPRegOrder) {
if (!VRM.getRegInfo().isReserved(CandidateReg)) {
PReg = CandidateReg;
break;
@@ -765,7 +779,7 @@ void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
"No un-reserved physical registers in this register class");
}
- VRM.assignVirt2Phys(LI.reg, PReg);
+ VRM.assignVirt2Phys(LI.reg(), PReg);
}
}
@@ -779,13 +793,6 @@ void RegAllocPBQP::postOptimization(Spiller &VRegSpiller, LiveIntervals &LIS) {
DeadRemats.clear();
}
-static inline float normalizePBQPSpillWeight(float UseDefFreq, unsigned Size,
- unsigned NumInstr) {
- // All intervals have a spill weight that is mostly proportional to the number
- // of uses, with uses in loops having a bigger weight.
- return NumInstr * normalizeSpillWeight(UseDefFreq, Size, 1);
-}
-
bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
LiveIntervals &LIS = getAnalysis<LiveIntervals>();
MachineBlockFrequencyInfo &MBFI =
@@ -793,8 +800,8 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
VirtRegMap &VRM = getAnalysis<VirtRegMap>();
- calculateSpillWeightsAndHints(LIS, MF, &VRM, getAnalysis<MachineLoopInfo>(),
- MBFI, normalizePBQPSpillWeight);
+ PBQPVirtRegAuxInfo VRAI(MF, LIS, VRM, getAnalysis<MachineLoopInfo>(), MBFI);
+ VRAI.calculateSpillWeightsAndHints();
std::unique_ptr<Spiller> VRegSpiller(createInlineSpiller(*this, MF, VRM));
@@ -878,7 +885,7 @@ static Printable PrintNodeInfo(PBQP::RegAlloc::PBQPRAGraph::NodeId NId,
return Printable([NId, &G](raw_ostream &OS) {
const MachineRegisterInfo &MRI = G.getMetadata().MF.getRegInfo();
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
- unsigned VReg = G.getNodeMetadata(NId).getVReg();
+ Register VReg = G.getNodeMetadata(NId).getVReg();
const char *RegClassName = TRI->getRegClassName(MRI.getRegClass(VReg));
OS << NId << " (" << RegClassName << ':' << printReg(VReg, TRI) << ')';
});