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] = {};
curr_small_class_check++;
overall = losers = addr_losers = 0;
static_reject = reject = reload_nregs = reload_sum = 0;
@@ -2175,7 +2176,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 +2926,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 +2954,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",