]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR bootstrap/41241 (bootstrap comparison failure)
authorJakub Jelinek <jakub@redhat.com>
Sun, 6 Sep 2009 19:31:55 +0000 (21:31 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sun, 6 Sep 2009 19:31:55 +0000 (21:31 +0200)
PR bootstrap/41241
* combine-stack-adj.c (struct csa_memlist): Rename to...
(struct csa_reflist): ... this.  Rename mem field to ref.
(free_csa_memlist): Rename to...
(free_csa_reflist): ... this.
(record_one_stack_memref): Rename to...
(record_one_stack_ref): ... this.  Handle also REG_P.
(try_apply_stack_adjustment): Handle also REG_P.
(struct record_stack_memrefs_data): Rename to...
(struct record_stack_refs_data): ... this.  Rename memlist field to
reflist.
(record_stack_memrefs): Rename to...
(record_stack_refs): ... this.  For DEBUG_INSNs keep traversing
subexpressions instead of failing when a MEM contains SP references.
For SP itself in DEBUG_INSNs queue it also onto reflist chain.
(combine_stack_adjustments_for_block): Adjust for mem to ref renaming.

* gcc.dg/pr41241.c: New test.

From-SVN: r151462

gcc/ChangeLog
gcc/combine-stack-adj.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr41241.c [new file with mode: 0644]

index 76d93f60fd729b441dfb7bf83ea765aba0e14551..9824c28fc89abd2c83190e4518e35a39d3455db3 100644 (file)
@@ -1,3 +1,22 @@
+2009-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR bootstrap/41241
+       * combine-stack-adj.c (struct csa_memlist): Rename to...
+       (struct csa_reflist): ... this.  Rename mem field to ref.
+       (free_csa_memlist): Rename to...
+       (free_csa_reflist): ... this.
+       (record_one_stack_memref): Rename to...
+       (record_one_stack_ref): ... this.  Handle also REG_P.
+       (try_apply_stack_adjustment): Handle also REG_P.
+       (struct record_stack_memrefs_data): Rename to...
+       (struct record_stack_refs_data): ... this.  Rename memlist field to
+       reflist.
+       (record_stack_memrefs): Rename to...
+       (record_stack_refs): ... this.  For DEBUG_INSNs keep traversing
+       subexpressions instead of failing when a MEM contains SP references.
+       For SP itself in DEBUG_INSNs queue it also onto reflist chain.
+       (combine_stack_adjustments_for_block): Adjust for mem to ref renaming.
+
 2009-09-06  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/41144
index 1f1759e104921f727e7c00fbc45b73dce075934b..babd6d27e93238ed401d862fafaf00c76277756c 100644 (file)
@@ -71,25 +71,26 @@ along with GCC; see the file COPYING3.  If not see
 #define STACK_GROWS_DOWNWARD 0
 #endif
 
-/* This structure records stack memory references between stack adjusting
-   instructions.  */
+/* This structure records two kinds of stack references between stack
+   adjusting instructions: stack references in memory addresses for
+   regular insns and all stack references for debug insns.  */
 
-struct csa_memlist
+struct csa_reflist
 {
   HOST_WIDE_INT sp_offset;
-  rtx insn, *mem;
-  struct csa_memlist *next;
+  rtx insn, *ref;
+  struct csa_reflist *next;
 };
 
 static int stack_memref_p (rtx);
 static rtx single_set_for_csa (rtx);
-static void free_csa_memlist (struct csa_memlist *);
-static struct csa_memlist *record_one_stack_memref (rtx, rtx *,
-                                                   struct csa_memlist *);
-static int try_apply_stack_adjustment (rtx, struct csa_memlist *,
+static void free_csa_reflist (struct csa_reflist *);
+static struct csa_reflist *record_one_stack_ref (rtx, rtx *,
+                                                struct csa_reflist *);
+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_memrefs (rtx *, void *);
+static int record_stack_refs (rtx *, void *);
 
 
 /* Main entry point for stack adjustment combination.  */
@@ -157,65 +158,75 @@ single_set_for_csa (rtx insn)
   return XVECEXP (tmp, 0, 0);
 }
 
-/* Free the list of csa_memlist nodes.  */
+/* Free the list of csa_reflist nodes.  */
 
 static void
-free_csa_memlist (struct csa_memlist *memlist)
+free_csa_reflist (struct csa_reflist *reflist)
 {
-  struct csa_memlist *next;
-  for (; memlist ; memlist = next)
+  struct csa_reflist *next;
+  for (; reflist ; reflist = next)
     {
-      next = memlist->next;
-      free (memlist);
+      next = reflist->next;
+      free (reflist);
     }
 }
 
-/* Create a new csa_memlist node from the given memory reference.
-   It is already known that the memory is stack_memref_p.  */
+/* Create a new csa_reflist node from the given stack reference.
+   It is already known that the reference is either a MEM satisfying the
+   predicate stack_memref_p or a REG representing the stack pointer.  */
 
-static struct csa_memlist *
-record_one_stack_memref (rtx insn, rtx *mem, struct csa_memlist *next_memlist)
+static struct csa_reflist *
+record_one_stack_ref (rtx insn, rtx *ref, struct csa_reflist *next_reflist)
 {
-  struct csa_memlist *ml;
+  struct csa_reflist *ml;
 
-  ml = XNEW (struct csa_memlist);
+  ml = XNEW (struct csa_reflist);
 
-  if (XEXP (*mem, 0) == stack_pointer_rtx)
+  if (REG_P (*ref) || XEXP (*ref, 0) == stack_pointer_rtx)
     ml->sp_offset = 0;
   else
-    ml->sp_offset = INTVAL (XEXP (XEXP (*mem, 0), 1));
+    ml->sp_offset = INTVAL (XEXP (XEXP (*ref, 0), 1));
 
   ml->insn = insn;
-  ml->mem = mem;
-  ml->next = next_memlist;
+  ml->ref = ref;
+  ml->next = next_reflist;
 
   return ml;
 }
 
 /* Attempt to apply ADJUST to the stack adjusting insn INSN, as well
-   as each of the memories in MEMLIST.  Return true on success.  */
+   as each of the memories and stack references in REFLIST.  Return true
+   on success.  */
 
 static int
-try_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT new_adjust,
-                           HOST_WIDE_INT delta)
+try_apply_stack_adjustment (rtx insn, struct csa_reflist *reflist,
+                           HOST_WIDE_INT new_adjust, HOST_WIDE_INT delta)
 {
-  struct csa_memlist *ml;
+  struct csa_reflist *ml;
   rtx set;
 
   set = single_set_for_csa (insn);
   validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
 
-  for (ml = memlist; ml ; ml = ml->next)
-    validate_change
-      (ml->insn, ml->mem,
-       replace_equiv_address_nv (*ml->mem,
-                                plus_constant (stack_pointer_rtx,
-                                               ml->sp_offset - delta)), 1);
+  for (ml = reflist; ml ; ml = ml->next)
+    {
+      rtx new_addr = plus_constant (stack_pointer_rtx, ml->sp_offset - delta);
+      rtx new_val;
+
+      if (MEM_P (*ml->ref))
+       new_val = replace_equiv_address_nv (*ml->ref, new_addr);
+      else if (GET_MODE (*ml->ref) == GET_MODE (stack_pointer_rtx))
+       new_val = new_addr;
+      else
+       new_val = lowpart_subreg (GET_MODE (*ml->ref), new_addr,
+                                 GET_MODE (new_addr));
+      validate_change (ml->insn, ml->ref, new_val, 1);
+    }
 
   if (apply_change_group ())
     {
-      /* Succeeded.  Update our knowledge of the memory references.  */
-      for (ml = memlist; ml ; ml = ml->next)
+      /* Succeeded.  Update our knowledge of the stack references.  */
+      for (ml = reflist; ml ; ml = ml->next)
        ml->sp_offset -= delta;
 
       return 1;
@@ -224,20 +235,20 @@ try_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT
     return 0;
 }
 
-/* Called via for_each_rtx and used to record all stack memory references in
-   the insn and discard all other stack pointer references.  */
-struct record_stack_memrefs_data
+/* 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_memlist *memlist;
+  struct csa_reflist *reflist;
 };
 
 static int
-record_stack_memrefs (rtx *xp, void *data)
+record_stack_refs (rtx *xp, void *data)
 {
   rtx x = *xp;
-  struct record_stack_memrefs_data *d =
-    (struct record_stack_memrefs_data *) data;
+  struct record_stack_refs_data *d =
+    (struct record_stack_refs_data *) data;
   if (!x)
     return 0;
   switch (GET_CODE (x))
@@ -249,10 +260,11 @@ record_stack_memrefs (rtx *xp, void *data)
          stack pointer, so this check is necessary.  */
       if (stack_memref_p (x))
        {
-         d->memlist = record_one_stack_memref (d->insn, xp, d->memlist);
+         d->reflist = record_one_stack_ref (d->insn, xp, d->reflist);
          return -1;
        }
-      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
@@ -262,9 +274,17 @@ record_stack_memrefs (rtx *xp, void *data)
         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.  */
+        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)
-       return 1;
+       {
+         if (!DEBUG_INSN_P (d->insn))
+           return 1;
+         d->reflist = record_one_stack_ref (d->insn, xp, d->reflist);
+         return -1;
+       }
       break;
     default:
       break;
@@ -343,9 +363,9 @@ combine_stack_adjustments_for_block (basic_block bb)
 {
   HOST_WIDE_INT last_sp_adjust = 0;
   rtx last_sp_set = NULL_RTX;
-  struct csa_memlist *memlist = NULL;
+  struct csa_reflist *reflist = NULL;
   rtx insn, next, set;
-  struct record_stack_memrefs_data data;
+  struct record_stack_refs_data data;
   bool end_of_block = false;
 
   for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
@@ -379,7 +399,7 @@ combine_stack_adjustments_for_block (basic_block bb)
                  continue;
                }
 
-             /* If not all recorded memrefs can be adjusted, or the
+             /* If not all recorded refs can be adjusted, or the
                 adjustment is now too large for a constant addition,
                 we cannot merge the two stack adjustments.
 
@@ -403,7 +423,7 @@ combine_stack_adjustments_for_block (basic_block bb)
              /* Combine an allocation into the first instruction.  */
              if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0)
                {
-                 if (try_apply_stack_adjustment (last_sp_set, memlist,
+                 if (try_apply_stack_adjustment (last_sp_set, reflist,
                                                  last_sp_adjust + this_adjust,
                                                  this_adjust))
                    {
@@ -422,7 +442,7 @@ combine_stack_adjustments_for_block (basic_block bb)
              else if (STACK_GROWS_DOWNWARD
                       ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
                {
-                 if (try_apply_stack_adjustment (insn, memlist,
+                 if (try_apply_stack_adjustment (insn, reflist,
                                                  last_sp_adjust + this_adjust,
                                                  -last_sp_adjust))
                    {
@@ -430,8 +450,8 @@ combine_stack_adjustments_for_block (basic_block bb)
                      delete_insn (last_sp_set);
                      last_sp_set = insn;
                      last_sp_adjust += this_adjust;
-                     free_csa_memlist (memlist);
-                     memlist = NULL;
+                     free_csa_reflist (reflist);
+                     reflist = NULL;
                      continue;
                    }
                }
@@ -441,8 +461,8 @@ combine_stack_adjustments_for_block (basic_block bb)
                 delete the old deallocation insn.  */
              if (last_sp_set && last_sp_adjust == 0)
                delete_insn (last_sp_set);
-             free_csa_memlist (memlist);
-             memlist = NULL;
+             free_csa_reflist (reflist);
+             reflist = NULL;
              last_sp_set = insn;
              last_sp_adjust = this_adjust;
              continue;
@@ -451,7 +471,7 @@ combine_stack_adjustments_for_block (basic_block bb)
          /* Find a predecrement of exactly the previous adjustment and
             turn it into a direct store.  Obviously we can't do this if
             there were any intervening uses of the stack pointer.  */
-         if (memlist == NULL
+         if (reflist == NULL
              && MEM_P (dest)
              && ((GET_CODE (XEXP (dest, 0)) == PRE_DEC
                   && (last_sp_adjust
@@ -472,8 +492,8 @@ combine_stack_adjustments_for_block (basic_block bb)
                                  0))
            {
              delete_insn (last_sp_set);
-             free_csa_memlist (memlist);
-             memlist = NULL;
+             free_csa_reflist (reflist);
+             reflist = NULL;
              last_sp_set = NULL_RTX;
              last_sp_adjust = 0;
              continue;
@@ -481,14 +501,14 @@ combine_stack_adjustments_for_block (basic_block bb)
        }
 
       data.insn = insn;
-      data.memlist = memlist;
+      data.reflist = reflist;
       if (!CALL_P (insn) && last_sp_set
-         && !for_each_rtx (&PATTERN (insn), record_stack_memrefs, &data))
+         && !for_each_rtx (&PATTERN (insn), record_stack_refs, &data))
        {
-          memlist = data.memlist;
+          reflist = data.reflist;
           continue;
        }
-      memlist = data.memlist;
+      reflist = data.reflist;
 
       /* Otherwise, we were not able to process the instruction.
         Do not continue collecting data across such a one.  */
@@ -498,8 +518,8 @@ combine_stack_adjustments_for_block (basic_block bb)
        {
          if (last_sp_set && last_sp_adjust == 0)
            delete_insn (last_sp_set);
-         free_csa_memlist (memlist);
-         memlist = NULL;
+         free_csa_reflist (reflist);
+         reflist = NULL;
          last_sp_set = NULL_RTX;
          last_sp_adjust = 0;
        }
@@ -508,8 +528,8 @@ combine_stack_adjustments_for_block (basic_block bb)
   if (last_sp_set && last_sp_adjust == 0)
     delete_insn (last_sp_set);
 
-  if (memlist)
-    free_csa_memlist (memlist);
+  if (reflist)
+    free_csa_reflist (reflist);
 }
 \f
 
index b14aaf087bd80bcf630f1ad51615202f741642a4..567e58ced73c9d49dddb51c020614e5e269bc3ee 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR bootstrap/41241
+       * gcc.dg/pr41241.c: New test.
+
 2009-09-06  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/41144
diff --git a/gcc/testsuite/gcc.dg/pr41241.c b/gcc/testsuite/gcc.dg/pr41241.c
new file mode 100644 (file)
index 0000000..b69aa96
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR bootstrap/41241 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug -g" } */
+/* { dg-options "-O2 -fcompare-debug -g -march=i586 -mtune=i586 -fomit-frame-pointer" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+typedef struct { int t1; int t2; int t3; } *T;
+typedef struct { int s; } S;
+
+int fn1 (int);
+int fn2 (int, int, int);
+int fn3 (void);
+
+static S
+bar ()
+{
+  S s = { 0 };
+  return s;
+}
+
+void
+foo (T x)
+{
+  int a, b, c, d, e;
+  T f, g;
+  S h;
+  a = x->t2;
+  fn1 (x->t1);
+  h = bar (b);
+  c = fn1 (e);
+  d = fn3 ();
+  f->t3 &= g->t3 |= fn2 (0, b, x->t1);
+  fn2 (0, c, d);
+  fn2 (0, e, 0);
+}