Newer
Older
Lang Hames
committed
DEBUG(dbgs() << "VREG " << vreg << " -> SPILLED (Cost: "
<< oldWeight << ", New vregs: ");
// Copy any newly inserted live intervals into the list of regs to
// allocate.
for (std::vector<LiveInterval*>::const_iterator
itr = newSpills.begin(), end = newSpills.end();
itr != end; ++itr) {
assert(!(*itr)->empty() && "Empty spill range.");
DEBUG(dbgs() << (*itr)->reg << " ");
vregsToAlloc.insert((*itr)->reg);
Lang Hames
committed
}
// We need another round if spill intervals were added.
anotherRoundNeeded |= !newSpills.empty();
Lang Hames
committed
} else {
assert(false && "Unknown allocation option.");
}
}
return !anotherRoundNeeded;
}
Lang Hames
committed
void RegAllocPBQP::finalizeAlloc() const {
Lang Hames
committed
typedef LiveIntervals::iterator LIIterator;
typedef LiveInterval::Ranges::const_iterator LRIterator;
// First allocate registers for the empty intervals.
Lang Hames
committed
for (RegSet::const_iterator
itr = emptyIntervalVRegs.begin(), end = emptyIntervalVRegs.end();
Lang Hames
committed
itr != end; ++itr) {
Lang Hames
committed
LiveInterval *li = &lis->getInterval(*itr);
Lang Hames
committed
unsigned physReg = vrm->getRegAllocPref(li->reg);
Lang Hames
committed
Lang Hames
committed
if (physReg == 0) {
const TargetRegisterClass *liRC = mri->getRegClass(li->reg);
Lang Hames
committed
}
Lang Hames
committed
}
Lang Hames
committed
// Finally iterate over the basic blocks to compute and set the live-in sets.
SmallVector<MachineBasicBlock*, 8> liveInMBBs;
MachineBasicBlock *entryMBB = &*mf->begin();
for (LIIterator liItr = lis->begin(), liEnd = lis->end();
liItr != liEnd; ++liItr) {
const LiveInterval *li = liItr->second;
unsigned reg = 0;
Lang Hames
committed
// Get the physical register for this interval
if (TargetRegisterInfo::isPhysicalRegister(li->reg)) {
reg = li->reg;
}
else if (vrm->isAssignedReg(li->reg)) {
reg = vrm->getPhys(li->reg);
}
else {
// Ranges which are assigned a stack slot only are ignored.
continue;
}
if (reg == 0) {
Lang Hames
committed
// Filter out zero regs - they're for intervals that were spilled.
continue;
}
Lang Hames
committed
// Iterate over the ranges of the current interval...
for (LRIterator lrItr = li->begin(), lrEnd = li->end();
lrItr != lrEnd; ++lrItr) {
Lang Hames
committed
// Find the set of basic blocks which this range is live into...
if (lis->findLiveInMBBs(lrItr->start, lrItr->end, liveInMBBs)) {
// And add the physreg for this interval to their live-in sets.
for (unsigned i = 0; i < liveInMBBs.size(); ++i) {
if (liveInMBBs[i] != entryMBB) {
if (!liveInMBBs[i]->isLiveIn(reg)) {
liveInMBBs[i]->addLiveIn(reg);
}
}
}
liveInMBBs.clear();
}
}
}
Lang Hames
committed
}
Lang Hames
committed
bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
Lang Hames
committed
mf = &MF;
tm = &mf->getTarget();
tri = tm->getRegisterInfo();
Lang Hames
committed
tii = tm->getInstrInfo();
Lang Hames
committed
lis = &getAnalysis<LiveIntervals>();
lss = &getAnalysis<LiveStacks>();
loopInfo = &getAnalysis<MachineLoopInfo>();
rmf = &getAnalysis<RenderMachineFunction>();
vrm = &getAnalysis<VirtRegMap>();
DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n");
Lang Hames
committed
// Allocator main loop:
// * Map current regalloc problem to a PBQP problem
// * Solve the PBQP problem
// * Map the solution back to a register allocation
// * Spill if necessary
// This process is continued till no more spills are generated.
Lang Hames
committed
// Find the vreg intervals in need of allocation.
findVRegIntervalsToAlloc();
Lang Hames
committed
// If there are non-empty intervals allocate them using pbqp.
Lang Hames
committed
if (!vregsToAlloc.empty()) {
Lang Hames
committed
bool pbqpAllocComplete = false;
unsigned round = 0;
Lang Hames
committed
if (!pbqpBuilder) {
while (!pbqpAllocComplete) {
DEBUG(dbgs() << " PBQP Regalloc round " << round << ":\n");
Lang Hames
committed
Lang Hames
committed
PBQP::Graph problem = constructPBQPProblem();
PBQP::Solution solution =
PBQP::HeuristicSolver<PBQP::Heuristics::Briggs>::solve(problem);
Lang Hames
committed
pbqpAllocComplete = mapPBQPToRegAlloc(solution);
Lang Hames
committed
++round;
}
} else {
while (!pbqpAllocComplete) {
DEBUG(dbgs() << " PBQP Regalloc round " << round << ":\n");
std::auto_ptr<PBQPRAProblem> problem =
builder->build(mf, lis, loopInfo, vregsToAlloc);
Lang Hames
committed
PBQP::Solution solution =
PBQP::HeuristicSolver<PBQP::Heuristics::Briggs>::solve(
problem->getGraph());
Lang Hames
committed
pbqpAllocComplete = mapPBQPToRegAlloc2(*problem, solution);
++round;
}
Lang Hames
committed
}
}
Lang Hames
committed
// Finalise allocation, allocate empty ranges.
finalizeAlloc();
rmf->renderMachineFunction("After PBQP register allocation.", vrm);
Lang Hames
committed
vregsToAlloc.clear();
emptyIntervalVRegs.clear();
Lang Hames
committed
li2Node.clear();
node2LI.clear();
allowedSets.clear();
DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *vrm << "\n");
Lang Hames
committed
// Run rewriter
std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter());
rewriter->runOnMachineFunction(*mf, *vrm, lis);
Lang Hames
committed
}
Lang Hames
committed
FunctionPass* createPBQPRegisterAllocator() {
if (pbqpCoalescing) {
return new RegAllocPBQP(
std::auto_ptr<PBQPBuilder>(new PBQPBuilderWithCoalescing()));
} // else
return new RegAllocPBQP(
std::auto_ptr<PBQPBuilder>(new PBQPBuilder()));
}
Lang Hames
committed
}
#undef DEBUG_TYPE