diff options
author | Andrew Stubbs <ams@codesourcery.com> | 2018-10-22 14:23:37 +0000 |
---|---|---|
committer | Andrew Stubbs <ams@gcc.gnu.org> | 2018-10-22 14:23:37 +0000 |
commit | dbe7895c9df1b82a764f076aab75b54afd375271 (patch) | |
tree | 4ee7d0adc73737b64c868a7ecf0097a9fa860893 | |
parent | b333d8b6d0deca1126f1e206f6ba2678deec437a (diff) | |
download | gcc-dbe7895c9df1b82a764f076aab75b54afd375271.zip gcc-dbe7895c9df1b82a764f076aab75b54afd375271.tar.gz gcc-dbe7895c9df1b82a764f076aab75b54afd375271.tar.bz2 |
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-10-22 Andrew Stubbs <ams@codesourcery.com>
gcc/
* lra-constraints.c (process_alt_operands): New local array,
matching_early_clobber. Check matching_early_clobber before
decrementing reject, and set matching_early_clobber after.
From-SVN: r265393
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 22 |
2 files changed, 20 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d799af2..6c05108 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-10-22 Andrew Stubbs <ams@codesourcery.com> + + * lra-constraints.c (process_alt_operands): New local array, + matching_early_clobber. Check matching_early_clobber before + decrementing reject, and set matching_early_clobber after. + 2018-10-22 Segher Boessenkool <segher@kernel.crashing.org> PR target/87598 diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 3cbe046..ab61989 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]; curr_small_class_check++; overall = losers = addr_losers = 0; static_reject = reject = reload_nregs = reload_sum = 0; @@ -1980,6 +1981,7 @@ process_alt_operands (int only_alternative) fprintf (lra_dump_file, " Staticly defined alt reject+=%d\n", inc); static_reject += inc; + matching_early_clobber[nop] = 0; } reject += static_reject; early_clobbered_regs_num = 0; @@ -2175,7 +2177,11 @@ process_alt_operands (int only_alternative) " %d Matching earlyclobber alt:" " reject--\n", nop); - reject--; + if (!matching_early_clobber[m]) + { + reject--; + matching_early_clobber[m] = 1; + } } /* Otherwise we prefer no matching alternatives because it gives more freedom @@ -2921,15 +2927,11 @@ process_alt_operands (int only_alternative) curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = last_conflict_j; losers++; - /* Early clobber was already reflected in REJECT. */ - lra_assert (reject > 0); if (lra_dump_file != NULL) fprintf (lra_dump_file, " %d Conflict early clobber reload: reject--\n", i); - reject--; - overall += LRA_LOSER_COST_FACTOR - 1; } else { @@ -2953,17 +2955,21 @@ process_alt_operands (int only_alternative) } curr_alt_win[i] = curr_alt_match_win[i] = false; losers++; - /* Early clobber was already reflected in REJECT. */ - lra_assert (reject > 0); if (lra_dump_file != NULL) fprintf (lra_dump_file, " %d Matched conflict early clobber reloads: " "reject--\n", i); + } + /* Early clobber was already reflected in REJECT. */ + if (!matching_early_clobber[i]) + { + lra_assert (reject > 0); reject--; - overall += LRA_LOSER_COST_FACTOR - 1; + matching_early_clobber[i] = 1; } + overall += LRA_LOSER_COST_FACTOR - 1; } if (lra_dump_file != NULL) fprintf (lra_dump_file, " alt=%d,overall=%d,losers=%d,rld_nregs=%d\n", |