Enable nonoverallping_component_refs even after the base pointers are equivalent
Richard Biener
rguenther@suse.de
Wed Jul 3 12:40:00 GMT 2019
On Tue, 2 Jul 2019, Jan Hubicka wrote:
> Hi,
> this patch adds the shortcut for must aliases discussed earlier and enables
> access path even if bases are proved to be equivalent - it could still do
> useful job for arrays etc.
>
> tramp3d stats go from:
>
> Alias oracle query stats:
> refs_may_alias_p: 4421560 disambiguations, 4781790 queries
> ref_maybe_used_by_call_p: 6790 disambiguations, 4447962 queries
> call_may_clobber_ref_p: 883 disambiguations, 883 queries
> nonoverlapping_component_refs_p: 0 disambiguations, 9272 queries
> nonoverlapping_component_refs_since_match_p: 31 disambiguations, 39391 queries
> aliasing_component_refs_p: 918 disambiguations, 30889 queries
> TBAA oracle: 1924468 disambiguations 3851145 queries
> 774336 are in alias set 0
> 714019 queries asked about the same object
> 0 queries asked about the same alias set
> 0 access volatile
> 282546 are dependent in the DAG
> 155776 are aritificially in conflict with void *
>
> to
>
> Alias oracle query stats:
> refs_may_alias_p: 4421611 disambiguations, 4781828 queries
> ref_maybe_used_by_call_p: 6790 disambiguations, 4448013 queries
> call_may_clobber_ref_p: 883 disambiguations, 883 queries
> nonoverlapping_component_refs_p: 0 disambiguations, 8964 queries
> nonoverlapping_component_refs_since_match_p: 66 disambiguations, 18470 queries
> aliasing_component_refs_p: 918 disambiguations, 30371 queries
> TBAA oracle: 1924492 disambiguations 3849967 queries
> 774336 are in alias set 0
> 714095 queries asked about the same object
> 0 queries asked about the same alias set
> 0 access volatile
> 281268 are dependent in the DAG
> 155776 are aritificially in conflict with void *
>
> PTA query stats:
> pt_solution_includes: 906632 disambiguations, 1214744 queries
> pt_solutions_intersect: 121330 disambiguations, 553172 queries
>
> So twice as many nonoverlapping_component_refs_since_match_p disambiguations,
> half of querries.
>
> We can miss some of disambiguations where addresses are same but types
> are different, but I think those are not useful - this is the case where
> memory type was dynamically changed. If we walk with TBAA enabled and
> see the prevoius use, we got kind of lost anyway and propagating even
> older values seems to have no use.
>
> Note that i tried to implement ranges_must_overlap_p predicate which could
> save us from more tests but got lost in polyints and I think it is not worth
> the effort since these cases are quite borderline.
>
> Similar test would make sense in aliasing_component_refs_p but I think
> it may make more sense to reorder the tests there. Right now we do:
>
> get_ref_base_and_extent (match2, &offadj, &sztmp, &msztmp, &reverse);
> offset2 -= offadj;
> get_ref_base_and_extent (match1, &offadj, &sztmp, &msztmp, &reverse);
> offset1 -= offadj;
> if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
>
> First I think that one get_ref_base_and_extent is always redundant since either
> match1 or match2 is base so we could pass it down.
>
> However it seems to me that perhaps doing
> nonoverlapping_component_refs_since_match_p would be cheaper and one can do the
> range check only after this one returns -1 saving quite many
> get_ref_base_and_extent calls.
Yeah, that sounds worthwhile (this function is the worst offender
compile-time wise)
> Bootstrapped/regtested x86_64-linux, OK?
>
> Honza
>
> Index: testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/alias-access-path-3.c (nonexistent)
> +++ testsuite/gcc.dg/tree-ssa/alias-access-path-3.c (working copy)
> @@ -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"} } */
> Index: testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/alias-access-path-8.c (nonexistent)
> +++ testsuite/gcc.dg/tree-ssa/alias-access-path-8.c (working copy)
> @@ -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"} } */
Why does this only happen in fre3?!
Otherwise OK.
Thanks,
Richard.
> Index: tree-ssa-alias.c
> ===================================================================
> --- tree-ssa-alias.c (revision 272927)
> +++ tree-ssa-alias.c (working copy)
> @@ -1452,8 +1452,10 @@ nonoverlapping_component_refs_p (const_t
> 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 b
> 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 b
> 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
> && (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
> 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 ATT
> 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 ATT
> 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
> 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
> /* 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);
>
More information about the Gcc-patches
mailing list