gcc/
        * combine-stack-adj.c: Include rtl-iter.h.
        (record_stack_refs_data): Delete.
        (record_stack_refs): Turn from being a for_each_rtx callback
        to being a function that examines each subrtx itself.
        Take a pointer to the reflist.  Invert sense of return value
        so that true means success and false means failure.  Don't
        handle null rtxes.
        (combine_stack_adjustments_for_block): Update accordingly.

Index: gcc/combine-stack-adj.c
===================================================================
--- gcc/combine-stack-adj.c     2014-08-03 11:25:10.425959254 +0100
+++ gcc/combine-stack-adj.c     2014-08-03 11:25:22.308076727 +0100
@@ -56,6 +56,7 @@ Software Foundation; either version 3, o
 #include "except.h"
 #include "reload.h"
 #include "tree-pass.h"
+#include "rtl-iter.h"
 
 
 /* Turn STACK_GROWS_DOWNWARD into a boolean.  */
@@ -85,7 +86,6 @@ static struct csa_reflist *record_one_st
 static int try_apply_stack_adjustment (rtx, struct csa_reflist *,
                                       HOST_WIDE_INT, HOST_WIDE_INT);
 static void combine_stack_adjustments_for_block (basic_block);
-static int record_stack_refs (rtx *, void *);
 
 
 /* Main entry point for stack adjustment combination.  */
@@ -236,61 +236,63 @@ try_apply_stack_adjustment (rtx insn, st
     return 0;
 }
 
-/* Called via for_each_rtx and used to record all stack memory and other
-   references in the insn and discard all other stack pointer references.  */
-struct record_stack_refs_data
-{
-  rtx insn;
-  struct csa_reflist *reflist;
-};
-
-static int
-record_stack_refs (rtx *xp, void *data)
-{
-  rtx x = *xp;
-  struct record_stack_refs_data *d =
-    (struct record_stack_refs_data *) data;
-  if (!x)
-    return 0;
-  switch (GET_CODE (x))
-    {
-    case MEM:
-      if (!reg_mentioned_p (stack_pointer_rtx, x))
-       return -1;
-      /* We are not able to handle correctly all possible memrefs containing
-         stack pointer, so this check is necessary.  */
-      if (stack_memref_p (x))
-       {
-         d->reflist = record_one_stack_ref (d->insn, xp, d->reflist);
-         return -1;
-       }
-      /* Try harder for DEBUG_INSNs, handle e.g. (mem (mem (sp + 16) + 4).  */
-      return !DEBUG_INSN_P (d->insn);
-    case REG:
-      /* ??? We want be able to handle non-memory stack pointer
-        references later.  For now just discard all insns referring to
-        stack pointer outside mem expressions.  We would probably
-        want to teach validate_replace to simplify expressions first.
-
-        We can't just compare with STACK_POINTER_RTX because the
-        reference to the stack pointer might be in some other mode.
-        In particular, an explicit clobber in an asm statement will
-        result in a QImode clobber.
-
-        In DEBUG_INSNs, we want to replace all occurrences, otherwise
-        they will cause -fcompare-debug failures.  */
-      if (REGNO (x) == STACK_POINTER_REGNUM)
+/* For non-debug insns, record all stack memory references in INSN
+   and return true if there were no other (unrecorded) references to the
+   stack pointer.  For debug insns, record all stack references regardless
+   of context and unconditionally return true.  */
+
+static bool
+record_stack_refs (rtx insn, struct csa_reflist **reflist)
+{
+  subrtx_ptr_iterator::array_type array;
+  FOR_EACH_SUBRTX_PTR (iter, array, &PATTERN (insn), NONCONST)
+    {
+      rtx *loc = *iter;
+      rtx x = *loc;
+      switch (GET_CODE (x))
        {
-         if (!DEBUG_INSN_P (d->insn))
-           return 1;
-         d->reflist = record_one_stack_ref (d->insn, xp, d->reflist);
-         return -1;
+       case MEM:
+         if (!reg_mentioned_p (stack_pointer_rtx, x))
+           iter.skip_subrtxes ();
+         /* We are not able to handle correctly all possible memrefs
+            containing stack pointer, so this check is necessary.  */
+         else if (stack_memref_p (x))
+           {
+             *reflist = record_one_stack_ref (insn, loc, *reflist);
+             iter.skip_subrtxes ();
+           }
+         /* Try harder for DEBUG_INSNs, handle e.g.
+            (mem (mem (sp + 16) + 4).  */
+         else if (!DEBUG_INSN_P (insn))
+           return false;
+         break;
+
+       case REG:
+         /* ??? We want be able to handle non-memory stack pointer
+            references later.  For now just discard all insns referring to
+            stack pointer outside mem expressions.  We would probably
+            want to teach validate_replace to simplify expressions first.
+
+            We can't just compare with STACK_POINTER_RTX because the
+            reference to the stack pointer might be in some other mode.
+            In particular, an explicit clobber in an asm statement will
+            result in a QImode clobber.
+
+            In DEBUG_INSNs, we want to replace all occurrences, otherwise
+            they will cause -fcompare-debug failures.  */
+         if (REGNO (x) == STACK_POINTER_REGNUM)
+           {
+             if (!DEBUG_INSN_P (insn))
+               return false;
+             *reflist = record_one_stack_ref (insn, loc, *reflist);
+           }
+         break;
+
+       default:
+         break;
        }
-      break;
-    default:
-      break;
     }
-  return 0;
+  return true;
 }
 
 /* If INSN has a REG_ARGS_SIZE note, move it to LAST.
@@ -429,7 +431,6 @@ combine_stack_adjustments_for_block (bas
   rtx last2_sp_set = NULL_RTX;
   struct csa_reflist *reflist = NULL;
   rtx insn, next, set;
-  struct record_stack_refs_data data;
   bool end_of_block = false;
 
   for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
@@ -580,15 +581,9 @@ combine_stack_adjustments_for_block (bas
            }
        }
 
-      data.insn = insn;
-      data.reflist = reflist;
       if (!CALL_P (insn) && last_sp_set
-         && !for_each_rtx (&PATTERN (insn), record_stack_refs, &data))
-       {
-          reflist = data.reflist;
-          continue;
-       }
-      reflist = data.reflist;
+         && record_stack_refs (insn, &reflist))
+       continue;
 
       /* Otherwise, we were not able to process the instruction.
         Do not continue collecting data across such a one.  */

Reply via email to