Register Allocator: check other options before using a CSR for the first time.
[oota-llvm.git] / lib / CodeGen / RegAllocGreedy.cpp
index 5293e3160fe5f1927a9592bce3ae01d149a9f4c0..3a4ad620d073633b8f6954b22379438586a60d27 100644 (file)
@@ -71,6 +71,12 @@ static cl::opt<unsigned> LastChanceRecoloringMaxInterference(
              " interference at a time"),
     cl::init(8));
 
+// FIXME: Find a good default for this flag and remove the flag.
+static cl::opt<unsigned>
+CSRFirstTimeCost("regalloc-csr-first-time-cost",
+              cl::desc("Cost for first time use of callee-saved register."),
+              cl::init(0), cl::Hidden);
+
 static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
                                        createGreedyRegisterAllocator);
 
@@ -310,7 +316,7 @@ private:
   unsigned calculateRegionSplitCost(LiveInterval &VirtReg,
                                     AllocationOrder &Order,
                                     BlockFrequency &BestCost,
-                                    unsigned &NumCands);
+                                    unsigned &NumCands, bool IgnoreCSR);
   /// Perform region splitting.
   unsigned doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,
                          bool HasCompact,
@@ -1257,7 +1263,8 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
   }
 
   unsigned BestCand =
-      calculateRegionSplitCost(VirtReg, Order, BestCost, NumCands);
+      calculateRegionSplitCost(VirtReg, Order, BestCost, NumCands,
+                               false/*IgnoreCSR*/);
 
   // No solutions found, fall back to single block splitting.
   if (!HasCompact && BestCand == NoCand)
@@ -1269,10 +1276,15 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order,
 unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
                                             AllocationOrder &Order,
                                             BlockFrequency &BestCost,
-                                            unsigned &NumCands) {
+                                            unsigned &NumCands,
+                                            bool IgnoreCSR) {
   unsigned BestCand = NoCand;
   Order.rewind();
   while (unsigned PhysReg = Order.next()) {
+   if (unsigned CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg))
+     if (IgnoreCSR && !MRI->isPhysRegUsed(CSR))
+       continue;
+
     // Discard bad candidates before we run out of interference cache cursors.
     // This will only affect register classes with a lot of registers (>32).
     if (NumCands == IntfCache.getMaxCursors()) {
@@ -2099,10 +2111,49 @@ unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
                                      SmallVectorImpl<unsigned> &NewVRegs,
                                      SmallVirtRegSet &FixedRegisters,
                                      unsigned Depth) {
+  unsigned CostPerUseLimit = ~0u;
   // First try assigning a free register.
   AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo);
-  if (unsigned PhysReg = tryAssign(VirtReg, Order, NewVRegs))
-    return PhysReg;
+  if (unsigned PhysReg = tryAssign(VirtReg, Order, NewVRegs)) {
+    // We check other options if we are using a CSR for the first time.
+    bool CSRFirstUse = false;
+    if (unsigned CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg))
+      if (!MRI->isPhysRegUsed(CSR))
+        CSRFirstUse = true;
+
+    BlockFrequency CSRCost(CSRFirstTimeCost);
+    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;
+    } else
+      return PhysReg;
+  }
 
   LiveRangeStage Stage = getStage(VirtReg);
   DEBUG(dbgs() << StageName[Stage]
@@ -2112,7 +2163,7 @@ unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
   // queue. The RS_Split ranges already failed to do this, and they should not
   // get a second chance until they have been split.
   if (Stage != RS_Split)
-    if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs))
+    if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit))
       return PhysReg;
 
   assert(NewVRegs.empty() && "Cannot append to existing NewVRegs");