On 01-09-14 18:41, Ulrich Weigand wrote:
Tom de Vries wrote:

        * ira-costs.c (ira_tune_allocno_costs): Use
        ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS to adjust costs.

In debugging PR 53864 on s390x-linux, I ran into a weird change in behavior
that occurs when the following part of this patch was checked in:

-             if (ira_hard_reg_set_intersection_p (regno, mode, 
call_used_reg_set)
-                 || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
-               cost += (ALLOCNO_CALL_FREQ (a)
-                        * (ira_memory_move_cost[mode][rclass][0]
-                           + ira_memory_move_cost[mode][rclass][1]));
+             crossed_calls_clobber_regs
+               = &(ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+             if (ira_hard_reg_set_intersection_p (regno, mode,
+                                                  *crossed_calls_clobber_regs))
+               {
+                 if (ira_hard_reg_set_intersection_p (regno, mode,
+                                                      call_used_reg_set)
+                     || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+                   cost += (ALLOCNO_CALL_FREQ (a)
+                            * (ira_memory_move_cost[mode][rclass][0]
+                               + ira_memory_move_cost[mode][rclass][1]));
  #ifdef IRA_HARD_REGNO_ADD_COST_MULTIPLIER
-             cost += ((ira_memory_move_cost[mode][rclass][0]
-                       + ira_memory_move_cost[mode][rclass][1])
-                      * ALLOCNO_FREQ (a)
-                      * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
+                 cost += ((ira_memory_move_cost[mode][rclass][0]
+                           + ira_memory_move_cost[mode][rclass][1])
+                          * ALLOCNO_FREQ (a)
+                          * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
  #endif
+               }

Before that patch, this code would penalize all call-clobbered registers
(if the alloca is used across a call), and it would penalize *all* registers
in a target-dependent way if IRA_HARD_REGNO_ADD_COST_MULTIPLIER is defined;
the latter is completely independent of the presence of any calls.

However, after that patch, the IRA_HARD_REGNO_ADD_COST_MULTIPLIER penalty
is only applied for registers clobbered by calls in this function.  This
seems a completely unrelated change, and looks just wrong to me ...

Was this done intentionally or is this just an oversight?


Ulrich,

thanks for noticing this. I agree, this looks wrong, and is probably an oversight. [ It seems that s390 is the only target defining IRA_HARD_REGNO_ADD_COST_MULTIPLIER, so this problem didn't show up on any other target. ]

I think attached patch fixes it.

I've build the patch and ran the fuse-caller-save tests, and I'm currently bootstrapping and reg-testing it on x86_64.

Can you check whether this patches fixes the issue for s390 ?

Thanks,
- Tom

Bye,
Ulrich


diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 774a958..57239f5 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -2217,21 +2217,19 @@ ira_tune_allocno_costs (void)
 	      crossed_calls_clobber_regs
 		= &(ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
 	      if (ira_hard_reg_set_intersection_p (regno, mode,
-						   *crossed_calls_clobber_regs))
-		{
-		  if (ira_hard_reg_set_intersection_p (regno, mode,
+						   *crossed_calls_clobber_regs)
+		  && (ira_hard_reg_set_intersection_p (regno, mode,
 						       call_used_reg_set)
-		      || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
-		    cost += (ALLOCNO_CALL_FREQ (a)
-			     * (ira_memory_move_cost[mode][rclass][0]
-				+ ira_memory_move_cost[mode][rclass][1]));
+		      || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+		cost += (ALLOCNO_CALL_FREQ (a)
+			 * (ira_memory_move_cost[mode][rclass][0]
+			    + ira_memory_move_cost[mode][rclass][1]));
 #ifdef IRA_HARD_REGNO_ADD_COST_MULTIPLIER
-		  cost += ((ira_memory_move_cost[mode][rclass][0]
-			    + ira_memory_move_cost[mode][rclass][1])
-			   * ALLOCNO_FREQ (a)
-			   * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
+	      cost += ((ira_memory_move_cost[mode][rclass][0]
+			+ ira_memory_move_cost[mode][rclass][1])
+		       * ALLOCNO_FREQ (a)
+		       * IRA_HARD_REGNO_ADD_COST_MULTIPLIER (regno) / 2);
 #endif
-		}
 	      if (INT_MAX - cost < reg_costs[j])
 		reg_costs[j] = INT_MAX;
 	      else
-- 
1.9.1

Reply via email to