Andrew Stubbs <a...@codesourcery.com> writes:
> On 17/09/18 10:18, Richard Sandiford wrote:
>> The idea looks good to me FWIW, but you can't use curr_static_id for
>> the state, since that's a static description of the .md pattern rather
>> than data about this particular instance.
>
> I clearly misunderstood what that was for.
>
> This patch does the same thing, but uses a local variable to store the 
> state. That probably means it does it more correctly, too.
>
> OK?
>
> Andrew
>
> Don't double-count early-clobber matches.
>
> Given a pattern with a number of operands:
>
> (match_operand 0 "" "=&v")
> (match_operand 1 "" " v0")
> (match_operand 2 "" " v0")
> (match_operand 3 "" " v0")
>
> GCC will currently increment "reject" once, for operand 0, and then decrement
> it once for each of the other operands, ending with reject == -2 and an
> assertion failure.  If there's a conflict then it might try to decrement 
> reject
> yet again.
>
> Incidentally, what these patterns are trying to achieve is an allocation in
> which operand 0 may match one of the other operands, but may not partially
> overlap any of them.  Ideally there'd be a better way to do this.
>
> In any case, it will affect any pattern in which multiple operands may (or
> must) match an early-clobber operand.
>
> The patch only allows a reject-- when one has not already occurred, for that
> operand.
>
> 2018-09-27  Andrew Stubbs  <a...@codesourcery.com>
>
>       gcc/
>       * lra-constraints.c (process_alt_operands): Check
>       matching_early_clobber before decrementing reject, and set
>       matching_early_clobber after.
>       * lra-int.h (struct lra_operand_data): Add matching_early_clobber.
>       * lra.c (setup_operand_alternative): Initialize matching_early_clobber.
>
> diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
> index 774d1ff..e1d1688 100644
> --- a/gcc/lra-constraints.c
> +++ b/gcc/lra-constraints.c
> @@ -1969,6 +1969,7 @@ process_alt_operands (int only_alternative)
>        if (!TEST_BIT (preferred, nalt))
>       continue;
>  
> +      bool matching_early_clobber[MAX_RECOG_OPERANDS] = {};

This is potentially expensive, since MAX_RECOG_OPERANDS >= 30 and
most instructions have operand counts in the low single digits.
(And this is a very compile-time sensitive function -- it often
shows up at the top or near the top of a "cc1 -O0" profile.)

How about clearing it in this loop:

      curr_small_class_check++;
      overall = losers = addr_losers = 0;
      static_reject = reject = reload_nregs = reload_sum = 0;
      for (nop = 0; nop < n_operands; nop++)
        {
          ...
        }

OK with that change if it works, thanks.

Sorry for the slow reply...

Richard

Reply via email to