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
This commit is contained in:
parent
b333d8b6d0
commit
dbe7895c9d
@ -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
|
||||
|
@ -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);
|
||||
reject--;
|
||||
overall += LRA_LOSER_COST_FACTOR - 1;
|
||||
}
|
||||
/* Early clobber was already reflected in REJECT. */
|
||||
if (!matching_early_clobber[i])
|
||||
{
|
||||
lra_assert (reject > 0);
|
||||
reject--;
|
||||
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",
|
||||
|
Loading…
Reference in New Issue
Block a user