aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocBasic.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-05-02 19:34:44 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-05-02 19:34:44 +0000
commit6b943ff3a3f8617113ecbf611cf0f8957e4e19d2 (patch)
treefc5f365fb9035b2d0c622bbf06c9bbe8627d7279 /lib/CodeGen/RegAllocBasic.cpp
parentd0e4e96dc17a6c1c6de3340842c80f0e187ba349 (diff)
downloadsrc-6b943ff3a3f8617113ecbf611cf0f8957e4e19d2.tar.gz
src-6b943ff3a3f8617113ecbf611cf0f8957e4e19d2.zip
Vendor import of llvm trunk r130700:vendor/llvm/llvm-r130700
Notes
Notes: svn path=/vendor/llvm/dist/; revision=221337 svn path=/vendor/llvm/llvm-r130700/; revision=221338; tag=vendor/llvm/llvm-r130700
Diffstat (limited to 'lib/CodeGen/RegAllocBasic.cpp')
-rw-r--r--lib/CodeGen/RegAllocBasic.cpp89
1 files changed, 61 insertions, 28 deletions
diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp
index 6923908a32d9..d92d80f181fc 100644
--- a/lib/CodeGen/RegAllocBasic.cpp
+++ b/lib/CodeGen/RegAllocBasic.cpp
@@ -13,7 +13,9 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "regalloc"
+#include "LiveDebugVariables.h"
#include "LiveIntervalUnion.h"
+#include "LiveRangeEdit.h"
#include "RegAllocBase.h"
#include "RenderMachineFunction.h"
#include "Spiller.h"
@@ -136,6 +138,7 @@ char RABasic::ID = 0;
} // end anonymous namespace
RABasic::RABasic(): MachineFunctionPass(ID) {
+ initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
@@ -154,6 +157,8 @@ void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<AliasAnalysis>();
AU.addRequired<LiveIntervals>();
AU.addPreserved<SlotIndexes>();
+ AU.addRequired<LiveDebugVariables>();
+ AU.addPreserved<LiveDebugVariables>();
if (StrongPHIElim)
AU.addRequiredID(StrongPHIEliminationID);
AU.addRequiredTransitive<RegisterCoalescer>();
@@ -230,9 +235,12 @@ void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis) {
MRI = &vrm.getRegInfo();
VRM = &vrm;
LIS = &lis;
- PhysReg2LiveUnion.init(UnionAllocator, TRI->getNumRegs());
- // Cache an interferece query for each physical reg
- Queries.reset(new LiveIntervalUnion::Query[PhysReg2LiveUnion.numRegs()]);
+ const unsigned NumRegs = TRI->getNumRegs();
+ if (NumRegs != PhysReg2LiveUnion.numRegs()) {
+ PhysReg2LiveUnion.init(UnionAllocator, NumRegs);
+ // Cache an interferece query for each physical reg
+ Queries.reset(new LiveIntervalUnion::Query[PhysReg2LiveUnion.numRegs()]);
+ }
}
void RegAllocBase::LiveUnionArray::clear() {
@@ -246,13 +254,15 @@ void RegAllocBase::LiveUnionArray::clear() {
}
void RegAllocBase::releaseMemory() {
- PhysReg2LiveUnion.clear();
+ for (unsigned r = 0, e = PhysReg2LiveUnion.numRegs(); r != e; ++r)
+ PhysReg2LiveUnion[r].clear();
}
// Visit all the live 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::seedLiveRegs() {
+ NamedRegionTimer T("Seed Live Regs", TimerGroupName, TimePassesIsEnabled);
for (LiveIntervals::iterator I = LIS->begin(), E = LIS->end(); I != E; ++I) {
unsigned RegNum = I->first;
LiveInterval &VirtReg = *I->second;
@@ -268,6 +278,7 @@ void RegAllocBase::assign(LiveInterval &VirtReg, unsigned PhysReg) {
<< " to " << PrintReg(PhysReg, TRI) << '\n');
assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment");
VRM->assignVirt2Phys(VirtReg.reg, PhysReg);
+ MRI->setPhysRegUsed(PhysReg);
PhysReg2LiveUnion[PhysReg].unify(VirtReg);
++NumAssigned;
}
@@ -288,6 +299,18 @@ void RegAllocBase::allocatePhysRegs() {
// Continue assigning vregs one at a time to available physical registers.
while (LiveInterval *VirtReg = dequeue()) {
+ assert(!VRM->hasPhys(VirtReg->reg) && "Register already assigned");
+
+ // Unused registers can appear when the spiller coalesces snippets.
+ if (MRI->reg_nodbg_empty(VirtReg->reg)) {
+ DEBUG(dbgs() << "Dropping unused " << *VirtReg << '\n');
+ LIS->removeInterval(VirtReg->reg);
+ continue;
+ }
+
+ // Invalidate all interference queries, live ranges could have changed.
+ ++UserTag;
+
// selectOrSplit requests the allocator to return an available physical
// register if possible and populate a list of new live intervals that
// result from splitting.
@@ -304,7 +327,12 @@ void RegAllocBase::allocatePhysRegs() {
for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
I != E; ++I) {
LiveInterval *SplitVirtReg = *I;
- if (SplitVirtReg->empty()) continue;
+ assert(!VRM->hasPhys(SplitVirtReg->reg) && "Register already assigned");
+ if (MRI->reg_nodbg_empty(SplitVirtReg->reg)) {
+ DEBUG(dbgs() << "not queueing unused " << *SplitVirtReg << '\n');
+ LIS->removeInterval(SplitVirtReg->reg);
+ continue;
+ }
DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
"expect split value in virtual register");
@@ -344,7 +372,8 @@ void RegAllocBase::spillReg(LiveInterval& VirtReg, unsigned PhysReg,
unassign(SpilledVReg, PhysReg);
// Spill the extracted interval.
- spiller().spill(&SpilledVReg, SplitVRegs, PendingSpills);
+ LiveRangeEdit LRE(SpilledVReg, SplitVRegs, 0, &PendingSpills);
+ spiller().spill(LRE);
}
// After extracting segments, the query's results are invalid. But keep the
// contents valid until we're done accessing pendingSpills.
@@ -381,29 +410,31 @@ RegAllocBase::spillInterferences(LiveInterval &VirtReg, unsigned PhysReg,
// Add newly allocated physical registers to the MBB live in sets.
void RegAllocBase::addMBBLiveIns(MachineFunction *MF) {
NamedRegionTimer T("MBB Live Ins", TimerGroupName, TimePassesIsEnabled);
- typedef SmallVector<MachineBasicBlock*, 8> MBBVec;
- MBBVec liveInMBBs;
- MachineBasicBlock &entryMBB = *MF->begin();
+ SlotIndexes *Indexes = LIS->getSlotIndexes();
+ if (MF->size() <= 1)
+ return;
+ LiveIntervalUnion::SegmentIter SI;
for (unsigned PhysReg = 0; PhysReg < PhysReg2LiveUnion.numRegs(); ++PhysReg) {
LiveIntervalUnion &LiveUnion = PhysReg2LiveUnion[PhysReg];
if (LiveUnion.empty())
continue;
- for (LiveIntervalUnion::SegmentIter SI = LiveUnion.begin(); SI.valid();
- ++SI) {
-
- // Find the set of basic blocks which this range is live into...
- liveInMBBs.clear();
- if (!LIS->findLiveInMBBs(SI.start(), SI.stop(), liveInMBBs)) continue;
-
- // And add the physreg for this interval to their live-in sets.
- for (MBBVec::iterator I = liveInMBBs.begin(), E = liveInMBBs.end();
- I != E; ++I) {
- MachineBasicBlock *MBB = *I;
- if (MBB == &entryMBB) continue;
- if (MBB->isLiveIn(PhysReg)) continue;
- MBB->addLiveIn(PhysReg);
- }
+ MachineFunction::iterator MBB = llvm::next(MF->begin());
+ MachineFunction::iterator MFE = MF->end();
+ SlotIndex Start, Stop;
+ tie(Start, Stop) = Indexes->getMBBRange(MBB);
+ SI.setMap(LiveUnion.getMap());
+ SI.find(Start);
+ while (SI.valid()) {
+ if (SI.start() <= Start) {
+ if (!MBB->isLiveIn(PhysReg))
+ MBB->addLiveIn(PhysReg);
+ } else if (SI.start() > Stop)
+ MBB = Indexes->getMBBFromIndex(SI.start().getPrevIndex());
+ if (++MBB == MFE)
+ break;
+ tie(Start, Stop) = Indexes->getMBBRange(MBB);
+ SI.advanceTo(Start);
}
}
}
@@ -469,9 +500,8 @@ unsigned RABasic::selectOrSplit(LiveInterval &VirtReg,
}
// No other spill candidates were found, so spill the current VirtReg.
DEBUG(dbgs() << "spilling: " << VirtReg << '\n');
- SmallVector<LiveInterval*, 1> pendingSpills;
-
- spiller().spill(&VirtReg, SplitVRegs, pendingSpills);
+ LiveRangeEdit LRE(VirtReg, SplitVRegs);
+ spiller().spill(LRE);
// The live virtual register requesting allocation was spilled, so tell
// the caller not to allocate anything during this round.
@@ -490,7 +520,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
ReservedRegs = TRI->getReservedRegs(*MF);
- SpillerInstance.reset(createSpiller(*this, *MF, *VRM));
+ SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM));
allocatePhysRegs();
@@ -525,6 +555,9 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
// Run rewriter
VRM->rewrite(LIS->getSlotIndexes());
+ // Write out new DBG_VALUE instructions.
+ getAnalysis<LiveDebugVariables>().emitDebugValues(VRM);
+
// The pass output is in VirtRegMap. Release all the transient data.
releaseMemory();