https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107666
--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Martin Jambor <[email protected]>: https://gcc.gnu.org/g:7b3af2bfa1dee9a3e90de4d1c4bc03d73f825898 commit r16-6150-g7b3af2bfa1dee9a3e90de4d1c4bc03d73f825898 Author: Martin Jambor <[email protected]> Date: Tue Dec 16 00:44:45 2025 +0100 ipa-devirt: Add speculative direct calls based on stores to structures This patch extends the ipa-devirt pass with the ability to add speculative calls for indirect calls where the target was loaded from a record_type data structure and we have seen writes of address of only one particular function to the same offset of that record type (including static initializers). The idea is basically taken from Christoph Müllner's patch from 2022 (https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605934.html) but I have re-worked it so that it stores the required information in GC memory (which I belive is necessary) and does not require an additional pass through gimple statements of all functions because it uses the analysis phase of ipa-cp/ipa-fnsummary (which was an approach we agreed on with Honza). It also performs simple verification that the collected types match the type of the record field. We could verify that the function determined as the likely target matches the call statement expectations, but for that we would need to stream both types which is something I decided not to do. Co-authored by: Christoph Müllner <[email protected]> gcc/ChangeLog: 2025-11-28 Martin Jambor <[email protected]> PR ipa/107666 * common.opt (fspeculatively-call-stored-functions): New. * cgraph.h (cgraph_simple_indirect_info): New fields rec_type and fld_offset. * ipa-prop.h (ipa_analyze_var_static_initializer): Declare. (ipa_dump_noted_record_fnptrs): Likewise. (ipa_debug_noted_record_fnptrs): Likewise. (ipa_single_noted_fnptr_in_record): Likewise. (ipa_free_noted_fnptr_calls): Likewise. * ipa-cp.cc (ipcp_generate_summary): Call ipa_analyze_var_static_initializer on each varbool node with a static initializer. * ipa-devirt.cc (struct devirt_stats): New type. (devirt_target_ok_p): New function. (ipa_devirt): Move statistics counters to the new structure. dump noted function pointers stored in records. Check for edge hotness first and for odr_types only for polymorphic edges. Moved a number of checks to devirt_target_ok_p. Also add speculative direct calls for non-polymorphic indirect ones when ipa_single_noted_fnptr_in_record finds a likely target. Call ipa_free_noted_fnptr_calls. (pass_ipa_devirt::gate): Also check the new flag. * ipa-prop.cc (noted_fnptr_store): New type. (struct noted_fnptr_hasher): Likewise. (noted_fnptr_hasher::hash): New function. (noted_fnptr_hasher::equal): Likewise. (noted_fnptrs_in_records): New. (is_func_ptr_from_record): New function. (ipa_analyze_indirect_call_uses): Also simple create indirect info structures with fnptr_loaded_from_record set. (note_fnptr_in_record): New function. (ipa_dump_noted_record_fnptrs): Likewise. (ipa_debug_noted_record_fnptrs): Likewise. (ipa_single_noted_fnptr_in_record): Likewise. (ipa_free_noted_fnptr_calls): Likewise. (ipa_analyze_stmt_uses): Also look for stroes of function pointers to record structures. (ipa_analyze_var_static_initializer): New function. (ipa_write_indirect_edge_info): Also stream fnptr_loaded_from_record indirec infos. (ipa_read_indirect_edge_info): Likewise. (ipa_prop_write_jump_functions): Also stream the contents of noted_fnptrs_in_records. (ipa_prop_read_section): Likewise. * opts.cc (default_options_table): Also turn on OPT_fspeculatively_call_stored_functions at -O2. (common_handle_option): Turn flag_speculatively_call_stored_functions when using profile feedback. * doc/invoke.texi (-fspeculatively-call-stored-functions): New. gcc/testsuite/ChangeLog: 2025-10-24 Martin Jambor <[email protected]> * gcc.dg/lto/fnptr-from-rec-1_0.c: New test. * gcc.dg/lto/fnptr-from-rec-1_1.c: Likewise. * gcc.dg/lto/fnptr-from-rec-2_0.c: Likewise. * gcc.dg/lto/fnptr-from-rec-2_1.c: Likewise. * gcc.dg/lto/fnptr-from-rec-3_0.c: Likewise. * gcc.dg/lto/fnptr-from-rec-3_1.c: Likewise.
