Freeze reserved registers before starting register allocation.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 5 Jan 2012 00:26:49 +0000 (00:26 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 5 Jan 2012 00:26:49 +0000 (00:26 +0000)
The register allocators don't currently support adding reserved
registers while they are running.  Extend the MRI API to keep track of
the set of reserved registers when register allocation started.

Target hooks like hasFP() and needsStackRealignment() can look at this
set to avoid reserving more registers during register allocation.

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

docs/ReleaseNotes.html
include/llvm/CodeGen/MachineRegisterInfo.h
lib/CodeGen/MachineRegisterInfo.cpp
lib/CodeGen/RegAllocBasic.cpp
lib/CodeGen/RegAllocFast.cpp
lib/CodeGen/RegAllocPBQP.cpp

index 7dd0b8d55069a0b88803272dc068d00ee91d3bce..011cbbd344c434e6d1e746e0b4e0a87f39b56c15 100644 (file)
@@ -351,6 +351,10 @@ Release Notes</a>.</h1>
   represent combinations of constraints from instructions and sub-registers.
   The synthetic register classes inherit most of their properties form their
   closest user-defined super-class.</li>
+  <li><code>MachineRegisterInfo</code> now allows the reserved registers to be
+  frozen when register allocation starts.  Target hooks should use the
+  <code>MRI->canReserveReg(FramePtr)</code> method to avoid accidentally
+  disabling frame pointer elimination during register allocation.</li>
 </ul>
 </div>
 
index 773683a748059fb1b10deb463dc209ac95d08442..34d454ebc9cd37936ae9273b5e8a961b3dfc382e 100644 (file)
@@ -57,7 +57,13 @@ class MachineRegisterInfo {
   /// so that the code generator knows which callee save registers to save and
   /// for other target specific uses.
   BitVector UsedPhysRegs;
-  
+
+  /// ReservedRegs - This is a bit vector of reserved registers.  The target
+  /// may change its mind about which registers should be reserved.  This
+  /// vector is the frozen set of reserved registers when register allocation
+  /// started.
+  BitVector ReservedRegs;
+
   /// LiveIns/LiveOuts - Keep track of the physical registers that are
   /// livein/liveout of the function.  Live in values are typically arguments in
   /// registers, live out values are typically return values in registers.
@@ -309,6 +315,37 @@ public:
   /// subregisters. That means that if R is used, so are all subregisters.
   void closePhysRegsUsed(const TargetRegisterInfo&);
 
+
+  //===--------------------------------------------------------------------===//
+  // Reserved Register Info
+  //===--------------------------------------------------------------------===//
+  //
+  // The set of reserved registers must be invariant during register
+  // allocation.  For example, the target cannot suddenly decide it needs a
+  // frame pointer when the register allocator has already used the frame
+  // pointer register for something else.
+  //
+  // These methods can be used by target hooks like hasFP() to avoid changing
+  // the reserved register set during register allocation.
+
+  /// freezeReservedRegs - Called by the register allocator to freeze the set
+  /// of reserved registers before allocation begins.
+  void freezeReservedRegs(const MachineFunction&);
+
+  /// reservedRegsFrozen - Returns true after freezeReservedRegs() was called
+  /// to ensure the set of reserved registers stays constant.
+  bool reservedRegsFrozen() const {
+    return !ReservedRegs.empty();
+  }
+
+  /// canReserveReg - Returns true if PhysReg can be used as a reserved
+  /// register.  Any register can be reserved before freezeReservedRegs() is
+  /// called.
+  bool canReserveReg(unsigned PhysReg) const {
+    return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
+  }
+
+
   //===--------------------------------------------------------------------===//
   // LiveIn/LiveOut Management
   //===--------------------------------------------------------------------===//
index c35b154aa1ad1ad60881740521eedc2a1726a4e8..67291a0eb8cbdf702082851a952f21d5cce67258 100644 (file)
@@ -259,3 +259,7 @@ void MachineRegisterInfo::dumpUses(unsigned Reg) const {
     I.getOperand().getParent()->dump();
 }
 #endif
+
+void MachineRegisterInfo::freezeReservedRegs(const MachineFunction &MF) {
+  ReservedRegs = TRI->getReservedRegs(MF);
+}
index 5496d69fd3df1aa381faee2de9cdb4a3b9911100..8019cf227bdc3db68e14e0382a76ca50e2b7ee69 100644 (file)
@@ -233,6 +233,7 @@ void RegAllocBase::init(VirtRegMap &vrm, LiveIntervals &lis) {
   MRI = &vrm.getRegInfo();
   VRM = &vrm;
   LIS = &lis;
+  MRI->freezeReservedRegs(vrm.getMachineFunction());
   RegClassInfo.runOnMachineFunction(vrm.getMachineFunction());
 
   const unsigned NumRegs = TRI->getNumRegs();
index c2656c5e5c870141cdebce4179844a7297d1db1d..93f39b6c661e4e39c6b4ad5d12a4aa619c0c7065 100644 (file)
@@ -1047,6 +1047,7 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) {
   TM = &Fn.getTarget();
   TRI = TM->getRegisterInfo();
   TII = TM->getInstrInfo();
+  MRI->freezeReservedRegs(Fn);
   RegClassInfo.runOnMachineFunction(Fn);
   UsedInInstr.resize(TRI->getNumRegs());
 
index a053cccc9e03b7ad2e699c02ba02fc2590ca728c..f8b0b9fa6eb88bff413c943e3e228b8cbc9a0966 100644 (file)
@@ -619,6 +619,7 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
   vrm = &getAnalysis<VirtRegMap>();
   spiller.reset(createInlineSpiller(*this, MF, *vrm));
 
+  mri->freezeReservedRegs(MF);
 
   DEBUG(dbgs() << "PBQP Register Allocating for " << mf->getFunction()->getName() << "\n");