From f5fa046faa7f97662312e17aaab6da9713fe7518 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 4 Jul 2019 14:52:22 +0200 Subject: [PATCH] tree-ssa-alias.c (decl_refs_may_alias_p): Add size1 and size2 parameters; return early for must-alias. * 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 | 10 ++++ gcc/testsuite/ChangeLog | 5 ++ .../gcc.dg/tree-ssa/alias-access-path-3.c | 22 +++++++++ .../gcc.dg/tree-ssa/alias-access-path-8.c | 21 +++++++++ gcc/tree-ssa-alias.c | 54 ++++++++++++++++++---- 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 932eca2..5f88909 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-07-04 Jan Hubicka + + * 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 * tree-ssa-sccvn.h (vn_reference_lookup): Add last_vuse_ptr diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a974b11..a89a218 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-04 Jan Hubicka + + * 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 * 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 index 0000000..ef4ffac --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c @@ -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 index 0000000..1d5b57a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c @@ -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"} } */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index c3c127a..d76656e 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -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); -- 2.7.4