On Fri, Dec 02, 2016 at 12:34:13AM +0100, Jakub Jelinek wrote:
> On Thu, Dec 01, 2016 at 11:48:03PM +0100, Bernd Schmidt wrote:
> > On 12/01/2016 11:43 PM, Jakub Jelinek wrote:
> > >
> > >so we'd need to slow shallow_copy_rtx down by adding switch (code)
> > >in there or something similar.
> > 
> > Is there reason to assume it's time-critical? IMO eliminating the potential
> > for error by not having callers need to do this outweighs that concern.
> 
> Well, it isn't an error not to clear it, just missed optimization if some 
> caller
> cares, and most of the shallow_copy_rtx users really don't care, e.g.
> config/i386/i386.md and config/i386/i386.c callers.  cfgexpand.c doesn't
> either, at that point the used bit isn't set, the calls in cselib.c don't care
> either.  In emit-rtl.c one place explicitly sets used flag afterwards, another
> clears it (that one could be removed if the logic is moved down).  The 
> rs6000.c
> use indeed could get rid of the explicit used bit clearing.  Most of the
> other shallow_copy_rtx callers in the middle-end just don't care.
> I think it is really just simplify_replace_fn_rtx where (at least in the
> rs6000 case) it is useful to clear it, similar trick is not used in many
> places after initial unsharing during expansion before which the bit should
> be clear on everything shareable, I saw it in ifcvt.c (set_used_flags
> + some copying + unshare_*_chain afterwards).
> After expansion when everything is unshared, gradually the used bits are no
> longer relevant, they are set on stuff that has been originally unshared and
> clear on newly added rtxes.  Then the reload/postreload
> unshare_all_rtx_again clears it and unshares the shared stuff.
> So it is really just about spots that do the trick of set_used_flags,
> call some functions where clearing of used bit on new stuff is important,
> and finally call copy_rtx_if_shared.

Anyway, here is a patch that changes shallow_copy_rtx,
bootstrapped/regtested on x86_64-linux and i686-linux.  I believe only the
callers in the patch of the function actually care about used being 0 though
(including the simplify-rtx.c hunks).

2016-11-30  Jakub Jelinek  <ja...@redhat.com>

        PR target/78614
        * rtl.c (copy_rtx): Don't clear used flag here.
        (shallow_copy_rtx_stat): Clear used flag here unless code the rtx
        is shareable.
        * simplify-rtx.c (simplify_replace_fn_rtx): When copying rtx with
        'E' in format, copy all vectors.
        * emit-rtl.c (copy_insn_1): Don't clear used flag here.
        * valtrack.c (cleanup_auto_inc_dec): Likewise.
        * config/rs6000/rs6000.c (rs6000_frame_related): Likewise.

--- gcc/rtl.c.jj        2016-10-31 13:28:12.000000000 +0100
+++ gcc/rtl.c   2016-12-02 11:01:12.557553040 +0100
@@ -318,10 +318,6 @@ copy_rtx (rtx orig)
      us to explicitly document why we are *not* copying a flag.  */
   copy = shallow_copy_rtx (orig);
 
-  /* We do not copy the USED flag, which is used as a mark bit during
-     walks over the RTL.  */
-  RTX_FLAG (copy, used) = 0;
-
   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
 
   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
@@ -367,7 +363,29 @@ shallow_copy_rtx_stat (const_rtx orig ME
 {
   const unsigned int size = rtx_size (orig);
   rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT);
-  return (rtx) memcpy (copy, orig, size);
+  memcpy (copy, orig, size);
+  switch (GET_CODE (orig))
+    {
+      /* RTX codes copy_rtx_if_shared_1 considers are shareable,
+        the used flag is often used for other purposes.  */
+    case REG:
+    case DEBUG_EXPR:
+    case VALUE:
+    CASE_CONST_ANY:
+    case SYMBOL_REF:
+    case CODE_LABEL:
+    case PC:
+    case CC0:
+    case RETURN:
+    case SIMPLE_RETURN:
+    case SCRATCH:
+      break;
+    default:
+      /* For all other RTXes clear the used flag on the copy.  */
+      RTX_FLAG (copy, used) = 0;
+      break;
+    }
+  return copy;
 }
 
 /* Nonzero when we are generating CONCATs.  */
--- gcc/simplify-rtx.c.jj       2016-12-02 00:15:09.200779256 +0100
+++ gcc/simplify-rtx.c  2016-12-02 10:55:24.283989673 +0100
@@ -547,13 +547,19 @@ simplify_replace_fn_rtx (rtx x, const_rt
                                          old_rtx, fn, data);
            if (op != RTVEC_ELT (vec, j))
              {
-               if (newvec == vec)
+               if (x == newx)
                  {
-                   newvec = shallow_copy_rtvec (vec);
-                   if (x == newx)
-                     newx = shallow_copy_rtx (x);
-                   XVEC (newx, i) = newvec;
+                   newx = shallow_copy_rtx (x);
+                   /* If we copy X, we need to copy also all
+                      vectors in it, rather than copy only
+                      a subset of them and share the rest.  */
+                   for (int k = 0; fmt[k]; k++)
+                     if (fmt[k] == 'E')
+                       XVEC (newx, k) = shallow_copy_rtvec (XVEC (x, k));
+                   newvec = XVEC (newx, i);
                  }
+               else
+                 gcc_checking_assert (vec != newvec);
                RTVEC_ELT (newvec, j) = op;
              }
          }
@@ -566,7 +572,15 @@ simplify_replace_fn_rtx (rtx x, const_rt
            if (op != XEXP (x, i))
              {
                if (x == newx)
-                 newx = shallow_copy_rtx (x);
+                 {
+                   newx = shallow_copy_rtx (x);
+                   /* If we copy X, we need to copy also all
+                      vectors in it, rather than copy only
+                      a subset of them and share the rest.  */
+                   for (int k = 0; fmt[k]; k++)
+                     if (fmt[k] == 'E')
+                       XVEC (newx, k) = shallow_copy_rtvec (XVEC (x, k));
+                 }
                XEXP (newx, i) = op;
              }
          }
--- gcc/emit-rtl.c.jj   2016-12-02 09:43:19.000000000 +0100
+++ gcc/emit-rtl.c      2016-12-02 10:56:37.001061044 +0100
@@ -5552,10 +5552,6 @@ copy_insn_1 (rtx orig)
      us to explicitly document why we are *not* copying a flag.  */
   copy = shallow_copy_rtx (orig);
 
-  /* We do not copy the USED flag, which is used as a mark bit during
-     walks over the RTL.  */
-  RTX_FLAG (copy, used) = 0;
-
   /* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs.  */
   if (INSN_P (orig))
     {
--- gcc/valtrack.c.jj   2016-10-31 13:28:06.000000000 +0100
+++ gcc/valtrack.c      2016-12-02 11:01:44.690144705 +0100
@@ -119,10 +119,6 @@ cleanup_auto_inc_dec (rtx src, machine_m
      us to explicitly document why we are *not* copying a flag.  */
   x = shallow_copy_rtx (x);
 
-  /* We do not copy the USED flag, which is used as a mark bit during
-     walks over the RTL.  */
-  RTX_FLAG (x, used) = 0;
-
   /* We do not copy FRAME_RELATED for INSNs.  */
   if (INSN_P (x))
     RTX_FLAG (x, frame_related) = 0;
--- gcc/config/rs6000/rs6000.c.jj       2016-12-01 08:56:27.137105707 +0100
+++ gcc/config/rs6000/rs6000.c  2016-12-02 11:02:14.796762115 +0100
@@ -27186,7 +27186,6 @@ rs6000_frame_related (rtx_insn *insn, rt
     {
       pat = shallow_copy_rtx (pat);
       XVEC (pat, 0) = shallow_copy_rtvec (XVEC (pat, 0));
-      RTX_FLAG (pat, used) = 0;
 
       for (int i = 0; i < XVECLEN (pat, 0); i++)
        if (GET_CODE (XVECEXP (pat, 0, i)) == SET)


        Jakub

Reply via email to