Allow earlyclobbers in ira_get_dup_out_num
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 1 Jul 2019 08:58:35 +0000 (08:58 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 1 Jul 2019 08:58:35 +0000 (08:58 +0000)
ira_get_dup_out_num punted on operands that are matched to
earlyclobber outputs:

    /* It is better ignore an alternative with early clobber.  */
    else if (*str == '&')
      goto fail;

But I'm not sure why this is the right thing to do.  At this stage
we've established that *all* alternatives of interest require the
input to match the output, so

(a) the earlyclobber can only affect other operands and
(b) not tying the registers is bound to introduce a move

The code was part of the initial commit and so isn't obviously
related to a specific testcase.  Also, I can imagine LRA makes
a much better job of this situation than reload did.  (Certainly
SVE uses matched earlyclobbers extensively and I haven't seen any
problems.)

In case this turns out to regress something important: the main
case that matters for SVE is the one in which all alternatives
are earlyclobber.

2019-07-01  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* ira.c (ira_get_dup_out_num): Don't punt for earlyclobbers.
Use recog_data to test for an output operand.

From-SVN: r272850

gcc/ChangeLog
gcc/ira.c

index 8f70d1b385e1a3dcdc336c7fef36dd7f51911950..b49bc69045e723cb7a4c6dcb939360129cba48b4 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-01  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * ira.c (ira_get_dup_out_num): Don't punt for earlyclobbers.
+       Use recog_data to test for an output operand.
+
 2019-07-01  Richard Sandiford  <richard.sandiford@arm.com>
 
        * ira.c (ira_setup_alts): If any valid alternatives have zero cost,
index d9327db4e8fa54f6225b7760d5c975c8f5ba63b5..214fdffc5fe0cfab6af424322ed6e388ed991312 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1999,26 +1999,8 @@ ira_get_dup_out_num (int op_num, alternative_mask alts)
        }
       if (original == -1)
        goto fail;
-      dup = -1;
-      for (ignore_p = false, str = recog_data.constraints[original - '0'];
-          *str != 0;
-          str++)
-       if (ignore_p)
-         {
-           if (*str == ',')
-             ignore_p = false;
-         }
-       else if (*str == '#')
-         ignore_p = true;
-       else if (! ignore_p)
-         {
-           if (*str == '=')
-             dup = original - '0';
-           /* It is better ignore an alternative with early clobber.  */
-           else if (*str == '&')
-             goto fail;
-         }
-      if (dup >= 0)
+      dup = original - '0';
+      if (recog_data.operand_type[dup] == OP_OUT)
        return dup;
     fail:
       if (use_commut_op_p)