Switch PBQP to the modern InlineSpiller framework.

It is worth noting that the old spiller would split live ranges around
basic blocks. The new spiller doesn't do that.

PBQP should do its own live range splitting with
SplitEditor::splitSingleBlock() if desired.  See
RAGreedy::tryBlockSplit().

llvm-svn: 144476
This commit is contained in:
Jakob Stoklund Olesen 2011-11-12 23:17:52 +00:00
parent e7e50e6f45
commit 11bb63a756
1 changed files with 10 additions and 39 deletions

View File

@ -31,7 +31,9 @@
#define DEBUG_TYPE "regalloc" #define DEBUG_TYPE "regalloc"
#include "LiveRangeEdit.h"
#include "RenderMachineFunction.h" #include "RenderMachineFunction.h"
#include "Spiller.h"
#include "Splitter.h" #include "Splitter.h"
#include "VirtRegMap.h" #include "VirtRegMap.h"
#include "VirtRegRewriter.h" #include "VirtRegRewriter.h"
@ -132,6 +134,7 @@ private:
MachineRegisterInfo *mri; MachineRegisterInfo *mri;
RenderMachineFunction *rmf; RenderMachineFunction *rmf;
std::auto_ptr<Spiller> spiller;
LiveIntervals *lis; LiveIntervals *lis;
LiveStacks *lss; LiveStacks *lss;
VirtRegMap *vrm; VirtRegMap *vrm;
@ -141,10 +144,6 @@ private:
/// \brief Finds the initial set of vreg intervals to allocate. /// \brief Finds the initial set of vreg intervals to allocate.
void findVRegIntervalsToAlloc(); void findVRegIntervalsToAlloc();
/// \brief Adds a stack interval if the given live interval has been
/// spilled. Used to support stack slot coloring.
void addStackInterval(const LiveInterval *spilled,MachineRegisterInfo* mri);
/// \brief Given a solved PBQP problem maps this solution back to a register /// \brief Given a solved PBQP problem maps this solution back to a register
/// assignment. /// assignment.
bool mapPBQPToRegAlloc(const PBQPRAProblem &problem, bool mapPBQPToRegAlloc(const PBQPRAProblem &problem,
@ -488,29 +487,6 @@ void RegAllocPBQP::findVRegIntervalsToAlloc() {
} }
} }
void RegAllocPBQP::addStackInterval(const LiveInterval *spilled,
MachineRegisterInfo* mri) {
int stackSlot = vrm->getStackSlot(spilled->reg);
if (stackSlot == VirtRegMap::NO_STACK_SLOT) {
return;
}
const TargetRegisterClass *RC = mri->getRegClass(spilled->reg);
LiveInterval &stackInterval = lss->getOrCreateInterval(stackSlot, RC);
VNInfo *vni;
if (stackInterval.getNumValNums() != 0) {
vni = stackInterval.getValNumInfo(0);
} else {
vni = stackInterval.getNextValue(
SlotIndex(), 0, lss->getVNInfoAllocator());
}
LiveInterval &rhsInterval = lis->getInterval(spilled->reg);
stackInterval.MergeRangesInAsValue(rhsInterval, vni);
}
bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem, bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,
const PBQP::Solution &solution) { const PBQP::Solution &solution) {
// Set to true if we have any spills // Set to true if we have any spills
@ -535,22 +511,16 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,
vrm->assignVirt2Phys(vreg, preg); vrm->assignVirt2Phys(vreg, preg);
} else if (problem.isSpillOption(vreg, alloc)) { } else if (problem.isSpillOption(vreg, alloc)) {
vregsToAlloc.erase(vreg); vregsToAlloc.erase(vreg);
const LiveInterval* spillInterval = &lis->getInterval(vreg); SmallVector<LiveInterval*, 8> newSpills;
double oldWeight = spillInterval->weight; LiveRangeEdit LRE(lis->getInterval(vreg), newSpills);
rmf->rememberUseDefs(spillInterval); spiller->spill(LRE);
std::vector<LiveInterval*> newSpills =
lis->addIntervalsForSpills(*spillInterval, 0, loopInfo, *vrm);
addStackInterval(spillInterval, mri);
rmf->rememberSpills(spillInterval, newSpills);
(void) oldWeight;
DEBUG(dbgs() << "VREG " << vreg << " -> SPILLED (Cost: " DEBUG(dbgs() << "VREG " << vreg << " -> SPILLED (Cost: "
<< oldWeight << ", New vregs: "); << LRE.getParent().weight << ", New vregs: ");
// Copy any newly inserted live intervals into the list of regs to // Copy any newly inserted live intervals into the list of regs to
// allocate. // allocate.
for (std::vector<LiveInterval*>::const_iterator for (LiveRangeEdit::iterator itr = LRE.begin(), end = LRE.end();
itr = newSpills.begin(), end = newSpills.end();
itr != end; ++itr) { itr != end; ++itr) {
assert(!(*itr)->empty() && "Empty spill range."); assert(!(*itr)->empty() && "Empty spill range.");
DEBUG(dbgs() << (*itr)->reg << " "); DEBUG(dbgs() << (*itr)->reg << " ");
@ -560,7 +530,7 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,
DEBUG(dbgs() << ")\n"); DEBUG(dbgs() << ")\n");
// We need another round if spill intervals were added. // We need another round if spill intervals were added.
anotherRoundNeeded |= !newSpills.empty(); anotherRoundNeeded |= !LRE.empty();
} else { } else {
assert(false && "Unknown allocation option."); assert(false && "Unknown allocation option.");
} }
@ -650,6 +620,7 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
rmf = &getAnalysis<RenderMachineFunction>(); rmf = &getAnalysis<RenderMachineFunction>();
vrm = &getAnalysis<VirtRegMap>(); vrm = &getAnalysis<VirtRegMap>();
spiller.reset(createInlineSpiller(*this, MF, *vrm));
DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n"); DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n");