Add hook for re-using virtual base registers for local stack slot access.
authorJim Grosbach <grosbach@apple.com>
Wed, 18 Aug 2010 17:57:37 +0000 (17:57 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 18 Aug 2010 17:57:37 +0000 (17:57 +0000)
Nothing fancy, just ask the target if any currently available base reg
is in range for the instruction under consideration and use the first one
that is. Placeholder ARM implementation simply returns false for now.

ongoing saga of rdar://8277890

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

include/llvm/Target/TargetRegisterInfo.h
lib/CodeGen/LocalStackSlotAllocation.cpp
lib/Target/ARM/ARMBaseRegisterInfo.cpp
lib/Target/ARM/ARMBaseRegisterInfo.h

index b1cf3e9db4ee95f93e565fa6436b813c472d50a2..e36cc4f9cec46095be3ac45360202fb466ca3fd8 100644 (file)
@@ -659,6 +659,13 @@ public:
     assert(0 && "resolveFrameIndex does not exist on this target");
   }
 
+  /// isBaseRegInRange - Determine whether a given base register definition
+  /// is in range to resolve a frame index.
+  virtual bool isBaseRegInRange(const MachineInstr *MI, unsigned Reg,
+                                int64_t Offset) const {
+    assert(0 && "isBaseRegInRange does not exist on this target");
+    return false; // Must return a value in order to compile with VS 2005
+  }
 
   /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
   /// frame setup/destroy instructions if they exist (-1 otherwise).  Some
index 3927beec1144dd51e2c20f2fc49ffe19c946ecba..219b845c0210b482c724bf8a96a7aec462adda6d 100644 (file)
@@ -146,6 +146,20 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
   MFI->setLocalFrameMaxAlign(MaxAlign);
 }
 
+static inline bool
+lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
+                       std::pair<unsigned, int64_t> &RegOffset,
+                       const MachineInstr *MI,
+                       const TargetRegisterInfo *TRI) {
+  unsigned e = Regs.size();
+  for (unsigned i = 0; i < e; ++i) {
+    RegOffset = Regs[i];
+    if (TRI->isBaseRegInRange(MI, RegOffset.first, RegOffset.second))
+      return true;
+  }
+  return false;
+}
+
 void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
   // Scan the function's instructions looking for frame index references.
   // For each, ask the target if it wants a virtual base register for it
@@ -169,6 +183,9 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
       if (MI->isDebugValue())
         continue;
 
+      // A base register definition is a register+offset pair.
+      SmallVector<std::pair<unsigned, int64_t>, 8> BaseRegisters;
+
       // For now, allocate the base register(s) within the basic block
       // where they're used, and don't try to keep them around outside
       // of that. It may be beneficial to try sharing them more broadly
@@ -186,27 +203,39 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
 
           DEBUG(dbgs() << "Considering: " << *MI);
           if (TRI->needsFrameBaseReg(MI, i)) {
+            unsigned BaseReg = 0;
+            unsigned Offset = 0;
+
             DEBUG(dbgs() << "  Replacing FI in: " << *MI);
-            // FIXME: Make sure any new base reg is aligned reasonably. TBD
-            // what "reasonably" really means. Conservatively, can just
-            // use the alignment of the local block.
 
             // If we have a suitable base register available, use it; otherwise
             // create a new one.
-            // FIXME: For the moment, just always create a new one.
-
-            const TargetRegisterClass *RC = TRI->getPointerRegClass();
-            unsigned BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
 
-            // Tell the target to insert the instruction to initialize
-            // the base register.
-            TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx);
+            std::pair<unsigned, int64_t> RegOffset;
+            if (lookupCandidateBaseReg(BaseRegisters, RegOffset, MI, TRI)) {
+              // We found a register to reuse.
+              BaseReg = RegOffset.first;
+              Offset = RegOffset.second;
+            } else {
+              // No previously defined register was in range, so create a
+              // new one.
+              const TargetRegisterClass *RC = TRI->getPointerRegClass();
+              BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
+
+              // Tell the target to insert the instruction to initialize
+              // the base register.
+              TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx);
+
+              BaseRegisters.push_back(std::pair<unsigned, int64_t>(BaseReg,
+                                                                   Offset));
+              ++NumBaseRegisters;
+            }
+            assert(BaseReg != 0 && "Unable to allocate virtual base register!");
 
             // Modify the instruction to use the new base register rather
             // than the frame index operand.
-            TRI->resolveFrameIndex(I, BaseReg, 0);
+            TRI->resolveFrameIndex(I, BaseReg, Offset);
 
-            ++NumBaseRegisters;
             ++NumReplacements;
           }
 
index 23fe6216f610dc0177850238a0b2c8b3cf51ebfd..b498075999f13b3d5784f8896aaa6c3c28aa3c89 100644 (file)
@@ -1451,6 +1451,12 @@ ARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
   assert (Done && "Unable to resolve frame index!");
 }
 
+bool ARMBaseRegisterInfo::isBaseRegInRange(const MachineInstr *MI,
+                                           unsigned Reg, int64_t Offset) const {
+
+  return false;
+}
+
 unsigned
 ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
                                          int SPAdj, FrameIndexValue *Value,
index 7570d1fd16198882af919ac3c86ecc81f116eb79..716c91d9ad09fa67329686601f72a6e3cb3e2591 100644 (file)
@@ -110,6 +110,8 @@ public:
                                     unsigned BaseReg, int FrameIdx) const;
   void resolveFrameIndex(MachineBasicBlock::iterator I,
                          unsigned BaseReg, int64_t Offset) const;
+  bool isBaseRegInRange(const MachineInstr *MI, unsigned Reg,
+                        int64_t Offset) const;
 
   bool cannotEliminateFrame(const MachineFunction &MF) const;