On Mon, 17 Jun 2019, Jan Hubicka wrote: > Hi, > while working on testcases for nonoverlapping_component_refs_p I run into > issue > that we often bypass it because the indirect-decl and indirect-indirect > oracles > give up if they manage to match bases and ranges_maybe_overlap_p return true. > (one testcase is included in patch). > > The issue is that decl-decl oracle first test base+offsets and if that > fails it proceeds to nonoverlapping_component_refs_of_decl_p which is > still able to do some useful disambiguations when the access paths > contains non-constat ARRAY_REFs where max_size is not very informative. > > I modified the other two oracles to avoid the early return which increased > effectivity of nonoverlapping_component_refs_p and aliasing_component_refs_p > somewhat but also about doubled number of calls of them. > > I can't say if the early return is just omision or intended to save compile > time > but it appeared to me that most of those nondisambiguated comparsions acutally > covers the case we know that access paths are the same and in such case > we could still return early. > > This patch adds same_access_paths_p which implements simple logic matching > max_size with type size (thus ruling out variable array accesses) and then > verifying that there are no unions on the way (in that case we still may have > different access paths to same memory location. > > With this patch I get relatively reasonable increase in number of querries > and disambiguations. > > For tramp3d: > > Alias oracle query stats: > refs_may_alias_p: 3021539 disambiguations, 3321136 queries > ref_maybe_used_by_call_p: 7118 disambiguations, 3047133 queries > call_may_clobber_ref_p: 817 disambiguations, 817 queries > nonoverlapping_component_refs_p: 22 disambiguations, 61735 queries > nonoverlapping_component_refs_of_decl_p: 19 disambiguations, 2192 queries > aliasing_component_refs_p: 2050 disambiguations, 19908 queries > TBAA oracle: 1419961 disambiguations 2916692 queries > 555158 are in alias set 0 > 575103 queries asked about the same object > 0 queries asked about the same alias set > 0 access volatile > 252874 are dependent in the DAG > 113596 are aritificially in conflict with void * > > PTA query stats: > pt_solution_includes: 671982 disambiguations, 952513 queries > pt_solutions_intersect: 97060 disambiguations, 437912 queries > > to: > > Alias oracle query stats: > refs_may_alias_p: 3021842 disambiguations, 3321308 queries > ref_maybe_used_by_call_p: 7118 disambiguations, 3047440 queries > call_may_clobber_ref_p: 817 disambiguations, 817 queries > nonoverlapping_component_refs_p: 25 disambiguations, 63108 queries > nonoverlapping_component_refs_of_decl_p: 19 disambiguations, 2192 queries > aliasing_component_refs_p: 2236 disambiguations, 20594 queries > TBAA oracle: 1420030 disambiguations 2918103 queries > 555158 are in alias set 0 > 575109 queries asked about the same object > 0 queries asked about the same alias set > 0 access volatile > 253260 are dependent in the DAG > 114546 are aritificially in conflict with void * > > PTA query stats: > pt_solution_includes: 671990 disambiguations, 952532 queries > pt_solutions_intersect: 97060 disambiguations, 438091 queries > > So 3% new querries on wich we seems to have have about 30% disambiguation rate > (190 new disambiguations) > > For cc1: > > Alias oracle query stats: > refs_may_alias_p: 38345354 disambiguations, 46034874 queries > ref_maybe_used_by_call_p: 57452 disambiguations, 38905700 queries > call_may_clobber_ref_p: 5856 disambiguations, 8685 queries > nonoverlapping_component_refs_p: 9674 disambiguations, 743745 queries > nonoverlapping_component_refs_of_decl_p: 6962 disambiguations, 212637 > queries > aliasing_component_refs_p: 103234 disambiguations, 291017 queries > TBAA oracle: 10719978 disambiguations 32885735 queries > 13521045 are in alias set 0 > 5233132 queries asked about the same object > 200 queries asked about the same alias set > 0 access volatile > 1459189 are dependent in the DAG > 1952191 are aritificially in conflict with void * > > PTA query stats: > pt_solution_includes: 465494 disambiguations, 6918046 queries > pt_solutions_intersect: 342384 disambiguations, 6435014 queries > > to: > > Alias oracle query stats: > refs_may_alias_p: 38345581 disambiguations, 46035002 queries > ref_maybe_used_by_call_p: 57452 disambiguations, 38905936 queries > call_may_clobber_ref_p: 5856 disambiguations, 8685 queries > nonoverlapping_component_refs_p: 9754 disambiguations, 768725 queries > nonoverlapping_component_refs_of_decl_p: 6962 disambiguations, 212637 > queries > aliasing_component_refs_p: 103316 disambiguations, 314129 queries > TBAA oracle: 10720037 disambiguations 32893789 queries > 13521037 are in alias set 0 > 5233163 queries asked about the same object > 200 queries asked about the same alias set > 0 access volatile > 1462737 are dependent in the DAG > 1956615 are aritificially in conflict with void * > > PTA query stats: > pt_solution_includes: 465494 disambiguations, 6918049 queries > pt_solutions_intersect: 342386 disambiguations, 6435109 queries > > So 23112 (7%) increase in the number of querries to access path and 162 more > disambiguations which is not great, but I hope it will still increase > as the access path oracle starts to work better. > > It will also let me to glue aliasing_coponent_refs into decl-decl oracle > w/o wasting too much of compile time. This seems useful since we now > have a lot of non-trivial MEM_REFs on decls resulting from inlining of > member functions which we do not disambiguate very well if they mix with > arrays (nonoverlapping_component_refs_of_decl_p gives up and we do > nothing except for base/offset/maxsize tests). > > Bootstrapped/regtested x86_64-linux, seems reasonable? > > * gcc.dg/tree-ssa/alias-access-path-3.c > * tree-ssa-alias.c (same_access_paths_p): New predicate. > (indirect_ref_may_alias_decl_p, indirect_refs_may_alias_p): > Use it. > > 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,23 @@ > +/* { 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=124; > + 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"} } */ > +/* { dg-final { scan-tree-dump-not "return 124" "fre1"} } */ > Index: tree-ssa-alias.c > =================================================================== > --- tree-ssa-alias.c (revision 272358) > +++ tree-ssa-alias.c (working copy) > @@ -1413,6 +1413,36 @@ decl_refs_may_alias_p (tree ref1, tree b > return true; > } > > +/* Return true if access paths are same and thus access path > + oracles can be skiped. This is just a quick check for common > + cases where we assume that outer types or addresses has been > + previously matched. */ > + > +bool > +same_access_paths_p (tree ref1, poly_int64 max_size1, > + tree ref2, poly_int64 max_size2) > +{ > + poly_uint64 size; > + if (!ref1 || !ref2 > + || !known_eq (max_size1, max_size2) > + || TYPE_SIZE (TREE_TYPE (ref1)) != TYPE_SIZE (TREE_TYPE (ref2)) > + || !poly_int_tree_p (TYPE_SIZE (TREE_TYPE (ref1)), &size) > + || !known_eq ((poly_int64)size, max_size1)) > + return false; > + while (handled_component_p (ref1)) > + { > + if (!handled_component_p (ref2)) > + return false; > + if (TREE_CODE (TREE_TYPE (ref1)) == UNION_TYPE > + || TREE_CODE (TREE_TYPE (ref1)) > + != TREE_CODE (TREE_TYPE (ref2))) > + return false; > + ref1 = TREE_OPERAND (ref1, 0); > + ref2 = TREE_OPERAND (ref2, 0); > + }
But part of the expensiveness we want to avoid is this (repeated) walking of the ref tree... So... > + return !handled_component_p (ref2); > +} > + > /* Return true if an indirect reference based on *PTR1 constrained > to [OFFSET1, OFFSET1 + MAX_SIZE1) may alias a variable based on BASE2 > constrained to [OFFSET2, OFFSET2 + MAX_SIZE2). *PTR1 and BASE2 have > @@ -1533,7 +1563,12 @@ 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 (same_access_paths_p (ref1, max_size1, ref2, max_size2)) > + return true; how about a simpler test like if (known_size_p (max_size1) && known_size_p (max_size2)) return true; /* If there's an unconstrained variable access in the ref fall through to access-path based disambiguation. */ ? I'd certainly like to see testcases btw... A more stricter test would be if (!maybe_eq (max_size1, size1) && !maybe_eq (max_size2, size2)) return true; /* If there's a variable access in one of the refs fall through to access-path based disambiguation. */ where you'd need to pass down ao_ref_size in addition to max_size as well. Richard. > + } > > if (ref1 && ref2 > && nonoverlapping_component_refs_p (ref1, ref2)) > @@ -1613,8 +1648,9 @@ indirect_refs_may_alias_p (tree ref1 ATT > { > poly_offset_int moff1 = mem_ref_offset (base1) << LOG2_BITS_PER_UNIT; > poly_offset_int moff2 = mem_ref_offset (base2) << LOG2_BITS_PER_UNIT; > - return ranges_maybe_overlap_p (offset1 + moff1, max_size1, > - offset2 + moff2, max_size2); > + if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1, > + offset2 + moff2, max_size2)) > + return false; > } > if (!ptr_derefs_may_alias_p (ptr1, ptr2)) > return false; > @@ -1654,7 +1690,12 @@ 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 (same_access_paths_p (ref1, max_size1, ref2, max_size2)) > + return true; > + } > > if (ref1 && ref2 > && nonoverlapping_component_refs_p (ref1, ref2)) > -- Richard Biener <rguent...@suse.de> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)