tree-ssa-alias.c (decl_refs_may_alias_p): Add size1 and size2 parameters; return...
authorJan Hubicka <jh@suse.cz>
Thu, 4 Jul 2019 12:52:22 +0000 (14:52 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 4 Jul 2019 12:52:22 +0000 (12:52 +0000)
* tree-ssa-alias.c (decl_refs_may_alias_p): Add size1 and size2
parameters; return early for must-alias.
(indirect_ref_may_alias_decl_p): Likewise; when establishing
outer types match, try nonoverlapping_component_refs
if must-alias is not obvious.
(indirect_refs_may_alias_p): Likewise.
(refs_may_alias_p_2): Likewise.

* gcc.dg/tree-ssa/alias-access-path-3.c: New testcase.
* gcc.dg/tree-ssa/alias-access-path-8.c: New testcase.

From-SVN: r273079

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

index 932eca2519c3acb158dd82ea42ed41352ea0b3fb..5f889096dac2bf4ec3d2c2e9bdda274cdbd0aced 100644 (file)
@@ -1,3 +1,13 @@
+2019-07-04  Jan Hubicka  <jh@suse.cz>
+
+       * tree-ssa-alias.c (decl_refs_may_alias_p): Add size1 and size2
+       parameters; return early for must-alias.
+       (indirect_ref_may_alias_decl_p): Likewise; when establishing
+       outer types match, try nonoverlapping_component_refs
+       if must-alias is not obvious.
+       (indirect_refs_may_alias_p): Likewise.
+       (refs_may_alias_p_2): Likewise.
+
 2019-07-04  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-sccvn.h (vn_reference_lookup): Add last_vuse_ptr
index a974b11b5c28f43518892a6361f71a92cd5afa32..a89a21893be33526658c0da5065ca6c141a49720 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-04  Jan Hubicka  <jh@suse.cz>
+
+       * gcc.dg/tree-ssa/alias-access-path-3.c: New testcase.
+       * gcc.dg/tree-ssa/alias-access-path-8.c: New testcase.
+
 2019-07-04  Andrew Stubbs  <ams@codesourcery.com>
 
        * g++.dg/gomp/unmappable-1.C: New file.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
new file mode 100644 (file)
index 0000000..ef4ffac
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+struct a {int v1;
+         int v2;};
+struct b {struct a a[0];};
+
+int
+test (struct b *bptr1, struct b *bptr2, int i, int j)
+{
+  bptr1->a[i].v1=123;
+  bptr2->a[j].v2=1;
+  return bptr1->a[i].v1;
+}
+int
+test2 (struct b *bptr1, struct b *bptr2, int i, int j)
+{
+  bptr1->a[i].v1=123;
+  bptr2->a[j].v1=1;
+  return bptr1->a[i].v1;
+}
+/* test should be optimized, while test2 should not.  */
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
new file mode 100644 (file)
index 0000000..1d5b57a
--- /dev/null
@@ -0,0 +1,21 @@
+/* { 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,*cptr2;
+
+
+int
+test (int i, int j, int k, int l)
+{
+  cptr->b[i].a[j].val=123;
+  cptr2->b[k].a2[l].val=2;
+  return cptr->b[i].a[j].val;
+}
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */
index c3c127a761ef296d2eeef6b6a571362ff0ffe5b5..d76656e57afe42894bb5e6642caabbf5a1470990 100644 (file)
@@ -1452,8 +1452,10 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
 static bool
 decl_refs_may_alias_p (tree ref1, tree base1,
                       poly_int64 offset1, poly_int64 max_size1,
+                      poly_int64 size1,
                       tree ref2, tree base2,
-                      poly_int64 offset2, poly_int64 max_size2)
+                      poly_int64 offset2, poly_int64 max_size2,
+                      poly_int64 size2)
 {
   gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
 
@@ -1466,6 +1468,10 @@ decl_refs_may_alias_p (tree ref1, tree base1,
   if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
     return false;
 
+  /* If there is must alias, there is no use disambiguating further.  */
+  if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
+    return true;
+
   /* For components with variable position, the above test isn't sufficient,
      so we disambiguate component references manually.  */
   if (ref1 && ref2
@@ -1487,10 +1493,12 @@ decl_refs_may_alias_p (tree ref1, tree base1,
 static bool
 indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
                               poly_int64 offset1, poly_int64 max_size1,
+                              poly_int64 size1,
                               alias_set_type ref1_alias_set,
                               alias_set_type base1_alias_set,
                               tree ref2 ATTRIBUTE_UNUSED, tree base2,
                               poly_int64 offset2, poly_int64 max_size2,
+                              poly_int64 size2,
                               alias_set_type ref2_alias_set,
                               alias_set_type base2_alias_set, bool tbaa_p)
 {
@@ -1598,7 +1606,19 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
       && (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE
          || (TYPE_SIZE (TREE_TYPE (base1))
              && TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))
-    return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);
+    {
+      if (!ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2))
+       return false;
+      if (!ref1 || !ref2
+         /* If there is must alias, there is no use disambiguating further.  */
+         || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
+       return true;
+      int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
+                                                            base2, ref2);
+      if (res == -1)
+       return !nonoverlapping_component_refs_p (ref1, ref2);
+      return !res;
+    }
 
   /* Do access-path based disambiguation.  */
   if (ref1 && ref2
@@ -1623,10 +1643,12 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
 static bool
 indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
                           poly_int64 offset1, poly_int64 max_size1,
+                          poly_int64 size1,
                           alias_set_type ref1_alias_set,
                           alias_set_type base1_alias_set,
                           tree ref2 ATTRIBUTE_UNUSED, tree base2,
                           poly_int64 offset2, poly_int64 max_size2,
+                          poly_int64 size2,
                           alias_set_type ref2_alias_set,
                           alias_set_type base2_alias_set, bool tbaa_p)
 {
@@ -1671,6 +1693,9 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
       if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1,
                                   offset2 + moff2, max_size2))
        return false;
+      /* If there is must alias, there is no use disambiguating further.  */
+      if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
+       return true;
       if (ref1 && ref2)
        {
          int res = nonoverlapping_component_refs_since_match_p (NULL, ref1,
@@ -1717,7 +1742,18 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
          can overlap by an exact multiple of their element size.
          See gcc.dg/torture/alias-2.c.  */
       && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)
-    return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);
+    {
+      if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
+       return false;
+      if (!ref1 || !ref2
+         || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
+       return true;
+      int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
+                                                            base2, ref2);
+      if (res == -1)
+       return !nonoverlapping_component_refs_p (ref1, ref2);
+      return !res;
+    }
 
   /* Do access-path based disambiguation.  */
   if (ref1 && ref2
@@ -1802,7 +1838,9 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
   var2_p = DECL_P (base2);
   if (var1_p && var2_p)
     return decl_refs_may_alias_p (ref1->ref, base1, offset1, max_size1,
-                                 ref2->ref, base2, offset2, max_size2);
+                                 ref1->size,
+                                 ref2->ref, base2, offset2, max_size2,
+                                 ref2->size);
 
   /* Handle restrict based accesses.
      ???  ao_ref_base strips inner MEM_REF [&decl], recover from that
@@ -1870,21 +1908,21 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
   /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
   if (var1_p && ind2_p)
     return indirect_ref_may_alias_decl_p (ref2->ref, base2,
-                                         offset2, max_size2,
+                                         offset2, max_size2, ref2->size,
                                          ao_ref_alias_set (ref2),
                                          ao_ref_base_alias_set (ref2),
                                          ref1->ref, base1,
-                                         offset1, max_size1,
+                                         offset1, max_size1, ref1->size,
                                          ao_ref_alias_set (ref1),
                                          ao_ref_base_alias_set (ref1),
                                          tbaa_p);
   else if (ind1_p && ind2_p)
     return indirect_refs_may_alias_p (ref1->ref, base1,
-                                     offset1, max_size1,
+                                     offset1, max_size1, ref1->size,
                                      ao_ref_alias_set (ref1),
                                      ao_ref_base_alias_set (ref1),
                                      ref2->ref, base2,
-                                     offset2, max_size2,
+                                     offset2, max_size2, ref2->size,
                                      ao_ref_alias_set (ref2),
                                      ao_ref_base_alias_set (ref2),
                                      tbaa_p);