mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 13:37:07 +00:00
Calculate liveness on the fly for local registers.
When working top-down in a basic block, substituting physregs for virtregs, the use-def chains are kept up to date. That means we can recognize a virtreg kill by the use-def chain becoming empty. This makes the fast allocator independent of incoming kill flags. llvm-svn: 103866
This commit is contained in:
parent
9c2a75e5e3
commit
671a452627
@ -132,6 +132,8 @@ namespace {
|
||||
bool runOnMachineFunction(MachineFunction &Fn);
|
||||
void AllocateBasicBlock(MachineBasicBlock &MBB);
|
||||
int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC);
|
||||
bool isLastUseOfLocalReg(MachineOperand&);
|
||||
|
||||
void addKillFlag(LiveRegMap::iterator i);
|
||||
void killVirtReg(LiveRegMap::iterator i);
|
||||
void killVirtReg(unsigned VirtReg);
|
||||
@ -174,6 +176,26 @@ int RAFast::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) {
|
||||
return FrameIdx;
|
||||
}
|
||||
|
||||
/// isLastUseOfLocalReg - Return true if MO is the only remaining reference to
|
||||
/// its virtual register, and it is guaranteed to be a block-local register.
|
||||
///
|
||||
bool RAFast::isLastUseOfLocalReg(MachineOperand &MO) {
|
||||
// Check for non-debug uses or defs following MO.
|
||||
// This is the most likely way to fail - fast path it.
|
||||
MachineOperand *i = &MO;
|
||||
while ((i = i->getNextOperandForReg()))
|
||||
if (!i->isDebug())
|
||||
return false;
|
||||
|
||||
// If the register has ever been spilled or reloaded, we conservatively assume
|
||||
// it is a global register used in multiple blocks.
|
||||
if (StackSlotForVirtReg[MO.getReg()] != -1)
|
||||
return false;
|
||||
|
||||
// Check that the use/def chain has exactly one operand - MO.
|
||||
return &MRI->reg_nodbg_begin(MO.getReg()).getOperand() == &MO;
|
||||
}
|
||||
|
||||
/// addKillFlag - Set kill flags on last use of a virtual register.
|
||||
void RAFast::addKillFlag(LiveRegMap::iterator lri) {
|
||||
assert(lri != LiveVirtRegs.end() && "Killing unmapped virtual register");
|
||||
@ -566,6 +588,15 @@ unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||
TII->loadRegFromStackSlot(MBB, MI, lri->second.PhysReg, FrameIndex, RC,
|
||||
TRI);
|
||||
++NumLoads;
|
||||
} else if (lri->second.Dirty) {
|
||||
MachineOperand &MO = MI->getOperand(OpNum);
|
||||
if (isLastUseOfLocalReg(MO)) {
|
||||
DEBUG(dbgs() << "Killing last use: " << MO << "\n");
|
||||
MO.setIsKill();
|
||||
} else if (MO.isKill()) {
|
||||
DEBUG(dbgs() << "Clearing dubious kill: " << MO << "\n");
|
||||
MO.setIsKill(false);
|
||||
}
|
||||
}
|
||||
LiveReg &LR = lri->second;
|
||||
LR.LastUse = MI;
|
||||
|
Loading…
Reference in New Issue
Block a user