diff options
author | J"orn Rennecke <amylaar@cygnus.co.uk> | 1998-05-14 00:44:02 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 1998-05-14 01:44:02 +0100 |
commit | 029b38ff0437ff2ea5fc84c8e026d6f055727194 (patch) | |
tree | 051fe061feaa27120cdc1d7f7ca4ce4be1c132a8 /gcc | |
parent | f824910ea1f3cb4ec56581a1f752c0c777720d49 (diff) | |
download | gcc-029b38ff0437ff2ea5fc84c8e026d6f055727194.zip gcc-029b38ff0437ff2ea5fc84c8e026d6f055727194.tar.gz gcc-029b38ff0437ff2ea5fc84c8e026d6f055727194.tar.bz2 |
reload.c (remove_replacements): New function.
* reload.c (remove_replacements): New function.
* reload.h (remove_replacements): Declare.
* reload1.c (choose_reload_regs): Disable some reloads that
belong to inherited reloads.
From-SVN: r19735
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/reload.c | 15 | ||||
-rw-r--r-- | gcc/reload.h | 3 | ||||
-rw-r--r-- | gcc/reload1.c | 41 |
4 files changed, 66 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d692794..807e2b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Thu May 14 08:41:46 1998 J"orn Rennecke <amylaar@cygnus.co.uk> + + * reload.c (remove_replacements): New function. + * reload.h (remove_replacements): Declare. + * reload1.c (choose_reload_regs): Disable some reloads that + belong to inherited reloads. + Thu May 14 02:17:17 1998 J"orn Rennecke <amylaar@cygnus.co.uk> * reload1.c (merge_assigned_reloads): When merging, reset diff --git a/gcc/reload.c b/gcc/reload.c index 7d7350e2..ef62ef9 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -1506,6 +1506,21 @@ transfer_replacements (to, from) replacements[i].what = to; } +/* Remove all replacements in reload FROM. */ +void +remove_replacements (from) + int from; +{ + int i, j; + + for (i = 0, j = 0; i < n_replacements; i++) + { + if (replacements[i].what == from) + continue; + replacements[j++] = replacements[i]; + } +} + /* If there is only one output reload, and it is not for an earlyclobber operand, try to combine it with a (logically unrelated) input reload to reduce the number of reload registers needed. diff --git a/gcc/reload.h b/gcc/reload.h index d35dc3fa..d99b0c1 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -157,6 +157,9 @@ extern void clear_secondary_mem PROTO((void)); reload TO. */ extern void transfer_replacements PROTO((int, int)); +/* Remove all replacements in reload FROM. */ +extern void remove_replacements PROTO((int)); + /* Like rtx_equal_p except that it allows a REG and a SUBREG to match if they are the same hard reg, and has special hacks for autoincrement and autodecrement. */ diff --git a/gcc/reload1.c b/gcc/reload1.c index 3d849b6..f6d9a0f 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -5799,6 +5799,47 @@ choose_reload_regs (insn, avoid_return_reg) reload_opnum[r], reload_when_needed[r])) reload_inherited[r] = 0; + /* If we can inherit a RELOAD_FOR_INPUT, then we do not need its related + RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads. + ??? This could be extended to other reload types, but these are + more tricky to handle: + RELOAD_FOR_OTHER_ADDRESS reloads might have been merged, so we + can't eliminate them without a check that *all* references are + now unused due to inheritance. + While RELOAD_FOR_INPADDR_ADDRESS and RELOAD_FOR_OUTADDR_ADDRESS are + not merged, we can't be sure that we have eliminated the use of + that particular reload if we have seen just one + RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS being inherited, + since there might be multiple of the latter two reloads for a single + operand. + RELOAD_FOR_OPADDR_ADDR reloads for different operands are not + merged, but might share the same register by courtesy of + reload_reg_free_for_value_p. reload_reg_used_in_op_addr_reload + does not differentiate by opnum, thus calling clear_reload_reg_in_use + for one of these reloads would mark the register as free even though + another RELOAD_FOR_OPADDR_ADDR reload might still use it. */ + else if (reload_inherited[r] && reload_when_needed[r] == RELOAD_FOR_INPUT) + { + for (i = 0; i < n_reloads; i++) + { + if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS + || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS) + && reload_opnum[i] == reload_opnum[r] + && reload_in[i] && reload_reg_rtx[i]) + { + int regno = true_regnum (reload_reg_rtx[i]); + + reload_in[i] = 0; + if (spill_reg_order[regno] >= 0) + clear_reload_reg_in_use (regno, reload_opnum[i], + reload_when_needed[i], + reload_mode[i]); + reload_reg_rtx[i] = 0; + reload_spill_index[i] = -1; + remove_replacements (i); + } + } + } /* If we found a better place to reload from, validate it in the same fashion, if it is a reload reg. */ |