summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1998-07-01 13:20:50 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-07-01 14:20:50 +0100
commit826e3854538c21e6a42bc73ad5d02f2ee2a13f14 (patch)
tree7f203b5d56a52fb6eb3200e2ef40d79aa3203a9e
parentd7921434ac4825e33e59bc22df7c716d9990ff87 (diff)
downloadgcc-826e3854538c21e6a42bc73ad5d02f2ee2a13f14.tar.gz
reload.c (find_reloads): If there are multiple RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS...
* reload.c (find_reloads): If there are multiple RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads for one operand, change RELOAD_FOR_INPADDR_ADDRESS / RELOAD_FOR_OUTADDR_ADDRESS for all but the first RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads. From-SVN: r20877
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/reload.c83
2 files changed, 82 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9688de22732..48f626c14b1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+Wed Jul 1 21:17:36 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reload.c (find_reloads): If there are multiple
+ RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads for
+ one operand, change RELOAD_FOR_INPADDR_ADDRESS /
+ RELOAD_FOR_OUTADDR_ADDRESS for all but the first
+ RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads.
+
Wed Jul 1 17:23:23 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* regmove.c (fixup_match_2): Check that P has RTX_CLASS 'i' before
diff --git a/gcc/reload.c b/gcc/reload.c
index 6431f156093..c010943021b 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -3994,17 +3994,82 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
actually fail are extremely rare, so it turns out to be better to fix
the problem here by not generating cases that choose_reload_regs will
fail for. */
-
+ /* There is a similar problem with RELAOD_FOR_INPUT_ADDRESS /
+ RELOAD_FOR_OUTPUT_ADDRESS when there is more than one of a kind for
+ a single operand.
+ We can reduce the register pressure by exploiting that a
+ RELOAD_FOR_X_ADDR_ADDR that precedes all RELOAD_FOR_X_ADDRESS reloads
+ does not conflict with any of them. */
{
- int op_addr_reloads = 0;
- for (i = 0; i < n_reloads; i++)
- if (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS)
- op_addr_reloads++;
+ int first_op_addr_num = -2;
+ int first_inpaddr_num[MAX_RECOG_OPERANDS];
+ int first_outpaddr_num[MAX_RECOG_OPERANDS];
+ int need_change= 0;
+ /* We use last_op_addr_reload and the contents of the above arrays
+ first as flags - -2 means no instance encountered, -1 means exactly
+ one instance encountered.
+ If more than one instance has been encountered, we store the reload
+ number of the first reload of the kind in question; reload numbers
+ are known to be non-negative. */
+ for (i = 0; i < noperands; i++)
+ first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
+ for (i = n_reloads - 1; i >= 0; i--)
+ {
+ switch (reload_when_needed[i])
+ {
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ if (! ++first_op_addr_num)
+ {
+ first_op_addr_num= i;
+ need_change = 1;
+ }
+ break;
+ case RELOAD_FOR_INPUT_ADDRESS:
+ if (! ++first_inpaddr_num[reload_opnum[i]])
+ {
+ first_inpaddr_num[reload_opnum[i]] = i;
+ need_change = 1;
+ }
+ break;
+ case RELOAD_FOR_OUTPUT_ADDRESS:
+ if (! ++first_outpaddr_num[reload_opnum[i]])
+ {
+ first_outpaddr_num[reload_opnum[i]] = i;
+ need_change = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- if (op_addr_reloads > 1)
- for (i = 0; i < n_reloads; i++)
- if (reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR)
- reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
+ if (need_change)
+ {
+ for (i = 0; i < n_reloads; i++)
+ {
+ int first_num, type;
+
+ switch (reload_when_needed[i])
+ {
+ case RELOAD_FOR_OPADDR_ADDR:
+ first_num = first_op_addr_num;
+ type = RELOAD_FOR_OPERAND_ADDRESS;
+ break;
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ first_num = first_inpaddr_num[reload_opnum[i]];
+ type = RELOAD_FOR_INPUT_ADDRESS;
+ break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ first_num = first_outpaddr_num[reload_opnum[i]];
+ type = RELOAD_FOR_OUTPUT_ADDRESS;
+ break;
+ default:
+ continue;
+ }
+ if (i > first_num)
+ reload_when_needed[i] = type;
+ }
+ }
}
/* See if we have any reloads that are now allowed to be merged