Reg Scavenging generalization (Thumb support):
authorJohn Mosby <ojomojo@gmail.com>
Thu, 6 Aug 2009 16:32:47 +0000 (16:32 +0000)
committerJohn Mosby <ojomojo@gmail.com>
Thu, 6 Aug 2009 16:32:47 +0000 (16:32 +0000)
- start support for new PEI w/reg alloc, allow running RS from emit{Pro,Epi}logue() target hooks.
- fix minor issue with recursion detection.

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

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

index fc75aea2bcb8b76901f50026fc4f70e7ffae513e..dbd9032c80b396be76ba52aef0b9cfc6528f53bb 100644 (file)
@@ -86,6 +86,10 @@ public:
   /// basic block.
   void enterBasicBlock(MachineBasicBlock *mbb);
 
+  /// initRegState - allow resetting register state info for multiple
+  /// passes over/within the same function.
+  void initRegState();
+
   /// forward / backward - Move the internal MBB iterator and update register
   /// states.
   void forward();
index 97751cd9fc8800c1022a77185e06aa887fa35288..c3e03ab676e53e0b16b5e3c5ea2b86073c68ddf1 100644 (file)
@@ -16,6 +16,7 @@
 
 #define DEBUG_TYPE "reg-scavenging"
 #include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -84,6 +85,28 @@ void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
       RegsAvailable.set(SubReg);
 }
 
+void RegScavenger::initRegState() {
+  ScavengedReg = 0;
+  ScavengedRC = NULL;
+  ScavengeRestore = NULL;
+  CurrDist = 0;
+  DistanceMap.clear();
+
+  // All registers started out unused.
+  RegsAvailable.set();
+
+  // Reserved registers are always used.
+  RegsAvailable ^= ReservedRegs;
+
+  // Live-in registers are in use.
+  if (MBB) {
+    if (!MBB->livein_empty())
+      for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
+             E = MBB->livein_end(); I != E; ++I)
+        setUsed(*I);
+  }
+}
+
 void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
   MachineFunction &MF = *mbb->getParent();
   const TargetMachine &TM = MF.getTarget();
@@ -94,6 +117,7 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
   assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) &&
          "Target changed?");
 
+  // Self-initialize.
   if (!MBB) {
     NumPhysRegs = TRI->getNumRegs();
     RegsAvailable.resize(NumPhysRegs);
@@ -104,29 +128,23 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
     // Create callee-saved registers bitvector.
     CalleeSavedRegs.resize(NumPhysRegs);
     const unsigned *CSRegs = TRI->getCalleeSavedRegs();
-    if (CSRegs != NULL)
-      for (unsigned i = 0; CSRegs[i]; ++i)
-        CalleeSavedRegs.set(CSRegs[i]);
+    if (CSRegs != NULL) {
+      // At this point we know which CSRs are used by the current function,
+      // so allow those that are _not_ already used to be available to RS.
+      MachineFrameInfo *FFI = MF.getFrameInfo();
+      const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
+
+      for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+        CalleeSavedRegs.set(CSI[i].getReg());
+      }
+    }
   }
 
-  MBB = mbb;
-  ScavengedReg = 0;
-  ScavengedRC = NULL;
-  ScavengeRestore = NULL;
-  CurrDist = 0;
-  DistanceMap.clear();
-
-  // All registers started out unused.
-  RegsAvailable.set();
-
-  // Reserved registers are always used.
-  RegsAvailable ^= ReservedRegs;
-
-  // Live-in registers are in use.
-  if (!MBB->livein_empty())
-    for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
-           E = MBB->livein_end(); I != E; ++I)
-      setUsed(*I);
+  //  RS used within emit{Pro,Epi}logue()
+  if (mbb != MBB) {
+    MBB = mbb;
+    initRegState();
+  }
 
   Tracking = false;
 }
@@ -216,7 +234,7 @@ void RegScavenger::forward() {
       UseMOs.push_back(std::make_pair(&MO,i));
     else if (MO.isEarlyClobber())
       EarlyClobberMOs.push_back(std::make_pair(&MO,i));
-    else
+    else if (MO.isDef())
       DefMOs.push_back(std::make_pair(&MO,i));
   }
 
@@ -227,7 +245,9 @@ void RegScavenger::forward() {
     unsigned Idx = UseMOs[i].second;
     unsigned Reg = MO.getReg();
 
-    assert(isUsed(Reg) && "Using an undefined register!");
+    // Allow free CSRs to be processed as uses.
+    assert((isUsed(Reg) || !CalleeSavedRegs[Reg]) &&
+           "Using an undefined register!");
 
     // Two-address operands implicitly kill.
     if ((MO.isKill() || MI->isRegTiedToDefOperand(Idx)) && !isReserved(Reg)) {
@@ -427,7 +447,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
   // Mask off the registers which are not in the TargetRegisterClass.
   BitVector Candidates(NumPhysRegs, false);
   CreateRegClassMask(RC, Candidates);
-  Candidates ^= ReservedRegs & Candidates; // Do not include reserved registers.
+  // Do not include reserved registers.
+  Candidates ^= ReservedRegs & Candidates;
 
   // Exclude all the registers being used by the instruction.
   for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
@@ -463,8 +484,11 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
   assert(ScavengedReg == 0 &&
          "Scavenger slot is live, unable to scavenge another register!");
 
-  // Make sure SReg is marked as used. It could be considered available if it is
-  // one of the callee saved registers, but hasn't been spilled.
+  // Avoid infinite regress
+  ScavengedReg = SReg;
+
+  // Make sure SReg is marked as used. It could be considered available
+  // if it is one of the callee saved registers, but hasn't been spilled.
   if (!isUsed(SReg)) {
     MBB->addLiveIn(SReg);
     setUsed(SReg);
@@ -480,7 +504,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
     ? MachineBasicBlock::iterator(MaxUseMI) : MBB->getFirstTerminator();
   TII->loadRegFromStackSlot(*MBB, II, SReg, ScavengingFrameIndex, RC);
   ScavengeRestore = prior(II);
-  ScavengedReg = SReg;
+  // Doing this here leads to infinite regress
+  // ScavengedReg = SReg;
   ScavengedRC = RC;
 
   return SReg;