>
> gcc/ChangeLog:
>
> 2018-04-24 Martin Liska <[email protected]>
>
> * ipa-cp.c (class edge_clone_summary): New summary.
> (grow_edge_clone_vectors): Remove.
> (ipcp_edge_duplication_hook): Remove.
> (class edge_clone_summary_t): New call_summary class.
> (ipcp_edge_removal_hook): Remove.
> (edge_clone_summary_t::duplicate): New function.
> (get_next_cgraph_edge_clone): Use edge_clone_summaries.
> (create_specialized_node): Likewise.
> (ipcp_driver): Initialize edge_clone_summaries and do not
> register hooks.
I will be happy to leave this one to Martin Jambor as well. Looks fine to me :)
Honza
> ---
> gcc/ipa-cp.c | 102
> ++++++++++++++++++++++++++++-------------------------------
> 1 file changed, 49 insertions(+), 53 deletions(-)
>
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index d8b04d14310..ed756c5ccf2 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -3392,54 +3392,56 @@ ipcp_discover_new_direct_edges (struct cgraph_node
> *node,
> ipa_update_overall_fn_summary (node);
> }
>
> -/* Vector of pointers which for linked lists of clones of an original crgaph
> - edge. */
> +class edge_clone_summary;
> +static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
>
> -static vec<cgraph_edge *> next_edge_clone;
> -static vec<cgraph_edge *> prev_edge_clone;
> +/* Edge clone summary. */
>
> -static inline void
> -grow_edge_clone_vectors (void)
> +struct edge_clone_summary
> {
> - if (next_edge_clone.length ()
> - <= (unsigned) symtab->edges_max_uid)
> - next_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
> - if (prev_edge_clone.length ()
> - <= (unsigned) symtab->edges_max_uid)
> - prev_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
> -}
> + /* Default constructor. */
> + edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
>
> -/* Edge duplication hook to grow the appropriate linked list in
> - next_edge_clone. */
> + /* Default destructor. */
> + ~edge_clone_summary ()
> + {
> + if (prev_clone)
> + edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
> + if (next_clone)
> + edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
> + }
>
> -static void
> -ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
> - void *)
> -{
> - grow_edge_clone_vectors ();
> + cgraph_edge *prev_clone;
> + cgraph_edge *next_clone;
> +};
>
> - struct cgraph_edge *old_next = next_edge_clone[src->uid];
> - if (old_next)
> - prev_edge_clone[old_next->uid] = dst;
> - prev_edge_clone[dst->uid] = src;
> +class edge_clone_summary_t:
> + public call_summary <edge_clone_summary *>
> +{
> +public:
> + edge_clone_summary_t (symbol_table *symtab):
> + call_summary <edge_clone_summary *> (symtab)
> + {
> + m_initialize_when_cloning = true;
> + }
>
> - next_edge_clone[dst->uid] = old_next;
> - next_edge_clone[src->uid] = dst;
> -}
> + virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
> + edge_clone_summary *src_data,
> + edge_clone_summary *dst_data);
> +};
>
> -/* Hook that is called by cgraph.c when an edge is removed. */
> +/* Edge duplication hook. */
>
> -static void
> -ipcp_edge_removal_hook (struct cgraph_edge *cs, void *)
> +void
> +edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge
> *dst_edge,
> + edge_clone_summary *src_data,
> + edge_clone_summary *dst_data)
> {
> - grow_edge_clone_vectors ();
> -
> - struct cgraph_edge *prev = prev_edge_clone[cs->uid];
> - struct cgraph_edge *next = next_edge_clone[cs->uid];
> - if (prev)
> - next_edge_clone[prev->uid] = next;
> - if (next)
> - prev_edge_clone[next->uid] = prev;
> + if (src_data->next_clone)
> + edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
> + dst_data->prev_clone = src_edge;
> + dst_data->next_clone = src_data->next_clone;
> + src_data->next_clone = dst_edge;
> }
>
> /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
> @@ -3567,7 +3569,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs,
> static inline struct cgraph_edge *
> get_next_cgraph_edge_clone (struct cgraph_edge *cs)
> {
> - return next_edge_clone[cs->uid];
> + edge_clone_summary *s = edge_clone_summaries->get (cs);
> + return s != NULL ? s->next_clone : NULL;
> }
>
> /* Given VAL that is intended for DEST, iterate over all its sources and if
> any
> @@ -3871,7 +3874,7 @@ create_specialized_node (struct cgraph_node *node,
> bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
> for (unsigned j = 0; j < self_recursive_calls.length (); j++)
> {
> - cgraph_edge *cs = next_edge_clone[self_recursive_calls[j]->uid];
> + cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
> /* Cloned edges can disappear during cloning as speculation can be
> resolved, check that we have one and that it comes from the last
> cloning. */
> @@ -3881,8 +3884,8 @@ create_specialized_node (struct cgraph_node *node,
> edge would confuse this mechanism, so let's check that does not
> happen. */
> gcc_checking_assert (!cs
> - || !next_edge_clone[cs->uid]
> - || next_edge_clone[cs->uid]->caller != new_node);
> + || !get_next_cgraph_edge_clone (cs)
> + || get_next_cgraph_edge_clone (cs)->caller !=
> new_node);
> }
> if (have_self_recursive_calls)
> new_node->expand_all_artificial_thunks ();
> @@ -5075,17 +5078,13 @@ ipcp_store_vr_results (void)
> static unsigned int
> ipcp_driver (void)
> {
> - struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
> - struct cgraph_edge_hook_list *edge_removal_hook_holder;
> struct ipa_topo_info topo;
>
> + if (edge_clone_summaries == NULL)
> + edge_clone_summaries = new edge_clone_summary_t (symtab);
> +
> ipa_check_create_node_params ();
> ipa_check_create_edge_args ();
> - grow_edge_clone_vectors ();
> - edge_duplication_hook_holder
> - = symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
> - edge_removal_hook_holder
> - = symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
>
> if (dump_file)
> {
> @@ -5108,10 +5107,7 @@ ipcp_driver (void)
>
> /* Free all IPCP structures. */
> free_toporder_info (&topo);
> - next_edge_clone.release ();
> - prev_edge_clone.release ();
> - symtab->remove_edge_removal_hook (edge_removal_hook_holder);
> - symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
> + delete edge_clone_summaries;
> ipa_free_all_structures_after_ipa_cp ();
> if (dump_file)
> fprintf (dump_file, "\nIPA constant propagation end\n");