Commit dbe7895c by Andrew Stubbs Committed by Andrew Stubbs

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
parent b333d8b6
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> 2018-10-22 Segher Boessenkool <segher@kernel.crashing.org>
PR target/87598 PR target/87598
...@@ -1969,6 +1969,7 @@ process_alt_operands (int only_alternative) ...@@ -1969,6 +1969,7 @@ process_alt_operands (int only_alternative)
if (!TEST_BIT (preferred, nalt)) if (!TEST_BIT (preferred, nalt))
continue; continue;
bool matching_early_clobber[MAX_RECOG_OPERANDS];
curr_small_class_check++; curr_small_class_check++;
overall = losers = addr_losers = 0; overall = losers = addr_losers = 0;
static_reject = reject = reload_nregs = reload_sum = 0; static_reject = reject = reload_nregs = reload_sum = 0;
...@@ -1980,6 +1981,7 @@ process_alt_operands (int only_alternative) ...@@ -1980,6 +1981,7 @@ process_alt_operands (int only_alternative)
fprintf (lra_dump_file, fprintf (lra_dump_file,
" Staticly defined alt reject+=%d\n", inc); " Staticly defined alt reject+=%d\n", inc);
static_reject += inc; static_reject += inc;
matching_early_clobber[nop] = 0;
} }
reject += static_reject; reject += static_reject;
early_clobbered_regs_num = 0; early_clobbered_regs_num = 0;
...@@ -2175,7 +2177,11 @@ process_alt_operands (int only_alternative) ...@@ -2175,7 +2177,11 @@ process_alt_operands (int only_alternative)
" %d Matching earlyclobber alt:" " %d Matching earlyclobber alt:"
" reject--\n", " reject--\n",
nop); nop);
reject--; if (!matching_early_clobber[m])
{
reject--;
matching_early_clobber[m] = 1;
}
} }
/* Otherwise we prefer no matching /* Otherwise we prefer no matching
alternatives because it gives more freedom alternatives because it gives more freedom
...@@ -2921,15 +2927,11 @@ process_alt_operands (int only_alternative) ...@@ -2921,15 +2927,11 @@ process_alt_operands (int only_alternative)
curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++]
= last_conflict_j; = last_conflict_j;
losers++; losers++;
/* Early clobber was already reflected in REJECT. */
lra_assert (reject > 0);
if (lra_dump_file != NULL) if (lra_dump_file != NULL)
fprintf fprintf
(lra_dump_file, (lra_dump_file,
" %d Conflict early clobber reload: reject--\n", " %d Conflict early clobber reload: reject--\n",
i); i);
reject--;
overall += LRA_LOSER_COST_FACTOR - 1;
} }
else else
{ {
...@@ -2953,17 +2955,21 @@ process_alt_operands (int only_alternative) ...@@ -2953,17 +2955,21 @@ process_alt_operands (int only_alternative)
} }
curr_alt_win[i] = curr_alt_match_win[i] = false; curr_alt_win[i] = curr_alt_match_win[i] = false;
losers++; losers++;
/* Early clobber was already reflected in REJECT. */
lra_assert (reject > 0);
if (lra_dump_file != NULL) if (lra_dump_file != NULL)
fprintf fprintf
(lra_dump_file, (lra_dump_file,
" %d Matched conflict early clobber reloads: " " %d Matched conflict early clobber reloads: "
"reject--\n", "reject--\n",
i); i);
}
/* Early clobber was already reflected in REJECT. */
if (!matching_early_clobber[i])
{
lra_assert (reject > 0);
reject--; reject--;
overall += LRA_LOSER_COST_FACTOR - 1; matching_early_clobber[i] = 1;
} }
overall += LRA_LOSER_COST_FACTOR - 1;
} }
if (lra_dump_file != NULL) if (lra_dump_file != NULL)
fprintf (lra_dump_file, " alt=%d,overall=%d,losers=%d,rld_nregs=%d\n", fprintf (lra_dump_file, " alt=%d,overall=%d,losers=%d,rld_nregs=%d\n",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment