]> gcc.gnu.org Git - gcc.git/commitdiff
reload.c (remove_replacements): New function.
authorJ"orn Rennecke <amylaar@cygnus.co.uk>
Thu, 14 May 1998 00:44:02 +0000 (00:44 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Thu, 14 May 1998 00:44:02 +0000 (01:44 +0100)
* 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

gcc/ChangeLog
gcc/reload.c
gcc/reload.h
gcc/reload1.c

index d692794932d9b300765eb3e26e55c3b944b4416d..807e2b9cff1e3d1ea840560b101caab8f38b427b 100644 (file)
@@ -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
index 7d7350e29fa3b5f3e10925f26dd08bc3ee6091d8..ef62ef92f442f97e53935b01ebc4019f01e3c2bf 100644 (file)
@@ -1506,6 +1506,21 @@ transfer_replacements (to, from)
       replacements[i].what = to;
 }
 \f
+/* 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];
+    }
+}
+\f
 /* 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.
index d35dc3fa6b5b4cbc689f8b360c4ce7126a107a3a..d99b0c128a5d04b36b8b1cdbd1c1cef1d3e2ae9a 100644 (file)
@@ -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.  */
index 3d849b613146b7f7c30db1c8f1770328fe9e0fd4..f6d9a0f04523e653599e69b8b62841d7b21f484c 100644 (file)
@@ -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.  */
This page took 0.087809 seconds and 5 git commands to generate.