[llvm-commits] [llvm] r83336 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/RegisterScavenging.cpp lib/Target/ARM/ARMBaseRegisterInfo.cpp lib/Target/ARM/Thumb1RegisterInfo.cpp lib/Target/ARM/Thumb1RegisterInfo.h

Jim Grosbach grosbach at apple.com
Mon Oct 5 15:30:23 PDT 2009


Author: grosbach
Date: Mon Oct  5 17:30:23 2009
New Revision: 83336

URL: http://llvm.org/viewvc/llvm-project?rev=83336&view=rev
Log:
In Thumb1, the register scavenger is not always able to use an emergency
spill slot. When frame references are via the frame pointer, they will be
negative, but Thumb1 load/store instructions only allow positive immediate
offsets. Instead, Thumb1 will spill to R12.


Modified:
    llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
    llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
    llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp
    llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp
    llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h

Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=83336&r1=83335&r2=83336&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Mon Oct  5 17:30:23 2009
@@ -635,6 +635,24 @@
   virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
   }
 
+  /// saveScavengerRegister - Save the register so it can be used by the
+  /// register scavenger. Return true if the register was saved, false
+  /// otherwise. If this function does not save the register, the scavenger
+  /// will instead spill it to the emergency spill slot.
+  ///
+  virtual bool saveScavengerRegister(MachineBasicBlock &MBB,
+                                     MachineBasicBlock::iterator I,
+                                     const TargetRegisterClass *RC,
+                                     unsigned Reg) const {return false;}
+
+  /// restoreScavengerRegister - Restore a register saved by
+  /// saveScavengerRegister().
+  ///
+  virtual void restoreScavengerRegister(MachineBasicBlock &MBB,
+                                        MachineBasicBlock::iterator I,
+                                        const TargetRegisterClass *RC,
+                                        unsigned Reg) const {}
+
   /// eliminateFrameIndex - This method must be overriden to eliminate abstract
   /// frame indices from instructions which may use them.  The instruction
   /// referenced by the iterator contains an MO_FrameIndex operand which must be

Modified: llvm/trunk/lib/CodeGen/RegisterScavenging.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterScavenging.cpp?rev=83336&r1=83335&r2=83336&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterScavenging.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterScavenging.cpp Mon Oct  5 17:30:23 2009
@@ -268,9 +268,6 @@
 unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
                                         MachineBasicBlock::iterator I,
                                         int SPAdj) {
-  assert(ScavengingFrameIndex >= 0 &&
-         "Cannot scavenge a register without an emergency spill slot!");
-
   // Mask off the registers which are not in the TargetRegisterClass.
   BitVector Candidates(NumPhysRegs, false);
   CreateRegClassMask(RC, Candidates);
@@ -301,14 +298,23 @@
   // Avoid infinite regress
   ScavengedReg = SReg;
 
-  // Spill the scavenged register before I.
-  TII->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC);
-  MachineBasicBlock::iterator II = prior(I);
-  TRI->eliminateFrameIndex(II, SPAdj, this);
+  // If the target knows how to save/restore the register, let it do so;
+  // otherwise, use the emergency stack spill slot.
+  if (!TRI->saveScavengerRegister(*MBB, I, RC, SReg)) {
+    // Spill the scavenged register before I.
+    assert(ScavengingFrameIndex >= 0 &&
+           "Cannot scavenging register without an emergency spill slot!");
+    TII->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC);
+    MachineBasicBlock::iterator II = prior(I);
+    TRI->eliminateFrameIndex(II, SPAdj, this);
+
+    // Restore the scavenged register before its use (or first terminator).
+    TII->loadRegFromStackSlot(*MBB, UseMI, SReg, ScavengingFrameIndex, RC);
+  } else
+    TRI->restoreScavengerRegister(*MBB, UseMI, RC, SReg);
 
-  // Restore the scavenged register before its use (or first terminator).
-  TII->loadRegFromStackSlot(*MBB, UseMI, SReg, ScavengingFrameIndex, RC);
   ScavengeRestore = prior(UseMI);
+
   // Doing this here leads to infinite regress.
   // ScavengedReg = SReg;
   ScavengedRC = RC;

Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=83336&r1=83335&r2=83336&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Mon Oct  5 17:30:23 2009
@@ -660,8 +660,7 @@
       // off the frame pointer, the effective stack size is 4 bytes larger
       // since the FP points to the stack slot of the previous FP.
       if (estimateStackSize(MF, MFI) + (hasFP(MF) ? 4 : 0)
-          >= estimateRSStackSizeLimit(MF)
-          || AFI->isThumb1OnlyFunction()) {
+          >= estimateRSStackSizeLimit(MF)) {
         // 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;
@@ -690,7 +689,8 @@
             MF.getRegInfo().setPhysRegUsed(Extras[i]);
             AFI->setCSRegisterIsSpilled(Extras[i]);
           }
-        } else {
+        } else if (!AFI->isThumb1OnlyFunction()) {
+          // note: Thumb1 functions spill to R12, not the stack.
           // Reserve a slot closest to SP or frame pointer.
           const TargetRegisterClass *RC = ARM::GPRRegisterClass;
           RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),

Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp?rev=83336&r1=83335&r2=83336&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Mon Oct  5 17:30:23 2009
@@ -402,6 +402,31 @@
   return 0;
 }
 
+/// saveScavengerRegister - Save the register so it can be used by the
+/// register scavenger. Return true.
+bool Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
+                                               MachineBasicBlock::iterator I,
+                                               const TargetRegisterClass *RC,
+                                               unsigned Reg) const {
+  // Thumb1 can't use the emergency spill slot on the stack because
+  // ldr/str immediate offsets must be positive, and if we're referencing
+  // off the frame pointer (if, for example, there are alloca() calls in
+  // the function, the offset will be negative. Use R12 instead since that's
+  // a call clobbered register that we know won't be used in Thumb1 mode.
+
+  TII.copyRegToReg(MBB, I, ARM::R12, Reg, ARM::GPRRegisterClass, RC);
+  return true;
+}
+
+/// restoreScavengerRegister - restore a registers saved by
+// saveScavengerRegister().
+void Thumb1RegisterInfo::restoreScavengerRegister(MachineBasicBlock &MBB,
+                                               MachineBasicBlock::iterator I,
+                                               const TargetRegisterClass *RC,
+                                               unsigned Reg) const {
+  TII.copyRegToReg(MBB, I, Reg, ARM::R12, RC, ARM::GPRRegisterClass);
+}
+
 void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
                                              int SPAdj, RegScavenger *RS) const{
   unsigned i = 0;

Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h?rev=83336&r1=83335&r2=83336&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h Mon Oct  5 17:30:23 2009
@@ -54,6 +54,14 @@
                         unsigned FrameReg, int Offset,
                         unsigned MOVOpc, unsigned ADDriOpc, unsigned SUBriOpc) const;
 
+  bool saveScavengerRegister(MachineBasicBlock &MBB,
+                             MachineBasicBlock::iterator I,
+                             const TargetRegisterClass *RC,
+                             unsigned Reg) const;
+  void restoreScavengerRegister(MachineBasicBlock &MBB,
+                                MachineBasicBlock::iterator I,
+                                const TargetRegisterClass *RC,
+                                unsigned Reg) const;
   void eliminateFrameIndex(MachineBasicBlock::iterator II,
                            int SPAdj, RegScavenger *RS = NULL) const;
 





More information about the llvm-commits mailing list