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

Jakob Stoklund Olesen stoklund at 2pi.dk
Fri Apr 16 16:32:37 PDT 2010


Author: stoklund
Date: Fri Apr 16 18:32:37 2010
New Revision: 101574

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

This makes the local register allocator about 20% faster.

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=101574&r1=101573&r2=101574&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Fri Apr 16 18:32:37 2010
@@ -76,15 +76,16 @@
     //
     std::vector<int> PhysRegsUsed;
 
-    // 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.
+    // InstrNum - Number of the current instruction. This is used for the
+    // PhysLastUse map.
     //
-    std::vector<unsigned> PhysRegsUseOrder;
+    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;
 
     // Virt2LastUseMap - This maps each virtual register to its last use
     // (MachineInstr*, operand index pair).
@@ -123,28 +124,8 @@
       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) {
-      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
-      }
+      PhysLastUse[Reg] = InstrNum;
     }
 
   public:
@@ -279,11 +260,6 @@
 ///
 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);
 }
 
 
@@ -365,7 +341,7 @@
   // it holds VirtReg.
   PhysRegsUsed[PhysReg] = VirtReg;
   getVirt2PhysRegMapSlot(VirtReg) = PhysReg;
-  AddToPhysRegsUseOrder(PhysReg);   // New use of PhysReg
+  MarkPhysRegRecentlyUsed(PhysReg);   // New use of PhysReg
 }
 
 
@@ -419,58 +395,22 @@
     // 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??");
+  }
 
-  // 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;
-      }
-    }
+  // 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;
   }
 
   assert(PhysReg && "Physical register not assigned!?!?");
 
-  // At this point PhysRegsUseOrder[i] is the least recently used register of
-  // compatible register class.  Spill it to memory and reap its remains.
+  // 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!
@@ -638,21 +578,13 @@
       
       if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
       
-      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 (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);
       }
     }
-    
+
     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:
@@ -767,7 +699,7 @@
 void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
   // loop over each instruction
   MachineBasicBlock::iterator MII = MBB.begin();
-  
+
   DEBUG({
       const BasicBlock *LBB = MBB.getBasicBlock();
       if (LBB)
@@ -780,12 +712,11 @@
     unsigned Reg = *I;
     MF->getRegInfo().setPhysRegUsed(Reg);
     PhysRegsUsed[Reg] = 0;            // It is free and reserved now
-    AddToPhysRegsUseOrder(Reg); 
+    MarkPhysRegRecentlyUsed(Reg);
     for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
          *SubRegs; ++SubRegs) {
       if (PhysRegsUsed[*SubRegs] == -2) continue;
-      
-      AddToPhysRegsUseOrder(*SubRegs); 
+      MarkPhysRegRecentlyUsed(*SubRegs);
       PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
       MF->getRegInfo().setPhysRegUsed(*SubRegs);
     }
@@ -796,6 +727,7 @@
   // 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;
@@ -874,14 +806,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
-          AddToPhysRegsUseOrder(Reg); 
+          MarkPhysRegRecentlyUsed(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
-            AddToPhysRegsUseOrder(*SubRegs); 
+            MarkPhysRegRecentlyUsed(*SubRegs);
           }
         }
       }
@@ -971,7 +903,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
-      AddToPhysRegsUseOrder(Reg); 
+      MarkPhysRegRecentlyUsed(Reg);
 
       for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
            *SubRegs; ++SubRegs) {
@@ -979,7 +911,7 @@
         
         MF->getRegInfo().setPhysRegUsed(*SubRegs);
         PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
-        AddToPhysRegsUseOrder(*SubRegs); 
+        MarkPhysRegRecentlyUsed(*SubRegs);
       }
     }
 
@@ -990,7 +922,7 @@
         unsigned Reg = *ImplicitDefs;
         if (PhysRegsUsed[Reg] != -2) {
           spillPhysReg(MBB, MI, Reg, true);
-          AddToPhysRegsUseOrder(Reg); 
+          MarkPhysRegRecentlyUsed(Reg);
           PhysRegsUsed[Reg] = 0;            // It is free and reserved now
         }
         MF->getRegInfo().setPhysRegUsed(Reg);
@@ -998,7 +930,7 @@
              *SubRegs; ++SubRegs) {
           if (PhysRegsUsed[*SubRegs] == -2) continue;
           
-          AddToPhysRegsUseOrder(*SubRegs); 
+          MarkPhysRegRecentlyUsed(*SubRegs);
           PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
           MF->getRegInfo().setPhysRegUsed(*SubRegs);
         }
@@ -1123,11 +1055,6 @@
     }
   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
@@ -1140,7 +1067,9 @@
   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