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