summaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-03 07:15:51 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-03 07:15:51 +0000
commit43ee3f43c8355e623faca36246804e55a784b985 (patch)
treebe310b3c549e4a26b6cc910f7f7dc8dcbd09a174 /gcc/reload.c
parentc5f9099f3c8c8e7e3a89952504f01eec289117bd (diff)
downloadgcc-43ee3f43c8355e623faca36246804e55a784b985.tar.gz
2009-09-03 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 151367 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@151369 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 257acd0a509..1435945d62c 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -112,6 +112,7 @@ a register with any other reload. */
#include "params.h"
#include "target.h"
#include "df.h"
+#include "ira.h"
/* True if X is a constant that can be forced into the constant pool. */
#define CONST_POOL_OK_P(X) \
@@ -2589,6 +2590,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
int goal_alternative_swapped;
int best;
+ int best_small_class_operands_num;
int commutative;
char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
rtx substed_operand[MAX_RECOG_OPERANDS];
@@ -2914,6 +2916,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
all the operands together against the register constraints. */
best = MAX_RECOG_OPERANDS * 2 + 600;
+ best_small_class_operands_num = 0;
swapped = 0;
goal_alternative_swapped = 0;
@@ -3697,22 +3700,48 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
/* If this alternative can be made to work by reloading,
and it needs less reloading than the others checked so far,
record it as the chosen goal for reloading. */
- if (! bad && best > losers)
+ if (! bad)
{
- for (i = 0; i < noperands; i++)
+ bool change_p = false;
+ int small_class_operands_num = 0;
+
+ if (best >= losers)
{
- goal_alternative[i] = this_alternative[i];
- goal_alternative_win[i] = this_alternative_win[i];
- goal_alternative_match_win[i] = this_alternative_match_win[i];
- goal_alternative_offmemok[i] = this_alternative_offmemok[i];
- goal_alternative_matches[i] = this_alternative_matches[i];
- goal_alternative_earlyclobber[i]
- = this_alternative_earlyclobber[i];
+ for (i = 0; i < noperands; i++)
+ small_class_operands_num
+ += SMALL_REGISTER_CLASS_P (this_alternative[i]) ? 1 : 0;
+ if (best > losers
+ || (best == losers
+ /* If the cost of the reloads is the same,
+ prefer alternative which requires minimal
+ number of small register classes for the
+ operands. This improves chances of reloads
+ for insn requiring small register
+ classes. */
+ && (small_class_operands_num
+ < best_small_class_operands_num)))
+ change_p = true;
+ }
+ if (change_p)
+ {
+ for (i = 0; i < noperands; i++)
+ {
+ goal_alternative[i] = this_alternative[i];
+ goal_alternative_win[i] = this_alternative_win[i];
+ goal_alternative_match_win[i]
+ = this_alternative_match_win[i];
+ goal_alternative_offmemok[i]
+ = this_alternative_offmemok[i];
+ goal_alternative_matches[i] = this_alternative_matches[i];
+ goal_alternative_earlyclobber[i]
+ = this_alternative_earlyclobber[i];
+ }
+ goal_alternative_swapped = swapped;
+ best = losers;
+ best_small_class_operands_num = small_class_operands_num;
+ goal_alternative_number = this_alternative_number;
+ goal_earlyclobber = this_earlyclobber;
}
- goal_alternative_swapped = swapped;
- best = losers;
- goal_alternative_number = this_alternative_number;
- goal_earlyclobber = this_earlyclobber;
}
}
@@ -6736,6 +6765,8 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other,
while (1)
{
p = PREV_INSN (p);
+ if (p && DEBUG_INSN_P (p))
+ continue;
num++;
if (p == 0 || LABEL_P (p)
|| num > PARAM_VALUE (PARAM_MAX_RELOAD_SEARCH_INSNS))