Store the Dirty bit in the LiveReg structure instead of a bit vector.

llvm-svn: 103522
This commit is contained in:
Jakob Stoklund Olesen 2010-05-11 23:24:47 +00:00
parent 132668102e
commit 11f1ba1535
1 changed files with 28 additions and 34 deletions

View File

@ -58,11 +58,13 @@ namespace {
// Everything we know about a live virtual register. // Everything we know about a live virtual register.
struct LiveReg { struct LiveReg {
MachineInstr *LastUse; // Last instr to use reg. MachineInstr *LastUse; // Last instr to use reg.
unsigned PhysReg; // Currently held here. unsigned PhysReg; // Currently held here.
unsigned LastOpNum; // OpNum on LastUse. unsigned short LastOpNum; // OpNum on LastUse.
bool Dirty; // Register needs spill.
LiveReg(unsigned p=0) : LastUse(0), PhysReg(p), LastOpNum(0) { LiveReg(unsigned p=0) : LastUse(0), PhysReg(p), LastOpNum(0),
Dirty(false) {
assert(p && "Don't create LiveRegs without a PhysReg"); assert(p && "Don't create LiveRegs without a PhysReg");
} }
}; };
@ -100,11 +102,6 @@ namespace {
// instruction, and so cannot be allocated. // instruction, and so cannot be allocated.
BitVector UsedInInstr; BitVector UsedInInstr;
// PhysRegDirty - A bit is set for each physreg that holds a dirty virtual
// register. Bits for physregs that are not mapped to a virtual register are
// invalid.
BitVector PhysRegDirty;
// ReservedRegs - vector of reserved physical registers. // ReservedRegs - vector of reserved physical registers.
BitVector ReservedRegs; BitVector ReservedRegs;
@ -200,15 +197,15 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB,
"Spilling a physical register is illegal!"); "Spilling a physical register is illegal!");
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg); LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
assert(i != LiveVirtRegs.end() && "Spilling unmapped virtual register"); assert(i != LiveVirtRegs.end() && "Spilling unmapped virtual register");
const LiveReg &LR = i->second; LiveReg &LR = i->second;
assert(PhysRegState[LR.PhysReg] == VirtReg && "Broken RegState mapping"); assert(PhysRegState[LR.PhysReg] == VirtReg && "Broken RegState mapping");
// If this physreg is used by the instruction, we want to kill it on the // If this physreg is used by the instruction, we want to kill it on the
// instruction, not on the spill. // instruction, not on the spill.
bool spillKill = isKill && LR.LastUse != MI; bool spillKill = isKill && LR.LastUse != MI;
if (PhysRegDirty.test(LR.PhysReg)) { if (LR.Dirty) {
PhysRegDirty.reset(LR.PhysReg); LR.Dirty = false;
DEBUG(dbgs() << " Spilling register " << TRI->getName(LR.PhysReg) DEBUG(dbgs() << " Spilling register " << TRI->getName(LR.PhysReg)
<< " containing %reg" << VirtReg); << " containing %reg" << VirtReg);
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg); const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
@ -219,11 +216,11 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB,
++NumStores; // Update statistics ++NumStores; // Update statistics
if (spillKill) if (spillKill)
i->second.LastUse = 0; // Don't kill register again LR.LastUse = 0; // Don't kill register again
else if (!isKill) { else if (!isKill) {
MachineInstr *Spill = llvm::prior(MI); MachineInstr *Spill = llvm::prior(MI);
i->second.LastUse = Spill; LR.LastUse = Spill;
i->second.LastOpNum = Spill->findRegisterUseOperandIdx(LR.PhysReg); LR.LastOpNum = Spill->findRegisterUseOperandIdx(LR.PhysReg);
} }
} }
@ -236,7 +233,7 @@ void RAFast::spillAll(MachineBasicBlock &MBB, MachineInstr *MI) {
SmallVector<unsigned, 16> Dirty; SmallVector<unsigned, 16> Dirty;
for (LiveRegMap::iterator i = LiveVirtRegs.begin(), for (LiveRegMap::iterator i = LiveVirtRegs.begin(),
e = LiveVirtRegs.end(); i != e; ++i) e = LiveVirtRegs.end(); i != e; ++i)
if (PhysRegDirty.test(i->second.PhysReg)) if (i->second.Dirty)
Dirty.push_back(i->first); Dirty.push_back(i->first);
for (unsigned i = 0, e = Dirty.size(); i != e; ++i) for (unsigned i = 0, e = Dirty.size(); i != e; ++i)
spillVirtReg(MBB, MI, Dirty[i], false); spillVirtReg(MBB, MI, Dirty[i], false);
@ -351,10 +348,8 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
continue; continue;
default: default:
// Grab the first spillable register we meet. // Grab the first spillable register we meet.
if (!BestReg && !UsedInInstr.test(PhysReg)) { if (!BestReg && !UsedInInstr.test(PhysReg))
BestReg = PhysReg; BestReg = PhysReg, BestCost = spillCost;
BestCost = PhysRegDirty.test(PhysReg) ? spillCost : 1;
}
continue; continue;
} }
} }
@ -388,7 +383,7 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
Cost++; Cost++;
break; break;
default: default:
Cost += PhysRegDirty.test(Alias) ? spillCost : 1; Cost += spillCost;
break; break;
} }
} }
@ -450,11 +445,12 @@ unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg); LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
if (i == LiveVirtRegs.end()) if (i == LiveVirtRegs.end())
i = allocVirtReg(MBB, MI, VirtReg); i = allocVirtReg(MBB, MI, VirtReg);
i->second.LastUse = MI; LiveReg &LR = i->second;
i->second.LastOpNum = OpNum; LR.LastUse = MI;
UsedInInstr.set(i->second.PhysReg); LR.LastOpNum = OpNum;
PhysRegDirty.set(i->second.PhysReg); LR.Dirty = true;
return i->second.PhysReg; UsedInInstr.set(LR.PhysReg);
return LR.PhysReg;
} }
/// reloadVirtReg - Make sure VirtReg is available in a physreg and return it. /// reloadVirtReg - Make sure VirtReg is available in a physreg and return it.
@ -465,7 +461,6 @@ unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg); LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
if (i == LiveVirtRegs.end()) { if (i == LiveVirtRegs.end()) {
i = allocVirtReg(MBB, MI, VirtReg); i = allocVirtReg(MBB, MI, VirtReg);
PhysRegDirty.reset(i->second.PhysReg);
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg); const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
int FrameIndex = getStackSpaceFor(VirtReg, RC); int FrameIndex = getStackSpaceFor(VirtReg, RC);
DEBUG(dbgs() << " Reloading %reg" << VirtReg << " into " DEBUG(dbgs() << " Reloading %reg" << VirtReg << " into "
@ -473,10 +468,11 @@ unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
TII->loadRegFromStackSlot(MBB, MI, i->second.PhysReg, FrameIndex, RC, TRI); TII->loadRegFromStackSlot(MBB, MI, i->second.PhysReg, FrameIndex, RC, TRI);
++NumLoads; ++NumLoads;
} }
i->second.LastUse = MI; LiveReg &LR = i->second;
i->second.LastOpNum = OpNum; LR.LastUse = MI;
UsedInInstr.set(i->second.PhysReg); LR.LastOpNum = OpNum;
return i->second.PhysReg; UsedInInstr.set(LR.PhysReg);
return LR.PhysReg;
} }
/// reservePhysReg - Mark PhysReg as reserved. This is very similar to /// reservePhysReg - Mark PhysReg as reserved. This is very similar to
@ -534,7 +530,6 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
PhysRegState.assign(TRI->getNumRegs(), regDisabled); PhysRegState.assign(TRI->getNumRegs(), regDisabled);
assert(LiveVirtRegs.empty() && "Mapping not cleared form last block?"); assert(LiveVirtRegs.empty() && "Mapping not cleared form last block?");
PhysRegDirty.reset();
MachineBasicBlock::iterator MII = MBB.begin(); MachineBasicBlock::iterator MII = MBB.begin();
@ -562,7 +557,7 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
break; break;
default: default:
dbgs() << "=%reg" << PhysRegState[Reg]; dbgs() << "=%reg" << PhysRegState[Reg];
if (PhysRegDirty.test(Reg)) if (LiveVirtRegs[PhysRegState[Reg]].Dirty)
dbgs() << "*"; dbgs() << "*";
assert(LiveVirtRegs[PhysRegState[Reg]].PhysReg == Reg && assert(LiveVirtRegs[PhysRegState[Reg]].PhysReg == Reg &&
"Bad inverse map"); "Bad inverse map");
@ -727,7 +722,6 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) {
TRI = TM->getRegisterInfo(); TRI = TM->getRegisterInfo();
TII = TM->getInstrInfo(); TII = TM->getInstrInfo();
PhysRegDirty.resize(TRI->getNumRegs());
UsedInInstr.resize(TRI->getNumRegs()); UsedInInstr.resize(TRI->getNumRegs());
ReservedRegs = TRI->getReservedRegs(*MF); ReservedRegs = TRI->getReservedRegs(*MF);