[llvm] r204962 - Register Allocator: refactoring and add comments.

Manman Ren manman.ren at gmail.com
Thu Mar 27 14:21:58 PDT 2014


Author: mren
Date: Thu Mar 27 16:21:57 2014
New Revision: 204962

URL: http://llvm.org/viewvc/llvm-project?rev=204962&view=rev
Log:
Register Allocator: refactoring and add comments.

No functionality change. Thanks Andy for reviewing.

rdar://16162005

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

Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=204962&r1=204961&r2=204962&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Thu Mar 27 16:21:57 2014
@@ -321,6 +321,11 @@ private:
   unsigned doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
                          bool HasCompact,
                          SmallVectorImpl<unsigned> &NewVRegs);
+  /// Check other options before using a callee-saved register for the first
+  /// time.
+  unsigned tryAssignCSRFirstTime(LiveInterval &VirtReg, AllocationOrder &Order,
+                                 unsigned PhysReg, unsigned &CostPerUseLimit,
+                                 SmallVectorImpl<unsigned> &NewVRegs);
   unsigned tryBlockSplit(LiveInterval&, AllocationOrder&,
                          SmallVectorImpl<unsigned>&);
   unsigned tryInstructionSplit(LiveInterval&, AllocationOrder&,
@@ -2107,6 +2112,49 @@ unsigned RAGreedy::selectOrSplit(LiveInt
   return selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters);
 }
 
+/// Using a CSR for the first time has a cost because it causes push|pop
+/// to be added to prologue|epilogue. Splitting a cold section of the live
+/// range can have lower cost than using the CSR for the first time;
+/// Spilling a live range in the cold path can have lower cost than using
+/// the CSR for the first time. Returns the physical register if we decide
+/// to use the CSR; otherwise return 0.
+unsigned RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg,
+                                         AllocationOrder &Order,
+                                         unsigned PhysReg,
+                                         unsigned &CostPerUseLimit,
+                                         SmallVectorImpl<unsigned> &NewVRegs) {
+  BlockFrequency CSRCost(CSRFirstTimeCost);
+  if (getStage(VirtReg) == RS_Spill && VirtReg.isSpillable()) {
+    // We choose spill over using the CSR for the first time if the spill cost
+    // is lower than CSRCost.
+    SA->analyze(&VirtReg);
+    if (calcSpillCost() >= CSRCost)
+      return PhysReg;
+
+    // We are going to spill, set CostPerUseLimit to 1 to make sure that
+    // we will not use a callee-saved register in tryEvict.
+    CostPerUseLimit = 1;
+    return 0;
+  }
+  if (getStage(VirtReg) < RS_Split) {
+    // We choose pre-splitting over using the CSR for the first time if
+    // the cost of splitting is lower than CSRCost.
+    SA->analyze(&VirtReg);
+    unsigned NumCands = 0;
+    unsigned BestCand =
+      calculateRegionSplitCost(VirtReg, Order, CSRCost, NumCands,
+                               true/*IgnoreCSR*/);
+    if (BestCand == NoCand)
+      // Use the CSR if we can't find a region split below CSRCost.
+      return PhysReg;
+
+    // Perform the actual pre-splitting.
+    doRegionSplit(VirtReg, BestCand, false/*HasCompact*/, NewVRegs);
+    return 0;
+  }
+  return PhysReg;
+}
+
 unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
                                      SmallVectorImpl<unsigned> &NewVRegs,
                                      SmallVirtRegSet &FixedRegisters,
@@ -2121,41 +2169,16 @@ unsigned RAGreedy::selectOrSplitImpl(Liv
       if (!MRI->isPhysRegUsed(CSR))
         CSRFirstUse = true;
 
-    BlockFrequency CSRCost(CSRFirstTimeCost);
-    // Using a CSR for the first time has a cost because it causes push|pop
-    // to be added to prologue|epilogue. Splitting a cold section of the live
-    // range can have lower cost than using the CSR for the first time;
-    // Spilling a live range in the cold path can have lower cost than using
-    // the CSR for the first time.
-    if (getStage(VirtReg) == RS_Spill && CSRFirstUse && NewVRegs.empty() &&
-        CSRFirstTimeCost > 0 && VirtReg.isSpillable()) {
-      // We choose spill over using the CSR for the first time if the spill cost
-      // is lower than CSRCost.
-      SA->analyze(&VirtReg);
-      if (calcSpillCost() >= CSRCost)
-        return PhysReg;
-
-      // We are going to spill, set CostPerUseLimit to 1 to make sure that
-      // we will not use a callee-saved register in tryEvict.
-      CostPerUseLimit = 1;
-    }
-    else if (getStage(VirtReg) < RS_Split && CSRFirstUse &&
-             NewVRegs.empty() && CSRFirstTimeCost > 0) {
-      // We choose pre-splitting over using the CSR for the first time if
-      // the cost of splitting is lower than CSRCost.
-      SA->analyze(&VirtReg);
-      unsigned NumCands = 0;
-      unsigned BestCand =
-        calculateRegionSplitCost(VirtReg, Order, CSRCost, NumCands,
-                                 true/*IgnoreCSR*/);
-      if (BestCand == NoCand)
-        // Use the CSR if we can't find a region split below CSRCost.
-        return PhysReg;
-
-      // Perform the actual pre-splitting.
-      doRegionSplit(VirtReg, BestCand, false/*HasCompact*/, NewVRegs);
-      if (!NewVRegs.empty())
-        return 0;
+    // When NewVRegs is not empty, we may have made decisions such as evicting
+    // a virtual register, go with the earlier decisions and use the physical
+    // register.
+    if (CSRFirstTimeCost > 0 && CSRFirstUse && NewVRegs.empty()) {
+      unsigned CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
+                                              CostPerUseLimit, NewVRegs);
+      if (CSRReg || !NewVRegs.empty())
+        // Return now if we decide to use a CSR or create new vregs due to
+        // pre-splitting.
+        return CSRReg;
     } else
       return PhysReg;
   }





More information about the llvm-commits mailing list