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); + } + 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; + } 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))