aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1998-05-14 00:44:02 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-05-14 01:44:02 +0100
commit029b38ff0437ff2ea5fc84c8e026d6f055727194 (patch)
tree051fe061feaa27120cdc1d7f7ca4ce4be1c132a8 /gcc
parentf824910ea1f3cb4ec56581a1f752c0c777720d49 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/reload.c15
-rw-r--r--gcc/reload.h3
-rw-r--r--gcc/reload1.c41
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. */