This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: better register prefs with CLASS_CANNOT_CHANGE_SIZE


> Date: Sat, 27 May 2000 09:39:55 -0700
> From: Richard Henderson <rth@cygnus.com>
> Cc: gcc-patches@gcc.gnu.org
> 
> On Fri, May 26, 2000 at 06:45:59PM -0700, Geoff Keating wrote:
> > +static int class_can_change_size_subclass[N_REG_CLASSES];
> 
> This probably isn't the most obvious data we could be collecting.
> 
> > +		      && class != class_can_change_size_subclass [class])
> 
> A predicate that did this would be easier to understand.

How about this?

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/rs6000-64bugs2-changesize-3.patch===
2000-05-27  Geoff Keating  <geoffk@cygnus.com>

	* regclass.c [CLASS_CANNOT_CHANGE_SIZE]
	(class_can_change_size): New variable.
	(reg_changes_size): New variable.
	(init_reg_sets_1): Initialise class_can_change_size.
	(record_operand_costs): Remove subreg_changes_size.
	Don't pass it around.  Instead update reg_changes_size.
	(regclass): Initialise and free reg_changes_size.  If a register
	changes size, don't preference it to a class that contains
	registers that can't change size.
	(record_reg_classes): Don't look at subreg_changes_size.

Index: regclass.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/regclass.c,v
retrieving revision 1.97
diff -u -p -r1.97 regclass.c
--- regclass.c	2000/05/20 19:45:33	1.97
+++ regclass.c	2000/05/28 01:49:57
@@ -203,6 +203,19 @@ static char *in_inc_dec;
 
 #endif /* FORBIDDEN_INC_DEC_CLASSES */
 
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+
+/* These are the classes containing only registers that can be used in
+   a SUBREG expression that changes the size of the register.  */
+
+static int class_can_change_size[N_REG_CLASSES];
+
+/* Registers, including pseudos, which change size.  */
+
+static regset reg_changes_size;
+
+#endif /* CLASS_CANNOT_CHANGE_SIZE */
+
 #ifdef HAVE_SECONDARY_RELOADS
 
 /* Sample MEM values for use by memory_move_secondary_cost.  */
@@ -444,6 +457,22 @@ init_reg_sets_1 ()
 	else
 	  may_move_out_cost[i][j] = cost;
       }
+
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+  {
+    HARD_REG_SET c;
+    COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_SIZE]);
+      
+    for (i = 0; i < N_REG_CLASSES; i++)
+      {
+	GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class);
+	class_can_change_size [i] = 0;
+	continue;
+      ok_class:
+	class_can_change_size [i] = 1;
+      }
+    }
+#endif /* CLASS_CANNOT_CHANGE_SIZE */
 }
 
 /* Compute the table of register modes.
@@ -725,7 +754,7 @@ static rtx scan_one_insn	PARAMS ((rtx, i
 static void record_operand_costs PARAMS ((rtx, struct costs *, struct reg_pref *));
 static void dump_regclass	PARAMS ((FILE *));
 static void record_reg_classes	PARAMS ((int, int, rtx *, enum machine_mode *,
-				       char *, const char **, rtx,
+				       const char **, rtx,
 				       struct costs *, struct reg_pref *));
 static int copy_cost		PARAMS ((rtx, enum machine_mode, 
 				       enum reg_class, int));
@@ -809,7 +838,6 @@ record_operand_costs (insn, op_costs, re
 {
   const char *constraints[MAX_RECOG_OPERANDS];
   enum machine_mode modes[MAX_RECOG_OPERANDS];
-  char subreg_changes_size[MAX_RECOG_OPERANDS];
   int i;
 
   for (i = 0; i < recog_data.n_operands; i++)
@@ -817,7 +845,6 @@ record_operand_costs (insn, op_costs, re
       constraints[i] = recog_data.constraints[i];
       modes[i] = recog_data.operand_mode[i];
     }
-  memset (subreg_changes_size, 0, sizeof (subreg_changes_size));
 
   /* If we get here, we are set up to record the costs of all the
      operands for this insn.  Start by initializing the costs.
@@ -832,8 +859,9 @@ record_operand_costs (insn, op_costs, re
       if (GET_CODE (recog_data.operand[i]) == SUBREG)
 	{
 	  rtx inner = SUBREG_REG (recog_data.operand[i]);
-	  if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner)))
-	    subreg_changes_size[i] = 1;
+	  if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner))
+	      && GET_CODE (inner) == REG)
+	    SET_REGNO_REG_SET (reg_changes_size, REGNO (inner));
 	  recog_data.operand[i] = inner;
 	}
 
@@ -864,12 +892,12 @@ record_operand_costs (insn, op_costs, re
 	xconstraints[i] = constraints[i+1];
 	xconstraints[i+1] = constraints[i];
 	record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
-			    recog_data.operand, modes, subreg_changes_size,
+			    recog_data.operand, modes, 
 			    xconstraints, insn, op_costs, reg_pref);
       }
 
   record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
-		      recog_data.operand, modes, subreg_changes_size,
+		      recog_data.operand, modes, 
 		      constraints, insn, op_costs, reg_pref);
 }
 
@@ -1017,6 +1045,10 @@ regclass (f, nregs, dump)
 
   costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
 
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+  reg_changes_size = BITMAP_XMALLOC();
+#endif  
+
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 
   in_inc_dec = (char *) xmalloc (nregs);
@@ -1155,6 +1187,10 @@ regclass (f, nregs, dump)
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 		  || (in_inc_dec[i] && forbidden_inc_dec_class[class])
 #endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+		  || (REGNO_REG_SET_P (reg_changes_size, i)
+		      && ! class_can_change_size [class])
+#endif
 		  )
 		;
 	      else if (p->cost[class] < best_cost)
@@ -1181,6 +1217,10 @@ regclass (f, nregs, dump)
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 		  && ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
 #endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+		  && ! (REGNO_REG_SET_P (reg_changes_size, i)
+			&& ! class_can_change_size [class])
+#endif
 		  )
 		alt = reg_class_subunion[(int) alt][class];
 	  
@@ -1213,6 +1253,9 @@ regclass (f, nregs, dump)
 #ifdef FORBIDDEN_INC_DEC_CLASSES
   free (in_inc_dec);
 #endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+  BITMAP_XFREE (reg_changes_size);
+#endif
   free (costs);
 }
 
@@ -1241,13 +1284,12 @@ regclass (f, nregs, dump)
    alternatives.  */
 
 static void
-record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
+record_reg_classes (n_alts, n_ops, ops, modes,
 		    constraints, insn, op_costs, reg_pref)
      int n_alts;
      int n_ops;
      rtx *ops;
      enum machine_mode *modes;
-     char *subreg_changes_size ATTRIBUTE_UNUSED;
      const char **constraints;
      rtx insn;
      struct costs *op_costs;
@@ -1545,16 +1587,6 @@ record_reg_classes (n_alts, n_ops, ops, 
 
 	  constraints[i] = p;
 
-#ifdef CLASS_CANNOT_CHANGE_SIZE
-	  /* If we noted a subreg earlier, and the selected class is a 
-	     subclass of CLASS_CANNOT_CHANGE_SIZE, zap it.  */
-	  if (subreg_changes_size[i]
-	      && (reg_class_subunion[(int) CLASS_CANNOT_CHANGE_SIZE]
-				    [(int) classes[i]]
-		  == CLASS_CANNOT_CHANGE_SIZE))
-	    classes[i] = NO_REGS;
-#endif
-
 	  /* How we account for this operand now depends on whether it is  a
 	     pseudo register or not.  If it is, we first check if any
 	     register classes are valid.  If not, we ignore this alternative,
@@ -1566,13 +1598,13 @@ record_reg_classes (n_alts, n_ops, ops, 
 	    {
 	      if (classes[i] == NO_REGS)
 		{
-		    /* We must always fail if the operand is a REG, but
-		       we did not find a suitable class.
-
-		       Otherwise we may perform an uninitialized read
-		       from this_op_costs after the `continue' statement
-		       below.  */
-		    alt_fail = 1;
+		  /* We must always fail if the operand is a REG, but
+		     we did not find a suitable class.
+		     
+		     Otherwise we may perform an uninitialized read
+		     from this_op_costs after the `continue' statement
+		     below.  */
+		  alt_fail = 1;
 		}
 	      else
 		{
============================================================

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]