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
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
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. */
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 ();
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)
{
/* 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");