diff options
author | J"orn Rennecke <amylaar@cygnus.co.uk> | 1998-07-01 13:20:50 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 1998-07-01 14:20:50 +0100 |
commit | 826e3854538c21e6a42bc73ad5d02f2ee2a13f14 (patch) | |
tree | 7f203b5d56a52fb6eb3200e2ef40d79aa3203a9e | |
parent | d7921434ac4825e33e59bc22df7c716d9990ff87 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/reload.c | 83 |
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 |