gensupport.h (pattern_stats): New structure.
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 1 Apr 2011 08:15:08 +0000 (08:15 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 1 Apr 2011 08:15:08 +0000 (08:15 +0000)
gcc/
* gensupport.h (pattern_stats): New structure.
* gensupport.c (get_pattern_stats_1, get_pattern_stats): New functions.
* genemit.c (max_opno, max_dupno, max_scratch_opno): Delete.
(max_operand_1, max_operand_vec): Delete.
(gen_insn, gen_expand, gen_split): Use get_pattern_stats.

From-SVN: r171821

gcc/ChangeLog
gcc/genemit.c
gcc/gensupport.c
gcc/gensupport.h

index 922f6e6f2ee5e69219255e5ffe68cdea92700661..d048013b65857b41662e3e79bbfab25c4dcda6d4 100644 (file)
@@ -1,3 +1,11 @@
+2011-04-01  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * gensupport.h (pattern_stats): New structure.
+       * gensupport.c (get_pattern_stats_1, get_pattern_stats): New functions.
+       * genemit.c (max_opno, max_dupno, max_scratch_opno): Delete.
+       (max_operand_1, max_operand_vec): Delete.
+       (gen_insn, gen_expand, gen_split): Use get_pattern_stats.
+
 2011-03-31  Nathan Froyd  <froydnj@codesourcery.com>
 
        * emit-rtl.c (emit_pattern_after_setloc): New function.
index 6b1ae7d8608833ec118627d8d96555f4bd54e393..aea7cb8b68a48c298a35bb4592b390f10d7cb6a7 100644 (file)
@@ -29,9 +29,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "gensupport.h"
 
 
-static int max_opno;
-static int max_dup_opno;
-static int max_scratch_opno;
 static int insn_code_number;
 static int insn_index_number;
 
@@ -56,8 +53,6 @@ struct clobber_ent
   struct clobber_ent *next;
 };
 
-static void max_operand_1              (rtx);
-static int max_operand_vec             (rtx, int);
 static void print_code                 (RTX_CODE);
 static void gen_exp                    (rtx, enum rtx_code, char *);
 static void gen_insn                   (rtx, int);
@@ -68,58 +63,6 @@ static void output_added_clobbers_hard_reg_p (void);
 static void gen_rtx_scratch            (rtx, enum rtx_code);
 static void output_peephole2_scratches (rtx);
 
-\f
-static void
-max_operand_1 (rtx x)
-{
-  RTX_CODE code;
-  int i;
-  int len;
-  const char *fmt;
-
-  if (x == 0)
-    return;
-
-  code = GET_CODE (x);
-
-  if (code == MATCH_OPERAND || code == MATCH_OPERATOR
-      || code == MATCH_PARALLEL)
-    max_opno = MAX (max_opno, XINT (x, 0));
-  if (code == MATCH_DUP || code == MATCH_OP_DUP || code == MATCH_PAR_DUP)
-    max_dup_opno = MAX (max_dup_opno, XINT (x, 0));
-  if (code == MATCH_SCRATCH)
-    max_scratch_opno = MAX (max_scratch_opno, XINT (x, 0));
-
-  fmt = GET_RTX_FORMAT (code);
-  len = GET_RTX_LENGTH (code);
-  for (i = 0; i < len; i++)
-    {
-      if (fmt[i] == 'e' || fmt[i] == 'u')
-       max_operand_1 (XEXP (x, i));
-      else if (fmt[i] == 'E')
-       {
-         int j;
-         for (j = 0; j < XVECLEN (x, i); j++)
-           max_operand_1 (XVECEXP (x, i, j));
-       }
-    }
-}
-
-static int
-max_operand_vec (rtx insn, int arg)
-{
-  int len = XVECLEN (insn, arg);
-  int i;
-
-  max_opno = -1;
-  max_dup_opno = -1;
-  max_scratch_opno = -1;
-
-  for (i = 0; i < len; i++)
-    max_operand_1 (XVECEXP (insn, arg, i));
-
-  return max_opno + 1;
-}
 \f
 static void
 print_code (RTX_CODE code)
@@ -317,7 +260,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used)
 static void
 gen_insn (rtx insn, int lineno)
 {
-  int operands;
+  struct pattern_stats stats;
   int i;
 
   /* See if the pattern for this insn ends with a group of CLOBBERs of (hard)
@@ -402,14 +345,14 @@ gen_insn (rtx insn, int lineno)
   printf ("/* %s:%d */\n", read_md_filename, lineno);
 
   /* Find out how many operands this function has.  */
-  operands = max_operand_vec (insn, 1);
-  if (max_dup_opno >= operands)
+  get_pattern_stats (&stats, XVEC (insn, 1));
+  if (stats.max_dup_opno > stats.max_opno)
     fatal ("match_dup operand number has no match_operand");
 
   /* Output the function name and argument declarations.  */
   printf ("rtx\ngen_%s (", XSTR (insn, 0));
-  if (operands)
-    for (i = 0; i < operands; i++)
+  if (stats.num_generator_args)
+    for (i = 0; i < stats.num_generator_args; i++)
       if (i)
        printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
       else
@@ -429,7 +372,7 @@ gen_insn (rtx insn, int lineno)
     }
   else
     {
-      char *used = XCNEWVEC (char, operands);
+      char *used = XCNEWVEC (char, stats.num_generator_args);
 
       printf ("  return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (%d",
              XVECLEN (insn, 1));
@@ -449,7 +392,7 @@ gen_insn (rtx insn, int lineno)
 static void
 gen_expand (rtx expand)
 {
-  int operands;
+  struct pattern_stats stats;
   int i;
   char *used;
 
@@ -459,12 +402,12 @@ gen_expand (rtx expand)
     fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
 
   /* Find out how many operands this function has.  */
-  operands = max_operand_vec (expand, 1);
+  get_pattern_stats (&stats, XVEC (expand, 1));
 
   /* Output the function name and argument declarations.  */
   printf ("rtx\ngen_%s (", XSTR (expand, 0));
-  if (operands)
-    for (i = 0; i < operands; i++)
+  if (stats.num_generator_args)
+    for (i = 0; i < stats.num_generator_args; i++)
       if (i)
        printf (",\n\trtx operand%d", i);
       else
@@ -478,7 +421,7 @@ gen_expand (rtx expand)
      and no MATCH_DUPs are present, we can just return the desired insn
      like we do for a DEFINE_INSN.  This saves memory.  */
   if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0')
-      && operands > max_dup_opno
+      && stats.max_opno >= stats.max_dup_opno
       && XVECLEN (expand, 1) == 1)
     {
       printf ("  return ");
@@ -489,9 +432,9 @@ gen_expand (rtx expand)
 
   /* For each operand referred to only with MATCH_DUPs,
      make a local variable.  */
-  for (i = operands; i <= max_dup_opno; i++)
+  for (i = stats.num_generator_args; i <= stats.max_dup_opno; i++)
     printf ("  rtx operand%d;\n", i);
-  for (; i <= max_scratch_opno; i++)
+  for (; i <= stats.max_scratch_opno; i++)
     printf ("  rtx operand%d ATTRIBUTE_UNUSED;\n", i);
   printf ("  rtx _val = 0;\n");
   printf ("  start_sequence ();\n");
@@ -505,11 +448,11 @@ gen_expand (rtx expand)
   if (XSTR (expand, 3) && *XSTR (expand, 3))
     {
       printf ("  {\n");
-      if (operands > 0 || max_dup_opno >= 0 || max_scratch_opno >= 0)
-       printf ("    rtx operands[%d];\n",
-           MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1));
+      if (stats.num_operand_vars > 0)
+       printf ("    rtx operands[%d];\n", stats.num_operand_vars);
+
       /* Output code to copy the arguments into `operands'.  */
-      for (i = 0; i < operands; i++)
+      for (i = 0; i < stats.num_generator_args; i++)
        printf ("    operands[%d] = operand%d;\n", i, i);
 
       /* Output the special code to be executed before the sequence
@@ -521,9 +464,7 @@ gen_expand (rtx expand)
         (unless we aren't going to use them at all).  */
       if (XVEC (expand, 1) != 0)
        {
-         for (i = 0;
-              i < MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1);
-              i++)
+         for (i = 0; i < stats.num_operand_vars; i++)
            {
              printf ("    operand%d = operands[%d];\n", i, i);
              printf ("    (void) operand%d;\n", i);
@@ -536,8 +477,7 @@ gen_expand (rtx expand)
      Use emit_insn to add them to the sequence being accumulated.
      But don't do this if the user's code has set `no_more' nonzero.  */
 
-  used = XCNEWVEC (char,
-                  MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1));
+  used = XCNEWVEC (char, stats.num_operand_vars);
 
   for (i = 0; i < XVECLEN (expand, 1); i++)
     {
@@ -591,8 +531,8 @@ gen_expand (rtx expand)
 static void
 gen_split (rtx split)
 {
+  struct pattern_stats stats;
   int i;
-  int operands;
   const char *const name =
     ((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split");
   const char *unused;
@@ -607,10 +547,9 @@ gen_split (rtx split)
 
   /* Find out how many operands this function has.  */
 
-  max_operand_vec (split, 2);
-  operands = MAX (max_opno, MAX (max_dup_opno, max_scratch_opno)) + 1;
-  unused = (operands == 0 ? " ATTRIBUTE_UNUSED" : "");
-  used = XCNEWVEC (char, operands);
+  get_pattern_stats (&stats, XVEC (split, 2));
+  unused = (stats.num_operand_vars == 0 ? " ATTRIBUTE_UNUSED" : "");
+  used = XCNEWVEC (char, stats.num_operand_vars);
 
   /* Output the prototype, function name and argument declarations.  */
   if (GET_CODE (split) == DEFINE_PEEPHOLE2)
@@ -629,7 +568,7 @@ gen_split (rtx split)
   printf ("{\n");
 
   /* Declare all local variables.  */
-  for (i = 0; i < operands; i++)
+  for (i = 0; i < stats.num_operand_vars; i++)
     printf ("  rtx operand%d;\n", i);
   printf ("  rtx _val = 0;\n");
 
@@ -648,7 +587,7 @@ gen_split (rtx split)
     }
 
   /* Output code to copy the arguments back out of `operands'  */
-  for (i = 0; i < operands; i++)
+  for (i = 0; i < stats.num_operand_vars; i++)
     {
       printf ("  operand%d = operands[%d];\n", i, i);
       printf ("  (void) operand%d;\n", i);
index e81682c7c21723019788786f81b0d5714a7b37d6..7bdfc41a4a156e44744be6c7d39753295005dc50 100644 (file)
@@ -1367,3 +1367,80 @@ record_insn_name (int code, const char *name)
 
   insn_name_ptr[code] = new_name;
 }
+\f
+/* Make STATS describe the operands that appear in rtx X.  */
+
+static void
+get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
+{
+  RTX_CODE code;
+  int i;
+  int len;
+  const char *fmt;
+
+  if (x == NULL_RTX)
+    return;
+
+  code = GET_CODE (x);
+  switch (code)
+    {
+    case MATCH_OPERAND:
+    case MATCH_OPERATOR:
+    case MATCH_PARALLEL:
+      stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
+      break;
+
+    case MATCH_DUP:
+    case MATCH_OP_DUP:
+    case MATCH_PAR_DUP:
+      stats->num_dups++;
+      stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
+      break;
+
+    case MATCH_SCRATCH:
+      stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
+      break;
+
+    default:
+      break;
+    }
+
+  fmt = GET_RTX_FORMAT (code);
+  len = GET_RTX_LENGTH (code);
+  for (i = 0; i < len; i++)
+    {
+      if (fmt[i] == 'e' || fmt[i] == 'u')
+       get_pattern_stats_1 (stats, XEXP (x, i));
+      else if (fmt[i] == 'E')
+       {
+         int j;
+         for (j = 0; j < XVECLEN (x, i); j++)
+           get_pattern_stats_1 (stats, XVECEXP (x, i, j));
+       }
+    }
+}
+
+/* Make STATS describe the operands that appear in instruction pattern
+   PATTERN.  */
+
+void
+get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
+{
+  int i, len;
+
+  stats->max_opno = -1;
+  stats->max_dup_opno = -1;
+  stats->max_scratch_opno = -1;
+  stats->num_dups = 0;
+
+  len = GET_NUM_ELEM (pattern);
+  for (i = 0; i < len; i++)
+    get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
+
+  stats->num_generator_args = stats->max_opno + 1;
+  stats->num_insn_operands = MAX (stats->max_opno,
+                                 stats->max_scratch_opno) + 1;
+  stats->num_operand_vars = MAX (stats->max_opno,
+                                 MAX (stats->max_dup_opno,
+                                      stats->max_scratch_opno)) + 1;
+}
index 999c2222ecba0db90acc60bd0aa2de62a5bc7977..5ae32d5f40d4f1b00e451ecb12cd33b7d395dff8 100644 (file)
@@ -83,4 +83,32 @@ extern void add_predicate (struct pred_data *);
 
 #define FOR_ALL_PREDICATES(p) for (p = first_predicate; p; p = p->next)
 
+struct pattern_stats
+{
+  /* The largest match_operand, match_operator or match_parallel
+     number found.  */
+  int max_opno;
+
+  /* The largest match_dup, match_op_dup or match_par_dup number found.  */
+  int max_dup_opno;
+
+  /* The largest match_scratch number found.  */
+  int max_scratch_opno;
+
+  /* The number of times match_dup, match_op_dup or match_par_dup appears
+     in the pattern.  */
+  int num_dups;
+
+  /* The number of rtx arguments to the generator function.  */
+  int num_generator_args;
+
+  /* The number of rtx operands in an insn.  */
+  int num_insn_operands;
+
+  /* The number of operand variables that are needed.  */
+  int num_operand_vars;
+};
+
+extern void get_pattern_stats (struct pattern_stats *ranges, rtvec vec);
+
 #endif /* GCC_GENSUPPORT_H */