> I don't think it works like this, peeling arrays/vectors from
> types individually instead of in lock-step?
> 
> I think for better testing coverage you want to force
> TYPE_STRUCTURAL_EQUALITY on all types here - this shouldn't
> make things invalid but otherwise these code-paths are not
> tested very well.

Here is coverage of the function compiling tramp3d with -flto.
All the paths through are relatively frequent.
Most of time we call function for case where type1 and type2 have same
main variants.  Out of 1.5m remaining cases approx 30k are
pointers/arrays and go the structural walk which in 17k cases goes to
mismatched pointer types.

2k cases are considered equivalent because of canonical check and
126k cases we disprove equivalence.

        -:  780:/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent 
for the
        -:  781:   purpose of TBAA.  Return 0 if they are distinct and -1 if we 
cannot
        -:  782:   decide.  */
        -:  783:
        -:  784:static inline int
   669818:  785:same_type_for_tbaa (tree type1, tree type2)
        -:  786:{
   669818:  787:  type1 = TYPE_MAIN_VARIANT (type1);
   669818:  788:  type2 = TYPE_MAIN_VARIANT (type2);
        -:  789:
        -:  790:  /* If same_type_for_tbaa returns true we make an assumption 
that pointers to
        -:  791:     TYPE1 and TYPE2 can either point to same copy of the type 
or completely
        -:  792:     different.
        -:  793:
        -:  794:     This is not necessarily true for arrays where overlap can 
be partial
        -:  795:     as in gcc.dg/torture/alias-2.c.  So we can only prove that 
arrays are
        -:  796:     disjoint becuase they are derived from different types but 
we can not
        -:  797:     prove they are same.
        -:  798:
        -:  799:     On the other hand for pointers we can always consider them 
to be same
        -:  800:     unless we can prove that pointed-to types are different.
        -:  801:
        -:  802:     So normally return values are
        -:  803:       0  if types are known to be different
        -:  804:       1  if types are same and there is no partial overlap
        -:  805:       -1 otherwise.
        -:  806:
        -:  807:     However if comparing two pointers return values are
        -:  808:       0  if pointed to types are known to be different
        -:  809:       1  otherwise (because partial overlaps do not happen).
        -:  810:
        -:  811:     If comparing array or vector to other type return values 
are
        -:  812:       0  if types array/vector are derived from are known to 
be different
        -:  813:       -1 otherwise (to watch for partial overlaps).  */
        -:  814:
   669818:  815:  bool in_ptr = false;
   669818:  816:  bool in_array = false;
        -:  817:
   669818:  818:  if (type1 == type2)
   515089:  819:    return 1;
        -:  820:
        -:  821:  /* Do structural comparsion for types that have no canonical 
types in LTO.  */
   162119:  822:  while (TYPE_STRUCTURAL_EQUALITY_P (type1)
   162119:  823:         || TYPE_STRUCTURAL_EQUALITY_P (type2))
        -:  824:    {
        -:  825:      /* Pointer types are same if they point to same types.  */
    30761:  826:      if (POINTER_TYPE_P (type1) && POINTER_TYPE_P (type2))
        -:  827:        {
     4662:  828:          type1 = TYPE_MAIN_VARIANT (TREE_TYPE (type1));
     4662:  829:          type2 = TYPE_MAIN_VARIANT (TREE_TYPE (type2));
     4662:  830:          if (!in_array)
     4662:  831:            in_ptr = true;
        -:  832:        }
        -:  833:      /* Peel out arrays and vector to compare inner types.  */
    52198:  834:      else if ((TREE_CODE (type1) == ARRAY_TYPE
    23728:  835:                || TREE_CODE (type1) == VECTOR_TYPE)
    49827:  836:               && TYPE_STRUCTURAL_EQUALITY_P (type1))
        -:  837:        {
     2371:  838:          type1 = TYPE_MAIN_VARIANT (TREE_TYPE (type1));
     2371:  839:          if (!in_ptr)
     2371:  840:            in_array = true;
        -:  841:        }
    47456:  842:      else if ((TREE_CODE (type2) == ARRAY_TYPE
    21042:  843:                || TREE_CODE (type2) == VECTOR_TYPE)
    44770:  844:               && TYPE_STRUCTURAL_EQUALITY_P (type2))
        -:  845:        {
     2686:  846:          type2 = TYPE_MAIN_VARIANT (TREE_TYPE (type2));
     2686:  847:          if (!in_ptr)
     2686:  848:            in_array = true;
        -:  849:        }
        -:  850:      else
        -:  851:        {
    21042:  852:          if (POINTER_TYPE_P (type1) != POINTER_TYPE_P (type2))
    17208:  853:            return 0;
    3834*:  854:          return in_ptr ? 1 : -1;
        -:  855:        }
        -:  856:
     9719:  857:      if (type1 == type2)
     2329:  858:        return in_array ? -1 : 1;
        -:  859:    }
        -:  860:
        -:  861:  /* Compare the canonical types.  */
   131358:  862:  if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
    2604*:  863:    return in_array ? -1 : 1;
        -:  864:
        -:  865:  /* ??? Array types are not properly unified in all cases as 
we have
        -:  866:     spurious changes in the index types for example.  Removing 
this
        -:  867:     causes all sorts of problems with the Fortran frontend.  */
   128754:  868:  if (TREE_CODE (type1) == ARRAY_TYPE
    #####:  869:      && TREE_CODE (type2) == ARRAY_TYPE)
    #####:  870:    return in_ptr ? 1 : -1;
        -:  871:
        -:  872:  /* ??? In Ada, an lvalue of an unconstrained type can be used 
to access an
        -:  873:     object of one of its constrained subtypes, e.g. when a 
function with an
        -:  874:     unconstrained parameter passed by reference is called on 
an object and
        -:  875:     inlined.  But, even in the case of a fixed size, type and 
subtypes are
        -:  876:     not equivalent enough as to share the same TYPE_CANONICAL, 
since this
        -:  877:     would mean that conversions between them are useless, 
whereas they are
        -:  878:     not (e.g. type and subtypes can have different modes).  
So, in the end,
        -:  879:     they are only guaranteed to have the same alias set.  */
   128754:  880:  if (get_alias_set (type1) == get_alias_set (type2))
    1950*:  881:    return in_ptr ? 1 : -1;
        -:  882:
        -:  883:  /* The types are known to be not equal.  */
   126804:  884:  return 0;
        -:  885:}

Here is profile with unpatched version

        -:  780:/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent 
for the
        -:  781:   purpose of TBAA.  Return 0 if they are distinct and -1 if we 
cannot
        -:  782:   decide.  */
        -:  783:
        -:  784:static inline int
   610943:  785:same_type_for_tbaa (tree type1, tree type2)
        -:  786:{
   610943:  787:  type1 = TYPE_MAIN_VARIANT (type1);
   610943:  788:  type2 = TYPE_MAIN_VARIANT (type2);
        -:  789:
        -:  790:  /* If we would have to do structural comparison bail out.  */
   610943:  791:  if (TYPE_STRUCTURAL_EQUALITY_P (type1)
   610943:  792:      || TYPE_STRUCTURAL_EQUALITY_P (type2))
    36090:  793:    return -1;
        -:  794:
        -:  795:  /* Compare the canonical types.  */
   574853:  796:  if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
   452828:  797:    return 1;
        -:  798:
        -:  799:  /* ??? Array types are not properly unified in all cases as 
we have
        -:  800:     spurious changes in the index types for example.  Removing 
this
        -:  801:     causes all sorts of problems with the Fortran frontend.  */
   122025:  802:  if (TREE_CODE (type1) == ARRAY_TYPE
    #####:  803:      && TREE_CODE (type2) == ARRAY_TYPE)
    #####:  804:    return -1;
        -:  805:
        -:  806:  /* ??? In Ada, an lvalue of an unconstrained type can be used 
to access an
        -:  807:     object of one of its constrained subtypes, e.g. when a 
function with an
        -:  808:     unconstrained parameter passed by reference is called on 
an object and
        -:  809:     inlined.  But, even in the case of a fixed size, type and 
subtypes are
        -:  810:     not equivalent enough as to share the same TYPE_CANONICAL, 
since this
        -:  811:     would mean that conversions between them are useless, 
whereas they are
        -:  812:     not (e.g. type and subtypes can have different modes).  
So, in the end,
        -:  813:     they are only guaranteed to have the same alias set.  */
   122025:  814:  if (get_alias_set (type1) == get_alias_set (type2))
     1945:  815:    return -1;
        -:  816:
        -:  817:  /* The types are known to be not equal.  */
   120080:  818:  return 0;
        -:  819:}

I have started bootstrap where the pointer and array walks are forced
even for non-lto builds.
Honza

Reply via email to