> gcc/ChangeLog:
>
> 2025-10-17 Martin Jambor <[email protected]>
>
> * cgraph.h (cgraph_node): Adjust the comment of member function
> create_indirect_edge.
> (enum cgraph_indirect_info_kind): New.
> (cgraph_indirect_call_info): Convert into a base class.
> (cgraph_simple_indirect_info): New.
> (cgraph_polymorphic_indirect_info): Likewise.
> (usable_polymorphic_info_p): Likewise.
> (is_a_helper <cgraph_simple_indirect_info *>::test): Likewise.
> (is_a_helper <cgraph_polymorphic_indirect_info *>::test): Likewise.
> (cgraph_allocate_init_indirect_info): Remove declaration.
> (ipa_polymorphic_call_context::ipa_polymorphic_call_context): Use the
> appropriate derived type of indirect info.
> * cgraph.cc (cgraph_allocate_init_indirect_info): Removed.
> (cgraph_node::create_indirect_edge): Create an appropriate type of
> indirect_info.
> (cgraph_node::dump): Dump indirect info using its dump function.
> (cgraph_indirect_call_info::dump): New function.
> (cgraph_indirect_call_info::debug): Likewise.
> * cgraphclones.cc (cgraph_edge::clone): Create an appropriate type of
> indirect_info.
> * cgraphunit.cc (analyze_functions): Use the appropriate derived type
> of indirect info.
> * ipa-cp.cc (initialize_node_lattices): Adjust the check for
> polymorphic indirect info.
> (ipa_get_indirect_edge_target_1): Use the appropriate derived types of
> indirect info.
> (ipcp_discover_new_direct_edges): Likewise.
> * ipa-devirt.cc (ipa_devirt): Use the polymorphis derived type of
> indirect info and check that it is usable.
> * ipa-inline.cc (dump_inline_stats): Adjust the check for polymorphic
> indirect info.
> * ipa-profile.cc (ipa_profile): Likewise and check usability.
> * ipa-prop.cc (ipa_print_node_jump_functions): Dump indirect info
> using its dumping member function.
> (ipa_note_param_call): Removed.
> (ipa_analyze_indirect_call_uses): Use the appropriate derived type of
> indirect info, set all fields of indirect info separately rather than
> relying on ipa_note_param_call.
> (ipa_analyze_virtual_call_uses): Use the polymorphis derived type of
> indirect info and check that it is usable, set all fields of indirect
> info separately rather than relying on ipa_note_param_call.
> (ipa_analyze_call_uses): Use the appropriate derived type of indirect
> info.
> (ipa_make_edge_direct_to_target): Use the appropriate derived type of
> indirect info. Remove wrong note that member_ptr check was not
> needed. Adjust check for polymorphic call when dumping.
> (try_make_edge_direct_simple_call): Use the appropriate derived type
> of indirect info.
> (try_make_edge_direct_virtual_call): Use the polymorphis derived type
> of indirect info and check that it is usable.
> (update_indirect_edges_after_inlining): Use the appropriate derived
> type of indirect info. Define local variables only before their first
> use.
> (ipa_write_indirect_edge_info): Also stream indirect info kind. Use
> the appropriate derived type of indirect info.
> (ipa_read_indirect_edge_info): Check that the streamed in indirect
> info kind matches rthe structure at hand. Use the appropriate derived
> type of indirect info.
> * ipa-utils.h (possible_polymorphic_call_targets): Use the
> polymorphis derived type of indirect info. Assert it is usable.
> (dump_possible_polymorphic_call_targets): Use the polymorphis
> derived type of indirect info and check it is usable.
> (possible_polymorphic_call_target_p): Likewise.
> * ipa.cc (symbol_table::remove_unreachable_nodes): Use
> usable_polymorphic_info_p.
> * lto-cgraph.cc (lto_output_edge): Stream indirect info kind.
> (compute_ltrans_boundary): Use usable_polymorphic_info_p.
> (input_edge): Move definition of ecf_flags before its first use.
> Pass true as the last parameter to create_indirect_edge. Stream
> indirect info kind and create a corresponding type to hold the
> information.
> * trans-mem.cc (ipa_tm_insert_gettmclone_call): Use the
> polymorphis derived type of indirect info.
> -/* Structure containing additional information about an indirect call. */
> +/* Denotes the kind of call that a particular cgraph_indirect_call_info
> + instance describes. */
> +
> +enum cgraph_indirect_info_kind {
> + /* Unspecified kind. Only to be used when no information about the call
> + statement is available or it does not fall into any of the other
> + categories. */
> + CIIK_UNSPECIFIED,
I guess alternative to CIIK prefixes avoiding namespace polution
would be to put the enum into chraph_indirect_call_info itself .
> + /* A normal indirect call when the target is an SSA_NAME. */
> + CIIK_SIMPLE,
> + /* Call of a virtual method when the target is an OBJ_TYPE_REF which
> conforms
> + to virtual_method_call_p. */
> + CIIK_POLYMORPHIC,
> + /* Must be last */
> + CIIK_N_KINDS
> +};
> +
> +/* The base class containing additional information about all kinds of
> indirect
> + calls. It can also be used when no information about the call statement
> is
> + available or it does not fall into any of the other categories. */
>
> -class GTY(()) cgraph_indirect_call_info
> +class GTY((desc ("%h.kind"), tag ("CIIK_UNSPECIFIED")))
> + cgraph_indirect_call_info
> {
> public:
> - /* When agg_content is set, an offset where the call pointer is located
> - within the aggregate. */
> - HOST_WIDE_INT offset;
> - /* Context of the polymorphic call; use only when POLYMORPHIC flag is set.
> */
> - ipa_polymorphic_call_context context;
> - /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set). */
> - HOST_WIDE_INT otr_token;
> - /* Type of the object from OBJ_TYPE_REF_OBJECT. */
> - tree otr_type;
> - /* Index of the parameter that is called. */
> - int param_index;
> + cgraph_indirect_call_info (int flags)
> + : ecf_flags (flags), param_index (-1), kind (CIIK_UNSPECIFIED),
> + num_speculative_call_targets (0) {}
> + cgraph_indirect_call_info (enum cgraph_indirect_info_kind k, int flags)
> + : ecf_flags (flags), param_index (-1), kind (k),
> + num_speculative_call_targets (0) {}
> +
> + /* Dump human readable information about the indirect call to F. If
> NEWLINE
> + is true, it will be terminated by a newline. */
> + void dump (FILE *f, bool newline = true) const;
> + void DEBUG_FUNCTION debug () const;
> +
> /* ECF flags determined from the caller. */
> int ecf_flags;
> + /* If we can relate this call target to a specific formal parameter of the
> + caller, then this is its index. Otherwise set to -1. */
> + int param_index;
>
> - /* Number of speculative call targets, it's less than GCOV_TOPN_VALUES. */
> + /* Identifier of the specific type of indirect info this actually is. */
> + enum cgraph_indirect_info_kind kind : 2;
> + /* Number of speculative call targets. */
> unsigned num_speculative_call_targets : 16;
> +};
> +
> +/* Structure containing additional information about non-virtual indirect
> calls
> + where the target is an SSA_NAME. */
> +
> +class GTY((tag ("CIIK_SIMPLE")))
> + cgraph_simple_indirect_info : public cgraph_indirect_call_info
> +{
> +public:
> + cgraph_simple_indirect_info (int flags)
> + : cgraph_indirect_call_info (CIIK_SIMPLE, flags), offset (0),
> + agg_contents (false), member_ptr (false), by_ref (false),
> + guaranteed_unmodified (false)
> + {}
> +
> + /* When agg_content is set, an offset where the call pointer is located
> + within the aggregate. */
> + HOST_WIDE_INT offset;
>
> - /* Set when the call is a virtual call with the parameter being the
> - associated object pointer rather than a simple direct call. */
> - unsigned polymorphic : 1;
> /* Set when the call is a call of a pointer loaded from contents of an
> aggregate at offset. */
> unsigned agg_contents : 1;
> @@ -1723,11 +1767,69 @@ public:
> never modified between the invocation of the function and the load
> point. */
> unsigned guaranteed_unmodified : 1;
> +};
> +
> +/* Structure containing additional information about non-virtual indirect
> calls
> + when the target is an OBJ_TYPE_REF which conforms to
> + virtual_method_call_p. */
> +
> +class GTY((tag ("CIIK_POLYMORPHIC")))
> + cgraph_polymorphic_indirect_info : public cgraph_indirect_call_info
> +{
> +public:
> + cgraph_polymorphic_indirect_info (int flags)
> + : cgraph_indirect_call_info (CIIK_POLYMORPHIC, flags), context (),
> + otr_token (0), otr_type (nullptr), offset (0), vptr_changed (true)
> + {}
> + cgraph_polymorphic_indirect_info (int flags,
> + const ipa_polymorphic_call_context &ctx,
> + HOST_WIDE_INT token, tree type)
> + : cgraph_indirect_call_info (CIIK_POLYMORPHIC, flags), context (ctx),
> + otr_token (token), otr_type (type), offset (0), vptr_changed (true)
> + {}
I suppose if we will be able to represent C-style virtual tables (i.e.
call via pointers to constant arrays of pointers) we may end up with
calls that are both polymorphic and tracked by ipa-cp, so we may want to
have common sucessor of simple and polymorphic.
The patch is OK.
honza