]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl.h (mem_expr_equal_p): Function prototype added.
authorAndreas Krebbel <krebbel1@de.ibm.com>
Sat, 6 Mar 2004 01:21:28 +0000 (01:21 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sat, 6 Mar 2004 01:21:28 +0000 (01:21 +0000)
2004-03-05  Andreas Krebbel  <krebbel1@de.ibm.com>

* rtl.h (mem_expr_equal_p): Function prototype added.
* cfgcleanup.c (merge_memattrs): New function.
(flow_find_cross_jump): Call merge_memattrs for matching insns.
* emit-rtl.c (mem_expr_equal_p): New function.

2004-03-05  Andreas Krebbel  <krebbel1@de.ibm.com>

* gcc.dg/20040305-1.c: New test.

From-SVN: r79005

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/emit-rtl.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20040305-1.c [new file with mode: 0644]

index 9200bbd2c8cd63a77ee39ff0397caac18808c0e4..76710e788cb122133c08d8c8ace9e75e03eda815 100644 (file)
@@ -1,3 +1,10 @@
+2004-03-05  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * rtl.h (mem_expr_equal_p): Function prototype added.
+       * cfgcleanup.c (merge_memattrs): New function.
+       (flow_find_cross_jump): Call merge_memattrs for matching insns.
+       * emit-rtl.c (mem_expr_equal_p): New function.
+
 2004-03-05  Ziemowit Laski  <zlaski@apple.com>
 
        * objc/objc-act.c (synth_module_prologue): Const-qualify
index b2dd0937d5ab3c1fc8b3848439271b40b151e26a..9029b5fb850be79a72d60bbad11217ddf0891a3f 100644 (file)
@@ -49,6 +49,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm_p.h"
 #include "target.h"
 #include "regs.h"
+#include "expr.h"
 
 /* cleanup_cfg maintains following flags for each basic block.  */
 
@@ -87,6 +88,7 @@ static bool mark_effect (rtx, bitmap);
 static void notice_new_block (basic_block);
 static void update_forwarder_flag (basic_block);
 static int mentions_nonequal_regs (rtx *, void *);
+static void merge_memattrs (rtx, rtx);
 \f
 /* Set flags for newly created block.  */
 
@@ -862,6 +864,88 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
 }
 \f
 
+/* Removes the memory attributes of MEM expression
+   if they are not equal.  */
+
+void
+merge_memattrs (rtx x, rtx y)
+{
+  int i;
+  int j;
+  enum rtx_code code;
+  const char *fmt;
+
+  if (x == y)
+    return;
+  if (x == 0 || y == 0)
+    return;
+
+  code = GET_CODE (x);
+
+  if (code != GET_CODE (y))
+    return;
+
+  if (GET_MODE (x) != GET_MODE (y))
+    return;
+
+  if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y))
+    {
+      if (! MEM_ATTRS (x))
+       MEM_ATTRS (y) = 0;
+      else if (! MEM_ATTRS (y))
+       MEM_ATTRS (x) = 0;
+      else 
+       {
+         if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
+           {
+             set_mem_alias_set (x, 0);
+             set_mem_alias_set (y, 0);
+           }
+         
+         if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
+           {
+             set_mem_expr (x, 0);
+             set_mem_expr (y, 0);
+             set_mem_offset (x, 0);
+             set_mem_offset (y, 0);
+           }
+         else if (MEM_OFFSET (x) != MEM_OFFSET (y))
+           {
+             set_mem_offset (x, 0);
+             set_mem_offset (y, 0);
+           }
+         
+         set_mem_size (x, MAX (MEM_SIZE (x), MEM_SIZE (y)));
+         set_mem_size (y, MEM_SIZE (x));
+
+         set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
+         set_mem_align (y, MEM_ALIGN (x));
+       }
+    }
+  
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    {
+      switch (fmt[i])
+       {
+       case 'E':
+         /* Two vectors must have the same length.  */
+         if (XVECLEN (x, i) != XVECLEN (y, i))
+           return;
+
+         for (j = 0; j < XVECLEN (x, i); j++)
+           merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
+
+         break;
+
+       case 'e':
+         merge_memattrs (XEXP (x, i), XEXP (y, i));
+       }
+    }
+  return;
+}
+
+
 /* Return true if I1 and I2 are equivalent and thus can be crossjumped.  */
 
 static bool
@@ -1022,6 +1106,8 @@ flow_find_cross_jump (int mode ATTRIBUTE_UNUSED, basic_block bb1,
       if (!insns_match_p (mode, i1, i2))
        break;
 
+      merge_memattrs (i1, i2);
+
       /* Don't begin a cross-jump with a NOTE insn.  */
       if (INSN_P (i1))
        {
index 6872afa33011fa44aa6d24f412e38d19105e649f..3032b539e297d758d9e59c383f593b9f2d030cba 100644 (file)
@@ -1434,6 +1434,40 @@ component_ref_for_mem_expr (tree ref)
                  TREE_OPERAND (ref, 1));
 }
 
+/* Returns 1 if both MEM_EXPR can be considered equal
+   and 0 otherwise.  */
+
+int
+mem_expr_equal_p (tree expr1, tree expr2)
+{
+  if (expr1 == expr2)
+    return 1;
+
+  if (! expr1 || ! expr2)
+    return 0;
+
+  if (TREE_CODE (expr1) != TREE_CODE (expr2))
+    return 0;
+
+  if (TREE_CODE (expr1) == COMPONENT_REF)
+    return 
+      mem_expr_equal_p (TREE_OPERAND (expr1, 0),
+                       TREE_OPERAND (expr2, 0))
+      && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
+                          TREE_OPERAND (expr2, 1));
+  
+  if (TREE_CODE (expr1) == INDIRECT_REF)
+    return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
+                            TREE_OPERAND (expr2, 0));
+  
+  /* Decls with different pointers can't be equal.  */
+  if (DECL_P (expr1))
+    return 0;
+
+  abort(); /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
+             have been resolved here.  */
+}
+
 /* Given REF, a MEM, and T, either the type of X or the expression
    corresponding to REF, set the memory attributes.  OBJECTP is nonzero
    if we are making a new object of this type.  BITPOS is nonzero if
index 94dc136e53beb91863175e337f621b7cb4be3423..6da77683fa3e3181d0ad269d7ce0640b382f62e0 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1569,6 +1569,7 @@ extern void set_reg_attrs_from_mem (rtx, rtx);
 extern void set_mem_attrs_from_reg (rtx, rtx);
 extern void set_reg_attrs_for_parm (rtx, rtx);
 extern void set_reg_pointer_align (rtx, unsigned int);
+extern int mem_expr_equal_p (tree, tree);
 
 /* In rtl.c */
 extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
index 115c67ec152a9a5412607829c8261bd3d7e6b318..00a174a74c9381584226f868117a9e4a86293666 100644 (file)
@@ -1,3 +1,7 @@
+2004-03-05  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * gcc.dg/20040305-1.c: New test.
+
 2004-03-05  Hans-Peter Nilsson  <hp@axis.com>
 
        PR other/14354
diff --git a/gcc/testsuite/gcc.dg/20040305-1.c b/gcc/testsuite/gcc.dg/20040305-1.c
new file mode 100644 (file)
index 0000000..62b920c
--- /dev/null
@@ -0,0 +1,50 @@
+
+/* The testcase failed due to corrupted alias information.
+   During the crossjump analyzing step the mem alias info of the
+   st instructions are merged and get copied during basic block
+   reordering which leads to an insn with wrong alias info.
+   The scheduler afterwards exchanges the mvc and st instructions 
+   not recognizing the anti dependence.  */
+/* { dg-do run { target s390-*-* } } */
+/* { dg-options "-O3 -mtune=z990 -fno-inline" } */
+
+int f;
+int g;
+int h;
+
+int* x  = &f;
+int* p1 = &g;
+int* p2 = &h;
+
+int
+foo(void)
+{
+
+  if (*x == 0)
+    {
+      x = p1;         /* mvc - memory to memory */
+      p1 = (int*)0;   /* st  - register to memory */
+      return 1;
+    }
+  if (*x == 5)
+    {
+      f = 1;
+      g = 2;
+
+      p2 = (int*)0;   /* st */   
+      return 1;
+    }
+}
+
+int
+main (int argc, char** argv)
+{
+  foo ();
+
+  /* If the scheduler has exchanged the mvc and st instructions,
+     x is 0. The expected result is &g.  */
+  if (x == &g)
+    exit (0);
+  else
+    abort ();
+}