https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114931

--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #12)
> Anyway, such changes are a partial shift towards the model to update derived
> types which you said you don't want; it doesn't actually update them, but
> basically forces new types after the base type(s) is/are finalized.

Yes, I was wondering if when we make TYPE_STRUCTURAL_EQUALITY_P part of
the hash we're papering over the issue that we have recorded equal types
we didn't mark for structural compare.  Though that would only be a missed
optimization I think (setting TYPE_STRUCTURAL_EQUALITY_P is).

> Another possibility might be simply in all the spots where we set
> TYPE_CANONICAL (t) = something; to add if (TYPE_STRUCTURAL_EQUALITY_P
> (TYPE_CANONICAL (t))) SET_TYPE_STRUCTURAL_EQUALITY (t);

But if TYPE_STRUCTURAL_EQUALITY_P (TYPE_CANONICAL (t)) then that canonical
type is broken.  We should avoid (at all cost) creating such a type.

> On the build_function_type it could be
> --- gcc/tree.cc.jj    2024-04-16 09:56:16.463008446 +0200
> +++ gcc/tree.cc       2024-05-03 10:21:04.119086667 +0200
> @@ -7511,17 +7511,25 @@ build_function_type (tree value_type, tr
>    hashval_t hash = type_hash_canon_hash (t);
>    t = type_hash_canon (hash, t);
>  
> -  /* Set up the canonical type. */
> -  any_structural_p   = TYPE_STRUCTURAL_EQUALITY_P (value_type);
> -  any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
> -  canon_argtypes = maybe_canonicalize_argtypes (arg_types,
> -                                             &any_structural_p,
> -                                             &any_noncanonical_p);
> -  if (any_structural_p)
> -    SET_TYPE_STRUCTURAL_EQUALITY (t);
> -  else if (any_noncanonical_p)
> -    TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type),
> -                                           canon_argtypes);
> +  if (TYPE_CANONICAL (t) == t)
> +    {
> +      /* Set up the canonical type. */
> +      any_structural_p = TYPE_STRUCTURAL_EQUALITY_P (value_type);
> +      any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
> +      canon_argtypes = maybe_canonicalize_argtypes (arg_types,
> +                                                 &any_structural_p,
> +                                                 &any_noncanonical_p);
> +      if (any_structural_p)
> +     SET_TYPE_STRUCTURAL_EQUALITY (t);
> +      else if (any_noncanonical_p)
> +     {
> +       TYPE_CANONICAL (t)
> +         = build_function_type (TYPE_CANONICAL (value_type),
> +                                canon_argtypes);

we shouldn't get a structual equality type here when !any_structural_p

Yes, ensuring this within type_hash_canon only papers over the issue in
different ways (to some extent).  But this is how things are.

I guess another option might be to have the FE set TYPE_STRUCTURAL_EQUALITY_P
on _all_ types that possibly get "finalized" only later and have a second
sweep over all those types after the unit is finished and recompute
TYPE_CANONICAL there, making sure to catch all derived types.  Like LTO
re-computes TYPE_CANONICAL.

> +       if (TYPE_STRUCTURAL_EQUALITY_P (TYPE_CANONICAL (t)))
> +         SET_TYPE_STRUCTURAL_EQUALITY (t);
> +     }
> +    }
>  
>    if (!COMPLETE_TYPE_P (t))
>      layout_type (t);

Reply via email to