Hello,
On Thu, Dec 11 2025, Jan Hubicka wrote:
>> 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 .
That would be nice but unfortunately gengtype cannot cope with it:
build/gengtype \
-S /home/mjambor/gcc/mine/src/gcc -I gtyp-input.list -w
tmp-gtype.state
/home/mjambor/gcc/mine/src/gcc/cgraph.h:1732: parse error: enum definitions not
supported in structures marked with automatic GTY markers. Use GTY((user)) to
mark this structure.
>> + /* 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.
We can extend this as needed, of course.
>
> The patch is OK.
> honza
Thanks. I'm re-testing a re-based original patch and plan to push it to
master soon.
Thanks,
Martin