public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [0/7] Tidy IRA move costs
@ 2012-05-30 18:12 Richard Sandiford
  2012-05-30 18:16 ` [1/7] " Richard Sandiford
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:12 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

At the moment there are three sets of move costs:

    move_cost
    may_move_in_cost
    may_move_out_cost

    ira_register_move_cost
    ira_may_move_in_cost
    ira_may_move_out_cost

    ira_max_register_move_cost
    ira_max_may_move_in_cost
    ira_max_may_move_out_cost

Having the first two sets around together dates back to when IRA
was an optional replacement for the old allocators.  The third set
is only used as a temporary while calculating the second set.

This series removes the first and third sets.  It isn't supposed
to change the output in any way.  Hopefully it will make things
a little more efficient, but the real motivation was to make it
easier to experiment with the costs.

Note that move_cost and ira_register_move_cost are already the same.
We make the latter an alias of the forner:

  ira_register_move_cost[mode] = move_cost[mode];

then modify it in-place:

	  ira_register_move_cost[mode][cl1][cl2]
	    = ira_max_register_move_cost[mode][cl1][cl2];

thus changing both.

Bootstrapped & regression-tested on x86_64-linux-gnu and i686-linux-gnu.
Also tested by making sure that the assembly output for recent cc1 .ii
files is unchanged.

Richard

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [1/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
@ 2012-05-30 18:16 ` Richard Sandiford
  2012-05-31  2:04   ` Vladimir Makarov
  2012-05-30 18:22 ` [2/7] " Richard Sandiford
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

For one of the later patches I wanted to test whether a class had any
allocatable registers.  It turns out that we have two arrays that hold
the number of allocatable registers in a class:

    ira_class_hard_regs_num
    ira_available_class_regs

We calculate them in quick succession and already assert that they're
the same:

      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
      ...
      for (n = 0, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (TEST_HARD_REG_BIT (temp_hard_regset, i))
	  ira_non_ordered_class_hard_regs[cl][n++] = i;
      ira_assert (ira_class_hard_regs_num[cl] == n);

      ...

      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]);
      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
      for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
	if (TEST_HARD_REG_BIT (temp_hard_regset, j))
	  ira_available_class_regs[i]++;

so this patch removes the latter in favour of the former.

Richard


gcc/
	* ira.h (target_ira): Delete x_ira_available_class_regs.
	(ira_available_class_regs): Delete.
	* ira.c (setup_available_class_regs): Delete.
	(setup_alloc_classes): Don't call it.
	(setup_pressure_classes): Use ira_class_hard_regs_num instead of
	ira_available_class_regs.
	* haifa-sched.c (print_curr_reg_pressure, setup_insn_reg_pressure_info)
	(model_spill_cost): Likewise.
	* ira-build.c (low_pressure_loop_node_p): Likewise.
	* ira-color.c (color_pass): Likewise.
	* ira-emit.c (change_loop): Likewise.
	* ira-lives.c (inc_register_pressure, dec_register_pressure)
	(single_reg_class, ira_implicitly_set_insn_hard_regs)
	(process_bb_node_lives): Likewise.
	* loop-invariant.c (gain_for_invariant): Likewise.

Index: gcc/ira.h
===================================================================
--- gcc/ira.h	2012-05-30 18:57:09.221912963 +0100
+++ gcc/ira.h	2012-05-30 19:08:35.848893000 +0100
@@ -25,10 +25,6 @@ Software Foundation; either version 3, o
 extern bool ira_conflicts_p;
 
 struct target_ira {
-  /* Number of given class hard registers available for the register
-     allocation for given classes.  */
-  int x_ira_available_class_regs[N_REG_CLASSES];
-
   /* Map: hard register number -> allocno class it belongs to.  If the
      corresponding class is NO_REGS, the hard register is not available
      for allocation.  */
@@ -95,8 +91,6 @@ struct target_ira {
 #define this_target_ira (&default_target_ira)
 #endif
 
-#define ira_available_class_regs \
-  (this_target_ira->x_ira_available_class_regs)
 #define ira_hard_regno_allocno_class \
   (this_target_ira->x_ira_hard_regno_allocno_class)
 #define ira_allocno_classes_num \
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-05-30 18:57:09.222912964 +0100
+++ gcc/ira.c	2012-05-30 19:08:35.848893000 +0100
@@ -490,23 +490,6 @@ setup_class_hard_regs (void)
     }
 }
 
-/* Set up IRA_AVAILABLE_CLASS_REGS.  */
-static void
-setup_available_class_regs (void)
-{
-  int i, j;
-
-  memset (ira_available_class_regs, 0, sizeof (ira_available_class_regs));
-  for (i = 0; i < N_REG_CLASSES; i++)
-    {
-      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]);
-      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-      for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
-	if (TEST_HARD_REG_BIT (temp_hard_regset, j))
-	  ira_available_class_regs[i]++;
-    }
-}
-
 /* Set up global variables defining info about hard registers for the
    allocation.  These depend on USE_HARD_FRAME_P whose TRUE value means
    that we can use the hard frame pointer for the allocation.  */
@@ -520,7 +503,6 @@ setup_alloc_regs (bool use_hard_frame_p)
   if (! use_hard_frame_p)
     SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM);
   setup_class_hard_regs ();
-  setup_available_class_regs ();
 }
 
 \f
@@ -799,9 +781,9 @@ setup_pressure_classes (void)
   n = 0;
   for (cl = 0; cl < N_REG_CLASSES; cl++)
     {
-      if (ira_available_class_regs[cl] == 0)
+      if (ira_class_hard_regs_num[cl] == 0)
 	continue;
-      if (ira_available_class_regs[cl] != 1
+      if (ira_class_hard_regs_num[cl] != 1
 	  /* A register class without subclasses may contain a few
 	     hard registers and movement between them is costly
 	     (e.g. SPARC FPCC registers).  We still should consider it
@@ -1504,7 +1486,7 @@ ira_init_register_move_cost (enum machin
     {
       /* Some subclasses are to small to have enough registers to hold
 	 a value of MODE.  Just ignore them.  */
-      if (ira_reg_class_max_nregs[cl1][mode] > ira_available_class_regs[cl1])
+      if (ira_reg_class_max_nregs[cl1][mode] > ira_class_hard_regs_num[cl1])
 	continue;
       COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]);
       AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
Index: gcc/haifa-sched.c
===================================================================
--- gcc/haifa-sched.c	2012-05-30 18:57:09.221912963 +0100
+++ gcc/haifa-sched.c	2012-05-30 19:08:35.840893001 +0100
@@ -1085,7 +1085,7 @@ print_curr_reg_pressure (void)
       gcc_assert (curr_reg_pressure[cl] >= 0);
       fprintf (sched_dump, "  %s:%d(%d)", reg_class_names[cl],
 	       curr_reg_pressure[cl],
-	       curr_reg_pressure[cl] - ira_available_class_regs[cl]);
+	       curr_reg_pressure[cl] - ira_class_hard_regs_num[cl]);
     }
   fprintf (sched_dump, "\n");
 }
@@ -1634,9 +1634,9 @@ setup_insn_reg_pressure_info (rtx insn)
       cl = ira_pressure_classes[i];
       gcc_assert (curr_reg_pressure[cl] >= 0);
       change = (int) pressure_info[i].set_increase - death[cl];
-      before = MAX (0, max_reg_pressure[i] - ira_available_class_regs[cl]);
+      before = MAX (0, max_reg_pressure[i] - ira_class_hard_regs_num[cl]);
       after = MAX (0, max_reg_pressure[i] + change
-		   - ira_available_class_regs[cl]);
+		   - ira_class_hard_regs_num[cl]);
       hard_regno = ira_class_hard_regs[cl][0];
       gcc_assert (hard_regno >= 0);
       mode = reg_raw_mode[hard_regno];
@@ -2227,7 +2227,7 @@ model_recompute (rtx insn)
 /* Return the cost of increasing the pressure in class CL from FROM to TO.
 
    Here we use the very simplistic cost model that every register above
-   ira_available_class_regs[CL] has a spill cost of 1.  We could use other
+   ira_class_hard_regs_num[CL] has a spill cost of 1.  We could use other
    measures instead, such as one based on MEMORY_MOVE_COST.  However:
 
       (1) In order for an instruction to be scheduled, the higher cost
@@ -2251,7 +2251,7 @@ model_recompute (rtx insn)
 static int
 model_spill_cost (int cl, int from, int to)
 {
-  from = MAX (from, ira_available_class_regs[cl]);
+  from = MAX (from, ira_class_hard_regs_num[cl]);
   return MAX (to, from) - from;
 }
 
Index: gcc/ira-build.c
===================================================================
--- gcc/ira-build.c	2012-05-30 18:57:09.220912962 +0100
+++ gcc/ira-build.c	2012-05-30 19:08:35.843893000 +0100
@@ -1829,8 +1829,8 @@ low_pressure_loop_node_p (ira_loop_tree_
   for (i = 0; i < ira_pressure_classes_num; i++)
     {
       pclass = ira_pressure_classes[i];
-      if (node->reg_pressure[pclass] > ira_available_class_regs[pclass]
-	  && ira_available_class_regs[pclass] > 1)
+      if (node->reg_pressure[pclass] > ira_class_hard_regs_num[pclass]
+	  && ira_class_hard_regs_num[pclass] > 1)
 	return false;
     }
   return true;
Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c	2012-05-30 18:57:09.220912962 +0100
+++ gcc/ira-color.c	2012-05-30 19:08:35.845893000 +0100
@@ -2766,7 +2766,7 @@ color_pass (ira_loop_tree_node_t loop_tr
 	pclass = ira_pressure_class_translate[rclass];
 	if (flag_ira_region == IRA_REGION_MIXED
 	    && (loop_tree_node->reg_pressure[pclass]
-		<= ira_available_class_regs[pclass]))
+		<= ira_class_hard_regs_num[pclass]))
 	  {
 	    mode = ALLOCNO_MODE (a);
 	    hard_regno = ALLOCNO_HARD_REGNO (a);
@@ -2819,7 +2819,7 @@ color_pass (ira_loop_tree_node_t loop_tr
 				    ALLOCNO_NUM (subloop_allocno)));
 	  if ((flag_ira_region == IRA_REGION_MIXED)
 	      && (loop_tree_node->reg_pressure[pclass]
-		  <= ira_available_class_regs[pclass]))
+		  <= ira_class_hard_regs_num[pclass]))
 	    {
 	      if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
 		{
Index: gcc/ira-emit.c
===================================================================
--- gcc/ira-emit.c	2012-05-30 18:57:09.220912962 +0100
+++ gcc/ira-emit.c	2012-05-30 19:08:35.846893000 +0100
@@ -606,7 +606,7 @@ change_loop (ira_loop_tree_node_t node)
 		  == ALLOCNO_HARD_REGNO (parent_allocno))
 	      && (ALLOCNO_HARD_REGNO (allocno) < 0
 		  || (parent->reg_pressure[pclass] + 1
-		      <= ira_available_class_regs[pclass])
+		      <= ira_class_hard_regs_num[pclass])
 		  || TEST_HARD_REG_BIT (ira_prohibited_mode_move_regs
 					[ALLOCNO_MODE (allocno)],
 					ALLOCNO_HARD_REGNO (allocno))
Index: gcc/ira-lives.c
===================================================================
--- gcc/ira-lives.c	2012-05-30 18:57:09.220912962 +0100
+++ gcc/ira-lives.c	2012-05-30 19:08:35.847893000 +0100
@@ -192,7 +192,7 @@ inc_register_pressure (enum reg_class pc
 	continue;
       curr_reg_pressure[cl] += n;
       if (high_pressure_start_point[cl] < 0
-	  && (curr_reg_pressure[cl] > ira_available_class_regs[cl]))
+	  && (curr_reg_pressure[cl] > ira_class_hard_regs_num[cl]))
 	high_pressure_start_point[cl] = curr_point;
       if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
 	curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
@@ -221,7 +221,7 @@ dec_register_pressure (enum reg_class pc
       curr_reg_pressure[cl] -= nregs;
       ira_assert (curr_reg_pressure[cl] >= 0);
       if (high_pressure_start_point[cl] >= 0
-	  && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+	  && curr_reg_pressure[cl] <= ira_class_hard_regs_num[cl])
 	set_p = true;
     }
   if (set_p)
@@ -235,7 +235,7 @@ dec_register_pressure (enum reg_class pc
 	  if (! ira_reg_pressure_class_p[cl])
 	    continue;
 	  if (high_pressure_start_point[cl] >= 0
-	      && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+	      && curr_reg_pressure[cl] <= ira_class_hard_regs_num[cl])
 	    high_pressure_start_point[cl] = -1;
 	}
     }
@@ -851,7 +851,7 @@ single_reg_class (const char *constraint
 		     ? GENERAL_REGS
 		     : REG_CLASS_FROM_CONSTRAINT (c, constraints));
 	  if ((cl != NO_REGS && next_cl != cl)
-	      || (ira_available_class_regs[next_cl]
+	      || (ira_class_hard_regs_num[next_cl]
 		  > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
 	    return NO_REGS;
 	  cl = next_cl;
@@ -864,7 +864,7 @@ single_reg_class (const char *constraint
 				recog_data.operand[c - '0'], NULL_RTX);
 	  if ((cl != NO_REGS && next_cl != cl)
 	      || next_cl == NO_REGS
-	      || (ira_available_class_regs[next_cl]
+	      || (ira_class_hard_regs_num[next_cl]
 		  > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
 	    return NO_REGS;
 	  cl = next_cl;
@@ -943,8 +943,8 @@ ira_implicitly_set_insn_hard_regs (HARD_
 		  if (cl != NO_REGS
 		      /* There is no register pressure problem if all of the
 			 regs in this class are fixed.  */
-		      && ira_available_class_regs[cl] != 0
-		      && (ira_available_class_regs[cl]
+		      && ira_class_hard_regs_num[cl] != 0
+		      && (ira_class_hard_regs_num[cl]
 			  <= ira_reg_class_max_nregs[cl][mode]))
 		    IOR_HARD_REG_SET (*set, reg_class_contents[cl]);
 		  break;
@@ -1170,7 +1170,7 @@ process_bb_node_lives (ira_loop_tree_nod
 		if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
 		  curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
 		ira_assert (curr_reg_pressure[cl]
-			    <= ira_available_class_regs[cl]);
+			    <= ira_class_hard_regs_num[cl]);
 	      }
 	  }
       EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
Index: gcc/loop-invariant.c
===================================================================
--- gcc/loop-invariant.c	2012-05-30 18:57:09.221912963 +0100
+++ gcc/loop-invariant.c	2012-05-30 19:08:35.849893000 +0100
@@ -1210,7 +1210,7 @@ gain_for_invariant (struct invariant *in
 	      + (int) regs_needed[pressure_class]
 	      + LOOP_DATA (curr_loop)->max_reg_pressure[pressure_class]
 	      + IRA_LOOP_RESERVED_REGS
-	      > ira_available_class_regs[pressure_class])
+	      > ira_class_hard_regs_num[pressure_class])
 	    break;
 	}
       if (i < ira_pressure_classes_num)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [2/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
  2012-05-30 18:16 ` [1/7] " Richard Sandiford
@ 2012-05-30 18:22 ` Richard Sandiford
  2012-05-31  2:04   ` Vladimir Makarov
  2012-05-30 18:25 ` [3/7] " Richard Sandiford
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

The only part of IRA that uses move_costs directly is copy_cost.
It looks like this might be an oversight, since all related costs
already use ira_register_move_cost.

As mentioned in the covering message, the two arrays are usually
the same anyway.  The only hitch is that we have:

      if (!move_cost[mode])
        init_move_cost (mode);

so if the move costs for this mode really haven't been calculated yet,
we could potentially end up with different costs then if we used the
normal ira_init_register_move_cost_if_necessary route.  In the former
case we'd use the original move_cost (before the IRA modifications),
while in the latter we'd use the value assigned by
ira_init_register_move_cost via the ira_register_move_cost alias.

Richard


gcc/
	* ira-costs.c (copy_cost): Use ira_init_register_move_cost_if_necessary
	and ira_register_move_cost instead of init_move_cost and move_cost.

Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	2012-05-30 18:57:09.040912969 +0100
+++ gcc/ira-costs.c	2012-05-30 19:16:22.921879419 +0100
@@ -359,9 +359,8 @@ copy_cost (rtx x, enum machine_mode mode
 
   if (secondary_class != NO_REGS)
     {
-      if (!move_cost[mode])
-        init_move_cost (mode);
-      return (move_cost[mode][(int) secondary_class][(int) rclass]
+      ira_init_register_move_cost_if_necessary (mode);
+      return (ira_register_move_cost[mode][(int) secondary_class][(int) rclass]
 	      + sri.extra_cost
 	      + copy_cost (x, mode, secondary_class, to_p, &sri));
     }
@@ -374,10 +373,11 @@ copy_cost (rtx x, enum machine_mode mode
 	   + ira_memory_move_cost[mode][(int) rclass][to_p != 0];
   else if (REG_P (x))
     {
-      if (!move_cost[mode])
-        init_move_cost (mode);
+      reg_class_t x_class = REGNO_REG_CLASS (REGNO (x));
+
+      ira_init_register_move_cost_if_necessary (mode);
       return (sri.extra_cost
-	      + move_cost[mode][REGNO_REG_CLASS (REGNO (x))][(int) rclass]);
+	      + ira_register_move_cost[mode][(int) x_class][(int) rclass]);
     }
   else
     /* If this is a constant, we may eventually want to call rtx_cost

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [3/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
  2012-05-30 18:16 ` [1/7] " Richard Sandiford
  2012-05-30 18:22 ` [2/7] " Richard Sandiford
@ 2012-05-30 18:25 ` Richard Sandiford
  2012-05-31  2:04   ` Vladimir Makarov
  2012-05-30 18:26 ` [4/7] " Richard Sandiford
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

After the preceding patch, only ira_init_register_move_cost uses
the regclass costs directly.  This patch moves them to IRA and makes
init_move_cost static to it.

This is just a stepping stone to make the later patches easier to review.

Richard


gcc/
	* regs.h (move_table, move_cost, may_move_in_cost, may_move_out_cost):
	Move these definitions and associated target_globals fields to...
	* ira-int.h: ...here.
	* rtl.h (init_move_cost): Delete.
	* reginfo.c (last_mode_for_init_move_cost, init_move_cost): Move to...
	* ira.c: ...here, making the latter static.

Index: gcc/regs.h
===================================================================
--- gcc/regs.h	2012-05-29 19:11:06.079795522 +0100
+++ gcc/regs.h	2012-05-29 19:27:41.214766589 +0100
@@ -240,8 +240,6 @@ #define HARD_REGNO_CALLER_SAVE_MODE(REGN
 #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0
 #endif
 
-typedef unsigned short move_table[N_REG_CLASSES];
-
 /* Target-dependent globals.  */
 struct target_regs {
   /* For each starting hard register, the number of consecutive hard
@@ -261,21 +259,6 @@ struct target_regs {
   /* 1 if the corresponding class contains a register of the given mode.  */
   char x_contains_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE];
 
-  /* Maximum cost of moving from a register in one class to a register
-     in another class.  Based on TARGET_REGISTER_MOVE_COST.  */
-  move_table *x_move_cost[MAX_MACHINE_MODE];
-
-  /* Similar, but here we don't have to move if the first index is a
-     subset of the second so in that case the cost is zero.  */
-  move_table *x_may_move_in_cost[MAX_MACHINE_MODE];
-
-  /* Similar, but here we don't have to move if the first index is a
-     superset of the second so in that case the cost is zero.  */
-  move_table *x_may_move_out_cost[MAX_MACHINE_MODE];
-
-  /* Keep track of the last mode we initialized move costs for.  */
-  int x_last_mode_for_init_move_cost;
-
   /* Record for each mode whether we can move a register directly to or
      from an object of that mode in memory.  If we can't, we won't try
      to use that mode directly when accessing a field of that mode.  */
@@ -301,12 +284,6 @@ #define have_regs_of_mode \
   (this_target_regs->x_have_regs_of_mode)
 #define contains_reg_of_mode \
   (this_target_regs->x_contains_reg_of_mode)
-#define move_cost \
-  (this_target_regs->x_move_cost)
-#define may_move_in_cost \
-  (this_target_regs->x_may_move_in_cost)
-#define may_move_out_cost \
-  (this_target_regs->x_may_move_out_cost)
 #define direct_load \
   (this_target_regs->x_direct_load)
 #define direct_store \
Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h	2012-05-29 19:11:06.079795522 +0100
+++ gcc/ira-int.h	2012-05-29 19:27:41.207766589 +0100
@@ -75,6 +75,8 @@ DEF_VEC_ALLOC_P(ira_copy_t, heap);
 /* Typedef for pointer to the subsequent structure.  */
 typedef struct ira_loop_tree_node *ira_loop_tree_node_t;
 
+typedef unsigned short move_table[N_REG_CLASSES];
+
 /* In general case, IRA is a regional allocator.  The regions are
    nested and form a tree.  Currently regions are natural loops.  The
    following structure describes loop tree node (representing basic
@@ -767,6 +769,21 @@ struct target_ira_int {
   HARD_REG_SET (x_ira_reg_mode_hard_regset
 		[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES]);
 
+  /* Maximum cost of moving from a register in one class to a register
+     in another class.  Based on TARGET_REGISTER_MOVE_COST.  */
+  move_table *x_move_cost[MAX_MACHINE_MODE];
+
+  /* Similar, but here we don't have to move if the first index is a
+     subset of the second so in that case the cost is zero.  */
+  move_table *x_may_move_in_cost[MAX_MACHINE_MODE];
+
+  /* Similar, but here we don't have to move if the first index is a
+     superset of the second so in that case the cost is zero.  */
+  move_table *x_may_move_out_cost[MAX_MACHINE_MODE];
+
+  /* Keep track of the last mode we initialized move costs for.  */
+  int x_last_mode_for_init_move_cost;
+
   /* Array based on TARGET_REGISTER_MOVE_COST.  Don't use
      ira_register_move_cost directly.  Use function of
      ira_get_may_move_cost instead.  */
@@ -888,6 +905,12 @@ #define this_target_ira_int (&default_ta
 
 #define ira_reg_mode_hard_regset \
   (this_target_ira_int->x_ira_reg_mode_hard_regset)
+#define move_cost \
+  (this_target_ira_int->x_move_cost)
+#define may_move_in_cost \
+  (this_target_ira_int->x_may_move_in_cost)
+#define may_move_out_cost \
+  (this_target_ira_int->x_may_move_out_cost)
 #define ira_register_move_cost \
   (this_target_ira_int->x_ira_register_move_cost)
 #define ira_max_memory_move_cost \
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2012-05-29 19:11:06.080795522 +0100
+++ gcc/rtl.h	2012-05-29 19:27:41.216766589 +0100
@@ -2045,8 +2045,6 @@ extern rtx remove_free_EXPR_LIST_node (r
 
 /* reginfo.c */
 
-/* Initialize may_move_cost and friends for mode M.  */
-extern void init_move_cost (enum machine_mode);
 /* Resize reg info.  */
 extern bool resize_reg_info (void);
 /* Free up register info memory.  */
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c	2012-05-29 19:11:06.079795522 +0100
+++ gcc/reginfo.c	2012-05-29 19:27:41.213766589 +0100
@@ -122,9 +122,6 @@ static const char *const initial_reg_nam
 /* Array containing all of the register class names.  */
 const char * reg_class_names[] = REG_CLASS_NAMES;
 
-#define last_mode_for_init_move_cost \
-  (this_target_regs->x_last_mode_for_init_move_cost)
-
 /* No more global register variables may be declared; true once
    reginfo has been initialized.  */
 static int no_global_reg_vars = 0;
@@ -197,95 +194,6 @@ init_reg_sets (void)
   SET_HARD_REG_SET (operand_reg_set);
 }
 
-/* Initialize may_move_cost and friends for mode M.  */
-void
-init_move_cost (enum machine_mode m)
-{
-  static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
-  bool all_match = true;
-  unsigned int i, j;
-
-  gcc_assert (have_regs_of_mode[m]);
-  for (i = 0; i < N_REG_CLASSES; i++)
-    if (contains_reg_of_mode[i][m])
-      for (j = 0; j < N_REG_CLASSES; j++)
-	{
-	  int cost;
-	  if (!contains_reg_of_mode[j][m])
-	    cost = 65535;
-	  else
-	    {
-	      cost = register_move_cost (m, (enum reg_class) i,
-					 (enum reg_class) j);
-	      gcc_assert (cost < 65535);
-	    }
-	  all_match &= (last_move_cost[i][j] == cost);
-	  last_move_cost[i][j] = cost;
-	}
-  if (all_match && last_mode_for_init_move_cost != -1)
-    {
-      move_cost[m] = move_cost[last_mode_for_init_move_cost];
-      may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
-      may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
-      return;
-    }
-  last_mode_for_init_move_cost = m;
-  move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
-					* N_REG_CLASSES);
-  may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
-					       * N_REG_CLASSES);
-  may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
-					        * N_REG_CLASSES);
-  for (i = 0; i < N_REG_CLASSES; i++)
-    if (contains_reg_of_mode[i][m])
-      for (j = 0; j < N_REG_CLASSES; j++)
-	{
-	  int cost;
-	  enum reg_class *p1, *p2;
-
-	  if (last_move_cost[i][j] == 65535)
-	    {
-	      move_cost[m][i][j] = 65535;
-	      may_move_in_cost[m][i][j] = 65535;
-	      may_move_out_cost[m][i][j] = 65535;
-	    }
-	  else
-	    {
-	      cost = last_move_cost[i][j];
-
-	      for (p2 = &reg_class_subclasses[j][0];
-		   *p2 != LIM_REG_CLASSES; p2++)
-		if (*p2 != i && contains_reg_of_mode[*p2][m])
-		  cost = MAX (cost, move_cost[m][i][*p2]);
-
-	      for (p1 = &reg_class_subclasses[i][0];
-		   *p1 != LIM_REG_CLASSES; p1++)
-		if (*p1 != j && contains_reg_of_mode[*p1][m])
-		  cost = MAX (cost, move_cost[m][*p1][j]);
-
-	      gcc_assert (cost <= 65535);
-	      move_cost[m][i][j] = cost;
-
-	      if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
-		may_move_in_cost[m][i][j] = 0;
-	      else
-		may_move_in_cost[m][i][j] = cost;
-
-	      if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
-		may_move_out_cost[m][i][j] = 0;
-	      else
-		may_move_out_cost[m][i][j] = cost;
-	    }
-	}
-    else
-      for (j = 0; j < N_REG_CLASSES; j++)
-	{
-	  move_cost[m][i][j] = 65535;
-	  may_move_in_cost[m][i][j] = 65535;
-	  may_move_out_cost[m][i][j] = 65535;
-	}
-}
-
 /* We need to save copies of some of the register information which
    can be munged by command-line switches so we can restore it during
    subsequent back-end reinitialization.  */
@@ -575,25 +483,6 @@ init_reg_sets_1 (void)
 	     have_regs_of_mode [m] = 1;
 	  }
      }
-
-  /* Reset move_cost and friends, making sure we only free shared
-     table entries once.  */
-  for (i = 0; i < MAX_MACHINE_MODE; i++)
-    if (move_cost[i])
-      {
-	for (j = 0; j < i && move_cost[i] != move_cost[j]; j++)
-	  ;
-	if (i == j)
-	  {
-	    free (move_cost[i]);
-	    free (may_move_in_cost[i]);
-	    free (may_move_out_cost[i]);
-	  }
-      }
-  memset (move_cost, 0, sizeof move_cost);
-  memset (may_move_in_cost, 0, sizeof may_move_in_cost);
-  memset (may_move_out_cost, 0, sizeof may_move_out_cost);
-  last_mode_for_init_move_cost = -1;
 }
 
 /* Compute the table of register modes.
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-05-29 19:19:03.148781651 +0100
+++ gcc/ira.c	2012-05-29 19:27:44.126766505 +0100
@@ -423,6 +423,8 @@ struct ira_spilled_reg_stack_slot *ira_s
 /* Temporary hard reg set used for a different calculation.  */
 static HARD_REG_SET temp_hard_regset;
 
+#define last_mode_for_init_move_cost \
+  (this_target_ira_int->x_last_mode_for_init_move_cost)
 \f
 
 /* The function sets up the map IRA_REG_MODE_HARD_REGSET.  */
@@ -1455,8 +1457,96 @@ clarify_prohibited_class_mode_regs (void
 	      }
 	}
 }
-
 \f
+/* Initialize may_move_cost and friends for mode M.  */
+
+static void
+init_move_cost (enum machine_mode m)
+{
+  static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
+  bool all_match = true;
+  unsigned int i, j;
+
+  gcc_assert (have_regs_of_mode[m]);
+  for (i = 0; i < N_REG_CLASSES; i++)
+    if (contains_reg_of_mode[i][m])
+      for (j = 0; j < N_REG_CLASSES; j++)
+	{
+	  int cost;
+	  if (!contains_reg_of_mode[j][m])
+	    cost = 65535;
+	  else
+	    {
+	      cost = register_move_cost (m, (enum reg_class) i,
+					 (enum reg_class) j);
+	      gcc_assert (cost < 65535);
+	    }
+	  all_match &= (last_move_cost[i][j] == cost);
+	  last_move_cost[i][j] = cost;
+	}
+  if (all_match && last_mode_for_init_move_cost != -1)
+    {
+      move_cost[m] = move_cost[last_mode_for_init_move_cost];
+      may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
+      may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
+      return;
+    }
+  last_mode_for_init_move_cost = m;
+  move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+					* N_REG_CLASSES);
+  may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+					       * N_REG_CLASSES);
+  may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+					        * N_REG_CLASSES);
+  for (i = 0; i < N_REG_CLASSES; i++)
+    if (contains_reg_of_mode[i][m])
+      for (j = 0; j < N_REG_CLASSES; j++)
+	{
+	  int cost;
+	  enum reg_class *p1, *p2;
+
+	  if (last_move_cost[i][j] == 65535)
+	    {
+	      move_cost[m][i][j] = 65535;
+	      may_move_in_cost[m][i][j] = 65535;
+	      may_move_out_cost[m][i][j] = 65535;
+	    }
+	  else
+	    {
+	      cost = last_move_cost[i][j];
+
+	      for (p2 = &reg_class_subclasses[j][0];
+		   *p2 != LIM_REG_CLASSES; p2++)
+		if (*p2 != i && contains_reg_of_mode[*p2][m])
+		  cost = MAX (cost, move_cost[m][i][*p2]);
+
+	      for (p1 = &reg_class_subclasses[i][0];
+		   *p1 != LIM_REG_CLASSES; p1++)
+		if (*p1 != j && contains_reg_of_mode[*p1][m])
+		  cost = MAX (cost, move_cost[m][*p1][j]);
+
+	      gcc_assert (cost <= 65535);
+	      move_cost[m][i][j] = cost;
+
+	      if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
+		may_move_in_cost[m][i][j] = 0;
+	      else
+		may_move_in_cost[m][i][j] = cost;
+
+	      if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
+		may_move_out_cost[m][i][j] = 0;
+	      else
+		may_move_out_cost[m][i][j] = cost;
+	    }
+	}
+    else
+      for (j = 0; j < N_REG_CLASSES; j++)
+	{
+	  move_cost[m][i][j] = 65535;
+	  may_move_in_cost[m][i][j] = 65535;
+	  may_move_out_cost[m][i][j] = 65535;
+	}
+}
 
 /* Allocate and initialize IRA_REGISTER_MOVE_COST,
    IRA_MAX_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST,
@@ -1577,8 +1667,26 @@ ira_init_once (void)
 static void
 free_register_move_costs (void)
 {
-  int mode;
+  int mode, i;
 
+  /* Reset move_cost and friends, making sure we only free shared
+     table entries once.  */
+  for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
+    if (move_cost[mode])
+      {
+	for (i = 0; i < mode && move_cost[i] != move_cost[mode]; i++)
+	  ;
+	if (i == mode)
+	  {
+	    free (move_cost[mode]);
+	    free (may_move_in_cost[mode]);
+	    free (may_move_out_cost[mode]);
+	  }
+      }
+  memset (move_cost, 0, sizeof move_cost);
+  memset (may_move_in_cost, 0, sizeof may_move_in_cost);
+  memset (may_move_out_cost, 0, sizeof may_move_out_cost);
+  last_mode_for_init_move_cost = -1;
   for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
     {
       free (ira_max_register_move_cost[mode]);

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [4/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
                   ` (2 preceding siblings ...)
  2012-05-30 18:25 ` [3/7] " Richard Sandiford
@ 2012-05-30 18:26 ` Richard Sandiford
  2012-05-31  2:05   ` Vladimir Makarov
  2012-05-30 18:28 ` [5/7] " Richard Sandiford
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

This patch adjusts init_move_cost to follow local conventions.
The new names are IMO more readable anyway (it's easier to see
that p1 is related to cl1 than i, etc.).

Richard


gcc/
	* ira.c (init_move_cost): Adjust local variable names to match
	file conventions.  Use ira_assert instead of gcc_assert.

Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-05-29 19:27:44.126766505 +0100
+++ gcc/ira.c	2012-05-29 19:27:46.987766420 +0100
@@ -1461,90 +1461,92 @@ clarify_prohibited_class_mode_regs (void
 /* Initialize may_move_cost and friends for mode M.  */
 
 static void
-init_move_cost (enum machine_mode m)
+init_move_cost (enum machine_mode mode)
 {
   static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
   bool all_match = true;
-  unsigned int i, j;
+  unsigned int cl1, cl2;
 
-  gcc_assert (have_regs_of_mode[m]);
-  for (i = 0; i < N_REG_CLASSES; i++)
-    if (contains_reg_of_mode[i][m])
-      for (j = 0; j < N_REG_CLASSES; j++)
+  ira_assert (have_regs_of_mode[mode]);
+  for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
+    if (contains_reg_of_mode[cl1][mode])
+      for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	{
 	  int cost;
-	  if (!contains_reg_of_mode[j][m])
+	  if (!contains_reg_of_mode[cl2][mode])
 	    cost = 65535;
 	  else
 	    {
-	      cost = register_move_cost (m, (enum reg_class) i,
-					 (enum reg_class) j);
-	      gcc_assert (cost < 65535);
+	      cost = register_move_cost (mode, (enum reg_class) cl1,
+					 (enum reg_class) cl2);
+	      ira_assert (cost < 65535);
 	    }
-	  all_match &= (last_move_cost[i][j] == cost);
-	  last_move_cost[i][j] = cost;
+	  all_match &= (last_move_cost[cl1][cl2] == cost);
+	  last_move_cost[cl1][cl2] = cost;
 	}
   if (all_match && last_mode_for_init_move_cost != -1)
     {
-      move_cost[m] = move_cost[last_mode_for_init_move_cost];
-      may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
-      may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
+      move_cost[mode] = move_cost[last_mode_for_init_move_cost];
+      may_move_in_cost[mode] = may_move_in_cost[last_mode_for_init_move_cost];
+      may_move_out_cost[mode] = may_move_out_cost[last_mode_for_init_move_cost];
       return;
     }
-  last_mode_for_init_move_cost = m;
-  move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+  last_mode_for_init_move_cost = mode;
+  move_cost[mode] = (move_table *)xmalloc (sizeof (move_table)
 					* N_REG_CLASSES);
-  may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+  may_move_in_cost[mode] = (move_table *)xmalloc (sizeof (move_table)
 					       * N_REG_CLASSES);
-  may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
+  may_move_out_cost[mode] = (move_table *)xmalloc (sizeof (move_table)
 					        * N_REG_CLASSES);
-  for (i = 0; i < N_REG_CLASSES; i++)
-    if (contains_reg_of_mode[i][m])
-      for (j = 0; j < N_REG_CLASSES; j++)
+  for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
+    if (contains_reg_of_mode[cl1][mode])
+      for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	{
 	  int cost;
 	  enum reg_class *p1, *p2;
 
-	  if (last_move_cost[i][j] == 65535)
+	  if (last_move_cost[cl1][cl2] == 65535)
 	    {
-	      move_cost[m][i][j] = 65535;
-	      may_move_in_cost[m][i][j] = 65535;
-	      may_move_out_cost[m][i][j] = 65535;
+	      move_cost[mode][cl1][cl2] = 65535;
+	      may_move_in_cost[mode][cl1][cl2] = 65535;
+	      may_move_out_cost[mode][cl1][cl2] = 65535;
 	    }
 	  else
 	    {
-	      cost = last_move_cost[i][j];
+	      cost = last_move_cost[cl1][cl2];
 
-	      for (p2 = &reg_class_subclasses[j][0];
+	      for (p2 = &reg_class_subclasses[cl2][0];
 		   *p2 != LIM_REG_CLASSES; p2++)
-		if (*p2 != i && contains_reg_of_mode[*p2][m])
-		  cost = MAX (cost, move_cost[m][i][*p2]);
+		if (*p2 != cl1 && contains_reg_of_mode[*p2][mode])
+		  cost = MAX (cost, move_cost[mode][cl1][*p2]);
 
-	      for (p1 = &reg_class_subclasses[i][0];
+	      for (p1 = &reg_class_subclasses[cl1][0];
 		   *p1 != LIM_REG_CLASSES; p1++)
-		if (*p1 != j && contains_reg_of_mode[*p1][m])
-		  cost = MAX (cost, move_cost[m][*p1][j]);
+		if (*p1 != cl2 && contains_reg_of_mode[*p1][mode])
+		  cost = MAX (cost, move_cost[mode][*p1][cl2]);
 
-	      gcc_assert (cost <= 65535);
-	      move_cost[m][i][j] = cost;
+	      ira_assert (cost <= 65535);
+	      move_cost[mode][cl1][cl2] = cost;
 
-	      if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
-		may_move_in_cost[m][i][j] = 0;
+	      if (reg_class_subset_p ((enum reg_class) cl1,
+				      (enum reg_class) cl2))
+		may_move_in_cost[mode][cl1][cl2] = 0;
 	      else
-		may_move_in_cost[m][i][j] = cost;
+		may_move_in_cost[mode][cl1][cl2] = cost;
 
-	      if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
-		may_move_out_cost[m][i][j] = 0;
+	      if (reg_class_subset_p ((enum reg_class) cl2,
+				      (enum reg_class) cl1))
+		may_move_out_cost[mode][cl1][cl2] = 0;
 	      else
-		may_move_out_cost[m][i][j] = cost;
+		may_move_out_cost[mode][cl1][cl2] = cost;
 	    }
 	}
     else
-      for (j = 0; j < N_REG_CLASSES; j++)
+      for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	{
-	  move_cost[m][i][j] = 65535;
-	  may_move_in_cost[m][i][j] = 65535;
-	  may_move_out_cost[m][i][j] = 65535;
+	  move_cost[mode][cl1][cl2] = 65535;
+	  may_move_in_cost[mode][cl1][cl2] = 65535;
+	  may_move_out_cost[mode][cl1][cl2] = 65535;
 	}
 }
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [5/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
                   ` (3 preceding siblings ...)
  2012-05-30 18:26 ` [4/7] " Richard Sandiford
@ 2012-05-30 18:28 ` Richard Sandiford
  2012-05-31  2:06   ` Vladimir Makarov
  2012-05-30 18:42 ` [6/7] " Richard Sandiford
  2012-05-30 18:44 ` [7/7] " Richard Sandiford
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

I needed to move an instance of:

      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
      if (hard_reg_set_empty_p (temp_hard_regset))
	continue;

But this can more easily be calculated as:

      ira_class_hard_regs_num[cl] == 0

so this patch uses that instead.

Richard


gcc/
	* ira.c (setup_allocno_and_important_classes): Use
	ira_class_hard_regs_num to check whether a class has any
	allocatable registers.
	(ira_init_register_move_cost): Likewise.

Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-05-29 19:27:46.987766420 +0100
+++ gcc/ira.c	2012-05-29 19:35:14.021753423 +0100
@@ -970,39 +970,32 @@ setup_allocno_and_important_classes (voi
      registers.  */
   ira_allocno_classes_num = 0;
   for (i = 0; (cl = classes[i]) != LIM_REG_CLASSES; i++)
-    {
-      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
-      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-      if (hard_reg_set_empty_p (temp_hard_regset))
-	continue;
+    if (ira_class_hard_regs_num[cl] > 0)
       ira_allocno_classes[ira_allocno_classes_num++] = (enum reg_class) cl;
-    }
   ira_important_classes_num = 0;
   /* Add non-allocno classes containing to non-empty set of
      allocatable hard regs.  */
   for (cl = 0; cl < N_REG_CLASSES; cl++)
-    {
-      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
-      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-      if (! hard_reg_set_empty_p (temp_hard_regset))
-	{
-	  set_p = false;
-	  for (j = 0; j < ira_allocno_classes_num; j++)
-	    {
-	      COPY_HARD_REG_SET (temp_hard_regset2,
-				 reg_class_contents[ira_allocno_classes[j]]);
-	      AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
-	      if ((enum reg_class) cl == ira_allocno_classes[j])
-		break;
-	      else if (hard_reg_set_subset_p (temp_hard_regset,
-					      temp_hard_regset2))
-		set_p = true;
-	    }
-	  if (set_p && j >= ira_allocno_classes_num)
-	    ira_important_classes[ira_important_classes_num++]
-	      = (enum reg_class) cl;
-	}
-    }
+    if (ira_class_hard_regs_num[cl] > 0)
+      {
+	COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+	AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
+	set_p = false;
+	for (j = 0; j < ira_allocno_classes_num; j++)
+	  {
+	    COPY_HARD_REG_SET (temp_hard_regset2,
+			       reg_class_contents[ira_allocno_classes[j]]);
+	    AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs);
+	    if ((enum reg_class) cl == ira_allocno_classes[j])
+	      break;
+	    else if (hard_reg_set_subset_p (temp_hard_regset,
+					    temp_hard_regset2))
+	      set_p = true;
+	  }
+	if (set_p && j >= ira_allocno_classes_num)
+	  ira_important_classes[ira_important_classes_num++]
+	    = (enum reg_class) cl;
+      }
   /* Now add allocno classes to the important classes.  */
   for (j = 0; j < ira_allocno_classes_num; j++)
     ira_important_classes[ira_important_classes_num++]
@@ -1575,15 +1568,10 @@ ira_init_register_move_cost (enum machin
   memcpy (ira_max_register_move_cost[mode], ira_register_move_cost[mode],
 	  sizeof (move_table) * N_REG_CLASSES);
   for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
-    {
-      /* Some subclasses are to small to have enough registers to hold
-	 a value of MODE.  Just ignore them.  */
-      if (ira_reg_class_max_nregs[cl1][mode] > ira_class_hard_regs_num[cl1])
-	continue;
-      COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]);
-      AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-      if (hard_reg_set_empty_p (temp_hard_regset))
-	continue;
+    /* Some subclasses are to small to have enough registers to hold
+       a value of MODE.  Just ignore them.  */
+    if (ira_class_hard_regs_num[cl1] > 0
+	&& ira_reg_class_max_nregs[cl1][mode] <= ira_class_hard_regs_num[cl1])
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	if (hard_reg_set_subset_p (reg_class_contents[cl1],
 				   reg_class_contents[cl2]))
@@ -1598,7 +1586,6 @@ ira_init_register_move_cost (enum machin
 		ira_max_register_move_cost[mode][cl3][cl2]
 		  = ira_register_move_cost[mode][cl3][cl1];
 	    }
-    }
   ira_may_move_in_cost[mode]
     = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
   memcpy (ira_may_move_in_cost[mode], may_move_in_cost[mode],
@@ -1619,9 +1606,7 @@ ira_init_register_move_cost (enum machin
     {
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	{
-	  COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl2]);
-	  AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
-	  if (hard_reg_set_empty_p (temp_hard_regset))
+	  if (ira_class_hard_regs_num[cl2] == 0)
 	    continue;
 	  if (ira_class_subset_p[cl1][cl2])
 	    ira_may_move_in_cost[mode][cl1][cl2] = 0;

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [6/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
                   ` (4 preceding siblings ...)
  2012-05-30 18:28 ` [5/7] " Richard Sandiford
@ 2012-05-30 18:42 ` Richard Sandiford
  2012-05-31  2:20   ` Vladimir Makarov
  2012-05-30 18:44 ` [7/7] " Richard Sandiford
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

This patch makes the original move_cost calculation match the value
currently calculated for ira_register_move_cost, asserting that the
"IRA code" now has nothing to do.

It seems like we really ought to be preserving the contains_reg_of_mode
part of the original move_cost check, i.e.:

		if (contains_reg_of_mode[*p2][mode])
		    && ira_class_hard_regs_num[*p2] > 0
		    && (ira_reg_class_max_nregs[*p2][mode]
			<= ira_class_hard_regs_num[*p2]))

etc.  But that changes the cc1 .ii output for x86_64, so the current
costs really do include the costs for subclasses that don't contain
registers of a particular mode.  I think adding the check "back"
should be a separate patch (by someone who can test the performance!).

A strict conversion for may_move_in_cost and may_move_out_cost would
be to convert the two instances of:

	      may_move_in_cost[mode][cl1][cl2] = 65535;
	      may_move_out_cost[mode][cl1][cl2] = 65535;

to:

	      if (ira_class_hard_regs_num[cl2] > 0
		  && ira_class_subset_p[cl1][cl2])
		may_move_in_cost[mode][cl1][cl2] = 0;
	      else
		may_move_in_cost[mode][cl1][cl2] = 65535;

	      if (ira_class_hard_regs_num[cl2] > 0
		  && ira_class_subset_p[cl2][cl1])
		may_move_in_cost[mode][cl1][cl2] = 0;
	      else
		may_move_out_cost[mode][cl1][cl2] = 65535;

because here too the current IRA costs don't take
contains_reg_of_mode into account.  But that change wouldn't
really make sense, because cl2 represents different things
for the "in" and "out" cost (the operand class and the allocation
class respectively).  The cc1 .ii output is the same either way,
so for this one I've just added the contains_reg_of_mode tests
to the IRA version.

It might seem odd to commit these asserts and then remove them
in the next patch.  But I'd like to commit them anyway so that,
if this series does mess things up, the asserts can help show why.

Richard


gcc/
	* ira.c (init_move_cost): Adjust choice of subclasses to match
	the current ira_init_register_move_cost choice.  Use
	ira_class_subset_p instead of reg_class_subset_p.
	(ira_init_register_move_cost): Assert that move_cost,
	may_move_in_cost and may_move_out_cost already hold the desired
	values for their ira_* equivalents.  For the latter two,
	ignore classes that can't store a register of the given mode.

Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-05-29 19:35:14.000000000 +0100
+++ gcc/ira.c	2012-05-30 18:56:57.930913292 +0100
@@ -1510,25 +1510,27 @@ init_move_cost (enum machine_mode mode)
 
 	      for (p2 = &reg_class_subclasses[cl2][0];
 		   *p2 != LIM_REG_CLASSES; p2++)
-		if (*p2 != cl1 && contains_reg_of_mode[*p2][mode])
+		if (ira_class_hard_regs_num[*p2] > 0
+		    && (ira_reg_class_max_nregs[*p2][mode]
+			<= ira_class_hard_regs_num[*p2]))
 		  cost = MAX (cost, move_cost[mode][cl1][*p2]);
 
 	      for (p1 = &reg_class_subclasses[cl1][0];
 		   *p1 != LIM_REG_CLASSES; p1++)
-		if (*p1 != cl2 && contains_reg_of_mode[*p1][mode])
+		if (ira_class_hard_regs_num[*p1] > 0
+		    && (ira_reg_class_max_nregs[*p1][mode]
+			<= ira_class_hard_regs_num[*p1]))
 		  cost = MAX (cost, move_cost[mode][*p1][cl2]);
 
 	      ira_assert (cost <= 65535);
 	      move_cost[mode][cl1][cl2] = cost;
 
-	      if (reg_class_subset_p ((enum reg_class) cl1,
-				      (enum reg_class) cl2))
+	      if (ira_class_subset_p[cl1][cl2])
 		may_move_in_cost[mode][cl1][cl2] = 0;
 	      else
 		may_move_in_cost[mode][cl1][cl2] = cost;
 
-	      if (reg_class_subset_p ((enum reg_class) cl2,
-				      (enum reg_class) cl1))
+	      if (ira_class_subset_p[cl2][cl1])
 		may_move_out_cost[mode][cl1][cl2] = 0;
 	      else
 		may_move_out_cost[mode][cl1][cl2] = cost;
@@ -1577,14 +1579,10 @@ ira_init_register_move_cost (enum machin
 				   reg_class_contents[cl2]))
 	  for (cl3 = 0; cl3 < N_REG_CLASSES; cl3++)
 	    {
-	      if (ira_max_register_move_cost[mode][cl2][cl3]
-		  < ira_register_move_cost[mode][cl1][cl3])
-		ira_max_register_move_cost[mode][cl2][cl3]
-		  = ira_register_move_cost[mode][cl1][cl3];
-	      if (ira_max_register_move_cost[mode][cl3][cl2]
-		  < ira_register_move_cost[mode][cl3][cl1])
-		ira_max_register_move_cost[mode][cl3][cl2]
-		  = ira_register_move_cost[mode][cl3][cl1];
+	      gcc_assert (ira_register_move_cost[mode][cl2][cl3]
+			  >= ira_register_move_cost[mode][cl1][cl3]);
+	      gcc_assert (ira_register_move_cost[mode][cl3][cl2]
+			  >= ira_register_move_cost[mode][cl3][cl1]);
 	    }
   ira_may_move_in_cost[mode]
     = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
@@ -1603,27 +1601,25 @@ ira_init_register_move_cost (enum machin
   memcpy (ira_max_may_move_out_cost[mode], ira_max_register_move_cost[mode],
 	  sizeof (move_table) * N_REG_CLASSES);
   for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
-    {
+    if (contains_reg_of_mode[cl1][mode])
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	{
-	  if (ira_class_hard_regs_num[cl2] == 0)
+	  if (!contains_reg_of_mode[cl2][mode]
+	      || ira_class_hard_regs_num[cl2] == 0)
 	    continue;
 	  if (ira_class_subset_p[cl1][cl2])
-	    ira_may_move_in_cost[mode][cl1][cl2] = 0;
+	    gcc_assert (ira_may_move_in_cost[mode][cl1][cl2] == 0);
 	  if (ira_class_subset_p[cl2][cl1])
-	    ira_may_move_out_cost[mode][cl1][cl2] = 0;
+	    gcc_assert (ira_may_move_out_cost[mode][cl1][cl2] == 0);
 	  if (ira_class_subset_p[cl1][cl2])
 	    ira_max_may_move_in_cost[mode][cl1][cl2] = 0;
 	  if (ira_class_subset_p[cl2][cl1])
 	    ira_max_may_move_out_cost[mode][cl1][cl2] = 0;
-	  ira_register_move_cost[mode][cl1][cl2]
-	    = ira_max_register_move_cost[mode][cl1][cl2];
-	  ira_may_move_in_cost[mode][cl1][cl2]
-	    = ira_max_may_move_in_cost[mode][cl1][cl2];
-	  ira_may_move_out_cost[mode][cl1][cl2]
-	    = ira_max_may_move_out_cost[mode][cl1][cl2];
+	  gcc_assert (ira_may_move_in_cost[mode][cl1][cl2]
+		      == ira_max_may_move_in_cost[mode][cl1][cl2]);
+	  gcc_assert (ira_may_move_out_cost[mode][cl1][cl2]
+		      == ira_max_may_move_out_cost[mode][cl1][cl2]);
 	}
-    }
 }
 
 \f

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [7/7] Tidy IRA move costs
  2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
                   ` (5 preceding siblings ...)
  2012-05-30 18:42 ` [6/7] " Richard Sandiford
@ 2012-05-30 18:44 ` Richard Sandiford
  2012-05-31  2:20   ` Vladimir Makarov
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Sandiford @ 2012-05-30 18:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

The previous patch asserted that the first and second sets are now the same,
which means that the second and (temporary) third sets are no longer needed.
This patch removes them and renames the first set to have the same names
as the second used to.

Richard


gcc/
	* ira-int.h (target_ira_int): Rename x_move_cost to
	x_ira_register_move_cost, x_may_move_in_cost to
	x_ira_may_move_in_cost and x_may_move_out_cost to
	x_ira_may_move_out_cost.  Delete the old fields with
	those names and also x_ira_max_register_move_cost,
	x_ira_max_may_move_in_cost and x_ira_max_may_move_out_cost.
	(move_cost, may_move_in_cost, may_move_out_cost)
	(ira_max_register_move_cost, ira_max_may_move_in_cost)
	(ira_max_may_move_out_cost): Delete.
	* ira.c (init_move_cost): Rename to...
	(ira_init_register_move_cost): ...this, deleting the old
	function with that name.  Apply above variable renamings.
	Retain asserts for null fields.
	(ira_init_once): Don't initialize register move costs here.
	(free_register_move_costs): Apply above variable renamings.
	Remove code for deleted fields.

Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h	2012-05-29 19:27:41.000000000 +0100
+++ gcc/ira-int.h	2012-05-29 20:25:48.514665195 +0100
@@ -771,48 +771,22 @@ struct target_ira_int {
 
   /* Maximum cost of moving from a register in one class to a register
      in another class.  Based on TARGET_REGISTER_MOVE_COST.  */
-  move_table *x_move_cost[MAX_MACHINE_MODE];
+  move_table *x_ira_register_move_cost[MAX_MACHINE_MODE];
 
   /* Similar, but here we don't have to move if the first index is a
      subset of the second so in that case the cost is zero.  */
-  move_table *x_may_move_in_cost[MAX_MACHINE_MODE];
+  move_table *x_ira_may_move_in_cost[MAX_MACHINE_MODE];
 
   /* Similar, but here we don't have to move if the first index is a
      superset of the second so in that case the cost is zero.  */
-  move_table *x_may_move_out_cost[MAX_MACHINE_MODE];
+  move_table *x_ira_may_move_out_cost[MAX_MACHINE_MODE];
 
   /* Keep track of the last mode we initialized move costs for.  */
   int x_last_mode_for_init_move_cost;
 
-  /* Array based on TARGET_REGISTER_MOVE_COST.  Don't use
-     ira_register_move_cost directly.  Use function of
-     ira_get_may_move_cost instead.  */
-  move_table *x_ira_register_move_cost[MAX_MACHINE_MODE];
-
-  /* Array analogs of the macros MEMORY_MOVE_COST and
-     REGISTER_MOVE_COST but they contain maximal cost not minimal as
-     the previous two ones do.  */
+  /* Array analog of the macro MEMORY_MOVE_COST but they contain maximal
+     cost not minimal.  */
   short int x_ira_max_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
-  move_table *x_ira_max_register_move_cost[MAX_MACHINE_MODE];
-
-  /* Similar to may_move_in_cost but it is calculated in IRA instead of
-     regclass.  Another difference we take only available hard registers
-     into account to figure out that one register class is a subset of
-     the another one.  Don't use it directly.  Use function of
-     ira_get_may_move_cost instead.  */
-  move_table *x_ira_may_move_in_cost[MAX_MACHINE_MODE];
-
-  /* Similar to may_move_out_cost but it is calculated in IRA instead of
-     regclass.  Another difference we take only available hard registers
-     into account to figure out that one register class is a subset of
-     the another one.  Don't use it directly.  Use function of
-     ira_get_may_move_cost instead.  */
-  move_table *x_ira_may_move_out_cost[MAX_MACHINE_MODE];
-
-/* Similar to ira_may_move_in_cost and ira_may_move_out_cost but they
-   return maximal cost.  */
-  move_table *x_ira_max_may_move_in_cost[MAX_MACHINE_MODE];
-  move_table *x_ira_max_may_move_out_cost[MAX_MACHINE_MODE];
 
   /* Map class->true if class is a possible allocno class, false
      otherwise. */
@@ -905,26 +879,14 @@ #define this_target_ira_int (&default_ta
 
 #define ira_reg_mode_hard_regset \
   (this_target_ira_int->x_ira_reg_mode_hard_regset)
-#define move_cost \
-  (this_target_ira_int->x_move_cost)
-#define may_move_in_cost \
-  (this_target_ira_int->x_may_move_in_cost)
-#define may_move_out_cost \
-  (this_target_ira_int->x_may_move_out_cost)
 #define ira_register_move_cost \
   (this_target_ira_int->x_ira_register_move_cost)
 #define ira_max_memory_move_cost \
   (this_target_ira_int->x_ira_max_memory_move_cost)
-#define ira_max_register_move_cost \
-  (this_target_ira_int->x_ira_max_register_move_cost)
 #define ira_may_move_in_cost \
   (this_target_ira_int->x_ira_may_move_in_cost)
 #define ira_may_move_out_cost \
   (this_target_ira_int->x_ira_may_move_out_cost)
-#define ira_max_may_move_in_cost \
-  (this_target_ira_int->x_ira_max_may_move_in_cost)
-#define ira_max_may_move_out_cost \
-  (this_target_ira_int->x_ira_max_may_move_out_cost)
 #define ira_reg_allocno_class_p \
   (this_target_ira_int->x_ira_reg_allocno_class_p)
 #define ira_reg_pressure_class_p \
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2012-05-29 20:18:55.000000000 +0100
+++ gcc/ira.c	2012-05-29 20:35:43.115647923 +0100
@@ -1451,15 +1451,18 @@ clarify_prohibited_class_mode_regs (void
 	}
 }
 \f
-/* Initialize may_move_cost and friends for mode M.  */
-
-static void
-init_move_cost (enum machine_mode mode)
+/* Allocate and initialize IRA_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST
+   and IRA_MAY_MOVE_OUT_COST for MODE.  */
+void
+ira_init_register_move_cost (enum machine_mode mode)
 {
   static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
   bool all_match = true;
   unsigned int cl1, cl2;
 
+  ira_assert (ira_register_move_cost[mode] == NULL
+	      && ira_may_move_in_cost[mode] == NULL
+	      && ira_may_move_out_cost[mode] == NULL);
   ira_assert (have_regs_of_mode[mode]);
   for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
     if (contains_reg_of_mode[cl1][mode])
@@ -1479,18 +1482,18 @@ init_move_cost (enum machine_mode mode)
 	}
   if (all_match && last_mode_for_init_move_cost != -1)
     {
-      move_cost[mode] = move_cost[last_mode_for_init_move_cost];
-      may_move_in_cost[mode] = may_move_in_cost[last_mode_for_init_move_cost];
-      may_move_out_cost[mode] = may_move_out_cost[last_mode_for_init_move_cost];
+      ira_register_move_cost[mode]
+	= ira_register_move_cost[last_mode_for_init_move_cost];
+      ira_may_move_in_cost[mode]
+	= ira_may_move_in_cost[last_mode_for_init_move_cost];
+      ira_may_move_out_cost[mode]
+	= ira_may_move_out_cost[last_mode_for_init_move_cost];
       return;
     }
   last_mode_for_init_move_cost = mode;
-  move_cost[mode] = (move_table *)xmalloc (sizeof (move_table)
-					* N_REG_CLASSES);
-  may_move_in_cost[mode] = (move_table *)xmalloc (sizeof (move_table)
-					       * N_REG_CLASSES);
-  may_move_out_cost[mode] = (move_table *)xmalloc (sizeof (move_table)
-					        * N_REG_CLASSES);
+  ira_register_move_cost[mode] = XNEWVEC (move_table, N_REG_CLASSES);
+  ira_may_move_in_cost[mode] = XNEWVEC (move_table, N_REG_CLASSES);
+  ira_may_move_out_cost[mode] = XNEWVEC (move_table, N_REG_CLASSES);
   for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
     if (contains_reg_of_mode[cl1][mode])
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
@@ -1500,9 +1503,9 @@ init_move_cost (enum machine_mode mode)
 
 	  if (last_move_cost[cl1][cl2] == 65535)
 	    {
-	      move_cost[mode][cl1][cl2] = 65535;
-	      may_move_in_cost[mode][cl1][cl2] = 65535;
-	      may_move_out_cost[mode][cl1][cl2] = 65535;
+	      ira_register_move_cost[mode][cl1][cl2] = 65535;
+	      ira_may_move_in_cost[mode][cl1][cl2] = 65535;
+	      ira_may_move_out_cost[mode][cl1][cl2] = 65535;
 	    }
 	  else
 	    {
@@ -1513,115 +1516,37 @@ init_move_cost (enum machine_mode mode)
 		if (ira_class_hard_regs_num[*p2] > 0
 		    && (ira_reg_class_max_nregs[*p2][mode]
 			<= ira_class_hard_regs_num[*p2]))
-		  cost = MAX (cost, move_cost[mode][cl1][*p2]);
+		  cost = MAX (cost, ira_register_move_cost[mode][cl1][*p2]);
 
 	      for (p1 = &reg_class_subclasses[cl1][0];
 		   *p1 != LIM_REG_CLASSES; p1++)
 		if (ira_class_hard_regs_num[*p1] > 0
 		    && (ira_reg_class_max_nregs[*p1][mode]
 			<= ira_class_hard_regs_num[*p1]))
-		  cost = MAX (cost, move_cost[mode][*p1][cl2]);
+		  cost = MAX (cost, ira_register_move_cost[mode][*p1][cl2]);
 
 	      ira_assert (cost <= 65535);
-	      move_cost[mode][cl1][cl2] = cost;
+	      ira_register_move_cost[mode][cl1][cl2] = cost;
 
 	      if (ira_class_subset_p[cl1][cl2])
-		may_move_in_cost[mode][cl1][cl2] = 0;
+		ira_may_move_in_cost[mode][cl1][cl2] = 0;
 	      else
-		may_move_in_cost[mode][cl1][cl2] = cost;
+		ira_may_move_in_cost[mode][cl1][cl2] = cost;
 
 	      if (ira_class_subset_p[cl2][cl1])
-		may_move_out_cost[mode][cl1][cl2] = 0;
+		ira_may_move_out_cost[mode][cl1][cl2] = 0;
 	      else
-		may_move_out_cost[mode][cl1][cl2] = cost;
+		ira_may_move_out_cost[mode][cl1][cl2] = cost;
 	    }
 	}
     else
       for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
 	{
-	  move_cost[mode][cl1][cl2] = 65535;
-	  may_move_in_cost[mode][cl1][cl2] = 65535;
-	  may_move_out_cost[mode][cl1][cl2] = 65535;
+	  ira_register_move_cost[mode][cl1][cl2] = 65535;
+	  ira_may_move_in_cost[mode][cl1][cl2] = 65535;
+	  ira_may_move_out_cost[mode][cl1][cl2] = 65535;
 	}
 }
-
-/* Allocate and initialize IRA_REGISTER_MOVE_COST,
-   IRA_MAX_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST,
-   IRA_MAY_MOVE_OUT_COST, IRA_MAX_MAY_MOVE_IN_COST, and
-   IRA_MAX_MAY_MOVE_OUT_COST for MODE if it is not done yet.  */
-void
-ira_init_register_move_cost (enum machine_mode mode)
-{
-  int cl1, cl2, cl3;
-
-  ira_assert (ira_register_move_cost[mode] == NULL
-	      && ira_max_register_move_cost[mode] == NULL
-	      && ira_may_move_in_cost[mode] == NULL
-	      && ira_may_move_out_cost[mode] == NULL
-	      && ira_max_may_move_in_cost[mode] == NULL
-	      && ira_max_may_move_out_cost[mode] == NULL);
-  if (move_cost[mode] == NULL)
-    init_move_cost (mode);
-  ira_register_move_cost[mode] = move_cost[mode];
-  /* Don't use ira_allocate because the tables exist out of scope of a
-     IRA call.  */
-  ira_max_register_move_cost[mode]
-    = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
-  memcpy (ira_max_register_move_cost[mode], ira_register_move_cost[mode],
-	  sizeof (move_table) * N_REG_CLASSES);
-  for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
-    /* Some subclasses are to small to have enough registers to hold
-       a value of MODE.  Just ignore them.  */
-    if (ira_class_hard_regs_num[cl1] > 0
-	&& ira_reg_class_max_nregs[cl1][mode] <= ira_class_hard_regs_num[cl1])
-      for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
-	if (hard_reg_set_subset_p (reg_class_contents[cl1],
-				   reg_class_contents[cl2]))
-	  for (cl3 = 0; cl3 < N_REG_CLASSES; cl3++)
-	    {
-	      gcc_assert (ira_register_move_cost[mode][cl2][cl3]
-			  >= ira_register_move_cost[mode][cl1][cl3]);
-	      gcc_assert (ira_register_move_cost[mode][cl3][cl2]
-			  >= ira_register_move_cost[mode][cl3][cl1]);
-	    }
-  ira_may_move_in_cost[mode]
-    = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
-  memcpy (ira_may_move_in_cost[mode], may_move_in_cost[mode],
-	  sizeof (move_table) * N_REG_CLASSES);
-  ira_may_move_out_cost[mode]
-    = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
-  memcpy (ira_may_move_out_cost[mode], may_move_out_cost[mode],
-	  sizeof (move_table) * N_REG_CLASSES);
-  ira_max_may_move_in_cost[mode]
-    = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
-  memcpy (ira_max_may_move_in_cost[mode], ira_max_register_move_cost[mode],
-	  sizeof (move_table) * N_REG_CLASSES);
-  ira_max_may_move_out_cost[mode]
-    = (move_table *) xmalloc (sizeof (move_table) * N_REG_CLASSES);
-  memcpy (ira_max_may_move_out_cost[mode], ira_max_register_move_cost[mode],
-	  sizeof (move_table) * N_REG_CLASSES);
-  for (cl1 = 0; cl1 < N_REG_CLASSES; cl1++)
-    if (contains_reg_of_mode[cl1][mode])
-      for (cl2 = 0; cl2 < N_REG_CLASSES; cl2++)
-	{
-	  if (!contains_reg_of_mode[cl2][mode]
-	      || ira_class_hard_regs_num[cl2] == 0)
-	    continue;
-	  if (ira_class_subset_p[cl1][cl2])
-	    gcc_assert (ira_may_move_in_cost[mode][cl1][cl2] == 0);
-	  if (ira_class_subset_p[cl2][cl1])
-	    gcc_assert (ira_may_move_out_cost[mode][cl1][cl2] == 0);
-	  if (ira_class_subset_p[cl1][cl2])
-	    ira_max_may_move_in_cost[mode][cl1][cl2] = 0;
-	  if (ira_class_subset_p[cl2][cl1])
-	    ira_max_may_move_out_cost[mode][cl1][cl2] = 0;
-	  gcc_assert (ira_may_move_in_cost[mode][cl1][cl2]
-		      == ira_max_may_move_in_cost[mode][cl1][cl2]);
-	  gcc_assert (ira_may_move_out_cost[mode][cl1][cl2]
-		      == ira_max_may_move_out_cost[mode][cl1][cl2]);
-	}
-}
-
 \f
 
 /* This is called once during compiler work.  It sets up
@@ -1630,23 +1555,11 @@ ira_init_register_move_cost (enum machin
 void
 ira_init_once (void)
 {
-  int mode;
-
-  for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
-    {
-      ira_register_move_cost[mode] = NULL;
-      ira_max_register_move_cost[mode] = NULL;
-      ira_may_move_in_cost[mode] = NULL;
-      ira_may_move_out_cost[mode] = NULL;
-      ira_max_may_move_in_cost[mode] = NULL;
-      ira_max_may_move_out_cost[mode] = NULL;
-    }
   ira_init_costs_once ();
 }
 
-/* Free ira_max_register_move_cost, ira_may_move_in_cost,
-   ira_may_move_out_cost, ira_max_may_move_in_cost, and
-   ira_max_may_move_out_cost for each mode.  */
+/* Free ira_max_register_move_cost, ira_may_move_in_cost and
+   ira_may_move_out_cost for each mode.  */
 static void
 free_register_move_costs (void)
 {
@@ -1655,35 +1568,24 @@ free_register_move_costs (void)
   /* Reset move_cost and friends, making sure we only free shared
      table entries once.  */
   for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
-    if (move_cost[mode])
+    if (ira_register_move_cost[mode])
       {
-	for (i = 0; i < mode && move_cost[i] != move_cost[mode]; i++)
+	for (i = 0;
+	     i < mode && (ira_register_move_cost[i]
+			  != ira_register_move_cost[mode]);
+	     i++)
 	  ;
 	if (i == mode)
 	  {
-	    free (move_cost[mode]);
-	    free (may_move_in_cost[mode]);
-	    free (may_move_out_cost[mode]);
+	    free (ira_register_move_cost[mode]);
+	    free (ira_may_move_in_cost[mode]);
+	    free (ira_may_move_out_cost[mode]);
 	  }
       }
-  memset (move_cost, 0, sizeof move_cost);
-  memset (may_move_in_cost, 0, sizeof may_move_in_cost);
-  memset (may_move_out_cost, 0, sizeof may_move_out_cost);
+  memset (ira_register_move_cost, 0, sizeof ira_register_move_cost);
+  memset (ira_may_move_in_cost, 0, sizeof ira_may_move_in_cost);
+  memset (ira_may_move_out_cost, 0, sizeof ira_may_move_out_cost);
   last_mode_for_init_move_cost = -1;
-  for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
-    {
-      free (ira_max_register_move_cost[mode]);
-      free (ira_may_move_in_cost[mode]);
-      free (ira_may_move_out_cost[mode]);
-      free (ira_max_may_move_in_cost[mode]);
-      free (ira_max_may_move_out_cost[mode]);
-      ira_register_move_cost[mode] = NULL;
-      ira_max_register_move_cost[mode] = NULL;
-      ira_may_move_in_cost[mode] = NULL;
-      ira_may_move_out_cost[mode] = NULL;
-      ira_max_may_move_in_cost[mode] = NULL;
-      ira_max_may_move_out_cost[mode] = NULL;
-    }
 }
 
 /* This is called every time when register related information is

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [2/7] Tidy IRA move costs
  2012-05-30 18:22 ` [2/7] " Richard Sandiford
@ 2012-05-31  2:04   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:04 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:21 PM, Richard Sandiford wrote:
> The only part of IRA that uses move_costs directly is copy_cost.
> It looks like this might be an oversight, since all related costs
> already use ira_register_move_cost.
move_cost was from code which was part or regclass before.
> As mentioned in the covering message, the two arrays are usually
> the same anyway.  The only hitch is that we have:
>
>        if (!move_cost[mode])
>          init_move_cost (mode);
>
> so if the move costs for this mode really haven't been calculated yet,
> we could potentially end up with different costs then if we used the
> normal ira_init_register_move_cost_if_necessary route.  In the former
> case we'd use the original move_cost (before the IRA modifications),
> while in the latter we'd use the value assigned by
> ira_init_register_move_cost via the ira_register_move_cost alias.
>
Ok.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [1/7] Tidy IRA move costs
  2012-05-30 18:16 ` [1/7] " Richard Sandiford
@ 2012-05-31  2:04   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:04 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:15 PM, Richard Sandiford wrote:
> For one of the later patches I wanted to test whether a class had any
> allocatable registers.  It turns out that we have two arrays that hold
> the number of allocatable registers in a class:
>
>      ira_class_hard_regs_num
>      ira_available_class_regs
When IRA was being developed, ira_available_class was added first.  It 
was enough for that time.  In some time I needed 
ira_class_hard_regs_num.  I should have removed ira_available_class_regs.
> We calculate them in quick succession and already assert that they're
> the same:
>
>        COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
>        AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
>        ...
>        for (n = 0, i = 0; i<  FIRST_PSEUDO_REGISTER; i++)
> 	if (TEST_HARD_REG_BIT (temp_hard_regset, i))
> 	  ira_non_ordered_class_hard_regs[cl][n++] = i;
>        ira_assert (ira_class_hard_regs_num[cl] == n);
>
>        ...
>
>        COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]);
>        AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
>        for (j = 0; j<  FIRST_PSEUDO_REGISTER; j++)
> 	if (TEST_HARD_REG_BIT (temp_hard_regset, j))
> 	  ira_available_class_regs[i]++;
>
> so this patch removes the latter in favour of the former.
>
Ok.  Thanks, Richard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [3/7] Tidy IRA move costs
  2012-05-30 18:25 ` [3/7] " Richard Sandiford
@ 2012-05-31  2:04   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:04 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:24 PM, Richard Sandiford wrote:
> After the preceding patch, only ira_init_register_move_cost uses
> the regclass costs directly.  This patch moves them to IRA and makes
> init_move_cost static to it.
>
> This is just a stepping stone to make the later patches easier to review.
>
> Richard
>
>
> gcc/
> 	* regs.h (move_table, move_cost, may_move_in_cost, may_move_out_cost):
> 	Move these definitions and associated target_globals fields to...
> 	* ira-int.h: ...here.
> 	* rtl.h (init_move_cost): Delete.
> 	* reginfo.c (last_mode_for_init_move_cost, init_move_cost): Move to...
> 	* ira.c: ...here, making the latter static.
>
>
Ok.  Thanks for code improving, Richard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [4/7] Tidy IRA move costs
  2012-05-30 18:26 ` [4/7] " Richard Sandiford
@ 2012-05-31  2:05   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:05 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:26 PM, Richard Sandiford wrote:
> This patch adjusts init_move_cost to follow local conventions.
> The new names are IMO more readable anyway (it's easier to see
> that p1 is related to cl1 than i, etc.).
>
> Richard
>
>
> gcc/
> 	* ira.c (init_move_cost): Adjust local variable names to match
> 	file conventions.  Use ira_assert instead of gcc_assert.
>
>
Ok.  Thanks.  The code looks better.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [5/7] Tidy IRA move costs
  2012-05-30 18:28 ` [5/7] " Richard Sandiford
@ 2012-05-31  2:06   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:06 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:28 PM, Richard Sandiford wrote:
> I needed to move an instance of:
>
>        COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
>        AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
>        if (hard_reg_set_empty_p (temp_hard_regset))
> 	continue;
>
> But this can more easily be calculated as:
>
>        ira_class_hard_regs_num[cl] == 0
>
> so this patch uses that instead.
>
> Richard
>
>
> gcc/
> 	* ira.c (setup_allocno_and_important_classes): Use
> 	ira_class_hard_regs_num to check whether a class has any
> 	allocatable registers.
> 	(ira_init_register_move_cost): Likewise.
>
>
Ok.  The code looks more clear and compact.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [7/7] Tidy IRA move costs
  2012-05-30 18:44 ` [7/7] " Richard Sandiford
@ 2012-05-31  2:20   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:20 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:44 PM, Richard Sandiford wrote:
> The previous patch asserted that the first and second sets are now the same,
> which means that the second and (temporary) third sets are no longer needed.
> This patch removes them and renames the first set to have the same names
> as the second used to.
>
> Richard
>
>
> gcc/
> 	* ira-int.h (target_ira_int): Rename x_move_cost to
> 	x_ira_register_move_cost, x_may_move_in_cost to
> 	x_ira_may_move_in_cost and x_may_move_out_cost to
> 	x_ira_may_move_out_cost.  Delete the old fields with
> 	those names and also x_ira_max_register_move_cost,
> 	x_ira_max_may_move_in_cost and x_ira_max_may_move_out_cost.
> 	(move_cost, may_move_in_cost, may_move_out_cost)
> 	(ira_max_register_move_cost, ira_max_may_move_in_cost)
> 	(ira_max_may_move_out_cost): Delete.
> 	* ira.c (init_move_cost): Rename to...
> 	(ira_init_register_move_cost): ...this, deleting the old
> 	function with that name.  Apply above variable renamings.
> 	Retain asserts for null fields.
> 	(ira_init_once): Don't initialize register move costs here.
> 	(free_register_move_costs): Apply above variable renamings.
> 	Remove code for deleted fields.
>
>
Ok. Richard, thanks for the patches which makes IRA code much more clear.

The divisions on the patches makes them easy to understand.  The 
explanation what the patches are doing were excelent too.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [6/7] Tidy IRA move costs
  2012-05-30 18:42 ` [6/7] " Richard Sandiford
@ 2012-05-31  2:20   ` Vladimir Makarov
  0 siblings, 0 replies; 15+ messages in thread
From: Vladimir Makarov @ 2012-05-31  2:20 UTC (permalink / raw)
  To: gcc-patches, rdsandiford

On 05/30/2012 02:41 PM, Richard Sandiford wrote:
> This patch makes the original move_cost calculation match the value
> currently calculated for ira_register_move_cost, asserting that the
> "IRA code" now has nothing to do.
>
> It seems like we really ought to be preserving the contains_reg_of_mode
> part of the original move_cost check, i.e.:
>
> 		if (contains_reg_of_mode[*p2][mode])
> 		&&  ira_class_hard_regs_num[*p2]>  0
> 		&&  (ira_reg_class_max_nregs[*p2][mode]
> 			<= ira_class_hard_regs_num[*p2]))
>
> etc.  But that changes the cc1 .ii output for x86_64, so the current
> costs really do include the costs for subclasses that don't contain
> registers of a particular mode.  I think adding the check "back"
> should be a separate patch (by someone who can test the performance!).
>
> A strict conversion for may_move_in_cost and may_move_out_cost would
> be to convert the two instances of:
>
> 	      may_move_in_cost[mode][cl1][cl2] = 65535;
> 	      may_move_out_cost[mode][cl1][cl2] = 65535;
>
> to:
>
> 	      if (ira_class_hard_regs_num[cl2]>  0
> 		&&  ira_class_subset_p[cl1][cl2])
> 		may_move_in_cost[mode][cl1][cl2] = 0;
> 	      else
> 		may_move_in_cost[mode][cl1][cl2] = 65535;
>
> 	      if (ira_class_hard_regs_num[cl2]>  0
> 		&&  ira_class_subset_p[cl2][cl1])
> 		may_move_in_cost[mode][cl1][cl2] = 0;
> 	      else
> 		may_move_out_cost[mode][cl1][cl2] = 65535;
>
> because here too the current IRA costs don't take
> contains_reg_of_mode into account.  But that change wouldn't
> really make sense, because cl2 represents different things
> for the "in" and "out" cost (the operand class and the allocation
> class respectively).  The cc1 .ii output is the same either way,
> so for this one I've just added the contains_reg_of_mode tests
> to the IRA version.
>
> It might seem odd to commit these asserts and then remove them
> in the next patch.  But I'd like to commit them anyway so that,
> if this series does mess things up, the asserts can help show why.
>
> Richard
>
>
> gcc/
> 	* ira.c (init_move_cost): Adjust choice of subclasses to match
> 	the current ira_init_register_move_cost choice.  Use
> 	ira_class_subset_p instead of reg_class_subset_p.
> 	(ira_init_register_move_cost): Assert that move_cost,
> 	may_move_in_cost and may_move_out_cost already hold the desired
> 	values for their ira_* equivalents.  For the latter two,
> 	ignore classes that can't store a register of the given mode.
>
>
Ok. Thanks.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2012-05-31  2:20 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-30 18:12 [0/7] Tidy IRA move costs Richard Sandiford
2012-05-30 18:16 ` [1/7] " Richard Sandiford
2012-05-31  2:04   ` Vladimir Makarov
2012-05-30 18:22 ` [2/7] " Richard Sandiford
2012-05-31  2:04   ` Vladimir Makarov
2012-05-30 18:25 ` [3/7] " Richard Sandiford
2012-05-31  2:04   ` Vladimir Makarov
2012-05-30 18:26 ` [4/7] " Richard Sandiford
2012-05-31  2:05   ` Vladimir Makarov
2012-05-30 18:28 ` [5/7] " Richard Sandiford
2012-05-31  2:06   ` Vladimir Makarov
2012-05-30 18:42 ` [6/7] " Richard Sandiford
2012-05-31  2:20   ` Vladimir Makarov
2012-05-30 18:44 ` [7/7] " Richard Sandiford
2012-05-31  2:20   ` Vladimir Makarov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).