From: feedable <[email protected]>

Now that we can operate on an arbitrary amout of operands, adapt the recog
machinery to work with an arbitrary amount of operands as well. This means
passing around references to operand vectors instead of pointers to opreand
arrays, and adjusting code generation to accomodate the variable sizes of
operand arrays.

gcc/ChangeLog:

        * genconfig.cc (main): Adjust comment.
        * genemit.cc (gen_split): Adjust for operand_vec.
        * genextract.cc (insn_extract): Remove memset and shorthands.
        (main): Adjust for vectors.
        * genrecog.cc (print_test_rtx): Use operand_vec.
        (print_test): Likewise.
        (print_acceptance): Likewsie.
        (print_decision): Likewise.
        (print_subroutine_start): Likewise.
        (print_subroutine): Likewise.
        (main): Likewise.
        * recog.h (struct recog_data_d): Define a helper for recog.
---
 gcc/genconfig.cc  |  5 +++--
 gcc/genemit.cc    | 17 +++++++++++++----
 gcc/genextract.cc | 23 ++++++++++-------------
 gcc/genrecog.cc   | 24 +++++++++++++-----------
 gcc/recog.h       | 14 ++++++++++++++
 5 files changed, 53 insertions(+), 30 deletions(-)

diff --git a/gcc/genconfig.cc b/gcc/genconfig.cc
index d24337c460490..284c2e295534a 100644
--- a/gcc/genconfig.cc
+++ b/gcc/genconfig.cc
@@ -280,8 +280,9 @@ main (int argc, const char **argv)
      This magic number is also used in genpreds to determine
      validity of a referenced operand when parsing dynamic register
      filters.  */
-  /* ??? We *really* ought to reorganize things such that there
-     is no fixed upper bound.  */
+  /* ??? While the core logic was reorganized to work with an arbitrary operand
+     count, many backends still rely on the old meaning of MAX_RECOG_OPERANDS,
+     so the logic has to stay.  */
   max_recog_operands = 29;  /* We will add 1 later.  */
   max_dup_operands = 1;
 
diff --git a/gcc/genemit.cc b/gcc/genemit.cc
index 6323aeb19fc47..bf6c4994e3c91 100644
--- a/gcc/genemit.cc
+++ b/gcc/genemit.cc
@@ -578,8 +578,9 @@ gen_split (const md_rtx_info &info, FILE *file)
     {
       fprintf (file, "extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
              name, info.index);
-      fprintf (file, "rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn 
ATTRIBUTE_UNUSED,"
-             " rtx *operands%s)\n",
+      fprintf (file, "rtx_insn *\ngen_%s_%d "
+             "(rtx_insn *curr_insn ATTRIBUTE_UNUSED, "
+             "operand_vec<rtx> &operand_vec%s)\n",
              name, info.index, unused);
     }
   else
@@ -587,11 +588,19 @@ gen_split (const md_rtx_info &info, FILE *file)
       fprintf (file, "extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
              info.index);
       fprintf (file, "rtx_insn *\ngen_split_%d "
-             "(rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
-             info.index, unused);
+             "(rtx_insn *curr_insn ATTRIBUTE_UNUSED, "
+             "operand_vec<rtx> &operand_vec%s)\n", info.index, unused);
     }
   fprintf (file, "{\n");
 
+  int out_operands = stats.num_operand_vars;
+  get_pattern_stats (&stats, XVEC (split, 0));
+  if (stats.num_operand_vars < out_operands)
+    fprintf (file, "  operand_vec.truncate (%d);\n"
+            "  operand_vec.safe_grow_cleared (%d);\n",
+            stats.num_operand_vars, out_operands);
+  fprintf (file, "  rtx *operands = operand_vec.address ();\n");
+
   if (GET_CODE (split) == DEFINE_PEEPHOLE2)
     output_peephole2_scratches (split, file);
 
diff --git a/gcc/genextract.cc b/gcc/genextract.cc
index 44094fdc281fd..e9e52e82a3ca1 100644
--- a/gcc/genextract.cc
+++ b/gcc/genextract.cc
@@ -378,16 +378,9 @@ static rtx junk ATTRIBUTE_UNUSED;\n");
   puts ("\
 void\n\
 insn_extract (rtx_insn *insn)\n{\n\
-  rtx *ro = recog_data.operand;\n\
-  rtx **ro_loc = recog_data.operand_loc;\n\
   rtx pat = PATTERN (insn);\n\
   int i ATTRIBUTE_UNUSED; /* only for peepholes */\n\
-\n\
-  if (flag_checking)\n\
-    {\n\
-      memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
-      memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
-    }\n");
+\n");
 
   puts ("\
   switch (INSN_CODE (insn))\n\
@@ -457,8 +450,10 @@ main (int argc, const char **argv)
         created just for the sake of this function.  We need to set the
         location of the operands for sake of simplifications after
         extraction, like eliminating subregs.  */
-      puts ("      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n"
-           "          ro[i] = *(ro_loc[i] = &XVECEXP (pat, 0, i));\n"
+      puts ("      recog_data.init (XVECLEN (pat, 0), 0);\n"
+           "      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n"
+           "\trecog_data.operand[i] = *(recog_data.operand_loc[i]"
+           " = &XVECEXP (pat, 0, i));\n"
            "      break;\n");
     }
 
@@ -475,16 +470,18 @@ main (int argc, const char **argv)
            printf ("    case %d:\n", i);
        }
 
+      printf ("      recog_data.init (%d, %d);\n", p->op_count, p->dup_count);
       for (i = 0; i < p->op_count; i++)
        {
          if (p->oplocs[i] == 0)
            {
-             printf ("      ro[%d] = const0_rtx;\n", i);
-             printf ("      ro_loc[%d] = &junk;\n", i);
+             printf ("      recog_data.operand[%d] = const0_rtx;\n", i);
+             printf ("      recog_data.operand_loc[%d] = &junk;\n", i);
            }
          else
            {
-             printf ("      ro[%d] = *(ro_loc[%d] = &", i, i);
+             printf ("      recog_data.operand[%d] = "
+                     "*(recog_data.operand_loc[%d] = &", i, i);
              print_path (p->oplocs[i]);
              puts (");");
            }
diff --git a/gcc/genrecog.cc b/gcc/genrecog.cc
index 663620224abd5..66839973df0a7 100644
--- a/gcc/genrecog.cc
+++ b/gcc/genrecog.cc
@@ -4575,7 +4575,7 @@ static void
 print_test_rtx (FILE *f, output_state *os, const rtx_test &test)
 {
   if (test.pos_operand >= 0)
-    fprintf (f, "operands[%d]", test.pos_operand);
+    fprintf (f, "operand_vec[%d]", test.pos_operand);
   else
     fprintf (f, "x%d", os->id_to_var[test.pos->id]);
 }
@@ -4753,7 +4753,7 @@ print_test (FILE *f, output_state *os, const rtx_test 
&test, bool is_param,
       gcc_assert (!is_param && value == 1);
       fprintf (f, "%srtx_equal_p (", invert_p ? "!" : "");
       print_test_rtx (f, os, test);
-      fprintf (f, ", operands[%d])", test.u.opno);
+      fprintf (f, ", operand_vec[%d])", test.u.opno);
       break;
 
     case rtx_test::HAVE_NUM_CLOBBERS:
@@ -4867,7 +4867,7 @@ print_acceptance (FILE *f, const acceptance_type 
&acceptance,
       return ES_RETURNED;
 
     case SPLIT:
-      printf_indent (f, indent, "return gen_split_%d (insn, operands);\n",
+      printf_indent (f, indent, "return gen_split_%d (insn, operand_vec);\n",
                     acceptance.u.full.code);
       return ES_RETURNED;
 
@@ -4877,14 +4877,14 @@ print_acceptance (FILE *f, const acceptance_type 
&acceptance,
       if (is_final)
        {
          printf_indent (f, indent,
-                        "return gen_peephole2_%d (insn, operands);\n",
+                        "return gen_peephole2_%d (insn, operand_vec);\n",
                         acceptance.u.full.code);
          return ES_RETURNED;
        }
       else
        {
-         printf_indent (f,
-                        indent, "res = gen_peephole2_%d (insn, operands);\n",
+         printf_indent (f, indent,
+                        "res = gen_peephole2_%d (insn, operand_vec);\n",
                         acceptance.u.full.code);
          printf_indent (f, indent, "if (res != NULL_RTX)\n");
          printf_indent (f, indent + 2, "return res;\n");
@@ -4952,7 +4952,7 @@ print_decision (FILE *f, output_state *os, decision *d, 
unsigned int indent,
     return print_acceptance (f, d->test.u.acceptance, indent, is_final);
   else if (d->test.kind == rtx_test::SET_OP)
     {
-      printf_indent (f, indent, "operands[%d] = ", d->test.u.opno);
+      printf_indent (f, indent, "recog_data.place (%d) = ", d->test.u.opno);
       print_test_rtx (f, os, d->test);
       fprintf (f, ";\n");
       return print_state (f, os, d->singleton ()->to, indent, is_final);
@@ -5122,8 +5122,9 @@ assign_position_vars (output_state *os, state *s)
 static void
 print_subroutine_start (FILE *f, output_state *os, state *s, position *root)
 {
-  fprintf (f, "{\n  rtx * const operands ATTRIBUTE_UNUSED"
-          " = &recog_data.operand[0];\n");
+  fprintf (f, "{\n  auto &operand_vec ATTRIBUTE_UNUSED"
+          " = recog_data.operand;\n");
+  fprintf (f, "  #define operands (operand_vec.address ())\n");
   os->var_to_id.truncate (0);
   os->seen_vars.truncate (0);
   if (root)
@@ -5280,6 +5281,7 @@ print_subroutine (FILE *f, output_state *os, state *s, 
int proc_id,
   if (proc_id == 0)
     {
       fprintf (f, "  recog_data.insn = NULL;\n");
+      fprintf (f, "  recog_data.init_recog ();\n");
     }
   print_state (f, os, s, 2, true);
   fprintf (f, "}\n");
@@ -5471,7 +5473,7 @@ main (int argc, const char **argv)
          /* Declare the gen_split routine that we'll call if the
             pattern matches.  The definition comes from insn-emit.cc.  */
          fprintf (header, "extern rtx_insn *gen_split_%d "
-                  "(rtx_insn *, rtx *);\n", info.index);
+                  "(rtx_insn *, operand_vec<rtx> &);\n", info.index);
          break;
 
        case DEFINE_PEEPHOLE2:
@@ -5483,7 +5485,7 @@ main (int argc, const char **argv)
          /* Declare the gen_peephole2 routine that we'll call if the
             pattern matches.  The definition comes from insn-emit.cc.  */
          fprintf (header, "extern rtx_insn *gen_peephole2_%d "
-                  "(rtx_insn *, rtx *);\n", info.index);
+                  "(rtx_insn *, operand_vec<rtx> &);\n", info.index);
          break;
 
        default:
diff --git a/gcc/recog.h b/gcc/recog.h
index 0eb0a99db1d77..08516fdcbd115 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -407,6 +407,20 @@ struct recog_data_d
     resize (dup_loc, ndups);
     resize (dup_num, ndups);
   }
+  rtx &place (unsigned index)
+  {
+    if (index >= operand.length ())
+      operand.safe_grow_cleared (index + 1);
+    return operand[index];
+  }
+  void init_recog ()
+  {
+    /* This is not supposed to be required, but many backends store
+       values that are not reflected in the pattern into the operands
+       array, so we can't really know how many operands are required
+       to be present.  */
+    operand.safe_grow_cleared (MAX_RECOG_OPERANDS);
+  }
   /* It is very tempting to make the 5 operand related arrays into a
      structure and index on that.  However, to be source compatible
      with all of the existing md file insn constraints and output
-- 
2.54.0

Reply via email to