alias-access-path-2.c: New testcase.
authorJan Hubicka <hubicka@ucw.cz>
Sat, 15 Jun 2019 18:33:26 +0000 (20:33 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 15 Jun 2019 18:33:26 +0000 (18:33 +0000)
* gcc.dg/tree-ssa/alias-access-path-2.c: New testcase.

* tree-ssa-alias.c (alias_stats): Add
nonoverlapping_component_refs_p_may_alias,
nonoverlapping_component_refs_p_no_alias,
nonoverlapping_component_refs_of_decl_p_may_alias,
nonoverlapping_component_refs_of_decl_p_no_alias.
(dump_alias_stats): Dump them.
(nonoverlapping_component_refs_of_decl_p): Add stats.
(nonoverlapping_component_refs_p): Add stats; do not stop on first
ARRAY_REF.

From-SVN: r272329

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c [new file with mode: 0644]
gcc/tree-ssa-alias.c

index 921e899f534770c744a461eff0cf539a45d7b671..e3799aec817e77eacb5909bc3f2afeef62d9e0fd 100644 (file)
@@ -1,3 +1,15 @@
+2019-06-15  Jan Hubicka  <hubicka@ucw.cz>
+
+       * tree-ssa-alias.c (alias_stats): Add
+       nonoverlapping_component_refs_p_may_alias,
+       nonoverlapping_component_refs_p_no_alias,
+       nonoverlapping_component_refs_of_decl_p_may_alias,
+       nonoverlapping_component_refs_of_decl_p_no_alias.
+       (dump_alias_stats): Dump them.
+       (nonoverlapping_component_refs_of_decl_p): Add stats.
+       (nonoverlapping_component_refs_p): Add stats; do not stop on first
+       ARRAY_REF.
+
 2019-06-15  Uroš Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (and<mode>3): Generate zero-extends for
index 56ab3ec0b49a01f23df6640aec19d9e5a1c1a5b2..411d4966765fad8be694b1073f2f71f9df50708a 100644 (file)
@@ -1,3 +1,7 @@
+2019-06-15  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gcc.dg/tree-ssa/alias-access-path-2.c: New testcase.
+
 2019-06-15  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        * gfortran.dg/ieee/ieee_4.f90: Un-xfail on i?86-*-freebsd.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c
new file mode 100644 (file)
index 0000000..974cdb0
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre3" } */
+struct a {
+  int val;
+};
+struct b {
+  struct a a[10],a2[10];
+};
+struct c {
+  struct b b[10];
+} *cptr;
+
+struct d {struct c c;} *dptr;
+
+int
+test (int i, int j, int k, int l)
+{
+  cptr->b[i].a[j].val=123;
+  dptr->c.b[k].a2[l].val=2;
+  return cptr->b[i].a[j].val;
+}
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */
index 8209b0dd34f62bb8703c7be69e62614e976ea786..42f02765824f6045099e8b1baba4d54ba1975795 100644 (file)
@@ -100,6 +100,10 @@ static struct {
   unsigned HOST_WIDE_INT call_may_clobber_ref_p_no_alias;
   unsigned HOST_WIDE_INT aliasing_component_refs_p_may_alias;
   unsigned HOST_WIDE_INT aliasing_component_refs_p_no_alias;
+  unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_may_alias;
+  unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_no_alias;
+  unsigned HOST_WIDE_INT nonoverlapping_component_refs_of_decl_p_may_alias;
+  unsigned HOST_WIDE_INT nonoverlapping_component_refs_of_decl_p_no_alias;
 } alias_stats;
 
 void
@@ -124,7 +128,19 @@ dump_alias_stats (FILE *s)
           alias_stats.call_may_clobber_ref_p_no_alias,
           alias_stats.call_may_clobber_ref_p_no_alias
           + alias_stats.call_may_clobber_ref_p_may_alias);
-  fprintf (s, "  aliasing_component_ref_p: "
+  fprintf (s, "  nonoverlapping_component_refs_p: "
+          HOST_WIDE_INT_PRINT_DEC" disambiguations, "
+          HOST_WIDE_INT_PRINT_DEC" queries\n",
+          alias_stats.nonoverlapping_component_refs_p_no_alias,
+          alias_stats.nonoverlapping_component_refs_p_no_alias
+          + alias_stats.nonoverlapping_component_refs_p_may_alias);
+  fprintf (s, "  nonoverlapping_component_refs_of_decl_p: "
+          HOST_WIDE_INT_PRINT_DEC" disambiguations, "
+          HOST_WIDE_INT_PRINT_DEC" queries\n",
+          alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias,
+          alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias
+          + alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias);
+  fprintf (s, "  aliasing_component_refs_p: "
           HOST_WIDE_INT_PRINT_DEC" disambiguations, "
           HOST_WIDE_INT_PRINT_DEC" queries\n",
           alias_stats.aliasing_component_refs_p_no_alias,
@@ -1047,7 +1063,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
   if (TREE_CODE (ref1) == MEM_REF)
     {
       if (!integer_zerop (TREE_OPERAND (ref1, 1)))
-       return false;
+       {
+         ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+         return false;
+       }
       ref1 = TREE_OPERAND (TREE_OPERAND (ref1, 0), 0);
     }
 
@@ -1060,7 +1079,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
   if (TREE_CODE (ref2) == MEM_REF)
     {
       if (!integer_zerop (TREE_OPERAND (ref2, 1)))
-       return false;
+       {
+         ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+         return false;
+       }
       ref2 = TREE_OPERAND (TREE_OPERAND (ref2, 0), 0);
     }
 
@@ -1080,7 +1102,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
       do
        {
          if (component_refs1.is_empty ())
-           return false;
+           {
+             ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+             return false;
+           }
          ref1 = component_refs1.pop ();
        }
       while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0))));
@@ -1088,7 +1113,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
       do
        {
          if (component_refs2.is_empty ())
-            return false;
+           {
+             ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+             return false;
+           }
          ref2 = component_refs2.pop ();
        }
       while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0))));
@@ -1096,7 +1124,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
       /* Beware of BIT_FIELD_REF.  */
       if (TREE_CODE (ref1) != COMPONENT_REF
          || TREE_CODE (ref2) != COMPONENT_REF)
-       return false;
+       {
+         ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+         return false;
+       }
 
       tree field1 = TREE_OPERAND (ref1, 1);
       tree field2 = TREE_OPERAND (ref2, 1);
@@ -1109,7 +1140,10 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
 
       /* We cannot disambiguate fields in a union or qualified union.  */
       if (type1 != type2 || TREE_CODE (type1) != RECORD_TYPE)
-        return false;
+       {
+         ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+         return false;
+       }
 
       if (field1 != field2)
        {
@@ -1117,15 +1151,23 @@ nonoverlapping_component_refs_of_decl_p (tree ref1, tree ref2)
             same.  */
          if (DECL_BIT_FIELD_REPRESENTATIVE (field1) == field2
              || DECL_BIT_FIELD_REPRESENTATIVE (field2) == field1)
-           return false;
+           {
+             ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+             return false;
+           }
          /* Different fields of the same record type cannot overlap.
             ??? Bitfields can overlap at RTL level so punt on them.  */
          if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2))
-           return false;
+           {
+             ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
+             return false;
+           }
+         ++alias_stats.nonoverlapping_component_refs_of_decl_p_no_alias;
          return true;
        }
     }
 
+  ++alias_stats.nonoverlapping_component_refs_of_decl_p_may_alias;
   return false;
 }
 
@@ -1154,40 +1196,67 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
 {
   if (!flag_strict_aliasing
       || !x || !y
-      || TREE_CODE (x) != COMPONENT_REF
-      || TREE_CODE (y) != COMPONENT_REF)
-    return false;
+      || !handled_component_p (x)
+      || !handled_component_p (y))
+    {
+      ++alias_stats.nonoverlapping_component_refs_p_may_alias;
+      return false;
+    }
 
   auto_vec<const_tree, 16> fieldsx;
-  while (TREE_CODE (x) == COMPONENT_REF)
+  while (handled_component_p (x))
     {
-      tree field = TREE_OPERAND (x, 1);
-      tree type = DECL_FIELD_CONTEXT (field);
-      if (TREE_CODE (type) == RECORD_TYPE)
-       fieldsx.safe_push (field);
+      if (TREE_CODE (x) == COMPONENT_REF)
+       {
+         tree field = TREE_OPERAND (x, 1);
+         tree type = DECL_FIELD_CONTEXT (field);
+         if (TREE_CODE (type) == RECORD_TYPE)
+           fieldsx.safe_push (field);
+       }
+      else if (TREE_CODE (x) == VIEW_CONVERT_EXPR)
+       fieldsx.truncate (0);
       x = TREE_OPERAND (x, 0);
     }
   if (fieldsx.length () == 0)
     return false;
   auto_vec<const_tree, 16> fieldsy;
-  while (TREE_CODE (y) == COMPONENT_REF)
+  while (handled_component_p (y))
     {
-      tree field = TREE_OPERAND (y, 1);
-      tree type = DECL_FIELD_CONTEXT (field);
-      if (TREE_CODE (type) == RECORD_TYPE)
-       fieldsy.safe_push (TREE_OPERAND (y, 1));
+      if (TREE_CODE (y) == COMPONENT_REF)
+       {
+         tree field = TREE_OPERAND (y, 1);
+         tree type = DECL_FIELD_CONTEXT (field);
+         if (TREE_CODE (type) == RECORD_TYPE)
+           fieldsy.safe_push (TREE_OPERAND (y, 1));
+       }
+      else if (TREE_CODE (y) == VIEW_CONVERT_EXPR)
+       fieldsx.truncate (0);
       y = TREE_OPERAND (y, 0);
     }
   if (fieldsy.length () == 0)
-    return false;
+    {
+      ++alias_stats.nonoverlapping_component_refs_p_may_alias;
+      return false;
+    }
 
   /* Most common case first.  */
   if (fieldsx.length () == 1
       && fieldsy.length () == 1)
-    return ((DECL_FIELD_CONTEXT (fieldsx[0])
-            == DECL_FIELD_CONTEXT (fieldsy[0]))
-           && fieldsx[0] != fieldsy[0]
-           && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0])));
+   {
+     if ((DECL_FIELD_CONTEXT (fieldsx[0])
+         == DECL_FIELD_CONTEXT (fieldsy[0]))
+        && fieldsx[0] != fieldsy[0]
+        && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0])))
+      {
+         ++alias_stats.nonoverlapping_component_refs_p_no_alias;
+         return true;
+      }
+     else
+      {
+         ++alias_stats.nonoverlapping_component_refs_p_may_alias;
+         return false;
+      }
+   }
 
   if (fieldsx.length () == 2)
     {
@@ -1222,11 +1291,18 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
                 same.  */
              if (DECL_BIT_FIELD_REPRESENTATIVE (fieldx) == fieldy
                  || DECL_BIT_FIELD_REPRESENTATIVE (fieldy) == fieldx)
-               return false;
+               {
+                  ++alias_stats.nonoverlapping_component_refs_p_may_alias;
+                  return false;
+               }
              /* Different fields of the same record type cannot overlap.
                 ??? Bitfields can overlap at RTL level so punt on them.  */
              if (DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy))
-               return false;
+               {
+                  ++alias_stats.nonoverlapping_component_refs_p_may_alias;
+                  return false;
+               }
+             ++alias_stats.nonoverlapping_component_refs_p_no_alias;
              return true;
            }
        }
@@ -1245,6 +1321,7 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
     }
   while (1);
 
+  ++alias_stats.nonoverlapping_component_refs_p_may_alias;
   return false;
 }