Simplify the tracking of virtual frame index registers. Ranges cannot overlap,

so a simple "current register" will suffice. Also add some additional
sanity-checking assertions to make sure things are as we expect.

llvm-svn: 83081
This commit is contained in:
Jim Grosbach 2009-09-29 18:23:15 +00:00
parent 6f6bc51d3b
commit 0e6ac9047c

View File

@ -727,6 +727,9 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
} }
} }
/// scavengeFrameVirtualRegs - Replace all frame index virtual registers
/// with physical registers. Use the register scavenger to find an
/// appropriate register to use.
void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
@ -735,33 +738,41 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
E = Fn.end(); BB != E; ++BB) { E = Fn.end(); BB != E; ++BB) {
RS->enterBasicBlock(BB); RS->enterBasicBlock(BB);
// Keep a map of which scratch reg we use for each virtual reg. unsigned CurrentVirtReg = 0;
// FIXME: Is a map like this the best solution? Seems like overkill, unsigned CurrentScratchReg;
// but to get rid of it would need some fairly strong assumptions
// that may not be valid as this gets smarter about reuse and such.
IndexedMap<unsigned, VirtReg2IndexFunctor> ScratchRegForVirtReg;
ScratchRegForVirtReg.grow(Fn.getRegInfo().getLastVirtReg());
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
MachineInstr *MI = I; MachineInstr *MI = I;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
if (MI->getOperand(i).isReg()) { if (MI->getOperand(i).isReg()) {
unsigned Reg = MI->getOperand(i).getReg(); unsigned Reg = MI->getOperand(i).getReg();
if (Reg && TRI->isVirtualRegister(Reg)) { if (Reg == 0 || !TRI->isVirtualRegister(Reg))
// If we already have a scratch for this virtual register, use it continue;
unsigned NewReg = ScratchRegForVirtReg[Reg];
if (!NewReg) { // If we already have a scratch for this virtual register, use it
const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); if (Reg != CurrentVirtReg) {
NewReg = RS->FindUnusedReg(RC); // When we first encounter a new virtual register, it
if (NewReg == 0) // must be a definition.
// No register is "free". Scavenge a register. assert(MI->getOperand(i).isDef() &&
// FIXME: Track SPAdj. Zero won't always be right "frame index virtual missing def!");
NewReg = RS->scavengeRegister(RC, I, 0); // We can't have nested virtual register live ranges because
assert (NewReg && "unable to scavenge register!"); // there's only a guarantee of one scavenged register at a time.
ScratchRegForVirtReg[Reg] = NewReg; assert (CurrentVirtReg == 0 &&
} "overlapping frame index virtual registers!");
MI->getOperand(i).setReg(NewReg); CurrentVirtReg = Reg;
const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg);
CurrentScratchReg = RS->FindUnusedReg(RC);
if (CurrentScratchReg == 0)
// No register is "free". Scavenge a register.
// FIXME: Track SPAdj. Zero won't always be right
CurrentScratchReg = RS->scavengeRegister(RC, I, 0);
} }
assert (CurrentScratchReg && "Missing scratch register!");
MI->getOperand(i).setReg(CurrentScratchReg);
// If this is the last use of the register, stop tracking it.
if (MI->getOperand(i).isKill())
CurrentVirtReg = 0;
} }
RS->forward(MI); RS->forward(MI);
} }