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