The patch here, https://gcc.gnu.org/ml/gcc-patches/2014-10/msg01872.html, 
attempted to scale down the register limit used by -fsched-pressure for the 
case where the block in question executes as frequently as the entry block to 
just the call_clobbered (i.e. call_used) regs. But the code is actually scaling 
toward call_saved registers. The following patch corrects the following two 
issues:

1) Computes and then removes the FIXED_REGS for the pressure class.
2) Computes CALL_SAVED regs per class and subtracts out some scaled portion of 
that.

Bootstrap/regtest on powerpc64le in progress. Ok for trunk if no new failures?

-Pat


2016-10-18  Pat Haugen  <pthau...@us.ibm.com>

        * haifa-sched.c (call_used_regs_num): Rename to...
        (call_saved_regs_num): ...this.
        (fixed_regs_num): New variable.
        (sched_pressure_start_bb): Subtract out fixed_regs. Scale call_saved 
        regs not call_used.
        (alloc_global_sched_pressure_data): Compute call_saved and fixed regs.


Index: gcc/haifa-sched.c
===================================================================
--- gcc/haifa-sched.c	(revision 240569)
+++ gcc/haifa-sched.c	(working copy)
@@ -932,9 +932,10 @@ static bitmap region_ref_regs;
 /* Effective number of available registers of a given class (see comment
    in sched_pressure_start_bb).  */
 static int sched_class_regs_num[N_REG_CLASSES];
-/* Number of call_used_regs.  This is a helper for calculating of
+/* Number of call_saved_regs and fixed_regs.  Helpers for calculating of
    sched_class_regs_num.  */
-static int call_used_regs_num[N_REG_CLASSES];
+static int call_saved_regs_num[N_REG_CLASSES];
+static int fixed_regs_num[N_REG_CLASSES];
 
 /* Initiate register pressure relative info for scheduling the current
    region.  Currently it is only clearing register mentioned in the
@@ -3896,17 +3897,19 @@ sched_pressure_start_bb (basic_block bb)
      * If the basic block executes much more often than the prologue/epilogue
      (e.g., inside a hot loop), then cost of spill in the prologue is close to
      nil, so the effective number of available registers is
-     (ira_class_hard_regs_num[cl] - 0).
+     (ira_class_hard_regs_num[cl] - fixed_regs_num[cl] - 0).
      * If the basic block executes as often as the prologue/epilogue,
      then spill in the block is as costly as in the prologue, so the effective
      number of available registers is
-     (ira_class_hard_regs_num[cl] - call_used_regs_num[cl]).
+     (ira_class_hard_regs_num[cl] - fixed_regs_num[cl]
+      - call_saved_regs_num[cl]).
      Note that all-else-equal, we prefer to spill in the prologue, since that
      allows "extra" registers for other basic blocks of the function.
      * If the basic block is on the cold path of the function and executes
      rarely, then we should always prefer to spill in the block, rather than
      in the prologue/epilogue.  The effective number of available register is
-     (ira_class_hard_regs_num[cl] - call_used_regs_num[cl]).  */
+     (ira_class_hard_regs_num[cl] - fixed_regs_num[cl]
+      - call_saved_regs_num[cl]).  */
   {
     int i;
     int entry_freq = ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency;
@@ -3923,9 +3926,10 @@ sched_pressure_start_bb (basic_block bb)
     for (i = 0; i < ira_pressure_classes_num; ++i)
       {
 	enum reg_class cl = ira_pressure_classes[i];
-	sched_class_regs_num[cl] = ira_class_hard_regs_num[cl];
+	sched_class_regs_num[cl] = ira_class_hard_regs_num[cl]
+				   - fixed_regs_num[cl];
 	sched_class_regs_num[cl]
-	  -= (call_used_regs_num[cl] * entry_freq) / bb_freq;
+	  -= (call_saved_regs_num[cl] * entry_freq) / bb_freq;
       }
   }
 
@@ -7237,17 +7241,20 @@ alloc_global_sched_pressure_data (void)
 	  region_ref_regs = BITMAP_ALLOC (NULL);
 	}
 
-      /* Calculate number of CALL_USED_REGS in register classes that
-	 we calculate register pressure for.  */
+      /* Calculate number of CALL_SAVED_REGS and FIXED_REGS in register classes
+	 that we calculate register pressure for.  */
       for (int c = 0; c < ira_pressure_classes_num; ++c)
 	{
 	  enum reg_class cl = ira_pressure_classes[c];
 
-	  call_used_regs_num[cl] = 0;
+	  call_saved_regs_num[cl] = 0;
+	  fixed_regs_num[cl] = 0;
 
 	  for (int i = 0; i < ira_class_hard_regs_num[cl]; ++i)
-	    if (call_used_regs[ira_class_hard_regs[cl][i]])
-	      ++call_used_regs_num[cl];
+	    if (!call_used_regs[ira_class_hard_regs[cl][i]])
+	      ++call_saved_regs_num[cl];
+	    else if (fixed_regs[ira_class_hard_regs[cl][i]])
+	      ++fixed_regs_num[cl];
 	}
     }
 }

Reply via email to