Provide a target override for the cost of using a callee-saved register
authorManman Ren <manman.ren@gmail.com>
Thu, 27 Mar 2014 23:10:04 +0000 (23:10 +0000)
committerManman Ren <manman.ren@gmail.com>
Thu, 27 Mar 2014 23:10:04 +0000 (23:10 +0000)
for the first time.

Thanks Andy for the discussion.
rdar://16162005

llvm-svn: 204979

llvm/include/llvm/Target/TargetRegisterInfo.h
llvm/lib/CodeGen/RegAllocGreedy.cpp

index b3dbb9c..53fa7ca 100644 (file)
@@ -689,6 +689,11 @@ public:
   /// debugging downstream codegen failures exposed by regalloc.
   virtual bool mayOverrideLocalAssignment() const { return true; }
 
+  /// Allow the target to override the cost of using a callee-saved register for
+  /// the first time. Default value of 0 means we will use a callee-saved
+  /// register if it is available.
+  virtual unsigned getCSRFirstUseCost() const { return 0; }
+
   /// requiresRegisterScavenging - returns true if the target requires (and can
   /// make use of) the register scavenger.
   virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
index 0eb91ab..6a623b8 100644 (file)
@@ -2123,7 +2123,10 @@ unsigned RAGreedy::tryAssignCSRFirstTime(LiveInterval &VirtReg,
                                          unsigned PhysReg,
                                          unsigned &CostPerUseLimit,
                                          SmallVectorImpl<unsigned> &NewVRegs) {
-  BlockFrequency CSRCost(CSRFirstTimeCost);
+  // We use the larger one out of the command-line option and the value report
+  // by TRI.
+  BlockFrequency CSRCost(std::max((unsigned)CSRFirstTimeCost,
+                                  TRI->getCSRFirstUseCost()));
   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.
@@ -2172,7 +2175,8 @@ unsigned RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
     // 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()) {
+    if ((CSRFirstTimeCost || TRI->getCSRFirstUseCost()) &&
+        CSRFirstUse && NewVRegs.empty()) {
       unsigned CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
                                               CostPerUseLimit, NewVRegs);
       if (CSRReg || !NewVRegs.empty())