Commit b5068425 by Andreas Krebbel Committed by Andreas Krebbel

reload.c (find_reloads): Change the loop nesting when trying an alternative with swapped operands.

2012-04-26  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* reload.c (find_reloads): Change the loop nesting when trying an
	alternative with swapped operands.

From-SVN: r186861
parent 1d72e96f
2012-04-26 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* reload.c (find_reloads): Change the loop nesting when trying an
alternative with swapped operands.
2012-04-26 Manuel López-Ibáñez <manu@gcc.gnu.org> 2012-04-26 Manuel López-Ibáñez <manu@gcc.gnu.org>
* tree-diagnostic.c (maybe_unwind_expanded_macro_loc): Fix * tree-diagnostic.c (maybe_unwind_expanded_macro_loc): Fix
......
...@@ -2592,7 +2592,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -2592,7 +2592,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
char this_alternative_offmemok[MAX_RECOG_OPERANDS]; char this_alternative_offmemok[MAX_RECOG_OPERANDS];
char this_alternative_earlyclobber[MAX_RECOG_OPERANDS]; char this_alternative_earlyclobber[MAX_RECOG_OPERANDS];
int this_alternative_matches[MAX_RECOG_OPERANDS]; int this_alternative_matches[MAX_RECOG_OPERANDS];
int swapped;
reg_class_t goal_alternative[MAX_RECOG_OPERANDS]; reg_class_t goal_alternative[MAX_RECOG_OPERANDS];
int this_alternative_number; int this_alternative_number;
int goal_alternative_number = 0; int goal_alternative_number = 0;
...@@ -2938,9 +2937,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -2938,9 +2937,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
best = MAX_RECOG_OPERANDS * 2 + 600; best = MAX_RECOG_OPERANDS * 2 + 600;
swapped = 0;
goal_alternative_swapped = 0; goal_alternative_swapped = 0;
try_swapped:
/* The constraints are made of several alternatives. /* The constraints are made of several alternatives.
Each operand's constraint looks like foo,bar,... with commas Each operand's constraint looks like foo,bar,... with commas
...@@ -2953,6 +2950,25 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -2953,6 +2950,25 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
this_alternative_number < n_alternatives; this_alternative_number < n_alternatives;
this_alternative_number++) this_alternative_number++)
{ {
int swapped;
if (!recog_data.alternative_enabled_p[this_alternative_number])
{
int i;
for (i = 0; i < recog_data.n_operands; i++)
constraints[i] = skip_alternative (constraints[i]);
continue;
}
/* If insn is commutative (it's safe to exchange a certain pair
of operands) then we need to try each alternative twice, the
second time matching those two operands as if we had
exchanged them. To do this, really exchange them in
operands. */
for (swapped = 0; swapped < (commutative >= 0 ? 2 : 1); swapped++)
{
/* Loop over operands for one constraint alternative. */ /* Loop over operands for one constraint alternative. */
/* LOSERS counts those that don't fit this alternative /* LOSERS counts those that don't fit this alternative
and would require loading. */ and would require loading. */
...@@ -2968,14 +2984,31 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -2968,14 +2984,31 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
a bad register class to only count 1/3 as much. */ a bad register class to only count 1/3 as much. */
int reject = 0; int reject = 0;
if (!recog_data.alternative_enabled_p[this_alternative_number]) if (swapped)
{ {
int i; enum reg_class tclass;
int t;
for (i = 0; i < recog_data.n_operands; i++) recog_data.operand[commutative] = substed_operand[commutative + 1];
constraints[i] = skip_alternative (constraints[i]); recog_data.operand[commutative + 1] = substed_operand[commutative];
/* Swap the duplicates too. */
for (i = 0; i < recog_data.n_dups; i++)
if (recog_data.dup_num[i] == commutative
|| recog_data.dup_num[i] == commutative + 1)
*recog_data.dup_loc[i]
= recog_data.operand[(int) recog_data.dup_num[i]];
continue; tclass = preferred_class[commutative];
preferred_class[commutative] = preferred_class[commutative + 1];
preferred_class[commutative + 1] = tclass;
t = pref_or_nothing[commutative];
pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
pref_or_nothing[commutative + 1] = t;
t = address_reloaded[commutative];
address_reloaded[commutative] = address_reloaded[commutative + 1];
address_reloaded[commutative + 1] = t;
} }
this_earlyclobber = 0; this_earlyclobber = 0;
...@@ -3475,6 +3508,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3475,6 +3508,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
} }
while ((p += len), c); while ((p += len), c);
if (swapped == (commutative >= 0 ? 1 : 0))
constraints[i] = p; constraints[i] = p;
/* If this operand could be handled with a reg, /* If this operand could be handled with a reg,
...@@ -3540,7 +3574,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3540,7 +3574,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS) if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS)
{ {
if (targetm.preferred_reload_class (operand, this_alternative[i]) if (targetm.preferred_reload_class (operand,
this_alternative[i])
== NO_REGS) == NO_REGS)
reject = 600; reject = 600;
...@@ -3572,26 +3607,29 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3572,26 +3607,29 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
reject++; reject++;
} }
/* If this operand is a pseudo register that didn't get a hard /* If this operand is a pseudo register that didn't get
reg and this alternative accepts some register, see if the a hard reg and this alternative accepts some
class that we want is a subset of the preferred class for this register, see if the class that we want is a subset
register. If not, but it intersects that class, use the of the preferred class for this register. If not,
preferred class instead. If it does not intersect the preferred but it intersects that class, use the preferred class
class, show that usage of this alternative should be discouraged; instead. If it does not intersect the preferred
it will be discouraged more still if the register is `preferred class, show that usage of this alternative should be
or nothing'. We do this because it increases the chance of discouraged; it will be discouraged more still if the
reusing our spill register in a later insn and avoiding a pair register is `preferred or nothing'. We do this
of memory stores and loads. because it increases the chance of reusing our spill
register in a later insn and avoiding a pair of
Don't bother with this if this alternative will accept this memory stores and loads.
operand.
Don't bother with this if this alternative will
Don't do this for a multiword operand, since it is only a accept this operand.
small win and has the risk of requiring more spill registers,
which could cause a large loss. Don't do this for a multiword operand, since it is
only a small win and has the risk of requiring more
Don't do this if the preferred class has only one register spill registers, which could cause a large loss.
because we might otherwise exhaust the class. */
Don't do this if the preferred class has only one
register because we might otherwise exhaust the
class. */
if (! win && ! did_match if (! win && ! did_match
&& this_alternative[i] != NO_REGS && this_alternative[i] != NO_REGS
...@@ -3689,7 +3727,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3689,7 +3727,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
if (losers == 0) if (losers == 0)
{ {
/* Unswap these so that they are never swapped at `finish'. */ /* Unswap these so that they are never swapped at `finish'. */
if (commutative >= 0) if (swapped)
{ {
recog_data.operand[commutative] = substed_operand[commutative]; recog_data.operand[commutative] = substed_operand[commutative];
recog_data.operand[commutative + 1] recog_data.operand[commutative + 1]
...@@ -3742,34 +3780,24 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3742,34 +3780,24 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
goal_earlyclobber = this_earlyclobber; goal_earlyclobber = this_earlyclobber;
} }
} }
}
/* If insn is commutative (it's safe to exchange a certain pair of operands)
then we need to try each alternative twice,
the second time matching those two operands
as if we had exchanged them.
To do this, really exchange them in operands.
If we have just tried the alternatives the second time,
return operands to normal and drop through. */
if (commutative >= 0)
{
swapped = !swapped;
if (swapped) if (swapped)
{ {
enum reg_class tclass; enum reg_class tclass;
int t; int t;
recog_data.operand[commutative] = substed_operand[commutative + 1]; /* If the commutative operands have been swapped, swap
recog_data.operand[commutative + 1] = substed_operand[commutative]; them back in order to check the next alternative. */
/* Swap the duplicates too. */ recog_data.operand[commutative] = substed_operand[commutative];
recog_data.operand[commutative + 1] = substed_operand[commutative + 1];
/* Unswap the duplicates too. */
for (i = 0; i < recog_data.n_dups; i++) for (i = 0; i < recog_data.n_dups; i++)
if (recog_data.dup_num[i] == commutative if (recog_data.dup_num[i] == commutative
|| recog_data.dup_num[i] == commutative + 1) || recog_data.dup_num[i] == commutative + 1)
*recog_data.dup_loc[i] *recog_data.dup_loc[i]
= recog_data.operand[(int) recog_data.dup_num[i]]; = recog_data.operand[(int) recog_data.dup_num[i]];
/* Unswap the operand related information as well. */
tclass = preferred_class[commutative]; tclass = preferred_class[commutative];
preferred_class[commutative] = preferred_class[commutative + 1]; preferred_class[commutative] = preferred_class[commutative + 1];
preferred_class[commutative + 1] = tclass; preferred_class[commutative + 1] = tclass;
...@@ -3781,22 +3809,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, ...@@ -3781,22 +3809,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
t = address_reloaded[commutative]; t = address_reloaded[commutative];
address_reloaded[commutative] = address_reloaded[commutative + 1]; address_reloaded[commutative] = address_reloaded[commutative + 1];
address_reloaded[commutative + 1] = t; address_reloaded[commutative + 1] = t;
memcpy (constraints, recog_data.constraints,
noperands * sizeof (const char *));
goto try_swapped;
} }
else
{
recog_data.operand[commutative] = substed_operand[commutative];
recog_data.operand[commutative + 1]
= substed_operand[commutative + 1];
/* Unswap the duplicates too. */
for (i = 0; i < recog_data.n_dups; i++)
if (recog_data.dup_num[i] == commutative
|| recog_data.dup_num[i] == commutative + 1)
*recog_data.dup_loc[i]
= recog_data.operand[(int) recog_data.dup_num[i]];
} }
} }
......
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