[llvm-commits] CVS: llvm/lib/Target/ARM/ARMRegisterInfo.cpp ARMRegisterInfo.h

Evan Cheng evan.cheng at apple.com
Tue Mar 6 02:04:13 PST 2007



Changes in directory llvm/lib/Target/ARM:

ARMRegisterInfo.cpp updated: 1.79 -> 1.80
ARMRegisterInfo.h updated: 1.15 -> 1.16
---
Log message:

Scavenge a register using the register scavenger when needed.

---
Diffs of the changes:  (+111 -14)

 ARMRegisterInfo.cpp |  115 ++++++++++++++++++++++++++++++++++++++++++++++++----
 ARMRegisterInfo.h   |   10 +---
 2 files changed, 111 insertions(+), 14 deletions(-)


Index: llvm/lib/Target/ARM/ARMRegisterInfo.cpp
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.79 llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.80
--- llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.79	Thu Mar  1 19:17:17 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.cpp	Tue Mar  6 04:03:56 2007
@@ -85,11 +85,6 @@
   : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
     TII(tii), STI(sti),
     FramePtr(STI.useThumbBacktraces() ? ARM::R7 : ARM::R11) {
-  RS = (EnableScavenging) ? new RegScavenger() : NULL;
-}
-
-ARMRegisterInfo::~ARMRegisterInfo() {
-  delete RS;
 }
 
 bool ARMRegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
@@ -329,6 +324,25 @@
 }
 
 bool
+ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
+  switch (Reg) {
+  default: break;
+  case ARM::SP:
+  case ARM::PC:
+    return true;
+  case ARM::R7:
+  case ARM::R11:
+    if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
+      return true;
+    break;
+  case ARM::R9:
+    return STI.isR9Reserved();
+  }
+
+  return false;
+}
+
+bool
 ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
   const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
   return EnableScavenging && !AFI->isThumbFunction();
@@ -918,15 +932,34 @@
     // to form it with a series of ADDri's.  Do this by taking 8-bit chunks
     // out of 'Offset'.
     unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
-    assert(ScratchReg && "Unable to find a free register!");
+    if (ScratchReg == 0)
+      // No register is "free". Scavenge a register.
+      ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II);
     emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
                             isSub ? -Offset : Offset, TII);
     MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
   }
 }
 
-void ARMRegisterInfo::
-processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
+static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
+  const MachineFrameInfo *FFI = MF.getFrameInfo();
+  int Offset = 0;
+  for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
+    int FixedOff = -FFI->getObjectOffset(i);
+    if (FixedOff > Offset) Offset = FixedOff;
+  }
+  for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
+    Offset += FFI->getObjectSize(i);
+    unsigned Align = FFI->getObjectAlignment(i);
+    // Adjust to alignment boundary
+    Offset = (Offset+Align-1)/Align*Align;
+  }
+  return (unsigned)Offset;
+}
+
+void
+ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+                                                      RegScavenger *RS) const {
   // This tells PEI to spill the FP as if it is any other callee-save register
   // to take advantage the eliminateFrameIndex machinery. This also ensures it
   // is spilled in the order specified by getCalleeSavedRegs() to make it easier
@@ -1020,6 +1053,7 @@
     }
   }
 
+  bool ExtraCSSpill = false;
   if (!CanEliminateFrame || hasFP(MF)) {
     AFI->setHasStackFrame(true);
 
@@ -1032,6 +1066,7 @@
       UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
                                     UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
       ForceLRSpill = false;
+      ExtraCSSpill = true;
     }
 
     // Darwin ABI requires FP to point to the stack slot that contains the
@@ -1050,10 +1085,74 @@
         unsigned Reg = UnspilledCS1GPRs.front();
         MF.changePhyRegUsed(Reg, true);
         AFI->setCSRegisterIsSpilled(Reg);
+        if (!isReservedReg(MF, Reg))
+          ExtraCSSpill = true;
       } else if (!UnspilledCS2GPRs.empty()) {
         unsigned Reg = UnspilledCS2GPRs.front();
         MF.changePhyRegUsed(Reg, true);
         AFI->setCSRegisterIsSpilled(Reg);
+        if (!isReservedReg(MF, Reg))
+          ExtraCSSpill = true;
+      }
+    }
+
+    // Estimate if we might need to scavenge a register at some point in order
+    // to materialize a stack offset. If so, either spill one additiona
+    // callee-saved register or reserve a special spill slot to facilitate
+    // register scavenging.
+    if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) {
+      MachineFrameInfo  *MFI = MF.getFrameInfo();
+      unsigned Size = estimateStackSize(MF, MFI);
+      unsigned Limit = (1 << 12) - 1;
+      for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
+        for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {
+          for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+            if (I->getOperand(i).isFrameIndex()) {
+              unsigned Opcode = I->getOpcode();
+              const TargetInstrDescriptor &Desc = TII.get(Opcode);
+              unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+              if (AddrMode == ARMII::AddrMode3) {
+                Limit = (1 << 8) - 1;
+                goto DoneEstimating;
+              } else if (AddrMode == ARMII::AddrMode5) {
+                Limit = ((1 << 8) - 1) * 4;
+                goto DoneEstimating;
+              }
+            }
+        }
+    DoneEstimating:
+      if (Size >= Limit) {
+        // If any non-reserved CS register isn't spilled, just spill one or two
+        // extra. That should take care of it!
+        unsigned NumExtras = TargetAlign / 4;
+        SmallVector<unsigned, 2> Extras;
+        while (NumExtras && !UnspilledCS1GPRs.empty()) {
+          unsigned Reg = UnspilledCS1GPRs.back();
+          UnspilledCS1GPRs.pop_back();
+          if (!isReservedReg(MF, Reg)) {
+            Extras.push_back(Reg);
+            NumExtras--;
+          }
+        }
+        while (NumExtras && !UnspilledCS2GPRs.empty()) {
+          unsigned Reg = UnspilledCS2GPRs.back();
+          UnspilledCS2GPRs.pop_back();
+          if (!isReservedReg(MF, Reg)) {
+            Extras.push_back(Reg);
+            NumExtras--;
+          }
+        }
+        if (Extras.size() && NumExtras == 0) {
+          for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
+            MF.changePhyRegUsed(Extras[i], true);
+            AFI->setCSRegisterIsSpilled(Extras[i]);
+          }
+        } else {
+          // Reserve a slot closest to SP or frame pointer.
+          const TargetRegisterClass *RC = &ARM::GPRRegClass;
+          RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
+                                                           RC->getAlignment()));
+        }
       }
     }
   }


Index: llvm/lib/Target/ARM/ARMRegisterInfo.h
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.h:1.15 llvm/lib/Target/ARM/ARMRegisterInfo.h:1.16
--- llvm/lib/Target/ARM/ARMRegisterInfo.h:1.15	Tue Feb 27 18:59:19 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.h	Tue Mar  6 04:03:56 2007
@@ -27,17 +27,12 @@
   const TargetInstrInfo &TII;
   const ARMSubtarget &STI;
 private:
-  /// RS - An instance of the register scavenger.
-  RegScavenger *RS;
-
   /// FramePtr - ARM physical register used as frame ptr.
   unsigned FramePtr;
 
 public:
   ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
 
-  ~ARMRegisterInfo();
-
   /// getRegisterNumbering - Given the enum value for some register, e.g.
   /// ARM::LR, return the number that it corresponds to (e.g. 14).
   static unsigned getRegisterNumbering(unsigned RegEnum);
@@ -74,6 +69,8 @@
 
   BitVector getReservedRegs(const MachineFunction &MF) const;
 
+  bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
+
   bool requiresRegisterScavenging(const MachineFunction &MF) const;
 
   bool hasFP(const MachineFunction &MF) const;
@@ -85,7 +82,8 @@
   void eliminateFrameIndex(MachineBasicBlock::iterator II,
                            RegScavenger *RS = NULL) const;
 
-  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const;
+  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+                                            RegScavenger *RS = NULL) const;
 
   void emitPrologue(MachineFunction &MF) const;
   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;






More information about the llvm-commits mailing list