https://gcc.gnu.org/g:8ebe8f5eff9fda40f22b9df7a0b8a6c2fdf5f8d7

commit r16-784-g8ebe8f5eff9fda40f22b9df7a0b8a6c2fdf5f8d7
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Wed May 21 10:01:30 2025 +0100

    genemit: Always track multiple uses of operands
    
    gen_exp has code to detect when the same operand is used multiple
    times.  It ensures that second and subsequent uses call copy_rtx,
    to enforce correct unsharing.
    
    However, for historical reasons that aren't clear to me, this was
    skipped for a define_insn unless the define_insn was a parallel.
    It was also skipped for a single define_expand instruction,
    regardless of its contents.
    
    This meant that a single parallel instruction was treated differently
    between define_insn (where sharing rules were followed) and
    define_expand (where sharing rules weren't followed).  define_splits
    and define_peephole2s followed the sharing rules in all cases.
    
    This patch makes everything follow the sharing rules.  The code
    it touches will be removed by the proposed bytecode-based expansion,
    which will use its own tracking when enforcing sharing rules.
    However, it seemed better for staging and bisection purposes
    to make this change first.
    
    gcc/
            * genemit.cc (generator::used): Update comment.
            (generator::gen_exp): Remove handling of null unused arrays.
            (gen_insn, gen_expand): Always pass a used array.
            (output_add_clobbers): Note why the used array is null here.

Diff:
---
 gcc/genemit.cc | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/gcc/genemit.cc b/gcc/genemit.cc
index 44be50fc933c..0529b916455f 100644
--- a/gcc/genemit.cc
+++ b/gcc/genemit.cc
@@ -78,9 +78,9 @@ struct generator
   /* The type of subroutine that we're expanding.  */
   rtx_code subroutine_type;
 
-  /* If nonnull, index N indicates that the original operand N has already
-     been used to replace a MATCH_OPERATOR or MATCH_DUP, and so any further
-     replacements must make a copy.  */
+  /* Index N indicates that the original operand N has already been used to
+     replace a MATCH_OPERATOR or MATCH_DUP, and so any further replacements
+     must make a copy.  */
   char *used;
 
   /* The construct that we're expanding.  */
@@ -135,15 +135,12 @@ generator::gen_exp (rtx x)
     {
     case MATCH_OPERAND:
     case MATCH_DUP:
-      if (used)
+      if (used[XINT (x, 0)])
        {
-         if (used[XINT (x, 0)])
-           {
-             fprintf (file, "copy_rtx (operands[%d])", XINT (x, 0));
-             return;
-           }
-         used[XINT (x, 0)] = 1;
+         fprintf (file, "copy_rtx (operands[%d])", XINT (x, 0));
+         return;
        }
+      used[XINT (x, 0)] = 1;
       fprintf (file, "operands[%d]", XINT (x, 0));
       return;
 
@@ -505,10 +502,7 @@ gen_insn (const md_rtx_info &info, FILE *file)
   /* Output code to construct and return the rtl for the instruction body.  */
 
   rtx pattern = add_implicit_parallel (XVEC (insn, 1));
-  /* ??? This is the traditional behavior, but seems suspect.  */
-  char *used = (XVECLEN (insn, 1) == 1
-               ? NULL
-               : XCNEWVEC (char, stats.num_generator_args));
+  char *used = XCNEWVEC (char, stats.num_generator_args);
   fprintf (file, "  return ");
   generator (DEFINE_INSN, used, info, file).gen_exp (pattern);
   fprintf (file, ";\n}\n\n");
@@ -555,10 +549,12 @@ gen_expand (const md_rtx_info &info, FILE *file)
       && stats.max_opno >= stats.max_dup_opno
       && XVECLEN (expand, 1) == 1)
     {
+      used = XCNEWVEC (char, stats.num_operand_vars);
       fprintf (file, "  return ");
-      generator (DEFINE_EXPAND, NULL, info, file)
+      generator (DEFINE_EXPAND, used, info, file)
        .gen_exp (XVECEXP (expand, 1, 0));
       fprintf (file, ";\n}\n\n");
+      XDELETEVEC (used);
       return;
     }
 
@@ -717,6 +713,7 @@ output_add_clobbers (const md_rtx_info &info, FILE *file)
        {
          fprintf (file, "      XVECEXP (pattern, 0, %d) = ", i);
          rtx clobbered_value = RTVEC_ELT (clobber->pattern, i);
+         /* Pass null for USED since there are no operands.  */
          generator (clobber->code, NULL, info, file)
            .gen_exp (clobbered_value);
          fprintf (file, ";\n");

Reply via email to