OSDN Git Service

* regclass.c (op_costs): Remove global variable.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Jan 2000 15:23:56 +0000 (15:23 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Jan 2000 15:23:56 +0000 (15:23 +0000)
(record_reg_classes): New parameter "op_costs" and "reg_pref".
(record_operand_costs): Break out from ...
(scan_one_insn): ... here.
(dump_regclass): Make dumps nicer.
(regclass): Dump preferrences choosed and changes done during passes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31179 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/regclass.c

index e2b4086..3bdb03a 100644 (file)
@@ -1,3 +1,12 @@
+Mon Jan  3 15:33:37 MET 2000  Jan Hubicka  <hubicka@freesoft.cz>
+
+       * regclass.c (op_costs): Remove global variable.
+       (record_reg_classes): New parameter "op_costs" and "reg_pref".
+       (record_operand_costs): Break out from ...
+       (scan_one_insn): ... here.
+       (dump_regclass): Make dumps nicer.
+       (regclass): Dump preferrences choosed and changes done during passes.
+
 2000-01-03  Jakub Jelinek  <jakub@redhat.com>
 
        * config/sparc/sparc.c (gen_df_reg): Fix for 32bit SPARC.
index 4344c58..1da14a4 100644 (file)
@@ -1,5 +1,5 @@
 /* Compute register class preferences for pseudo-registers.
-   Copyright (C) 1987, 88, 91-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 91-98, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -703,12 +703,6 @@ static struct costs *costs;
 
 static struct costs init_cost;
 
-/* Record the same data by operand number, accumulated for each alternative
-   in an insn.  The contribution to a pseudo is that of the minimum-cost
-   alternative.  */
-
-static struct costs op_costs[MAX_RECOG_OPERANDS];
-
 /* Record preferrences of each pseudo.
    This is available after `regclass' is run.  */
 
@@ -724,9 +718,11 @@ static struct reg_pref *reg_pref_buffer;
 static int loop_cost;
 
 static rtx scan_one_insn       PROTO((rtx, int));
+static void record_operand_costs PROTO((rtx, struct costs *, struct reg_pref *));
 static void dump_regclass      PROTO((FILE *));
 static void record_reg_classes PROTO((int, int, rtx *, enum machine_mode *,
-                                      char *, const char **, rtx));
+                                      char *, const char **, rtx,
+                                      struct costs *, struct reg_pref *));
 static int copy_cost           PROTO((rtx, enum machine_mode, 
                                       enum reg_class, int));
 static void record_address_regs        PROTO((rtx, enum reg_class, int));
@@ -789,15 +785,89 @@ dump_regclass (dump)
       enum reg_class class;
       if (REG_N_REFS (i))
        {
-         fprintf (dump, ";; Register %i costs:", i);
+         fprintf (dump, "  Register %i costs:", i);
          for (class = 0; class < N_REG_CLASSES; class++)
            fprintf (dump, " %s:%i", reg_class_names[(int) class],
                     costs[i].cost[class]);
-         fprintf (dump, " MEM:%i\n\n", costs[i].mem_cost);
+         fprintf (dump, " MEM:%i\n", costs[i].mem_cost);
        }
     }
 }
+\f
+
+/* Calculate the costs of insn operands.  */
+
+static void
+record_operand_costs (insn, op_costs, reg_pref)
+     rtx insn;
+     struct costs *op_costs;
+     struct reg_pref *reg_pref;
+{
+  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++)
+    {
+      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.
+     Then handle any address registers.  Finally record the desired
+     classes for any pseudos, doing it twice if some pair of
+     operands are commutative.  */
+            
+  for (i = 0; i < recog_data.n_operands; i++)
+    {
+      op_costs[i] = init_cost;
+
+      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;
+         recog_data.operand[i] = inner;
+       }
+
+      if (GET_CODE (recog_data.operand[i]) == MEM)
+       record_address_regs (XEXP (recog_data.operand[i], 0),
+                            BASE_REG_CLASS, loop_cost * 2);
+      else if (constraints[i][0] == 'p')
+       record_address_regs (recog_data.operand[i],
+                            BASE_REG_CLASS, loop_cost * 2);
+    }
+
+  /* Check for commutative in a separate loop so everything will
+     have been initialized.  We must do this even if one operand
+     is a constant--see addsi3 in m68k.md.  */
+
+  for (i = 0; i < (int) recog_data.n_operands - 1; i++)
+    if (constraints[i][0] == '%')
+      {
+       const char *xconstraints[MAX_RECOG_OPERANDS];
+       int j;
+
+       /* Handle commutative operands by swapping the constraints.
+          We assume the modes are the same.  */
+
+       for (j = 0; j < recog_data.n_operands; j++)
+         xconstraints[j] = constraints[j];
+
+       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,
+                           xconstraints, insn, op_costs, reg_pref);
+      }
+
+  record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
+                     recog_data.operand, modes, subreg_changes_size,
+                     constraints, insn, op_costs, reg_pref);
+}
 \f
 /* Subroutine of regclass, processes one insn INSN.  Scan it and record each
    time it would save code to put a certain register in a certain class.
@@ -813,11 +883,9 @@ scan_one_insn (insn, pass)
 {
   enum rtx_code code = GET_CODE (insn);
   enum rtx_code pat_code;
-  const char *constraints[MAX_RECOG_OPERANDS];
-  enum machine_mode modes[MAX_RECOG_OPERANDS];
-  char subreg_changes_size[MAX_RECOG_OPERANDS];
   rtx set, note;
   int i, j;
+  struct costs op_costs[MAX_RECOG_OPERANDS];
 
   if (GET_RTX_CLASS (code) != 'i')
     return insn;
@@ -833,13 +901,6 @@ scan_one_insn (insn, pass)
   set = single_set (insn);
   extract_insn (insn);
 
-  for (i = 0; i < recog_data.n_operands; i++)
-    {
-      constraints[i] = recog_data.constraints[i];
-      modes[i] = recog_data.operand_mode[i];
-    }
-  memset (subreg_changes_size, 0, sizeof (subreg_changes_size));
-
   /* If this insn loads a parameter from its stack slot, then
      it represents a savings, rather than a cost, if the
      parameter is stored in memory.  Record this fact.  */
@@ -913,58 +974,7 @@ scan_one_insn (insn, pass)
       return PREV_INSN (newinsn);
     }
 
-  /* If we get here, we are set up to record the costs of all the
-     operands for this insn.  Start by initializing the costs.
-     Then handle any address registers.  Finally record the desired
-     classes for any pseudos, doing it twice if some pair of
-     operands are commutative.  */
-            
-  for (i = 0; i < recog_data.n_operands; i++)
-    {
-      op_costs[i] = init_cost;
-
-      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;
-         recog_data.operand[i] = inner;
-       }
-
-      if (GET_CODE (recog_data.operand[i]) == MEM)
-       record_address_regs (XEXP (recog_data.operand[i], 0),
-                            BASE_REG_CLASS, loop_cost * 2);
-      else if (constraints[i][0] == 'p')
-       record_address_regs (recog_data.operand[i],
-                            BASE_REG_CLASS, loop_cost * 2);
-    }
-
-  /* Check for commutative in a separate loop so everything will
-     have been initialized.  We must do this even if one operand
-     is a constant--see addsi3 in m68k.md.  */
-
-  for (i = 0; i < (int) recog_data.n_operands - 1; i++)
-    if (constraints[i][0] == '%')
-      {
-       const char *xconstraints[MAX_RECOG_OPERANDS];
-       int j;
-
-       /* Handle commutative operands by swapping the constraints.
-          We assume the modes are the same.  */
-
-       for (j = 0; j < recog_data.n_operands; j++)
-         xconstraints[j] = constraints[j];
-
-       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,
-                           xconstraints, insn);
-      }
-
-  record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
-                     recog_data.operand, modes, subreg_changes_size,
-                     constraints, insn);
+  record_operand_costs(insn, op_costs, reg_pref);
 
   /* Now add the cost for each operand to the total costs for
      its register.  */
@@ -1064,6 +1074,9 @@ regclass (f, nregs, dump)
   for (pass = 0; pass <= flag_expensive_optimizations; pass++)
     {
       int index;
+
+      if (dump)
+        fprintf (dump, "\n\nPass %i\n\n",pass);
       /* Zero out our accumulation of the cost of each class for each reg.  */
 
       bzero ((char *) costs, nregs * sizeof (struct costs));
@@ -1110,6 +1123,11 @@ regclass (f, nregs, dump)
       if (pass == 0)
        reg_pref = reg_pref_buffer;
 
+      if (dump)
+        {
+         dump_regclass (dump);
+         fprintf(dump,"\n");
+       }
       for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
        {
          register int best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
@@ -1119,6 +1137,9 @@ regclass (f, nregs, dump)
          register int class;
          register struct costs *p = &costs[i];
 
+         if (!REG_N_REFS (i))
+           continue;
+
          for (class = (int) ALL_REGS - 1; class > 0; class--)
            {
              /* Ignore classes that are too small for this operand or
@@ -1146,7 +1167,7 @@ regclass (f, nregs, dump)
             should be provided as a register class.  Don't do this if we
             will be doing it again later.  */
 
-         if (pass == 1 || ! flag_expensive_optimizations)
+         if ((pass == 1  || dump) || ! flag_expensive_optimizations)
            for (class = 0; class < N_REG_CLASSES; class++)
              if (p->cost[class] < p->mem_cost
                  && (reg_class_size[(int) reg_class_subunion[(int) alt][class]]
@@ -1161,14 +1182,28 @@ regclass (f, nregs, dump)
          if (alt == best)
            alt = NO_REGS;
 
+         if (dump 
+             && (reg_pref[i].prefclass != (int) best
+                 || reg_pref[i].altclass != (int) alt))
+           {
+             static const char *const reg_class_names[] = REG_CLASS_NAMES;
+             fprintf(dump, "  Register %i", i);
+             if (alt == ALL_REGS || best == ALL_REGS)
+               fprintf (dump, " pref %s\n", reg_class_names[(int) best]);
+             else if (alt == NO_REGS)
+               fprintf (dump, " pref %s or none\n", reg_class_names[(int) best]);
+             else
+               fprintf (dump, " pref %s, else %s\n",
+                        reg_class_names[(int) best],
+                        reg_class_names[(int) alt]);
+           }
+
          /* We cast to (int) because (char) hits bugs in some compilers.  */
          reg_pref[i].prefclass = (int) best;
          reg_pref[i].altclass = (int) alt;
        }
     }
 
-  if (dump)
-    dump_regclass (dump);
 #ifdef FORBIDDEN_INC_DEC_CLASSES
   free (in_inc_dec);
 #endif
@@ -1201,7 +1236,7 @@ regclass (f, nregs, dump)
 
 static void
 record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
-                   constraints, insn)
+                   constraints, insn, op_costs, reg_pref)
      int n_alts;
      int n_ops;
      rtx *ops;
@@ -1209,6 +1244,8 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
      char *subreg_changes_size ATTRIBUTE_UNUSED;
      const char **constraints;
      rtx insn;
+     struct costs *op_costs;
+     struct reg_pref *reg_pref;
 {
   int alt;
   int i, j;