commit: 18415f19318fe277944953e2e1ec5ffcef125edf Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Tue Apr 15 21:08:41 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Tue Apr 15 21:08:41 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=18415f19
15.0.0: update IPA-VRP vs LTO patch >From Honza at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119614#c37. Signed-off-by: Sam James <sam <AT> gentoo.org> 15.0.0/gentoo/85_all_PR119614-ipa-vrp-lto.patch | 394 +++++++++--------------- 1 file changed, 153 insertions(+), 241 deletions(-) diff --git a/15.0.0/gentoo/85_all_PR119614-ipa-vrp-lto.patch b/15.0.0/gentoo/85_all_PR119614-ipa-vrp-lto.patch index 3049a2f..304b376 100644 --- a/15.0.0/gentoo/85_all_PR119614-ipa-vrp-lto.patch +++ b/15.0.0/gentoo/85_all_PR119614-ipa-vrp-lto.patch @@ -1,274 +1,186 @@ -https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119614#c32 -diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc -index 26b1496f29b..9b47c6c364d 100644 ---- a/gcc/ipa-cp.cc -+++ b/gcc/ipa-cp.cc -@@ -6334,6 +6334,13 @@ ipcp_store_vr_results (void) - - if (info->ipcp_orig_node) - info = ipa_node_params_sum->get (info->ipcp_orig_node); -+ -+ if (do_vr && info->m_return_vr) -+ { -+ clone_info *clone_info = clone_info::get_create (node); -+ clone_info->m_return_vr = info->m_return_vr; -+ } -+ - if (info->lattices.is_empty ()) - /* Newly expanded artificial thunks do not have lattices. */ - continue; +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119614#c37 + + PR tree-optimization/119614 + +gcc/ChangeLog: + + * ipa-prop.cc (ipa_write_return_summaries): New function. + (ipa_record_return_value_range_1): Break out from ... + (ipa_record_return_value_range): ... here. + (ipa_read_return_summaries): New function. + (ipa_prop_read_section): Read return summaries. + (read_ipcp_transformation_info): Read return summaries. + (ipcp_write_transformation_summaries): write return summaries + +gcc/testsuite/ChangeLog: + + * g++.dg/lto/pr119614_0.C: New test. + diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc -index 49d68ab044b..eb757658ad7 100644 +index 49d68ab044b..4a83062bfcc 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc -@@ -2323,6 +2323,27 @@ ipa_get_value_range (const vrange &tmp) - return vr; +@@ -5439,6 +5439,49 @@ ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node, + } } -+/* Read an IPA-VR from IB and DATA_IN. If it does not contain useful info, -+ return nullptr. If it is already in the hash of IPA-VRs, return the already -+ present value, otherwise add it to the hash and return this new value. */ -+ -+ipa_vr * -+streamer_read_and_hash (lto_input_block *ib, data_in *data_in) ++/* Stream out ipa_return_summary. */ ++static void ++ipa_write_return_summaries (output_block *ob) +{ -+ ipa_vr ivr; -+ ivr.streamer_read (ib, data_in); -+ if (ivr.known_p ()) ++ if (!ipa_return_value_sum) + { -+ if (!ipa_vr_hash_table) -+ ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37); ++ streamer_write_uhwi (ob, 0); ++ return; ++ } + -+ value_range tmp; -+ ivr.get_vrange (tmp); -+ return ipa_get_value_range (tmp); ++ lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder; ++ unsigned int count = 0; ++ for (int i = 0; i < lto_symtab_encoder_size (encoder); i++) ++ { ++ symtab_node *snode = lto_symtab_encoder_deref (encoder, i); ++ cgraph_node *cnode = dyn_cast <cgraph_node *> (snode); ++ ipa_return_value_summary *v; ++ ++ if (cnode && cnode->definition && !cnode->alias ++ && (v = ipa_return_value_sum->get (cnode)) ++ && v->vr) ++ count++; + } -+ return nullptr; -+} ++ streamer_write_uhwi (ob, count); + - /* Assign to JF a pointer to a range just like TMP but either fetch a - copy from ipa_vr_hash_table or allocate a new on in GC memory. */ - -@@ -3312,6 +3333,14 @@ ipa_analyze_node (struct cgraph_node *node) - analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun)); - disable_ranger (cfun); - -+ ipa_return_value_summary *rvs; ++ for (int i = 0; i < lto_symtab_encoder_size (encoder); i++) ++ { ++ symtab_node *snode = lto_symtab_encoder_deref (encoder, i); ++ cgraph_node *cnode = dyn_cast <cgraph_node *> (snode); ++ ipa_return_value_summary *v; + -+ if (ipa_return_value_sum -+ && (rvs = ipa_return_value_sum->get (node))) -+ /* The VRs in the summary already live in the cache, no need to go through -+ ipa_get_value_range. */ -+ info->m_return_vr = rvs->vr; ++ if (cnode && cnode->definition && !cnode->alias ++ && (v = ipa_return_value_sum->get (cnode)) ++ && v->vr) ++ { ++ streamer_write_uhwi ++ (ob, ++ lto_symtab_encoder_encode (encoder, cnode)); ++ v->vr->streamer_write (ob); ++ } ++ } ++} + - ipa_release_body_info (&fbi); - free_dominance_info (CDI_DOMINATORS); - pop_cfun (); -@@ -4793,6 +4822,8 @@ ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *, - new_info->known_csts = old_info->known_csts.copy (); - new_info->known_contexts = old_info->known_contexts.copy (); + /* Write jump functions for nodes in SET. */ -+ new_info->m_return_vr = old_info->m_return_vr; + void +@@ -5476,10 +5519,54 @@ ipa_prop_write_jump_functions (void) + ipa_write_node_info (ob, node); + } + streamer_write_char_stream (ob->main_stream, 0); ++ ipa_write_return_summaries (ob); + produce_asm (ob); + destroy_output_block (ob); + } + ++/* Record that current function return value range is VAL. */ + - new_info->analysis_done = old_info->analysis_done; - new_info->node_enqueued = old_info->node_enqueued; - new_info->versionable = old_info->versionable; -@@ -5272,6 +5303,15 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) - streamer_write_uhwi (ob, ipa_get_param_count (info)); - for (j = 0; j < ipa_get_param_count (info); j++) - streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j)); -+ if (info->m_return_vr) -+ info->m_return_vr->streamer_write (ob); -+ else ++static void ++ipa_record_return_value_range_1 (cgraph_node *n, value_range val) ++{ ++ if (!ipa_return_value_sum) + { -+ bp = bitpack_create (ob->main_stream); -+ bp_pack_value (&bp, false, 1); -+ streamer_write_bitpack (&bp); ++ if (!ipa_vr_hash_table) ++ ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37); ++ ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ()) ++ ipa_return_value_sum_t (symtab, true); ++ ipa_return_value_sum->disable_insertion_hook (); + } -+ - bp = bitpack_create (ob->main_stream); - gcc_assert (info->analysis_done - || ipa_get_param_count (info) == 0); -@@ -5407,6 +5447,15 @@ ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node, - for (k = 0; k < param_count; k++) - streamer_read_uhwi (ib); - -+ ipa_vr rvr; -+ rvr.streamer_read (ib, data_in); -+ if (prevails && rvr.known_p ()) ++ ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val); ++ if (dump_file && (dump_flags & TDF_DETAILS)) + { -+ value_range tmp; -+ rvr.get_vrange (tmp); -+ info->m_return_vr = ipa_get_value_range (tmp); ++ fprintf (dump_file, "Recording return range "); ++ val.dump (dump_file); ++ fprintf (dump_file, "\n"); + } ++} + - bp = streamer_read_bitpack (ib); - for (k = 0; k < param_count; k++) - { -@@ -6218,7 +6267,7 @@ bool - ipa_return_value_range (value_range &range, tree decl) - { - cgraph_node *n = cgraph_node::get (decl); -- if (!n || !ipa_return_value_sum) -+ if (!n) - return false; - enum availability avail; - n = n->ultimate_alias_target (&avail); -@@ -6226,11 +6275,24 @@ ipa_return_value_range (value_range &range, tree decl) - return false; - if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl))) - return false; -- ipa_return_value_summary *v = ipa_return_value_sum->get (n); -- if (!v) -- return false; -- v->vr->get_vrange (range); -- return true; -+ -+ if (ipa_return_value_sum) ++/* Stream out ipa_return_summary. */ ++static void ++ipa_read_return_summaries (lto_input_block *ib, ++ struct lto_file_decl_data *file_data, ++ class data_in *data_in) ++{ ++ unsigned int f_count = streamer_read_uhwi (ib); ++ for (unsigned int i = 0; i < f_count; i++) + { -+ if (ipa_return_value_summary *v = ipa_return_value_sum->get (n)) -+ { -+ v->vr->get_vrange (range); -+ return true; -+ } ++ unsigned int index = streamer_read_uhwi (ib); ++ lto_symtab_encoder_t encoder = file_data->symtab_node_encoder; ++ struct cgraph_node *node = dyn_cast <cgraph_node *> (lto_symtab_encoder_deref (encoder, ++ index)); ++ ipa_vr rvr; ++ rvr.streamer_read (ib, data_in); ++ value_range tmp; ++ rvr.get_vrange (tmp); ++ ipa_record_return_value_range_1 (node, tmp); + } ++} + -+ clone_info *info = clone_info::get (n); -+ if (info && info->m_return_vr) -+ { -+ gcc_assert (info->m_return_vr->known_p ()); -+ info->m_return_vr->get_vrange (range); -+ return true; -+ } -+ return false; - } + /* Read section in file FILE_DATA of length LEN with data DATA. */ - /* Reset all state within ipa-prop.cc so that we can rerun the compiler -diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h -index 3bd442fff39..8dc8e2f2ab5 100644 ---- a/gcc/ipa-prop.h -+++ b/gcc/ipa-prop.h -@@ -653,6 +653,9 @@ public: - /* If this node is an ipa-cp clone, these are the known polymorphic contexts - that describe what it has been specialized for. */ - vec<ipa_polymorphic_call_context> GTY((skip)) known_contexts; -+ /* If non-NULL, the known value range of the return value of this -+ function. */ -+ class ipa_vr *m_return_vr; - /* Whether the param uses analysis and jump function computation has already - been performed. */ - unsigned analysis_done : 1; -@@ -679,10 +682,10 @@ public: - inline - ipa_node_params::ipa_node_params () - : descriptors (NULL), lattices (vNULL), ipcp_orig_node (NULL), -- known_csts (vNULL), known_contexts (vNULL), analysis_done (0), -- node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0), -- node_dead (0), node_within_scc (0), node_is_self_scc (0), -- node_calling_single_call (0), versionable (0) -+ known_csts (vNULL), known_contexts (vNULL), m_return_vr (nullptr), -+ analysis_done (0), node_enqueued (0), do_clone_for_all_contexts (0), -+ is_all_contexts_clone (0), node_dead (0), node_within_scc (0), -+ node_is_self_scc (0), node_calling_single_call (0), versionable (0) - { + static void +@@ -5516,6 +5603,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data, + gcc_assert (node->definition); + ipa_read_node_info (&ib_main, node, data_in); + } ++ ipa_read_return_summaries (&ib_main, file_data, data_in); + lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data, + len); + lto_data_in_delete (data_in); +@@ -5635,6 +5723,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node, + } } -@@ -1275,6 +1278,7 @@ bool unadjusted_ptr_and_unit_offset (tree op, tree *ret, - poly_int64 *offset_ret); - void ipa_get_range_from_ip_invariant (vrange &r, tree val, cgraph_node *node); - void ipa_prop_cc_finalize (void); -+ipa_vr *streamer_read_and_hash (lto_input_block *ib, data_in *data_in); - - /* From tree-sra.cc: */ - tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree, -diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc -index ac835a435ec..a99e7227528 100644 ---- a/gcc/lto-cgraph.cc -+++ b/gcc/lto-cgraph.cc -@@ -44,6 +44,11 @@ along with GCC; see the file COPYING3. If not see - #include "symbol-summary.h" - #include "symtab-thunks.h" - #include "symtab-clones.h" -+#include "sreal.h" -+#include "value-range.h" -+#include "value-range-storage.h" -+#include "ipa-cp.h" -+#include "ipa-prop.h" ++ + /* Write all aggregate replacement for nodes in set. */ - /* True when asm nodes has been output. */ - bool asm_nodes_output = false; -@@ -1992,10 +1997,10 @@ input_offload_tables (bool do_force_output) - static int - output_cgraph_opt_summary_p (struct cgraph_node *node) - { -- if (node->clone_of || node->former_clone_of) -- return true; - clone_info *info = clone_info::get (node); -- return info && (info->tree_map || info->param_adjustments); -+ return info && (info->tree_map -+ || info->param_adjustments -+ || info->m_return_vr); + void +@@ -5674,6 +5763,7 @@ ipcp_write_transformation_summaries (void) + write_ipcp_transformation_info (ob, cnode, ts); + } + streamer_write_char_stream (ob->main_stream, 0); ++ ipa_write_return_summaries (ob); + produce_asm (ob); + destroy_output_block (ob); } - - /* Output optimization summary for EDGE to OB. */ -@@ -2065,6 +2070,15 @@ output_node_opt_summary (struct output_block *ob, - stream_write_tree (ob, map->new_tree, true); - } - -+ if (info && info->m_return_vr) -+ info->m_return_vr->streamer_write (ob); -+ else -+ { -+ bp = bitpack_create (ob->main_stream); -+ bp_pack_value (&bp, false, 1); -+ streamer_write_bitpack (&bp); -+ } -+ - if (lto_symtab_encoder_in_partition_p (encoder, node)) - { - for (e = node->callees; e; e = e->next_callee) -@@ -2181,6 +2195,9 @@ input_node_opt_summary (struct cgraph_node *node, - map->parm_num = streamer_read_uhwi (ib_main); - map->new_tree = stream_read_tree (ib_main, data_in); +@@ -5714,6 +5804,7 @@ read_replacements_section (struct lto_file_decl_data *file_data, + index)); + read_ipcp_transformation_info (&ib_main, node, data_in); } -+ -+ info->m_return_vr = streamer_read_and_hash (ib_main, data_in); -+ - for (e = node->callees; e; e = e->next_callee) - input_edge_opt_summary (e, ib_main); - for (e = node->indirect_calls; e; e = e->next_callee) -diff --git a/gcc/symtab-clones.h b/gcc/symtab-clones.h -index 362bcb63dd1..a63036fc94f 100644 ---- a/gcc/symtab-clones.h -+++ b/gcc/symtab-clones.h -@@ -21,12 +21,15 @@ along with GCC; see the file COPYING3. If not see - #ifndef GCC_SYMTAB_CLONES_H - #define GCC_SYMTAB_CLONES_H - -+class ipa_vr; -+ - struct GTY(()) clone_info ++ ipa_read_return_summaries (&ib_main, file_data, data_in); + lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data, + len); + lto_data_in_delete (data_in); +@@ -6194,22 +6285,7 @@ ipcp_transform_function (struct cgraph_node *node) + void + ipa_record_return_value_range (value_range val) { - /* Constructor. */ - clone_info () - : tree_map (NULL), -- param_adjustments (NULL) -+ param_adjustments (NULL), -+ m_return_vr (nullptr) - { - } - /* Constants discovered by IPA-CP, i.e. which parameter should be replaced -@@ -35,6 +38,10 @@ struct GTY(()) clone_info - /* Parameter modification that IPA-SRA decided to perform. */ - ipa_param_adjustments *param_adjustments; - -+ /* If non-NULL, the known value range of the return value of this -+ function. */ -+ ipa_vr *m_return_vr; -+ - /* Return clone_info, if available. */ - static clone_info *get (cgraph_node *node); +- cgraph_node *n = cgraph_node::get (current_function_decl); +- if (!ipa_return_value_sum) +- { +- if (!ipa_vr_hash_table) +- ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37); +- ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ()) +- ipa_return_value_sum_t (symtab, true); +- ipa_return_value_sum->disable_insertion_hook (); +- } +- ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val); +- if (dump_file && (dump_flags & TDF_DETAILS)) +- { +- fprintf (dump_file, "Recording return range "); +- val.dump (dump_file); +- fprintf (dump_file, "\n"); +- } ++ ipa_record_return_value_range_1 (cgraph_node::get (current_function_decl), val); + } + /* Return true if value range of DECL is known and if so initialize RANGE. */ diff --git a/gcc/testsuite/g++.dg/lto/pr119614_0.C b/gcc/testsuite/g++.dg/lto/pr119614_0.C new file mode 100644 index 00000000000..09c07fbf566
