diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-03 07:15:51 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-03 07:15:51 +0000 |
commit | 43ee3f43c8355e623faca36246804e55a784b985 (patch) | |
tree | be310b3c549e4a26b6cc910f7f7dc8dcbd09a174 /gcc/reload.c | |
parent | c5f9099f3c8c8e7e3a89952504f01eec289117bd (diff) | |
download | gcc-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.c | 57 |
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)) |