diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 84b726d73fb..c99ea18f610 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -98,10 +98,24 @@ public: /// getRegsUsed - return all registers currently in use in used. void getRegsUsed(BitVector &used, bool includeReserved); + /// getRegsAvailable - Return all available registers in the register class + /// in Mask. + void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask); + /// FindUnusedReg - Find a unused register of the specified register class. /// Return 0 if none is found. unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; + /// findSurvivorReg - Return the candidate register that is unused for the + /// longest after StartMI. UseMI is set to the instruction where the search + /// stopped. + /// + /// No more than InstrLimit instructions are inspected. + unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, + BitVector &Candidates, + unsigned InstrLimit, + MachineBasicBlock::iterator &UseMI); + /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of /// ScavengingFrameIndex. void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; } @@ -147,11 +161,6 @@ private: /// Add Reg and its aliases to BV. void addRegWithAliases(BitVector &BV, unsigned Reg); - unsigned findSurvivorReg(MachineBasicBlock::iterator MI, - BitVector &Candidates, - unsigned InstrLimit, - MachineBasicBlock::iterator &UseMI); - }; } // End llvm namespace diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index d6ee03477de..d1112d3c14a 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -885,10 +885,20 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { // Scavenge a new scratch register CurrentVirtReg = Reg; const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); - CurrentScratchReg = RS->FindUnusedReg(RC); - if (CurrentScratchReg == 0) + const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); + BitVector Candidates(TRI->getNumRegs()); + RS->getRegsAvailable(RC, Candidates); + + // If there are any registers available, use the one that's + // unused for the longest after this instruction. That increases + // the ability to reuse the value. + if (Candidates.any()) { + MachineBasicBlock::iterator UMI; + CurrentScratchReg = RS->findSurvivorReg(I, Candidates, 25, UMI); + } else { // No register is "free". Scavenge a register. CurrentScratchReg = RS->scavengeRegister(RC, I, SPAdj); + } PrevValue = Value; } diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 3eefedadf29..8a1ef5adf79 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -242,8 +242,18 @@ unsigned RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const { return 0; } +/// getRegsAvailable - Return all available registers in the register class +/// in Mask. +void RegScavenger::getRegsAvailable(const TargetRegisterClass *RC, + BitVector &Mask) { + for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); + I != E; ++I) + if (!isAliasUsed(*I)) + Mask.set(*I); +} + /// findSurvivorReg - Return the candidate register that is unused for the -/// longest after MBBI. UseMI is set to the instruction where the search +/// longest after StargMII. UseMI is set to the instruction where the search /// stopped. /// /// No more than InstrLimit instructions are inspected.