The estimate on target_clobbered_registers based on the call_used arrays is not 
correct. This is the worst case 
heuristics on the estimate on target_clobbered_registers. This disables many of 
the loop Invariant code motion 
opportunities in presence of call. Instead of considering the spill cost we 
consider only the target_reg_cost
aggressively.

With this  change with old logic used in regs_used gave the following gains.

diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c 
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -373,15 +373,23 @@ estimate_reg_pressure_cost (unsigned n_new, unsigned 
n_old, bool speed,
 
   /* If there is a call in the loop body, the call-clobbered registers
      are not available for loop invariants.  */
+
   if (call_p)
     available_regs = available_regs - target_clobbered_regs;
-
+  
   /* If we have enough registers, we should use them and not restrict
      the transformations unnecessarily.  */
   if (regs_needed + target_res_regs <= available_regs)
     return 0;
 
-  if (regs_needed <= available_regs)
+  /* Estimation of target_clobbered register is based on the call_used
+     arrays which is not the right estimate for the clobbered register
+     used in called function. Instead of considering the spill cost we
+     consider only the reg_cost aggressively.  */
+
+  if ((regs_needed <= available_regs) 
+      || (call_p && (regs_needed <= 
+          (available_regs + target_clobbered_regs))))
     /* If we are close to running out of registers, try to preserve
        them.  */
     cost = target_reg_cost [speed] * n_new;

SPEC CPU 2000 INT benchmarks
(Geomean Score without the above change vs Geomean score with the above change 
= 3745.193 vs vs 3752.717)

SPEC INT CPU 2000 benchmarks.
 (Geomean Score without the above change vs Geomean score with the above change 
= 4741.825 vs 4792.085) 

Thanks & Regards
Ajit

Reply via email to