aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocBasic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/RegAllocBasic.cpp')
-rw-r--r--lib/CodeGen/RegAllocBasic.cpp63
1 files changed, 17 insertions, 46 deletions
diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp
index d0e6355129..88446aa505 100644
--- a/lib/CodeGen/RegAllocBasic.cpp
+++ b/lib/CodeGen/RegAllocBasic.cpp
@@ -43,8 +43,6 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include <vector>
-#include <queue>
#include <cstdlib>
using namespace llvm;
@@ -103,6 +101,8 @@ public:
virtual Spiller &spiller() { return *SpillerInstance; }
+ virtual float getPriority(LiveInterval *LI) { return LI->weight; }
+
virtual unsigned selectOrSplit(LiveInterval &VirtReg,
SmallVectorImpl<LiveInterval*> &SplitVRegs);
@@ -230,49 +230,18 @@ void RegAllocBase::releaseMemory() {
PhysReg2LiveUnion.clear();
}
-namespace llvm {
-/// This class defines a queue of live virtual registers prioritized by spill
-/// weight. The heaviest vreg is popped first.
-///
-/// Currently, this is trivial wrapper that gives us an opaque type in the
-/// header, but we may later give it a virtual interface for register allocators
-/// to override the priority queue comparator.
-class LiveVirtRegQueue {
- typedef std::priority_queue
- <LiveInterval*, std::vector<LiveInterval*>, LessSpillWeightPriority>
- PriorityQ;
- PriorityQ PQ;
-
-public:
- // Is the queue empty?
- bool empty() { return PQ.empty(); }
-
- // Get the highest priority lvr (top + pop)
- LiveInterval *get() {
- LiveInterval *VirtReg = PQ.top();
- PQ.pop();
- return VirtReg;
- }
- // Add this lvr to the queue
- void push(LiveInterval *VirtReg) {
- PQ.push(VirtReg);
- }
-};
-} // end namespace llvm
-
// Visit all the live virtual registers. If they are already assigned to a
// physical register, unify them with the corresponding LiveIntervalUnion,
// otherwise push them on the priority queue for later assignment.
-void RegAllocBase::seedLiveVirtRegs(LiveVirtRegQueue &VirtRegQ) {
+void RegAllocBase::
+seedLiveVirtRegs(std::priority_queue<std::pair<float, unsigned> > &VirtRegQ) {
for (LiveIntervals::iterator I = LIS->begin(), E = LIS->end(); I != E; ++I) {
unsigned RegNum = I->first;
LiveInterval &VirtReg = *I->second;
- if (TargetRegisterInfo::isPhysicalRegister(RegNum)) {
+ if (TargetRegisterInfo::isPhysicalRegister(RegNum))
PhysReg2LiveUnion[RegNum].unify(VirtReg);
- }
- else {
- VirtRegQ.push(&VirtReg);
- }
+ else
+ VirtRegQ.push(std::make_pair(getPriority(&VirtReg), RegNum));
}
}
@@ -281,27 +250,28 @@ void RegAllocBase::seedLiveVirtRegs(LiveVirtRegQueue &VirtRegQ) {
void RegAllocBase::allocatePhysRegs() {
// Push each vreg onto a queue or "precolor" by adding it to a physreg union.
- LiveVirtRegQueue VirtRegQ;
+ std::priority_queue<std::pair<float, unsigned> > VirtRegQ;
seedLiveVirtRegs(VirtRegQ);
// Continue assigning vregs one at a time to available physical registers.
while (!VirtRegQ.empty()) {
// Pop the highest priority vreg.
- LiveInterval *VirtReg = VirtRegQ.get();
+ LiveInterval &VirtReg = LIS->getInterval(VirtRegQ.top().second);
+ VirtRegQ.pop();
// selectOrSplit requests the allocator to return an available physical
// register if possible and populate a list of new live intervals that
// result from splitting.
typedef SmallVector<LiveInterval*, 4> VirtRegVec;
VirtRegVec SplitVRegs;
- unsigned AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);
+ unsigned AvailablePhysReg = selectOrSplit(VirtReg, SplitVRegs);
if (AvailablePhysReg) {
DEBUG(dbgs() << "allocating: " << TRI->getName(AvailablePhysReg) <<
- " " << *VirtReg << '\n');
- assert(!VRM->hasPhys(VirtReg->reg) && "duplicate vreg in union");
- VRM->assignVirt2Phys(VirtReg->reg, AvailablePhysReg);
- PhysReg2LiveUnion[AvailablePhysReg].unify(*VirtReg);
+ " " << VirtReg << '\n');
+ assert(!VRM->hasPhys(VirtReg.reg) && "duplicate vreg in union");
+ VRM->assignVirt2Phys(VirtReg.reg, AvailablePhysReg);
+ PhysReg2LiveUnion[AvailablePhysReg].unify(VirtReg);
}
for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
I != E; ++I) {
@@ -310,7 +280,8 @@ void RegAllocBase::allocatePhysRegs() {
DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
"expect split value in virtual register");
- VirtRegQ.push(SplitVirtReg);
+ VirtRegQ.push(std::make_pair(getPriority(SplitVirtReg),
+ SplitVirtReg->reg));
}
}
}