On Mon, 10 Jun 2019, Jan Hubicka wrote:

> Hi,
> this is kind of minimal patch to handle pointers in access paths.
> I do not include logic for arrays nor attempt to deal better with incomparable
> pointers (such as pointers to two different incomplete record types).
> 
> A lazy way would be to simply compare alias sets, but I want to handle more
> because our rules for globbing pointers are not transitive. For example void *
> is equivalent to pointer to any incomplete type.  But we can still say that
> pointer to record is different from pointer to function which helps in 
> practice 
> since propagating pointers to functions is rather important.
> 
> Alias sets of pointer to record and pointer to function are both same as void 
> *
> because we have no way to distinguish multiple pointers of same kind and we
> special case only void * alias set.  Here we can work bit better without much
> of extra hassle and we also catch most of cases (since most accesses are to
> types w/o pointers which we disambiguate this way).
> 
> Number of disambiguations on tramp3d via access path grows from 1000 to 
> 
> Alias oracle query stats:
>   refs_may_alias_p: 3025065 disambiguations, 3321073 queries
>   ref_maybe_used_by_call_p: 7118 disambiguations, 3050683 queries
>   call_may_clobber_ref_p: 817 disambiguations, 817 queries
>   aliasing_component_ref_p: 8703 disambiguations, 24495 queries
>   TBAA oracle: 1429175 disambiguations 2934191 queries
>                552425 are in alias set 0
>                573848 queries asked about the same object
>                0 queries asked about the same alias set
>                0 access volatile
>                257310 are dependent in the DAG
>                121433 are aritificially in conflict with void *
> 
> So about 8x more.
> 
> lto-bootstrapped/regtested x86_64 with all languages, OK?

So the important thing is that during matching the paths
aptr->a and *bptr we return false for
same_type_for_tbaa (int *, struct a *), correct?  But if
we can do that then the alias sets should not conflict in
the first place and we shouldn't need any path-based disambiguation
here.

So to me this is the wrong place to fix.

Richard.

>       * gcc.dg/lto/alias-access-path-3_0.c: New testcase.
>       * tree-ssa-alias.c (same_type_for_tbaa): Look into pointed-to types
>       to test structural equivalence of pointer types.
> 
> Index: testsuite/gcc.dg/lto/alias-access-path-3_0.c
> ===================================================================
> --- testsuite/gcc.dg/lto/alias-access-path-3_0.c      (nonexistent)
> +++ testsuite/gcc.dg/lto/alias-access-path-3_0.c      (working copy)
> @@ -0,0 +1,37 @@
> +/* { dg-lto-do run } */
> +/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
> +#include <stdlib.h>
> +
> +/* We should disambiguate
> +     int *
> +   and
> +     struct a *
> +   despite the fact they get same alias set because struct a is incomplete.  
> */
> +
> +typedef int (*fnptr) ();
> +
> +__attribute__ ((used))
> +struct
> +{
> +  int *a;
> +} a, *aptr = &a;
> +
> +struct a **bptr;
> +
> +static void
> +inline_me_late (int argc)
> +{
> +  if (argc == -1)
> +    *bptr = (void *)(size_t)1;
> +}
> +
> +int
> +main (int argc)
> +{
> +  typeof (aptr) aptr2 = aptr;
> +  aptr2->a = 0;
> +  inline_me_late (argc);
> +  if (!__builtin_constant_p (aptr2->a == 0))
> +    __builtin_abort ();
> +  return 0;
> +}
> Index: tree-ssa-alias.c
> ===================================================================
> --- tree-ssa-alias.c  (revision 272037)
> +++ tree-ssa-alias.c  (working copy)
> @@ -791,10 +791,39 @@ same_type_for_tbaa (tree type1, tree typ
>    if (type1 == type2)
>      return 1;
>  
> +  /* For LTO we do not define canonical types of pointers.  Look into
> +     corresponding pointed-to-types.  To speed non-LTO checks,
> +     do not bother to do that if canonical types are defined though.  */
> +  while (POINTER_TYPE_P (type1) && POINTER_TYPE_P (type2)
> +       && (TYPE_STRUCTURAL_EQUALITY_P (type1)
> +           || TYPE_STRUCTURAL_EQUALITY_P (type2)))
> +    {
> +      type1 = TREE_TYPE (type1);
> +      type2 = TREE_TYPE (type2);
> +      /* As an extension, we consider void pointer TBAA compatible with all
> +      other pointer types.  This is especially importnat in LTO where
> +      non-C languages may want to bind to C pointers via void *.  */
> +      if (VOID_TYPE_P (type1) || VOID_TYPE_P (type2))
> +     return 1;
> +    }
> +
>    /* If we would have to do structural comparison bail out.  */
>    if (TYPE_STRUCTURAL_EQUALITY_P (type1)
>        || TYPE_STRUCTURAL_EQUALITY_P (type2))
> -    return -1;
> +    {
> +      /* If type1 and type2 are diferent kinds, return 0.
> +      This is important espcially when we hit incomplete types or
> +      function/method types after walking pointed-to types above.
> +
> +      ??? As a special case we want to consider ARRAY_TYPE possibly
> +      same as its base type to solve some issues with Fortran frontend.  */
> +      if (TREE_CODE (type1) != ARRAY_TYPE
> +       && TREE_CODE (type2) != ARRAY_TYPE
> +       && tree_code_for_canonical_type_merging (TREE_CODE (type1))
> +          != tree_code_for_canonical_type_merging (TREE_CODE (type2)))
> +     return 0;
> +      return -1;
> +    }
>  
>    /* Compare the canonical types.  */
>    if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
> 

-- 
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)

Reply via email to