]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
emit-rtl.h (replace_equiv_address, [...]): Add an inplace argument.
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 17 May 2014 07:00:02 +0000 (07:00 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 17 May 2014 07:00:02 +0000 (07:00 +0000)
gcc/
* emit-rtl.h (replace_equiv_address, replace_equiv_address_nv): Add an
inplace argument.  Store the new address in the original MEM when true.
* emit-rtl.c (change_address_1): Likewise.
(adjust_address_1, adjust_automodify_address_1, offset_address):
Update accordingly.
* rtl.h (plus_constant): Add an inplace argument.
* explow.c (plus_constant): Likewise.  Try to reuse the original PLUS
when true.  Avoid generating (plus X (const_int 0)).
* function.c (instantiate_virtual_regs_in_rtx): Adjust the PLUS
in-place.  Pass true to plus_constant.
(instantiate_virtual_regs_in_insn): Pass true to replace_equiv_address.

From-SVN: r210543

gcc/ChangeLog
gcc/emit-rtl.c
gcc/emit-rtl.h
gcc/explow.c
gcc/function.c
gcc/rtl.h

index 5b516955a40dcf0fb30e0fc10cf9b4e1c3977851..352a109bc203cf9f98c9498ec5c8dbef5bde55a7 100644 (file)
@@ -1,3 +1,17 @@
+2014-05-17  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * emit-rtl.h (replace_equiv_address, replace_equiv_address_nv): Add an
+       inplace argument.  Store the new address in the original MEM when true.
+       * emit-rtl.c (change_address_1): Likewise.
+       (adjust_address_1, adjust_automodify_address_1, offset_address):
+       Update accordingly.
+       * rtl.h (plus_constant): Add an inplace argument.
+       * explow.c (plus_constant): Likewise.  Try to reuse the original PLUS
+       when true.  Avoid generating (plus X (const_int 0)).
+       * function.c (instantiate_virtual_regs_in_rtx): Adjust the PLUS
+       in-place.  Pass true to plus_constant.
+       (instantiate_virtual_regs_in_insn): Pass true to replace_equiv_address.
+
 2014-05-16  Dehao Chen  <dehao@google.com>
 
        * tree-cfg.c (gimple_merge_blocks): Updates bb count with max count.
index 79763d8093751a9ac81df6a8c527609b290073fa..d48d761479986ee1479fe4041e5061b908ebef41 100644 (file)
@@ -145,7 +145,6 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
 #define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid)
 #define first_label_num (crtl->emit.x_first_label_num)
 
-static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
 static void set_used_decls (tree);
 static void mark_label_nuses (rtx);
 static hashval_t const_int_htab_hash (const void *);
@@ -2010,11 +2009,15 @@ clear_mem_size (rtx mem)
 /* Return a memory reference like MEMREF, but with its mode changed to MODE
    and its address changed to ADDR.  (VOIDmode means don't change the mode.
    NULL for ADDR means don't change the address.)  VALIDATE is nonzero if the
-   returned memory location is required to be valid.  The memory
-   attributes are not changed.  */
+   returned memory location is required to be valid.  INPLACE is true if any
+   changes can be made directly to MEMREF or false if MEMREF must be treated
+   as immutable.
+
+   The memory attributes are not changed.  */
 
 static rtx
-change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
+change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate,
+                 bool inplace)
 {
   addr_space_t as;
   rtx new_rtx;
@@ -2042,6 +2045,12 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
   if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
     return memref;
 
+  if (inplace)
+    {
+      XEXP (memref, 0) = addr;
+      return memref;
+    }
+
   new_rtx = gen_rtx_MEM (mode, addr);
   MEM_COPY_ATTRIBUTES (new_rtx, memref);
   return new_rtx;
@@ -2053,7 +2062,7 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
 rtx
 change_address (rtx memref, enum machine_mode mode, rtx addr)
 {
-  rtx new_rtx = change_address_1 (memref, mode, addr, 1);
+  rtx new_rtx = change_address_1 (memref, mode, addr, 1, false);
   enum machine_mode mmode = GET_MODE (new_rtx);
   struct mem_attrs attrs, *defattrs;
 
@@ -2166,7 +2175,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
        addr = plus_constant (address_mode, addr, offset);
     }
 
-  new_rtx = change_address_1 (memref, mode, addr, validate);
+  new_rtx = change_address_1 (memref, mode, addr, validate, false);
 
   /* If the address is a REG, change_address_1 rightfully returns memref,
      but this would destroy memref's MEM_ATTRS.  */
@@ -2236,7 +2245,7 @@ rtx
 adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
                             HOST_WIDE_INT offset, int validate)
 {
-  memref = change_address_1 (memref, VOIDmode, addr, validate);
+  memref = change_address_1 (memref, VOIDmode, addr, validate, false);
   return adjust_address_1 (memref, mode, offset, validate, 0, 0, 0);
 }
 
@@ -2272,7 +2281,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
     }
 
   update_temp_slot_address (XEXP (memref, 0), new_rtx);
-  new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1);
+  new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1, false);
 
   /* If there are no changes, just return the original memory reference.  */
   if (new_rtx == memref)
@@ -2292,23 +2301,25 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
 /* Return a memory reference like MEMREF, but with its address changed to
    ADDR.  The caller is asserting that the actual piece of memory pointed
    to is the same, just the form of the address is being changed, such as
-   by putting something into a register.  */
+   by putting something into a register.  INPLACE is true if any changes
+   can be made directly to MEMREF or false if MEMREF must be treated as
+   immutable.  */
 
 rtx
-replace_equiv_address (rtx memref, rtx addr)
+replace_equiv_address (rtx memref, rtx addr, bool inplace)
 {
   /* change_address_1 copies the memory attribute structure without change
      and that's exactly what we want here.  */
   update_temp_slot_address (XEXP (memref, 0), addr);
-  return change_address_1 (memref, VOIDmode, addr, 1);
+  return change_address_1 (memref, VOIDmode, addr, 1, inplace);
 }
 
 /* Likewise, but the reference is not required to be valid.  */
 
 rtx
-replace_equiv_address_nv (rtx memref, rtx addr)
+replace_equiv_address_nv (rtx memref, rtx addr, bool inplace)
 {
-  return change_address_1 (memref, VOIDmode, addr, 0);
+  return change_address_1 (memref, VOIDmode, addr, 0, inplace);
 }
 
 /* Return a memory reference like MEMREF, but with its mode widened to
index fe68de9475655e605ad9cf98ac48346f62537e1d..c72c24f4d88f66fce4fe13b89fb2c51c81a88d70 100644 (file)
@@ -52,10 +52,10 @@ extern tree get_spill_slot_decl (bool);
    ADDR.  The caller is asserting that the actual piece of memory pointed
    to is the same, just the form of the address is being changed, such as
    by putting something into a register.  */
-extern rtx replace_equiv_address (rtx, rtx);
+extern rtx replace_equiv_address (rtx, rtx, bool = false);
 
 /* Likewise, but the reference is not required to be valid.  */
-extern rtx replace_equiv_address_nv (rtx, rtx);
+extern rtx replace_equiv_address_nv (rtx, rtx, bool = false);
 
 extern rtx gen_blockage (void);
 extern rtvec gen_rtvec (int, ...);
index bc97c964e6136ab4bd5e17c9894aba36f2ec4454..e39db0507db9a8ebd7f7799afc7ae3693360768c 100644 (file)
@@ -74,10 +74,12 @@ trunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode)
 }
 
 /* Return an rtx for the sum of X and the integer C, given that X has
-   mode MODE.  */
+   mode MODE.  INPLACE is true if X can be modified inplace or false
+   if it must be treated as immutable.  */
 
 rtx
-plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c)
+plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c,
+              bool inplace)
 {
   RTX_CODE code;
   rtx y;
@@ -116,6 +118,8 @@ plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c)
     case CONST:
       /* If adding to something entirely constant, set a flag
         so that we can add a CONST around the result.  */
+      if (inplace && shared_const_p (x))
+       inplace = false;
       x = XEXP (x, 0);
       all_constant = 1;
       goto restart;
@@ -136,19 +140,25 @@ plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c)
 
       if (CONSTANT_P (XEXP (x, 1)))
        {
-         x = gen_rtx_PLUS (mode, XEXP (x, 0),
-                           plus_constant (mode, XEXP (x, 1), c));
+         rtx term = plus_constant (mode, XEXP (x, 1), c, inplace);
+         if (term == const0_rtx)
+           x = XEXP (x, 0);
+         else if (inplace)
+           XEXP (x, 1) = term;
+         else
+           x = gen_rtx_PLUS (mode, XEXP (x, 0), term);
          c = 0;
        }
-      else if (find_constant_term_loc (&y))
+      else if (rtx *const_loc = find_constant_term_loc (&y))
        {
-         /* We need to be careful since X may be shared and we can't
-            modify it in place.  */
-         rtx copy = copy_rtx (x);
-         rtx *const_loc = find_constant_term_loc (&copy);
-
-         *const_loc = plus_constant (mode, *const_loc, c);
-         x = copy;
+         if (!inplace)
+           {
+             /* We need to be careful since X may be shared and we can't
+                modify it in place.  */
+             x = copy_rtx (x);
+             const_loc = find_constant_term_loc (&x);
+           }
+         *const_loc = plus_constant (mode, *const_loc, c, true);
          c = 0;
        }
       break;
index 9be76a9ce15832572b799b3985f1840a9aa53624..d269c5434e25e37dc8c842af4943be8d77d03450 100644 (file)
@@ -1459,8 +1459,8 @@ instantiate_virtual_regs_in_rtx (rtx *loc, void *data)
       new_rtx = instantiate_new_reg (XEXP (x, 0), &offset);
       if (new_rtx)
        {
-         new_rtx = plus_constant (GET_MODE (x), new_rtx, offset);
-         *loc = simplify_gen_binary (PLUS, GET_MODE (x), new_rtx, XEXP (x, 1));
+         XEXP (x, 0) = new_rtx;
+         *loc = plus_constant (GET_MODE (x), x, offset, true);
          if (changed)
            *changed = true;
          return -1;
@@ -1622,7 +1622,7 @@ instantiate_virtual_regs_in_insn (rtx insn)
              continue;
 
            start_sequence ();
-           x = replace_equiv_address (x, addr);
+           x = replace_equiv_address (x, addr, true);
            /* It may happen that the address with the virtual reg
               was valid (e.g. based on the virtual stack reg, which might
               be acceptable to the predicates with all offsets), whereas
@@ -1635,7 +1635,7 @@ instantiate_virtual_regs_in_insn (rtx insn)
            if (!safe_insn_predicate (insn_code, i, x))
              {
                addr = force_reg (GET_MODE (addr), addr);
-               x = replace_equiv_address (x, addr);
+               x = replace_equiv_address (x, addr, true);
              }
            seq = get_insns ();
            end_sequence ();
index aad1853c036fce3e50ef48597770210dc1b19eee..8bead6c763049fe6f1ba6e204766747f652aeafb 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1952,7 +1952,7 @@ extern int currently_expanding_to_rtl;
 
 /* In explow.c */
 extern HOST_WIDE_INT trunc_int_for_mode        (HOST_WIDE_INT, enum machine_mode);
-extern rtx plus_constant (enum machine_mode, rtx, HOST_WIDE_INT);
+extern rtx plus_constant (enum machine_mode, rtx, HOST_WIDE_INT, bool = false);
 
 /* In rtl.c */
 extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);