aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocFast.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-05-14 00:02:20 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-05-14 00:02:20 +0000
commit7d4f25904de543b039a28eddbea3034a5d80e7f8 (patch)
tree39b1274f6604e86b1dc7807fc0e73becc74513e7 /lib/CodeGen/RegAllocFast.cpp
parentdbf67fefeaccfeb53fb9d6098180ba1f29e682d5 (diff)
Fix an embarrassing runtime regression for RegAllocFast.
This loop is quadratic in the capacity for a DenseMap: while(!map.empty()) map.erase(map.begin()); Instead we now do a normal begin() - end() iteration followed by map.clear(). That also has the nice sideeffect of shrinking the map capacity on demand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103747 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocFast.cpp')
-rw-r--r--lib/CodeGen/RegAllocFast.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp
index 0b03efffd6..2f59b1d849 100644
--- a/lib/CodeGen/RegAllocFast.cpp
+++ b/lib/CodeGen/RegAllocFast.cpp
@@ -45,7 +45,8 @@ namespace {
class RAFast : public MachineFunctionPass {
public:
static char ID;
- RAFast() : MachineFunctionPass(&ID), StackSlotForVirtReg(-1) {}
+ RAFast() : MachineFunctionPass(&ID), StackSlotForVirtReg(-1),
+ atEndOfBlock(false) {}
private:
const TargetMachine *TM;
MachineFunction *MF;
@@ -106,6 +107,11 @@ namespace {
// ReservedRegs - vector of reserved physical registers.
BitVector ReservedRegs;
+ // atEndOfBlock - This flag is set after allocating all instructions in a
+ // block, before emitting final spills. When it is set, LiveRegMap is no
+ // longer updated properly sonce it will be cleared anyway.
+ bool atEndOfBlock;
+
public:
virtual const char *getPassName() const {
return "Fast Register Allocator";
@@ -126,6 +132,8 @@ namespace {
void killVirtReg(LiveRegMap::iterator i);
void killVirtReg(unsigned VirtReg);
void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
+ LiveRegMap::iterator i, bool isKill);
+ void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
unsigned VirtReg, bool isKill);
void killPhysReg(unsigned PhysReg);
void spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
@@ -182,7 +190,10 @@ void RAFast::killVirtReg(LiveRegMap::iterator lri) {
const LiveReg &LR = lri->second;
assert(PhysRegState[LR.PhysReg] == lri->first && "Broken RegState mapping");
PhysRegState[LR.PhysReg] = regFree;
- LiveVirtRegs.erase(lri);
+ // Erase from LiveVirtRegs unless we're at the end of the block when
+ // everything will be bulk erased.
+ if (!atEndOfBlock)
+ LiveVirtRegs.erase(lri);
}
/// killVirtReg - Mark virtreg as no longer available.
@@ -204,8 +215,15 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB,
"Spilling a physical register is illegal!");
LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
assert(lri != LiveVirtRegs.end() && "Spilling unmapped virtual register");
+ spillVirtReg(MBB, MI, lri, isKill);
+}
+
+/// spillVirtReg - Do the actual work of spilling.
+void RAFast::spillVirtReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ LiveRegMap::iterator lri, bool isKill) {
LiveReg &LR = lri->second;
- assert(PhysRegState[LR.PhysReg] == VirtReg && "Broken RegState mapping");
+ assert(PhysRegState[LR.PhysReg] == lri->first && "Broken RegState mapping");
// If this physreg is used by the instruction, we want to kill it on the
// instruction, not on the spill.
@@ -213,10 +231,10 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB,
if (LR.Dirty) {
LR.Dirty = false;
- DEBUG(dbgs() << "Spilling register " << TRI->getName(LR.PhysReg)
- << " containing %reg" << VirtReg);
- const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
- int FrameIndex = getStackSpaceFor(VirtReg, RC);
+ DEBUG(dbgs() << "Spilling %reg" << lri->first
+ << " in " << TRI->getName(LR.PhysReg));
+ const TargetRegisterClass *RC = MRI->getRegClass(lri->first);
+ int FrameIndex = getStackSpaceFor(lri->first, RC);
DEBUG(dbgs() << " to stack slot #" << FrameIndex << "\n");
TII->storeRegToStackSlot(MBB, MI, LR.PhysReg, spillKill,
FrameIndex, RC, TRI);
@@ -573,6 +591,7 @@ void RAFast::setPhysReg(MachineOperand &MO, unsigned PhysReg) {
void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
DEBUG(dbgs() << "\nAllocating " << MBB);
+ atEndOfBlock = false;
PhysRegState.assign(TRI->getNumRegs(), regDisabled);
assert(LiveVirtRegs.empty() && "Mapping not cleared form last block?");
@@ -772,10 +791,13 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
}
// Spill all physical registers holding virtual registers now.
+ atEndOfBlock = true;
DEBUG(dbgs() << "Killing live registers at end of block.\n");
MachineBasicBlock::iterator MI = MBB.getFirstTerminator();
- while (!LiveVirtRegs.empty())
- spillVirtReg(MBB, MI, LiveVirtRegs.begin()->first, true);
+ for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end();
+ i != e; ++i)
+ spillVirtReg(MBB, MI, i, true);
+ LiveVirtRegs.clear();
DEBUG(MBB.dump());
}