Make MBB a class member instead of passing it around everywhere.

llvm-svn: 103925
This commit is contained in:
Jakob Stoklund Olesen 2010-05-17 02:07:22 +00:00
parent 166a7993ba
commit fb43e065a4
1 changed files with 62 additions and 62 deletions

View File

@ -58,6 +58,9 @@ namespace {
const TargetRegisterInfo *TRI; const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII; const TargetInstrInfo *TII;
// Basic block currently being allocated.
MachineBasicBlock *MBB;
// StackSlotForVirtReg - Maps virtual regs to the frame index where these // StackSlotForVirtReg - Maps virtual regs to the frame index where these
// values are spilled. // values are spilled.
IndexedMap<int, VirtReg2IndexFunctor> StackSlotForVirtReg; IndexedMap<int, VirtReg2IndexFunctor> StackSlotForVirtReg;
@ -130,30 +133,29 @@ namespace {
private: private:
bool runOnMachineFunction(MachineFunction &Fn); bool runOnMachineFunction(MachineFunction &Fn);
void AllocateBasicBlock(MachineBasicBlock &MBB); void AllocateBasicBlock();
int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC); int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC);
bool isLastUseOfLocalReg(MachineOperand&); bool isLastUseOfLocalReg(MachineOperand&);
void addKillFlag(LiveRegMap::iterator i); void addKillFlag(LiveRegMap::iterator i);
void killVirtReg(LiveRegMap::iterator i); void killVirtReg(LiveRegMap::iterator i);
void killVirtReg(unsigned VirtReg); void killVirtReg(unsigned VirtReg);
void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, void spillVirtReg(MachineBasicBlock::iterator MI, LiveRegMap::iterator i,
LiveRegMap::iterator i, bool isKill); bool isKill);
void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, void spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg,
unsigned VirtReg, bool isKill); bool isKill);
void usePhysReg(MachineOperand&); void usePhysReg(MachineOperand&);
void definePhysReg(MachineBasicBlock &MBB, MachineInstr *MI, void definePhysReg(MachineInstr *MI, unsigned PhysReg, RegState NewState);
unsigned PhysReg, RegState NewState);
LiveRegMap::iterator assignVirtToPhysReg(unsigned VirtReg, LiveRegMap::iterator assignVirtToPhysReg(unsigned VirtReg,
unsigned PhysReg); unsigned PhysReg);
LiveRegMap::iterator allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, LiveRegMap::iterator allocVirtReg(MachineInstr *MI, unsigned VirtReg,
unsigned VirtReg, unsigned Hint); unsigned Hint);
unsigned defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, unsigned defineVirtReg(MachineInstr *MI, unsigned OpNum, unsigned VirtReg,
unsigned Hint);
unsigned reloadVirtReg(MachineInstr *MI,
unsigned OpNum, unsigned VirtReg, unsigned Hint); unsigned OpNum, unsigned VirtReg, unsigned Hint);
unsigned reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, void spillAll(MachineInstr *MI);
unsigned OpNum, unsigned VirtReg, unsigned Hint);
void spillAll(MachineBasicBlock &MBB, MachineInstr *MI);
void setPhysReg(MachineOperand &MO, unsigned PhysReg); void setPhysReg(MachineOperand &MO, unsigned PhysReg);
}; };
char RAFast::ID = 0; char RAFast::ID = 0;
@ -233,19 +235,17 @@ void RAFast::killVirtReg(unsigned VirtReg) {
/// spillVirtReg - This method spills the value specified by VirtReg into the /// spillVirtReg - This method spills the value specified by VirtReg into the
/// corresponding stack slot if needed. If isKill is set, the register is also /// corresponding stack slot if needed. If isKill is set, the register is also
/// killed. /// killed.
void RAFast::spillVirtReg(MachineBasicBlock &MBB, void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,
MachineBasicBlock::iterator MI,
unsigned VirtReg, bool isKill) { unsigned VirtReg, bool isKill) {
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Spilling a physical register is illegal!"); "Spilling a physical register is illegal!");
LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg); LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
assert(lri != LiveVirtRegs.end() && "Spilling unmapped virtual register"); assert(lri != LiveVirtRegs.end() && "Spilling unmapped virtual register");
spillVirtReg(MBB, MI, lri, isKill); spillVirtReg(MI, lri, isKill);
} }
/// spillVirtReg - Do the actual work of spilling. /// spillVirtReg - Do the actual work of spilling.
void RAFast::spillVirtReg(MachineBasicBlock &MBB, void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,
MachineBasicBlock::iterator MI,
LiveRegMap::iterator lri, bool isKill) { LiveRegMap::iterator lri, bool isKill) {
LiveReg &LR = lri->second; LiveReg &LR = lri->second;
assert(PhysRegState[LR.PhysReg] == lri->first && "Broken RegState mapping"); assert(PhysRegState[LR.PhysReg] == lri->first && "Broken RegState mapping");
@ -259,10 +259,9 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB,
DEBUG(dbgs() << "Spilling %reg" << lri->first DEBUG(dbgs() << "Spilling %reg" << lri->first
<< " in " << TRI->getName(LR.PhysReg)); << " in " << TRI->getName(LR.PhysReg));
const TargetRegisterClass *RC = MRI->getRegClass(lri->first); const TargetRegisterClass *RC = MRI->getRegClass(lri->first);
int FrameIndex = getStackSpaceFor(lri->first, RC); int FI = getStackSpaceFor(lri->first, RC);
DEBUG(dbgs() << " to stack slot #" << FrameIndex << "\n"); DEBUG(dbgs() << " to stack slot #" << FI << "\n");
TII->storeRegToStackSlot(MBB, MI, LR.PhysReg, spillKill, TII->storeRegToStackSlot(*MBB, MI, LR.PhysReg, spillKill, FI, RC, TRI);
FrameIndex, RC, TRI);
++NumStores; // Update statistics ++NumStores; // Update statistics
if (spillKill) if (spillKill)
@ -279,14 +278,14 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB,
} }
/// spillAll - Spill all dirty virtregs without killing them. /// spillAll - Spill all dirty virtregs without killing them.
void RAFast::spillAll(MachineBasicBlock &MBB, MachineInstr *MI) { void RAFast::spillAll(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 (i->second.Dirty) 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(MI, Dirty[i], false);
} }
/// usePhysReg - Handle the direct use of a physical register. /// usePhysReg - Handle the direct use of a physical register.
@ -352,14 +351,14 @@ void RAFast::usePhysReg(MachineOperand &MO) {
/// definePhysReg - Mark PhysReg as reserved or free after spilling any /// definePhysReg - Mark PhysReg as reserved or free after spilling any
/// virtregs. This is very similar to defineVirtReg except the physreg is /// virtregs. This is very similar to defineVirtReg except the physreg is
/// reserved instead of allocated. /// reserved instead of allocated.
void RAFast::definePhysReg(MachineBasicBlock &MBB, MachineInstr *MI, void RAFast::definePhysReg(MachineInstr *MI, unsigned PhysReg,
unsigned PhysReg, RegState NewState) { RegState NewState) {
UsedInInstr.set(PhysReg); UsedInInstr.set(PhysReg);
switch (unsigned VirtReg = PhysRegState[PhysReg]) { switch (unsigned VirtReg = PhysRegState[PhysReg]) {
case regDisabled: case regDisabled:
break; break;
default: default:
spillVirtReg(MBB, MI, VirtReg, true); spillVirtReg(MI, VirtReg, true);
// Fall through. // Fall through.
case regFree: case regFree:
case regReserved: case regReserved:
@ -376,7 +375,7 @@ void RAFast::definePhysReg(MachineBasicBlock &MBB, MachineInstr *MI,
case regDisabled: case regDisabled:
break; break;
default: default:
spillVirtReg(MBB, MI, VirtReg, true); spillVirtReg(MI, VirtReg, true);
// Fall through. // Fall through.
case regFree: case regFree:
case regReserved: case regReserved:
@ -402,8 +401,7 @@ RAFast::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) {
} }
/// allocVirtReg - Allocate a physical register for VirtReg. /// allocVirtReg - Allocate a physical register for VirtReg.
RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB, RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr *MI,
MachineInstr *MI,
unsigned VirtReg, unsigned VirtReg,
unsigned Hint) { unsigned Hint) {
const unsigned spillCost = 100; const unsigned spillCost = 100;
@ -443,7 +441,7 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
case regReserved: case regReserved:
break; break;
default: default:
spillVirtReg(MBB, MI, PhysRegState[Hint], true); spillVirtReg(MI, PhysRegState[Hint], true);
// Fall through. // Fall through.
case regFree: case regFree:
return assignVirtToPhysReg(VirtReg, Hint); return assignVirtToPhysReg(VirtReg, Hint);
@ -520,7 +518,7 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
// BestCost is 0 when all aliases are already disabled. // BestCost is 0 when all aliases are already disabled.
if (BestCost) { if (BestCost) {
if (PhysRegState[BestReg] != regDisabled) if (PhysRegState[BestReg] != regDisabled)
spillVirtReg(MBB, MI, PhysRegState[BestReg], true); spillVirtReg(MI, PhysRegState[BestReg], true);
else { else {
// Make sure all aliases are disabled. // Make sure all aliases are disabled.
for (const unsigned *AS = TRI->getAliasSet(BestReg); for (const unsigned *AS = TRI->getAliasSet(BestReg);
@ -532,7 +530,7 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
PhysRegState[Alias] = regDisabled; PhysRegState[Alias] = regDisabled;
break; break;
default: default:
spillVirtReg(MBB, MI, PhysRegState[Alias], true); spillVirtReg(MI, PhysRegState[Alias], true);
PhysRegState[Alias] = regDisabled; PhysRegState[Alias] = regDisabled;
break; break;
} }
@ -556,13 +554,13 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
} }
/// defineVirtReg - Allocate a register for VirtReg and mark it as dirty. /// defineVirtReg - Allocate a register for VirtReg and mark it as dirty.
unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, unsigned RAFast::defineVirtReg(MachineInstr *MI, unsigned OpNum,
unsigned OpNum, unsigned VirtReg, unsigned Hint) { unsigned VirtReg, unsigned Hint) {
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual register"); "Not a virtual register");
LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg); LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
if (lri == LiveVirtRegs.end()) if (lri == LiveVirtRegs.end())
lri = allocVirtReg(MBB, MI, VirtReg, Hint); lri = allocVirtReg(MI, VirtReg, Hint);
else else
addKillFlag(lri); // Kill before redefine. addKillFlag(lri); // Kill before redefine.
LiveReg &LR = lri->second; LiveReg &LR = lri->second;
@ -574,18 +572,18 @@ unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
} }
/// reloadVirtReg - Make sure VirtReg is available in a physreg and return it. /// reloadVirtReg - Make sure VirtReg is available in a physreg and return it.
unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, unsigned RAFast::reloadVirtReg(MachineInstr *MI, unsigned OpNum,
unsigned OpNum, unsigned VirtReg, unsigned Hint) { unsigned VirtReg, unsigned Hint) {
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual register"); "Not a virtual register");
LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg); LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
if (lri == LiveVirtRegs.end()) { if (lri == LiveVirtRegs.end()) {
lri = allocVirtReg(MBB, MI, VirtReg, Hint); lri = allocVirtReg(MI, VirtReg, Hint);
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg); const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
int FrameIndex = getStackSpaceFor(VirtReg, RC); int FrameIndex = getStackSpaceFor(VirtReg, RC);
DEBUG(dbgs() << "Reloading %reg" << VirtReg << " into " DEBUG(dbgs() << "Reloading %reg" << VirtReg << " into "
<< TRI->getName(lri->second.PhysReg) << "\n"); << TRI->getName(lri->second.PhysReg) << "\n");
TII->loadRegFromStackSlot(MBB, MI, lri->second.PhysReg, FrameIndex, RC, TII->loadRegFromStackSlot(*MBB, MI, lri->second.PhysReg, FrameIndex, RC,
TRI); TRI);
++NumLoads; ++NumLoads;
} else if (lri->second.Dirty) { } else if (lri->second.Dirty) {
@ -614,25 +612,25 @@ void RAFast::setPhysReg(MachineOperand &MO, unsigned PhysReg) {
MO.setReg(PhysReg); MO.setReg(PhysReg);
} }
void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) { void RAFast::AllocateBasicBlock() {
DEBUG(dbgs() << "\nAllocating " << MBB); DEBUG(dbgs() << "\nAllocating " << *MBB);
atEndOfBlock = false; atEndOfBlock = false;
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?");
MachineBasicBlock::iterator MII = MBB.begin(); MachineBasicBlock::iterator MII = MBB->begin();
// Add live-in registers as live. // Add live-in registers as live.
for (MachineBasicBlock::livein_iterator I = MBB.livein_begin(), for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(),
E = MBB.livein_end(); I != E; ++I) E = MBB->livein_end(); I != E; ++I)
definePhysReg(MBB, MII, *I, regReserved); definePhysReg(MII, *I, regReserved);
SmallVector<unsigned, 8> VirtKills, PhysDefs; SmallVector<unsigned, 8> VirtKills, PhysDefs;
SmallVector<MachineInstr*, 32> Coalesced; SmallVector<MachineInstr*, 32> Coalesced;
// Otherwise, sequentially allocate each instruction in the MBB. // Otherwise, sequentially allocate each instruction in the MBB.
while (MII != MBB.end()) { while (MII != MBB->end()) {
MachineInstr *MI = MII++; MachineInstr *MI = MII++;
const TargetInstrDesc &TID = MI->getDesc(); const TargetInstrDesc &TID = MI->getDesc();
DEBUG({ DEBUG({
@ -711,7 +709,7 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
if (MO.isUse()) { if (MO.isUse()) {
usePhysReg(MO); usePhysReg(MO);
} else if (MO.isEarlyClobber()) { } else if (MO.isEarlyClobber()) {
definePhysReg(MBB, MI, Reg, MO.isDead() ? regFree : regReserved); definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved);
PhysDefs.push_back(Reg); PhysDefs.push_back(Reg);
} }
} }
@ -725,13 +723,13 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
unsigned Reg = MO.getReg(); unsigned Reg = MO.getReg();
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue; if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
if (MO.isUse()) { if (MO.isUse()) {
unsigned PhysReg = reloadVirtReg(MBB, MI, i, Reg, CopyDst); unsigned PhysReg = reloadVirtReg(MI, i, Reg, CopyDst);
CopySrc = (CopySrc == Reg || CopySrc == PhysReg) ? PhysReg : 0; CopySrc = (CopySrc == Reg || CopySrc == PhysReg) ? PhysReg : 0;
setPhysReg(MO, PhysReg); setPhysReg(MO, PhysReg);
if (MO.isKill()) if (MO.isKill())
VirtKills.push_back(Reg); VirtKills.push_back(Reg);
} else if (MO.isEarlyClobber()) { } else if (MO.isEarlyClobber()) {
unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg, 0); unsigned PhysReg = defineVirtReg(MI, i, Reg, 0);
setPhysReg(MO, PhysReg); setPhysReg(MO, PhysReg);
PhysDefs.push_back(PhysReg); PhysDefs.push_back(PhysReg);
} }
@ -763,11 +761,11 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
if (TargetRegisterInfo::isPhysicalRegister(Reg)) { if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
if (!Allocatable.test(Reg)) continue; if (!Allocatable.test(Reg)) continue;
definePhysReg(MBB, MI, Reg, (MO.isImplicit() || MO.isDead()) ? definePhysReg(MI, Reg, (MO.isImplicit() || MO.isDead()) ?
regFree : regReserved); regFree : regReserved);
continue; continue;
} }
unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg, CopySrc); unsigned PhysReg = defineVirtReg(MI, i, Reg, CopySrc);
if (MO.isDead()) { if (MO.isDead()) {
VirtKills.push_back(Reg); VirtKills.push_back(Reg);
CopyDst = 0; // cancel coalescing; CopyDst = 0; // cancel coalescing;
@ -779,7 +777,7 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
// Spill all dirty virtregs before a call, in case of an exception. // Spill all dirty virtregs before a call, in case of an exception.
if (TID.isCall()) { if (TID.isCall()) {
DEBUG(dbgs() << " Spilling remaining registers before call.\n"); DEBUG(dbgs() << " Spilling remaining registers before call.\n");
spillAll(MBB, MI); spillAll(MI);
} }
// Process virtreg deads. // Process virtreg deads.
@ -799,8 +797,8 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
// Spill all physical registers holding virtual registers now. // Spill all physical registers holding virtual registers now.
atEndOfBlock = true; atEndOfBlock = true;
MachineBasicBlock::iterator MI = MBB.getFirstTerminator(); MachineBasicBlock::iterator MI = MBB->getFirstTerminator();
if (MI != MBB.end() && MI->getDesc().isReturn()) { if (MI != MBB->end() && MI->getDesc().isReturn()) {
// This is a return block, kill all virtual registers. // This is a return block, kill all virtual registers.
DEBUG(dbgs() << "Killing live registers at end of return block.\n"); DEBUG(dbgs() << "Killing live registers at end of return block.\n");
for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end(); for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end();
@ -811,17 +809,17 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
DEBUG(dbgs() << "Spilling live registers at end of block.\n"); DEBUG(dbgs() << "Spilling live registers at end of block.\n");
for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end(); for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end();
i != e; ++i) i != e; ++i)
spillVirtReg(MBB, MI, i, true); spillVirtReg(MI, i, true);
} }
LiveVirtRegs.clear(); LiveVirtRegs.clear();
// Erase all the coalesced copies. We are delaying it until now because // Erase all the coalesced copies. We are delaying it until now because
// LiveVirtsRegs might refer to the instrs. // LiveVirtsRegs might refer to the instrs.
for (unsigned i = 0, e = Coalesced.size(); i != e; ++i) for (unsigned i = 0, e = Coalesced.size(); i != e; ++i)
MBB.erase(Coalesced[i]); MBB->erase(Coalesced[i]);
NumCopies += Coalesced.size(); NumCopies += Coalesced.size();
DEBUG(MBB.dump()); DEBUG(MBB->dump());
} }
/// runOnMachineFunction - Register allocate the whole function /// runOnMachineFunction - Register allocate the whole function
@ -847,9 +845,11 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) {
StackSlotForVirtReg.grow(LastVirtReg); StackSlotForVirtReg.grow(LastVirtReg);
// Loop over all of the basic blocks, eliminating virtual register references // Loop over all of the basic blocks, eliminating virtual register references
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); for (MachineFunction::iterator MBBi = Fn.begin(), MBBe = Fn.end();
MBB != MBBe; ++MBB) MBBi != MBBe; ++MBBi) {
AllocateBasicBlock(*MBB); MBB = &*MBBi;
AllocateBasicBlock();
}
// Make sure the set of used physregs is closed under subreg operations. // Make sure the set of used physregs is closed under subreg operations.
MRI->closePhysRegsUsed(*TRI); MRI->closePhysRegsUsed(*TRI);