When processing frame index virtual registers, consider all available registers
authorJim Grosbach <grosbach@apple.com>
Thu, 8 Jul 2010 00:38:54 +0000 (00:38 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 8 Jul 2010 00:38:54 +0000 (00:38 +0000)
(if there are any) and use the one which remains available for the longest
rather than just using the first one. This should help enable better re-use
of the loaded frame index values. rdar://7318760

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107847 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/RegisterScavenging.h
lib/CodeGen/PrologEpilogInserter.cpp
lib/CodeGen/RegisterScavenging.cpp

index 84b726d73fb3bf3db89752d4af55f7c19be30c04..c99ea18f6106bf72e0bb5a63d4ec532f037eeff9 100644 (file)
@@ -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
index d6ee03477de75820eb67c3360497838912c6b6fb..d1112d3c14aaaf50184087ab3ec62445c81c9106 100644 (file)
@@ -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;
           }
index 3eefedadf29e1d7e7bf2a67a62345604ac822cb4..8a1ef5adf7909cd7fae1f90e78d6ea7309d7c17a 100644 (file)
@@ -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.