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
This commit is contained in:
parent
8862ed139a
commit
f5fa046faa
5 changed files with 104 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
22
gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
Normal file
22
gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
Normal file
|
@ -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"} } */
|
21
gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
Normal file
21
gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
Normal file
|
@ -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"} } */
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue