diff mbox series

[4/5] Allow earlyclobbers in ira_get_dup_out_num

Message ID mpt7e9fm4vm.fsf@arm.com
State New
Headers show
Series Tweak IRA handling of tying and earlyclobbers | expand

Commit Message

Richard Sandiford June 21, 2019, 1:42 p.m. UTC
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-06-21  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.

Comments

Vladimir Makarov June 24, 2019, 2:32 p.m. UTC | #1
On 2019-06-21 9:42 a.m., Richard Sandiford wrote:
> 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.)
I don't remember the reason for this either as the code is more 10 years 
old.  I can only speculate that this approach was influenced by the old 
RA (global.c).  I remember that it processed earlyclobber registers too 
but may be in a different way.
> 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.
>
OK to commit.
> 2019-06-21  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.
>
> Index: gcc/ira.c
> ===================================================================
> --- gcc/ira.c	2019-06-21 14:34:13.239653892 +0100
> +++ gcc/ira.c	2019-06-21 14:34:15.947631377 +0100
> @@ -1999,26 +1999,8 @@ ira_get_dup_out_num (int op_num, alterna
>   	}
>         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)
diff mbox series

Patch

Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2019-06-21 14:34:13.239653892 +0100
+++ gcc/ira.c	2019-06-21 14:34:15.947631377 +0100
@@ -1999,26 +1999,8 @@  ira_get_dup_out_num (int op_num, alterna
 	}
       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)