#include <algorithm>
using namespace llvm;
-static cl::opt<bool> VerifyFastRegalloc("verify-fast-regalloc", cl::Hidden,
- cl::desc("Verify machine code before fast regalloc"));
-
STATISTIC(NumStores, "Number of stores added");
STATISTIC(NumLoads , "Number of loads added");
STATISTIC(NumCopies, "Number of copies coalesced");
// not be erased.
bool isBulkSpilling;
+ enum {
+ spillClean = 1,
+ spillDirty = 100,
+ spillImpossible = ~0u
+ };
public:
virtual const char *getPassName() const {
return "Fast Register Allocator";
void usePhysReg(MachineOperand&);
void definePhysReg(MachineInstr *MI, unsigned PhysReg, RegState NewState);
+ unsigned calcSpillCost(unsigned PhysReg) const;
void assignVirtToPhysReg(LiveRegEntry &LRE, unsigned PhysReg);
void allocVirtReg(MachineInstr *MI, LiveRegEntry &LRE, unsigned Hint);
LiveRegMap::iterator defineVirtReg(MachineInstr *MI, unsigned OpNum,
LiveRegMap::iterator reloadVirtReg(MachineInstr *MI, unsigned OpNum,
unsigned VirtReg, unsigned Hint);
void spillAll(MachineInstr *MI);
- bool setPhysReg(MachineOperand &MO, unsigned PhysReg);
+ bool setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg);
};
char RAFast::ID = 0;
}
void RAFast::addKillFlag(const LiveReg &LR) {
if (!LR.LastUse) return;
MachineOperand &MO = LR.LastUse->getOperand(LR.LastOpNum);
- if (MO.isDef())
- MO.setIsDead();
- else if (!LR.LastUse->isRegTiedToDefOperand(LR.LastOpNum))
- MO.setIsKill();
+ if (MO.getReg() == LR.PhysReg) {
+ if (MO.isDef())
+ MO.setIsDead();
+ else if (!LR.LastUse->isRegTiedToDefOperand(LR.LastOpNum))
+ MO.setIsKill();
+ } else {
+ if (MO.isDef())
+ LR.LastUse->addRegisterDead(LR.PhysReg, TRI, true);
+ else
+ LR.LastUse->addRegisterKilled(LR.PhysReg, TRI, true);
+ }
}
/// killVirtReg - Mark virtreg as no longer available.
/// spillAll - Spill all dirty virtregs without killing them.
void RAFast::spillAll(MachineInstr *MI) {
+ if (LiveVirtRegs.empty()) return;
isBulkSpilling = true;
- for (LiveRegMap::iterator i = LiveVirtRegs.begin(),
- e = LiveVirtRegs.end(); i != e; ++i)
+ // The LiveRegMap is keyed by an unsigned (the virtreg number), so the order
+ // of spilling here is deterministic, if arbitrary.
+ for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end();
+ i != e; ++i)
spillVirtReg(MI, i);
LiveVirtRegs.clear();
isBulkSpilling = false;
}
+// calcSpillCost - Return the cost of spilling clearing out PhysReg and
+// aliases so it is free for allocation.
+// Returns 0 when PhysReg is free or disabled with all aliases disabled - it
+// can be allocated directly.
+// Returns spillImpossible when PhysReg or an alias can't be spilled.
+unsigned RAFast::calcSpillCost(unsigned PhysReg) const {
+ if (UsedInInstr.test(PhysReg))
+ return spillImpossible;
+ switch (unsigned VirtReg = PhysRegState[PhysReg]) {
+ case regDisabled:
+ break;
+ case regFree:
+ return 0;
+ case regReserved:
+ return spillImpossible;
+ default:
+ return LiveVirtRegs.lookup(VirtReg).Dirty ? spillDirty : spillClean;
+ }
+
+ // This is a disabled register, add up const of aliases.
+ unsigned Cost = 0;
+ for (const unsigned *AS = TRI->getAliasSet(PhysReg);
+ unsigned Alias = *AS; ++AS) {
+ if (UsedInInstr.test(Alias))
+ return spillImpossible;
+ switch (unsigned VirtReg = PhysRegState[Alias]) {
+ case regDisabled:
+ break;
+ case regFree:
+ ++Cost;
+ break;
+ case regReserved:
+ return spillImpossible;
+ default:
+ Cost += LiveVirtRegs.lookup(VirtReg).Dirty ? spillDirty : spillClean;
+ break;
+ }
+ }
+ return Cost;
+}
+
+
/// assignVirtToPhysReg - This method updates local state so that we know
/// that PhysReg is the proper container for VirtReg now. The physical
/// register must not be used for anything else when this is called.
/// allocVirtReg - Allocate a physical register for VirtReg.
void RAFast::allocVirtReg(MachineInstr *MI, LiveRegEntry &LRE, unsigned Hint) {
- const unsigned SpillCost = 100;
const unsigned VirtReg = LRE.first;
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Can only allocate virtual registers");
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
- TargetRegisterClass::iterator AOB = RC->allocation_order_begin(*MF);
- TargetRegisterClass::iterator AOE = RC->allocation_order_end(*MF);
// Ignore invalid hints.
if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) ||
- !RC->contains(Hint) || UsedInInstr.test(Hint) ||
- !Allocatable.test(Hint)))
+ !RC->contains(Hint) || !Allocatable.test(Hint)))
Hint = 0;
// Take hint when possible.
if (Hint) {
- assert(RC->contains(Hint) && !UsedInInstr.test(Hint) &&
- Allocatable.test(Hint) && "Invalid hint should have been cleared");
- switch(PhysRegState[Hint]) {
- case regDisabled:
- case regReserved:
- break;
+ switch(calcSpillCost(Hint)) {
default:
- spillVirtReg(MI, PhysRegState[Hint]);
+ definePhysReg(MI, Hint, regFree);
// Fall through.
- case regFree:
+ case 0:
return assignVirtToPhysReg(LRE, Hint);
+ case spillImpossible:
+ break;
}
}
+ TargetRegisterClass::iterator AOB = RC->allocation_order_begin(*MF);
+ TargetRegisterClass::iterator AOE = RC->allocation_order_end(*MF);
+
// First try to find a completely free register.
- unsigned BestCost = 0, BestReg = 0;
- bool hasDisabled = false;
for (TargetRegisterClass::iterator I = AOB; I != AOE; ++I) {
unsigned PhysReg = *I;
- switch(PhysRegState[PhysReg]) {
- case regDisabled:
- hasDisabled = true;
- case regReserved:
- continue;
- case regFree:
- if (!UsedInInstr.test(PhysReg))
- return assignVirtToPhysReg(LRE, PhysReg);
- continue;
- default:
- // Grab the first spillable register we meet.
- if (!BestReg && !UsedInInstr.test(PhysReg))
- BestReg = PhysReg, BestCost = SpillCost;
- continue;
- }
+ if (PhysRegState[PhysReg] == regFree && !UsedInInstr.test(PhysReg))
+ return assignVirtToPhysReg(LRE, PhysReg);
}
DEBUG(dbgs() << "Allocating %reg" << VirtReg << " from " << RC->getName()
- << " candidate=" << TRI->getName(BestReg) << "\n");
+ << "\n");
- // Try to extend the working set for RC if there were any disabled registers.
- if (hasDisabled && (!BestReg || BestCost >= SpillCost)) {
- for (TargetRegisterClass::iterator I = AOB; I != AOE; ++I) {
- unsigned PhysReg = *I;
- if (PhysRegState[PhysReg] != regDisabled || UsedInInstr.test(PhysReg))
- continue;
-
- // Calculate the cost of bringing PhysReg into the working set.
- unsigned Cost=0;
- bool Impossible = false;
- for (const unsigned *AS = TRI->getAliasSet(PhysReg);
- unsigned Alias = *AS; ++AS) {
- if (UsedInInstr.test(Alias)) {
- Impossible = true;
- break;
- }
- switch (PhysRegState[Alias]) {
- case regDisabled:
- break;
- case regReserved:
- Impossible = true;
- break;
- case regFree:
- Cost++;
- break;
- default:
- Cost += SpillCost;
- break;
- }
- }
- if (Impossible) continue;
- DEBUG(dbgs() << "- candidate " << TRI->getName(PhysReg)
- << " cost=" << Cost << "\n");
- if (!BestReg || Cost < BestCost) {
- BestReg = PhysReg;
- BestCost = Cost;
- if (Cost < SpillCost) break;
- }
- }
+ unsigned BestReg = 0, BestCost = spillImpossible;
+ for (TargetRegisterClass::iterator I = AOB; I != AOE; ++I) {
+ unsigned Cost = calcSpillCost(*I);
+ // Cost is 0 when all aliases are already disabled.
+ if (Cost == 0)
+ return assignVirtToPhysReg(LRE, *I);
+ if (Cost < BestCost)
+ BestReg = *I, BestCost = Cost;
}
if (BestReg) {
- // BestCost is 0 when all aliases are already disabled.
- if (BestCost) {
- if (PhysRegState[BestReg] != regDisabled)
- spillVirtReg(MI, PhysRegState[BestReg]);
- else {
- // Make sure all aliases are disabled.
- for (const unsigned *AS = TRI->getAliasSet(BestReg);
- unsigned Alias = *AS; ++AS) {
- switch (PhysRegState[Alias]) {
- case regDisabled:
- continue;
- case regFree:
- PhysRegState[Alias] = regDisabled;
- break;
- default:
- spillVirtReg(MI, PhysRegState[Alias]);
- PhysRegState[Alias] = regDisabled;
- break;
- }
- }
- }
- }
+ definePhysReg(MI, BestReg, regFree);
return assignVirtToPhysReg(LRE, BestReg);
}
Hint = DstReg;
}
allocVirtReg(MI, *LRI, Hint);
- } else
- addKillFlag(LR); // Kill before redefine.
+ } else if (LR.LastUse) {
+ // Redefining a live register - kill at the last use, unless it is this
+ // instruction defining VirtReg multiple times.
+ if (LR.LastUse != MI || LR.LastUse->getOperand(LR.LastOpNum).isUse())
+ addKillFlag(LR);
+ }
assert(LR.PhysReg && "Register not assigned");
LR.LastUse = MI;
LR.LastOpNum = OpNum;
return LRI;
}
-// setPhysReg - Change MO the refer the PhysReg, considering subregs.
-// This may invalidate MO if it is necessary to add implicit kills for a
-// superregister.
-// Return tru if MO kills its register.
-bool RAFast::setPhysReg(MachineOperand &MO, unsigned PhysReg) {
+// setPhysReg - Change operand OpNum in MI the refer the PhysReg, considering
+// subregs. This may invalidate any operand pointers.
+// Return true if the operand kills its register.
+bool RAFast::setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg) {
+ MachineOperand &MO = MI->getOperand(OpNum);
if (!MO.getSubReg()) {
MO.setReg(PhysReg);
return MO.isKill() || MO.isDead();
MO.setSubReg(0);
if (MO.isUse()) {
if (MO.isKill()) {
- MO.getParent()->addRegisterKilled(PhysReg, TRI, true);
+ MI->addRegisterKilled(PhysReg, TRI, true);
return true;
}
return false;
}
// A subregister def implicitly defines the whole physreg.
if (MO.isDead()) {
- MO.getParent()->addRegisterDead(PhysReg, TRI, true);
+ MI->addRegisterDead(PhysReg, TRI, true);
return true;
}
- MO.getParent()->addRegisterDefined(PhysReg, TRI);
+ MI->addRegisterDefined(PhysReg, TRI);
return false;
}
E = MBB->livein_end(); I != E; ++I)
definePhysReg(MII, *I, regReserved);
- SmallVector<unsigned, 8> PhysECs;
+ SmallVector<unsigned, 8> PhysECs, VirtDead;
SmallVector<MachineInstr*, 32> Coalesced;
// Otherwise, sequentially allocate each instruction in the MBB.
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
LiveRegMap::iterator LRI = LiveVirtRegs.find(Reg);
if (LRI != LiveVirtRegs.end())
- setPhysReg(MO, LRI->second.PhysReg);
+ setPhysReg(MI, i, LRI->second.PhysReg);
else
MO.setReg(0); // We can't allocate a physreg for a DebugValue, sorry!
}
LiveRegMap::iterator LRI = reloadVirtReg(MI, i, Reg, CopyDst);
unsigned PhysReg = LRI->second.PhysReg;
CopySrc = (CopySrc == Reg || CopySrc == PhysReg) ? PhysReg : 0;
- if (setPhysReg(MO, PhysReg))
+ if (setPhysReg(MI, i, PhysReg))
killVirtReg(LRI);
} else if (MO.isEarlyClobber()) {
+ // Note: defineVirtReg may invalidate MO.
LiveRegMap::iterator LRI = defineVirtReg(MI, i, Reg, 0);
unsigned PhysReg = LRI->second.PhysReg;
- setPhysReg(MO, PhysReg);
+ setPhysReg(MI, i, PhysReg);
PhysECs.push_back(PhysReg);
}
}
}
LiveRegMap::iterator LRI = defineVirtReg(MI, i, Reg, CopySrc);
unsigned PhysReg = LRI->second.PhysReg;
- if (setPhysReg(MO, PhysReg)) {
- killVirtReg(LRI);
+ if (setPhysReg(MI, i, PhysReg)) {
+ VirtDead.push_back(Reg);
CopyDst = 0; // cancel coalescing;
} else
CopyDst = (CopyDst == Reg || CopyDst == PhysReg) ? PhysReg : 0;
}
+ // Kill dead defs after the scan to ensure that multiple defs of the same
+ // register are allocated identically. We didn't need to do this for uses
+ // because we are crerating our own kill flags, and they are always at the
+ // last use.
+ for (unsigned i = 0, e = VirtDead.size(); i != e; ++i)
+ killVirtReg(VirtDead[i]);
+ VirtDead.clear();
+
MRI->addPhysRegsUsed(UsedInInstr);
if (CopyDst && CopyDst == CopySrc && CopyDstSub == CopySrcSub) {
DEBUG(dbgs() << "********** FAST REGISTER ALLOCATION **********\n"
<< "********** Function: "
<< ((Value*)Fn.getFunction())->getName() << '\n');
- if (VerifyFastRegalloc)
- Fn.verify(this, true);
MF = &Fn;
MRI = &MF->getRegInfo();
TM = &Fn.getTarget();