[llvm-commits] [llvm] r101595 - /llvm/trunk/lib/CodeGen/RegAllocLocal.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Fri Apr 16 17:38:36 PDT 2010


Author: stoklund
Date: Fri Apr 16 19:38:36 2010
New Revision: 101595

URL: http://llvm.org/viewvc/llvm-project?rev=101595&view=rev
Log:
Revert "Use a simpler data structure to calculate the least recently used register in RegAllocLocal."

This reverts commit 101392. It broke a buildbot.

Modified:
    llvm/trunk/lib/CodeGen/RegAllocLocal.cpp

Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=101595&r1=101594&r2=101595&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Fri Apr 16 19:38:36 2010
@@ -76,16 +76,15 @@
     //
     std::vector<int> PhysRegsUsed;
 
-    // InstrNum - Number of the current instruction. This is used for the
-    // PhysLastUse map.
+    // PhysRegsUseOrder - This contains a list of the physical registers that
+    // currently have a virtual register value in them.  This list provides an
+    // ordering of registers, imposing a reallocation order.  This list is only
+    // used if all registers are allocated and we have to spill one, in which
+    // case we spill the least recently used register.  Entries at the front of
+    // the list are the least recently used registers, entries at the back are
+    // the most recently used.
     //
-    unsigned InstrNum;
-
-    // PhysLastUse - Store the instruction number of the last use of each physical
-    // register. This is used to find the least recently used register. when
-    // spilling.
-    //
-    std::vector<unsigned> PhysLastUse;
+    std::vector<unsigned> PhysRegsUseOrder;
 
     // Virt2LastUseMap - This maps each virtual register to its last use
     // (MachineInstr*, operand index pair).
@@ -124,8 +123,28 @@
       return VirtRegModified[Reg - TargetRegisterInfo::FirstVirtualRegister];
     }
 
+    void AddToPhysRegsUseOrder(unsigned Reg) {
+      std::vector<unsigned>::iterator It =
+        std::find(PhysRegsUseOrder.begin(), PhysRegsUseOrder.end(), Reg);
+      if (It != PhysRegsUseOrder.end())
+        PhysRegsUseOrder.erase(It);
+      PhysRegsUseOrder.push_back(Reg);
+    }
+
     void MarkPhysRegRecentlyUsed(unsigned Reg) {
-      PhysLastUse[Reg] = InstrNum;
+      if (PhysRegsUseOrder.empty() ||
+          PhysRegsUseOrder.back() == Reg) return;  // Already most recently used
+
+      for (unsigned i = PhysRegsUseOrder.size(); i != 0; --i) {
+        unsigned RegMatch = PhysRegsUseOrder[i-1];       // remove from middle
+        if (!areRegsEqual(Reg, RegMatch)) continue;
+        
+        PhysRegsUseOrder.erase(PhysRegsUseOrder.begin()+i-1);
+        // Add it to the end of the list
+        PhysRegsUseOrder.push_back(RegMatch);
+        if (RegMatch == Reg)
+          return;    // Found an exact match, exit early
+      }
     }
 
   public:
@@ -260,6 +279,11 @@
 ///
 void RALocal::removePhysReg(unsigned PhysReg) {
   PhysRegsUsed[PhysReg] = -1;      // PhyReg no longer used
+
+  std::vector<unsigned>::iterator It =
+    std::find(PhysRegsUseOrder.begin(), PhysRegsUseOrder.end(), PhysReg);
+  if (It != PhysRegsUseOrder.end())
+    PhysRegsUseOrder.erase(It);
 }
 
 
@@ -341,7 +365,7 @@
   // it holds VirtReg.
   PhysRegsUsed[PhysReg] = VirtReg;
   getVirt2PhysRegMapSlot(VirtReg) = PhysReg;
-  MarkPhysRegRecentlyUsed(PhysReg);   // New use of PhysReg
+  AddToPhysRegsUseOrder(PhysReg);   // New use of PhysReg
 }
 
 
@@ -395,22 +419,58 @@
     // Assign the register.
     assignVirtToPhysReg(VirtReg, PhysReg);
     return PhysReg;
-  }
+  }    
+    
+  // If we didn't find an unused register, scavenge one now!
+  assert(!PhysRegsUseOrder.empty() && "No allocated registers??");
 
-  // Find the least recently used register in the allocation order.
-  unsigned Oldest = 0;
-  TargetRegisterClass::iterator RI = RC->allocation_order_begin(*MF);
-  TargetRegisterClass::iterator RE = RC->allocation_order_end(*MF);
-  for (; RI != RE; ++RI) {
-    unsigned Age = InstrNum-PhysLastUse[*RI];
-    if (Age <= Oldest && PhysReg) continue;
-    PhysReg = *RI;
-    Oldest = Age;
+  // Loop over all of the preallocated registers from the least recently used
+  // to the most recently used.  When we find one that is capable of holding
+  // our register, use it.
+  for (unsigned i = 0; PhysReg == 0; ++i) {
+    assert(i != PhysRegsUseOrder.size() &&
+           "Couldn't find a register of the appropriate class!");
+
+    unsigned R = PhysRegsUseOrder[i];
+
+    // We can only use this register if it holds a virtual register (ie, it
+    // can be spilled).  Do not use it if it is an explicitly allocated
+    // physical register!
+    assert(PhysRegsUsed[R] != -1 &&
+           "PhysReg in PhysRegsUseOrder, but is not allocated?");
+    if (PhysRegsUsed[R] && PhysRegsUsed[R] != -2) {
+      // If the current register is compatible, use it.
+      if (RC->contains(R)) {
+        PhysReg = R;
+        break;
+      }
+      
+      // If one of the registers aliased to the current register is
+      // compatible, use it.
+      for (const unsigned *AliasIt = TRI->getAliasSet(R);
+           *AliasIt; ++AliasIt) {
+        if (!RC->contains(*AliasIt)) continue;
+        
+        // If this is pinned down for some reason, don't use it.  For
+        // example, if CL is pinned, and we run across CH, don't use
+        // CH as justification for using scavenging ECX (which will
+        // fail).
+        if (PhysRegsUsed[*AliasIt] == 0) continue;
+            
+        // Make sure the register is allocatable.  Don't allocate SIL on
+        // x86-32.
+        if (PhysRegsUsed[*AliasIt] == -2) continue;
+        
+        PhysReg = *AliasIt;    // Take an aliased register
+        break;
+      }
+    }
   }
 
   assert(PhysReg && "Physical register not assigned!?!?");
 
-  // Spill it to memory and reap its remains.
+  // At this point PhysRegsUseOrder[i] is the least recently used register of
+  // compatible register class.  Spill it to memory and reap its remains.
   spillPhysReg(MBB, I, PhysReg);
 
   // Now that we know which register we need to assign this to, do it now!
@@ -578,13 +638,21 @@
       
       if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
       
-      for (const unsigned *A = TRI->getAliasSet(MO.getReg()); *A; ++A) {
-        std::pair<MachineInstr*, unsigned> &LUD = LastUseDef[*A];
-        if (LUD.first != I)
-          LUD = std::make_pair(I, i);
+      const unsigned *Aliases = TRI->getAliasSet(MO.getReg());
+      if (Aliases == 0)
+        continue;
+      
+      while (*Aliases) {
+        DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
+          alias = LastUseDef.find(*Aliases);
+        
+        if (alias != LastUseDef.end() && alias->second.first != I)
+          LastUseDef[*Aliases] = std::make_pair(I, i);
+        
+        ++Aliases;
       }
     }
-
+    
     for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = I->getOperand(i);
       // Defs others than 2-addr redefs _do_ trigger flag changes:
@@ -699,7 +767,7 @@
 void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
   // loop over each instruction
   MachineBasicBlock::iterator MII = MBB.begin();
-
+  
   DEBUG({
       const BasicBlock *LBB = MBB.getBasicBlock();
       if (LBB)
@@ -712,11 +780,12 @@
     unsigned Reg = *I;
     MF->getRegInfo().setPhysRegUsed(Reg);
     PhysRegsUsed[Reg] = 0;            // It is free and reserved now
-    MarkPhysRegRecentlyUsed(Reg);
+    AddToPhysRegsUseOrder(Reg); 
     for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
          *SubRegs; ++SubRegs) {
       if (PhysRegsUsed[*SubRegs] == -2) continue;
-      MarkPhysRegRecentlyUsed(*SubRegs);
+      
+      AddToPhysRegsUseOrder(*SubRegs); 
       PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
       MF->getRegInfo().setPhysRegUsed(*SubRegs);
     }
@@ -727,7 +796,6 @@
   // Otherwise, sequentially allocate each instruction in the MBB.
   while (MII != MBB.end()) {
     MachineInstr *MI = MII++;
-    ++InstrNum;
     const TargetInstrDesc &TID = MI->getDesc();
     DEBUG({
         dbgs() << "\nStarting RegAlloc of: " << *MI;
@@ -806,14 +874,14 @@
           MF->getRegInfo().setPhysRegUsed(Reg);
           spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
           PhysRegsUsed[Reg] = 0;            // It is free and reserved now
-          MarkPhysRegRecentlyUsed(Reg);
+          AddToPhysRegsUseOrder(Reg); 
 
           for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
                *SubRegs; ++SubRegs) {
             if (PhysRegsUsed[*SubRegs] == -2) continue;
             MF->getRegInfo().setPhysRegUsed(*SubRegs);
             PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
-            MarkPhysRegRecentlyUsed(*SubRegs);
+            AddToPhysRegsUseOrder(*SubRegs); 
           }
         }
       }
@@ -903,7 +971,7 @@
       MF->getRegInfo().setPhysRegUsed(Reg);
       spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
       PhysRegsUsed[Reg] = 0;            // It is free and reserved now
-      MarkPhysRegRecentlyUsed(Reg);
+      AddToPhysRegsUseOrder(Reg); 
 
       for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
            *SubRegs; ++SubRegs) {
@@ -911,7 +979,7 @@
         
         MF->getRegInfo().setPhysRegUsed(*SubRegs);
         PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
-        MarkPhysRegRecentlyUsed(*SubRegs);
+        AddToPhysRegsUseOrder(*SubRegs); 
       }
     }
 
@@ -922,7 +990,7 @@
         unsigned Reg = *ImplicitDefs;
         if (PhysRegsUsed[Reg] != -2) {
           spillPhysReg(MBB, MI, Reg, true);
-          MarkPhysRegRecentlyUsed(Reg);
+          AddToPhysRegsUseOrder(Reg); 
           PhysRegsUsed[Reg] = 0;            // It is free and reserved now
         }
         MF->getRegInfo().setPhysRegUsed(Reg);
@@ -930,7 +998,7 @@
              *SubRegs; ++SubRegs) {
           if (PhysRegsUsed[*SubRegs] == -2) continue;
           
-          MarkPhysRegRecentlyUsed(*SubRegs);
+          AddToPhysRegsUseOrder(*SubRegs); 
           PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
           MF->getRegInfo().setPhysRegUsed(*SubRegs);
         }
@@ -1055,6 +1123,11 @@
     }
   assert(AllOk && "Virtual registers still in phys regs?");
 #endif
+
+  // Clear any physical register which appear live at the end of the basic
+  // block, but which do not hold any virtual registers.  e.g., the stack
+  // pointer.
+  PhysRegsUseOrder.clear();
 }
 
 /// runOnMachineFunction - Register allocate the whole function
@@ -1067,9 +1140,7 @@
   TII = TM->getInstrInfo();
 
   PhysRegsUsed.assign(TRI->getNumRegs(), -1);
-  InstrNum = 0;
-  PhysLastUse.assign(TRI->getNumRegs(), 0);
-
+  
   // At various places we want to efficiently check to see whether a register
   // is allocatable.  To handle this, we mark all unallocatable registers as
   // being pinned down, permanently.





More information about the llvm-commits mailing list