On Thu, Apr 11, 2019 at 09:54:24AM +0200, Richard Biener wrote:
> > The following patch just punts if we find loads from stack slots in between
> > where they are pushed and the const/pure call.  In addition to that, I've
> > outlined the same largish sequence that had 3 copies in the function already
> > and I'd need to add 4th copy, so in the end the dce.c changes are removing
> > more than adding:
> >  1 file changed, 118 insertions(+), 135 deletions(-)
> 
> The refactoring itself is probably OK (and if done separately
> makes reviewing easier).

Here is just the refactoring, ok for trunk?

2019-04-11  Jakub Jelinek  <ja...@redhat.com>
        
        PR rtl-optimization/89965
        * dce.c (sp_based_mem_offset): New function.
        (find_call_stack_args): Use sp_based_mem_offset.

--- gcc/dce.c.jj        2019-04-11 10:26:18.509365653 +0200
+++ gcc/dce.c   2019-04-11 10:30:00.436705065 +0200
@@ -272,6 +272,58 @@ check_argument_store (HOST_WIDE_INT size
   return true;
 }
 
+/* If MEM has sp address, return 0, if it has sp + const address,
+   return that const, if it has reg address where reg is set to sp + const
+   and FAST is false, return const, otherwise return
+   INTTYPE_MINUMUM (HOST_WIDE_INT).  */
+
+static HOST_WIDE_INT
+sp_based_mem_offset (rtx_call_insn *call_insn, const_rtx mem, bool fast)
+{
+  HOST_WIDE_INT off = 0;
+  rtx addr = XEXP (mem, 0);
+  if (GET_CODE (addr) == PLUS
+      && REG_P (XEXP (addr, 0))
+      && CONST_INT_P (XEXP (addr, 1)))
+    {
+      off = INTVAL (XEXP (addr, 1));
+      addr = XEXP (addr, 0);
+    }
+  if (addr == stack_pointer_rtx)
+    return off;
+
+  if (!REG_P (addr) || fast)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  /* If not fast, use chains to see if addr wasn't set to sp + offset.  */
+  df_ref use;
+  FOR_EACH_INSN_USE (use, call_insn)
+  if (rtx_equal_p (addr, DF_REF_REG (use)))
+    break;
+
+  if (use == NULL)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  struct df_link *defs;
+  for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
+    if (! DF_REF_IS_ARTIFICIAL (defs->ref))
+      break;
+
+  if (defs == NULL)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  rtx set = single_set (DF_REF_INSN (defs->ref));
+  if (!set)
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  if (GET_CODE (SET_SRC (set)) != PLUS
+      || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
+      || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
+    return INTTYPE_MINIMUM (HOST_WIDE_INT);
+
+  off += INTVAL (XEXP (SET_SRC (set), 1));
+  return off;
+}
 
 /* Try to find all stack stores of CALL_INSN arguments if
    ACCUMULATE_OUTGOING_ARGS.  If all stack stores have been found
@@ -309,58 +361,13 @@ find_call_stack_args (rtx_call_insn *cal
     if (GET_CODE (XEXP (p, 0)) == USE
        && MEM_P (XEXP (XEXP (p, 0), 0)))
       {
-       rtx mem = XEXP (XEXP (p, 0), 0), addr;
-       HOST_WIDE_INT off = 0, size;
+       rtx mem = XEXP (XEXP (p, 0), 0);
+       HOST_WIDE_INT size;
        if (!MEM_SIZE_KNOWN_P (mem) || !MEM_SIZE (mem).is_constant (&size))
          return false;
-       addr = XEXP (mem, 0);
-       if (GET_CODE (addr) == PLUS
-           && REG_P (XEXP (addr, 0))
-           && CONST_INT_P (XEXP (addr, 1)))
-         {
-           off = INTVAL (XEXP (addr, 1));
-           addr = XEXP (addr, 0);
-         }
-       if (addr != stack_pointer_rtx)
-         {
-           if (!REG_P (addr))
-             return false;
-           /* If not fast, use chains to see if addr wasn't set to
-              sp + offset.  */
-           if (!fast)
-             {
-               df_ref use;
-               struct df_link *defs;
-               rtx set;
-
-               FOR_EACH_INSN_USE (use, call_insn)
-                 if (rtx_equal_p (addr, DF_REF_REG (use)))
-                   break;
-
-               if (use == NULL)
-                 return false;
-
-               for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
-                 if (! DF_REF_IS_ARTIFICIAL (defs->ref))
-                   break;
-
-               if (defs == NULL)
-                 return false;
-
-               set = single_set (DF_REF_INSN (defs->ref));
-               if (!set)
-                 return false;
-
-               if (GET_CODE (SET_SRC (set)) != PLUS
-                   || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
-                   || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
-                 return false;
-
-               off += INTVAL (XEXP (SET_SRC (set), 1));
-             }
-           else
-             return false;
-         }
+       HOST_WIDE_INT off = sp_based_mem_offset (call_insn, mem, fast);
+       if (off == INTTYPE_MINIMUM (HOST_WIDE_INT))
+         return false;
        min_sp_off = MIN (min_sp_off, off);
        max_sp_off = MAX (max_sp_off, off + size);
       }
@@ -376,51 +383,19 @@ find_call_stack_args (rtx_call_insn *cal
     if (GET_CODE (XEXP (p, 0)) == USE
        && MEM_P (XEXP (XEXP (p, 0), 0)))
       {
-       rtx mem = XEXP (XEXP (p, 0), 0), addr;
-       HOST_WIDE_INT off = 0, byte, size;
+       rtx mem = XEXP (XEXP (p, 0), 0);
        /* Checked in the previous iteration.  */
-       size = MEM_SIZE (mem).to_constant ();
-       addr = XEXP (mem, 0);
-       if (GET_CODE (addr) == PLUS
-           && REG_P (XEXP (addr, 0))
-           && CONST_INT_P (XEXP (addr, 1)))
-         {
-           off = INTVAL (XEXP (addr, 1));
-           addr = XEXP (addr, 0);
-         }
-       if (addr != stack_pointer_rtx)
-         {
-           df_ref use;
-           struct df_link *defs;
-           rtx set;
-
-           FOR_EACH_INSN_USE (use, call_insn)
-             if (rtx_equal_p (addr, DF_REF_REG (use)))
-               break;
-
-           for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
-             if (! DF_REF_IS_ARTIFICIAL (defs->ref))
-               break;
-
-           set = single_set (DF_REF_INSN (defs->ref));
-           off += INTVAL (XEXP (SET_SRC (set), 1));
-         }
-       for (byte = off; byte < off + size; byte++)
-         {
-           if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
-             gcc_unreachable ();
-         }
+       HOST_WIDE_INT size = MEM_SIZE (mem).to_constant ();
+       HOST_WIDE_INT off = sp_based_mem_offset (call_insn, mem, fast);
+       gcc_checking_assert (off != INTTYPE_MINIMUM (HOST_WIDE_INT));
+       for (HOST_WIDE_INT byte = off; byte < off + size; byte++)
+         if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
+           gcc_unreachable ();
       }
 
-  /* Walk backwards, looking for argument stores.  The search stops
-     when seeing another call, sp adjustment or memory store other than
-     argument store.  */
   ret = false;
   for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
     {
-      rtx set, mem, addr;
-      HOST_WIDE_INT off;
-
       if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn)))
        prev_insn = NULL;
       else
@@ -432,61 +407,17 @@ find_call_stack_args (rtx_call_insn *cal
       if (!NONDEBUG_INSN_P (insn))
        continue;
 
-      set = single_set (insn);
+      rtx set = single_set (insn);
       if (!set || SET_DEST (set) == stack_pointer_rtx)
        break;
 
       if (!MEM_P (SET_DEST (set)))
        continue;
 
-      mem = SET_DEST (set);
-      addr = XEXP (mem, 0);
-      off = 0;
-      if (GET_CODE (addr) == PLUS
-         && REG_P (XEXP (addr, 0))
-         && CONST_INT_P (XEXP (addr, 1)))
-       {
-         off = INTVAL (XEXP (addr, 1));
-         addr = XEXP (addr, 0);
-       }
-      if (addr != stack_pointer_rtx)
-       {
-         if (!REG_P (addr))
-           break;
-         if (!fast)
-           {
-             df_ref use;
-             struct df_link *defs;
-             rtx set;
-
-             FOR_EACH_INSN_USE (use, insn)
-               if (rtx_equal_p (addr, DF_REF_REG (use)))
-                 break;
-
-             if (use == NULL)
-               break;
-
-             for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
-               if (! DF_REF_IS_ARTIFICIAL (defs->ref))
-                 break;
-
-             if (defs == NULL)
-               break;
-
-             set = single_set (DF_REF_INSN (defs->ref));
-             if (!set)
-               break;
-
-             if (GET_CODE (SET_SRC (set)) != PLUS
-                 || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
-                 || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
-               break;
-
-             off += INTVAL (XEXP (SET_SRC (set), 1));
-           }
-         else
-           break;
-       }
+      rtx mem = SET_DEST (set);
+      HOST_WIDE_INT off = sp_based_mem_offset (call_insn, mem, fast);
+      if (off == INTTYPE_MINIMUM (HOST_WIDE_INT))
+       break;
 
       HOST_WIDE_INT size;
       if (!MEM_SIZE_KNOWN_P (mem)


        Jakub

Reply via email to