public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass.
  2014-11-13 14:23 [PATCH 1/4] cgraph_summary data structure introduction mliska
  2014-11-13 14:23 ` [PATCH 4/4] Data structure is used for inline_summary struct mliska
@ 2014-11-13 14:23 ` mliska
  2014-11-14 14:12   ` Martin Liška
  2014-11-13 14:24 ` [PATCH 2/4] New data structure for cgraph_summary introduced mliska
  2014-11-13 14:34 ` [PATCH 1/4] cgraph_summary data structure introduction Richard Biener
  3 siblings, 1 reply; 40+ messages in thread
From: mliska @ 2014-11-13 14:23 UTC (permalink / raw)
  To: gcc-patches

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* auto-profile.c: Include cgraph_summary.h.
	* cgraph.c: Likewise.
	* cgraphbuild.c: Likewise.
	* cgraphclones.c: Likewise.
	* cgraphunit.c: Likewise.
	* ipa-cp.c: Likewise.
	* ipa-devirt.c: Likewise.
	* ipa-icf.c: Likewise.
	* ipa-inline-analysis.c (evaluate_properties_for_edge): Usage of
	ipa_node_params_vector is replaced with ipa_node_params_summary.
	(inline_node_duplication_hook): Likewise.
	(estimate_function_body_sizes): Likewise.
	(remap_edge_change_prob): Likewise.
	(inline_merge_summary): Likewise.
	* ipa-inline-transform.c: Include of cgraph_summary.h.
	* ipa-inline.c (early_inliner): Usage of
	ipa_node_params_vector is replaced with ipa_node_params_summary.
	* ipa-polymorphic-call.c: Include of cgraph_summary.h.
	* ipa-profile.c: Include of cgraph_summary.h.
	* ipa-prop.c (struct func_body_info): Struct keyword is removed.
	(struct ipa_cst_ref_desc): Likewise.
	(ipa_func_spec_opts_forbid_analysis_p): Likewise.
	(ipa_alloc_node_params): Likewise.
	(ipa_initialize_node_params): Likewise.
	(ipa_print_node_jump_functions_for_edge): Likewise.
	(ipa_print_node_jump_functions): Likewise.
	(ipa_print_all_jump_functions): Likewise.
	(ipa_set_jf_constant): Likewise.
	(check_stmt_for_type_change): Likewise.
	(detect_type_change_from_memory_writes): Likewise.
	(find_dominating_aa_status): Likewise.
	(parm_bb_aa_status_for_bb): Likewise.
	(parm_preserved_before_stmt_p): Likewise.
	(parm_ref_data_preserved_p): Likewise.
	(parm_ref_data_pass_through_p): Likewise.
	(struct ipa_known_agg_contents_list): Likewise.
	(get_place_in_agg_contents_list): Likewise.
	(build_agg_jump_func_from_list): Likewise.
	(determine_locally_known_aggregate_parts): Likewise.
	(ipa_compute_jump_functions_for_edge): Likewise.
	(ipa_compute_jump_functions_for_bb): Likewise.
	(ipa_note_param_call): Likewise.
	(ipa_analyze_indirect_call_uses) Likewise.:
	(ipa_analyze_virtual_call_uses): Likewise.
	(ipa_analyze_call_uses): Likewise.
	(visit_ref_for_mod_analysis): Likewise.
	(ipa_analyze_controlled_uses): Likewise.
	(ipa_analyze_node): Likewise.
	(update_jump_functions_after_inlining): Likewise.
	(ipa_make_edge_direct_to_target): Likewise.
	(ipa_find_agg_cst_for_param): Likewise.
	(remove_described_reference): Likewise.
	(jfunc_rdesc_usable): Likewise.
	(try_decrement_rdesc_refcount): Likewise.
	(try_make_edge_direct_simple_call): Likewise.
	(try_make_edge_direct_virtual_call): Likewise.
	(update_indirect_edges_after_inlining): Likewise.
	(propagate_info_to_inlined_callees): Likewise.
	(propagate_controlled_uses): Likewise.
	(ipa_propagate_indirect_call_infos): Likewise.
	(ipa_free_all_edge_args): Likewise.
	(ipa_node_params::~ipa_node_params): Likewise.
	(ipa_free_all_node_params): Likewise.
	(ipa_edge_removal_hook): Likewise.
	(ipa_node_removal_hook): Likewise.
	(ipa_edge_duplication_hook): Likewise.
	(ipa_add_new_function): Removed
	(ipa_node_params_cgraph_summary::duplication_hook): New function.
	(ipa_node_duplication_hook): Struct keyword removed.
	(ipa_register_cgraph_hooks): Removal of old hooks.
	(ipa_unregister_cgraph_hooks): Likewise.
	(ipa_print_node_params): Struct keyword is removed.
	(ipa_print_all_params): Likewise.
	(ipa_modify_formal_parameters): Likewise.
	(ipa_modify_call_arguments): Likewise.
	(ipa_modify_expr): Likewise.
	(ipa_get_adjustment_candidate): Likewise.
	(index_in_adjustments_multiple_times_p): Likewise.
	(ipa_combine_adjustments): Likewise.
	(ipa_dump_param_adjustments): Likewise.
	(ipa_write_jump_function): Likewise.
	(ipa_read_jump_function): Likewise.
	(ipa_write_indirect_edge_info): Likewise.
	(ipa_read_indirect_edge_info): Likewise.
	(ipa_write_node_info): Likewise.
	(ipa_read_node_info): Likewise.
	(ipa_prop_write_jump_functions): Likewise.
	(ipa_prop_read_section): Likewise.
	(ipa_prop_read_jump_functions): Likewise.
	(write_agg_replacement_chain): Likewise.
	(read_agg_replacement_chain): Likewise.
	(ipa_prop_write_all_agg_replacement): Likewise.
	(read_replacements_section): Likewise.
	(ipa_prop_read_all_agg_replacement): Likewise.
	(adjust_agg_replacement_values): Likewise.
	(ipcp_modif_dom_walker::before_dom_children): Likewise.
	(ipcp_transform_function): Likewise.
	* ipa-prop.h (struct ipa_node_params): Introduction of new class
	ipa_node_params_cgraph_summary.
	* ipa-split.c: Include cgraph_summary.h.
	* ipa-utils.c: Likewise.
	* ipa.c: Likewise.
	* omp-low.c: Likewise.
	* tree-inline.c: Likewise.
	* tree-sra.c: Likewise.
	* tree-ssa-pre.c: Likewise.

gcc/lto/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* lto-partition.c: Include cgraph_summary.h.
	* lto-symtab.c: Likewise.
	* lto.c: Likewise.
---
 gcc/auto-profile.c         |   1 +
 gcc/cgraph.c               |   1 +
 gcc/cgraphbuild.c          |   1 +
 gcc/cgraphclones.c         |   1 +
 gcc/cgraphunit.c           |   1 +
 gcc/ipa-cp.c               |   1 +
 gcc/ipa-devirt.c           |   1 +
 gcc/ipa-icf.c              |   1 +
 gcc/ipa-inline-analysis.c  |  13 +-
 gcc/ipa-inline-transform.c |   1 +
 gcc/ipa-inline.c           |   3 +-
 gcc/ipa-polymorphic-call.c |   1 +
 gcc/ipa-profile.c          |   1 +
 gcc/ipa-prop.c             | 700 ++++++++++++++++++++++-----------------------
 gcc/ipa-prop.h             |  46 +--
 gcc/ipa-split.c            |   1 +
 gcc/ipa-utils.c            |   1 +
 gcc/ipa.c                  |   1 +
 gcc/lto/lto-partition.c    |   1 +
 gcc/lto/lto-symtab.c       |   1 +
 gcc/lto/lto.c              |   1 +
 gcc/omp-low.c              |   1 +
 gcc/tree-inline.c          |   1 +
 gcc/tree-sra.c             |   1 +
 gcc/tree-ssa-pre.c         |   1 +
 25 files changed, 397 insertions(+), 386 deletions(-)

diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index 8c7b4ca..49f9b8c 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coverage.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 7216b89..af1835a 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index c72ceab..a93b0aa 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "except.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index c8892da..79f95ef 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-dump.h"
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 25af234..dbbdc44 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -204,6 +204,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 47f9f5c..da589af 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 32c6549..8e1f9ce 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 92ec82d..9778323 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index eb1c6ec..c7a52d2 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
@@ -910,7 +911,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
   if (known_binfos_ptr)
     known_binfos_ptr->create (0);
 
-  if (ipa_node_params_vector.exists ()
+  if (ipa_node_params_summary
       && !e->call_stmt_cannot_inline_p
       && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr))
     {
@@ -1130,7 +1131,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
 
   /* When there are any replacements in the function body, see if we can figure
      out that something was optimized out.  */
-  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
+  if (ipa_node_params_summary && dst->clone.tree_map)
     {
       vec<size_time_entry, va_gc> *entry = info->entry;
       /* Use SRC parm info since it may not be copied yet.  */
@@ -2476,7 +2477,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
       calculate_dominance_info (CDI_DOMINATORS);
       loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
 
-      if (ipa_node_params_vector.exists ())
+      if (ipa_node_params_summary)
 	{
 	  parms_info = IPA_NODE_REF (node);
 	  nonconstant_names.safe_grow_cleared
@@ -2624,7 +2625,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 		  nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
 		    = false_p;
 		}
-	      if (ipa_node_params_vector.exists ())
+	      if (ipa_node_params_summary)
 		{
 		  int count = gimple_call_num_args (stmt);
 		  int i;
@@ -3367,7 +3368,7 @@ static void
 remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 			struct cgraph_edge *edge)
 {
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_summary)
     {
       int i;
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
@@ -3523,7 +3524,7 @@ inline_merge_summary (struct cgraph_edge *edge)
   else
     toplev_predicate = true_predicate ();
 
-  if (ipa_node_params_vector.exists () && callee_info->conds)
+  if (ipa_node_params_summary && callee_info->conds)
     {
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
       int count = ipa_get_cs_argument_count (args);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index dbc56c5..fd700ff 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 5c97815..8a08cd4 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "except.h"
 #include "target.h"
@@ -2400,7 +2401,7 @@ early_inliner (function *fun)
      it.  This may confuse ourself when early inliner decide to inline call to
      function clone, because function clones don't have parameter list in
      ipa-prop matching their signature.  */
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_summary)
     return 0;
 
 #ifdef ENABLE_CHECKING
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 33dd1a8..e0555f2 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index b83d1cf..4fdee09 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index db85c7d..ce9745e 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "gimple-ssa.h"
@@ -119,7 +120,7 @@ struct func_body_info
   cgraph_node *node;
 
   /* Its info.  */
-  struct ipa_node_params *info;
+  ipa_node_params *info;
 
   /* Information about individual BBs. */
   vec<ipa_bb_info> bb_infos;
@@ -131,7 +132,8 @@ struct func_body_info
   unsigned int aa_walked;
 };
 
-/* Vector where the parameter infos are actually stored. */
+/* Callgraph summary where the parameter infos are actually stored. */
+ipa_node_params_cgraph_summary *ipa_node_params_summary = NULL;
 vec<ipa_node_params> ipa_node_params_vector;
 /* Vector of known aggregate values in cloned nodes.  */
 vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
@@ -139,19 +141,17 @@ vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
+static cgraph_edge_hook_list *edge_removal_hook_holder;
+static cgraph_2edge_hook_list *edge_duplication_hook_holder;
+static cgraph_node_hook_list *function_insertion_hook_holder;
 
 /* Description of a reference to an IPA constant.  */
 struct ipa_cst_ref_desc
 {
   /* Edge that corresponds to the statement which took the reference.  */
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   /* Linked list of duplicates created when call graph edges are cloned.  */
-  struct ipa_cst_ref_desc *next_duplicate;
+  ipa_cst_ref_desc *next_duplicate;
   /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
      if out of control.  */
   int refcount;
@@ -165,10 +165,10 @@ static alloc_pool ipa_refdesc_pool;
    with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
 
 static bool
-ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
+ipa_func_spec_opts_forbid_analysis_p (cgraph_node *node)
 {
   tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
-  struct cl_optimization *os;
+  cl_optimization *os;
 
   if (!fs_opts)
     return false;
@@ -196,7 +196,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
    to INFO.  */
 
 int
-ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
+ipa_get_param_decl_index (ipa_node_params *info, tree ptree)
 {
   return ipa_get_param_decl_index_1 (info->descriptors, ptree);
 }
@@ -205,7 +205,7 @@ ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
    NODE.  */
 
 static void
-ipa_populate_param_decls (struct cgraph_node *node,
+ipa_populate_param_decls (cgraph_node *node,
 			  vec<ipa_param_descriptor> &descriptors)
 {
   tree fndecl;
@@ -246,7 +246,7 @@ count_formal_params (tree fndecl)
    using ipa_initialize_node_params. */
 
 void
-ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
+ipa_dump_param (FILE *file, ipa_node_params *info, int i)
 {
   fprintf (file, "param #%i", i);
   if (info->descriptors[i].decl)
@@ -260,9 +260,9 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
    to hold PARAM_COUNT parameters.  */
 
 void
-ipa_alloc_node_params (struct cgraph_node *node, int param_count)
+ipa_alloc_node_params (cgraph_node *node, int param_count)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   if (!info->descriptors.exists () && param_count)
     info->descriptors.safe_grow_cleared (param_count);
@@ -273,9 +273,9 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
    param_decls.  */
 
 void
-ipa_initialize_node_params (struct cgraph_node *node)
+ipa_initialize_node_params (cgraph_node *node)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   if (!info->descriptors.exists ())
     {
@@ -287,14 +287,14 @@ ipa_initialize_node_params (struct cgraph_node *node)
 /* Print the jump functions associated with call graph edge CS to file F.  */
 
 static void
-ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
+ipa_print_node_jump_functions_for_edge (FILE *f, cgraph_edge *cs)
 {
   int i, count;
 
   count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *jump_func;
+      ipa_jump_func *jump_func;
       enum jump_func_type type;
 
       jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
@@ -360,7 +360,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 
       if (jump_func->agg.items)
 	{
-	  struct ipa_agg_jf_item *item;
+	  ipa_agg_jf_item *item;
 	  int j;
 
 	  fprintf (f, "         Aggregate passed by %s:\n",
@@ -390,9 +390,9 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
    NODE to file F.  */
 
 void
-ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
+ipa_print_node_jump_functions (FILE *f, cgraph_node *node)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   fprintf (f, "  Jump functions of caller  %s/%i:\n", node->name (),
 	   node->order);
@@ -410,7 +410,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 
   for (cs = node->indirect_calls; cs; cs = cs->next_callee)
     {
-      struct cgraph_indirect_call_info *ii;
+      cgraph_indirect_call_info *ii;
       if (!ipa_edge_args_info_available_for_edge_p (cs))
 	continue;
 
@@ -445,7 +445,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 void
 ipa_print_all_jump_functions (FILE *f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "\nJump functions:\n");
   FOR_EACH_FUNCTION (node)
@@ -457,7 +457,7 @@ ipa_print_all_jump_functions (FILE *f)
 /* Set JFUNC to be a known type jump function.  */
 
 static void
-ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
+ipa_set_jf_known_type (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
 		       tree base_type, tree component_type)
 {
   /* Recording and propagating main variants increases change that types
@@ -480,8 +480,8 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
    combination code).  The two functions will share their rdesc.  */
 
 static void
-ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
-		     struct ipa_jump_func *src)
+ipa_set_jf_cst_copy (ipa_jump_func *dst,
+		     ipa_jump_func *src)
 
 {
   gcc_checking_assert (src->type == IPA_JF_CONST);
@@ -492,8 +492,8 @@ ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
 /* Set JFUNC to be a constant jmp function.  */
 
 static void
-ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
-		     struct cgraph_edge *cs)
+ipa_set_jf_constant (ipa_jump_func *jfunc, tree constant,
+		     cgraph_edge *cs)
 {
   constant = unshare_expr (constant);
   if (constant && EXPR_P (constant))
@@ -504,12 +504,12 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
   if (TREE_CODE (constant) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
     {
-      struct ipa_cst_ref_desc *rdesc;
+      ipa_cst_ref_desc *rdesc;
       if (!ipa_refdesc_pool)
 	ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
-					sizeof (struct ipa_cst_ref_desc), 32);
+					sizeof (ipa_cst_ref_desc), 32);
 
-      rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+      rdesc = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
       rdesc->cs = cs;
       rdesc->next_duplicate = NULL;
       rdesc->refcount = 1;
@@ -521,7 +521,7 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
 
 /* Set JFUNC to be a simple pass-through jump function.  */
 static void
-ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+ipa_set_jf_simple_pass_through (ipa_jump_func *jfunc, int formal_id,
 				bool agg_preserved, bool type_preserved)
 {
   jfunc->type = IPA_JF_PASS_THROUGH;
@@ -535,7 +535,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 /* Set JFUNC to be an arithmetic pass through jump function.  */
 
 static void
-ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+ipa_set_jf_arith_pass_through (ipa_jump_func *jfunc, int formal_id,
 			       tree operand, enum tree_code operation)
 {
   jfunc->type = IPA_JF_PASS_THROUGH;
@@ -549,7 +549,7 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 /* Set JFUNC to be an ancestor jump function.  */
 
 static void
-ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
+ipa_set_ancestor_jf (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
 		     tree type, int formal_id, bool agg_preserved,
 		     bool type_preserved)
 {
@@ -572,7 +572,7 @@ ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
    jump function.  */
 
 tree
-ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
+ipa_binfo_from_known_type_jfunc (ipa_jump_func *jfunc)
 {
   if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
     return NULL_TREE;
@@ -602,8 +602,8 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
 /* Get IPA BB information about the given BB.  FBI is the context of analyzis
    of this function body.  */
 
-static struct ipa_bb_info *
-ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
+static ipa_bb_info *
+ipa_get_bb_info (func_body_info *fbi, basic_block bb)
 {
   gcc_checking_assert (fbi);
   return &fbi->bb_infos[bb->index];
@@ -700,7 +700,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
    identified, return the type.  Otherwise return NULL_TREE.  */
 
 static tree
-extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
+extr_type_from_vtbl_ptr_store (gimple stmt, prop_type_change_info *tci)
 {
   HOST_WIDE_INT offset, size, max_size;
   tree lhs, rhs, base, binfo;
@@ -752,7 +752,7 @@ static bool
 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
 {
   gimple stmt = SSA_NAME_DEF_STMT (vdef);
-  struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
+  prop_type_change_info *tci = (prop_type_change_info *) data;
 
   if (stmt_may_be_vtbl_ptr_store (stmt))
     {
@@ -847,10 +847,10 @@ param_type_may_change_p (tree function, tree arg, gimple call)
 
 static bool
 detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
-				       gimple call, struct ipa_jump_func *jfunc,
+				       gimple call, ipa_jump_func *jfunc,
 				       HOST_WIDE_INT offset)
 {
-  struct prop_type_change_info tci;
+  prop_type_change_info tci;
   ao_ref ao;
   bool entry_reached = false;
 
@@ -908,7 +908,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
 
 static bool
 detect_type_change (tree arg, tree base, tree comp_type, gimple call,
-		    struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
+		    ipa_jump_func *jfunc, HOST_WIDE_INT offset)
 {
   if (!flag_devirtualize)
     return false;
@@ -928,7 +928,7 @@ detect_type_change (tree arg, tree base, tree comp_type, gimple call,
 
 static bool
 detect_type_change_ssa (tree arg, tree comp_type,
-			gimple call, struct ipa_jump_func *jfunc)
+			gimple call, ipa_jump_func *jfunc)
 {
   gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
   if (!flag_devirtualize
@@ -961,7 +961,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
    should really just start giving up.  */
 
 static bool
-aa_overwalked (struct func_body_info *fbi)
+aa_overwalked (func_body_info *fbi)
 {
   gcc_checking_assert (fbi);
   return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
@@ -970,8 +970,8 @@ aa_overwalked (struct func_body_info *fbi)
 /* Find the nearest valid aa status for parameter specified by INDEX that
    dominates BB.  */
 
-static struct param_aa_status *
-find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
+static param_aa_status *
+find_dominating_aa_status (func_body_info *fbi, basic_block bb,
 			   int index)
 {
   while (true)
@@ -979,7 +979,7 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
       bb = get_immediate_dominator (CDI_DOMINATORS, bb);
       if (!bb)
 	return NULL;
-      struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+      ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
       if (!bi->param_aa_statuses.is_empty ()
 	  && bi->param_aa_statuses[index].valid)
 	return &bi->param_aa_statuses[index];
@@ -990,21 +990,21 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
    structures and/or intialize the result with a dominating description as
    necessary.  */
 
-static struct param_aa_status *
-parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
+static param_aa_status *
+parm_bb_aa_status_for_bb (func_body_info *fbi, basic_block bb,
 			  int index)
 {
   gcc_checking_assert (fbi);
-  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   if (bi->param_aa_statuses.is_empty ())
     bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
-  struct param_aa_status *paa = &bi->param_aa_statuses[index];
+  param_aa_status *paa = &bi->param_aa_statuses[index];
   if (!paa->valid)
     {
       gcc_checking_assert (!paa->parm_modified
 			   && !paa->ref_modified
 			   && !paa->pt_modified);
-      struct param_aa_status *dom_paa;
+      param_aa_status *dom_paa;
       dom_paa = find_dominating_aa_status (fbi, bb, index);
       if (dom_paa)
 	*paa = *dom_paa;
@@ -1021,10 +1021,10 @@ parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
    gathered but do not survive the summary building stage.  */
 
 static bool
-parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
+parm_preserved_before_stmt_p (func_body_info *fbi, int index,
 			      gimple stmt, tree parm_load)
 {
-  struct param_aa_status *paa;
+  param_aa_status *paa;
   bool modified = false;
   ao_ref refd;
 
@@ -1060,7 +1060,7 @@ parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
    modified.  Otherwise return -1.  */
 
 static int
-load_from_unmodified_param (struct func_body_info *fbi,
+load_from_unmodified_param (func_body_info *fbi,
 			    vec<ipa_param_descriptor> descriptors,
 			    gimple stmt)
 {
@@ -1087,10 +1087,10 @@ load_from_unmodified_param (struct func_body_info *fbi,
    before reaching statement STMT.  */
 
 static bool
-parm_ref_data_preserved_p (struct func_body_info *fbi,
+parm_ref_data_preserved_p (func_body_info *fbi,
 			   int index, gimple stmt, tree ref)
 {
-  struct param_aa_status *paa;
+  param_aa_status *paa;
   bool modified = false;
   ao_ref refd;
 
@@ -1126,7 +1126,7 @@ parm_ref_data_preserved_p (struct func_body_info *fbi,
    CALL into which it is passed.  FBI describes the function body.  */
 
 static bool
-parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
+parm_ref_data_pass_through_p (func_body_info *fbi, int index,
 			      gimple call, tree parm)
 {
   bool modified = false;
@@ -1140,7 +1140,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
       || aa_overwalked (fbi))
     return false;
 
-  struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
+  param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
 							  index);
   if (paa->pt_modified)
     return false;
@@ -1165,7 +1165,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
    reference respectively.  */
 
 static bool
-ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
+ipa_load_from_parm_agg_1 (func_body_info *fbi,
 			  vec<ipa_param_descriptor> descriptors,
 			  gimple stmt, tree op, int *index_p,
 			  HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
@@ -1240,7 +1240,7 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
    pointer, for users outside of this file.  */
 
 bool
-ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
+ipa_load_from_parm_agg (ipa_node_params *info, gimple stmt,
 			tree op, int *index_p, HOST_WIDE_INT *offset_p,
 			bool *by_ref_p)
 {
@@ -1302,9 +1302,9 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
    only needed for intraprocedural analysis.  */
 
 static void
-compute_complex_assign_jump_func (struct func_body_info *fbi,
-				  struct ipa_node_params *info,
-				  struct ipa_jump_func *jfunc,
+compute_complex_assign_jump_func (func_body_info *fbi,
+				  ipa_node_params *info,
+				  ipa_jump_func *jfunc,
 				  gimple call, gimple stmt, tree name,
 				  tree param_type)
 {
@@ -1458,9 +1458,9 @@ get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
      return D.1879_6;  */
 
 static void
-compute_complex_ancestor_jump_func (struct func_body_info *fbi,
-				    struct ipa_node_params *info,
-				    struct ipa_jump_func *jfunc,
+compute_complex_ancestor_jump_func (func_body_info *fbi,
+				    ipa_node_params *info,
+				    ipa_jump_func *jfunc,
 				    gimple call, gimple phi, tree param_type)
 {
   HOST_WIDE_INT offset;
@@ -1531,7 +1531,7 @@ compute_complex_ancestor_jump_func (struct func_body_info *fbi,
    EXPECTED_TYPE represents a type the argument should be in  */
 
 static void
-compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
+compute_known_type_jump_func (tree op, ipa_jump_func *jfunc,
 			      gimple call, tree expected_type)
 {
   HOST_WIDE_INT offset, size, max_size;
@@ -1629,7 +1629,7 @@ struct ipa_known_agg_contents_list
   /* Known constant value or NULL if the contents is known to be unknown.  */
   tree constant;
   /* Pointer to the next structure in the list.  */
-  struct ipa_known_agg_contents_list *next;
+  ipa_known_agg_contents_list *next;
 };
 
 /* Find the proper place in linked list of ipa_known_agg_contents_list
@@ -1637,13 +1637,13 @@ struct ipa_known_agg_contents_list
    unless there is a partial overlap, in which case return NULL, or such
    element is already there, in which case set *ALREADY_THERE to true.  */
 
-static struct ipa_known_agg_contents_list **
-get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
+static ipa_known_agg_contents_list **
+get_place_in_agg_contents_list (ipa_known_agg_contents_list **list,
 				HOST_WIDE_INT lhs_offset,
 				HOST_WIDE_INT lhs_size,
 				bool *already_there)
 {
-  struct ipa_known_agg_contents_list **p = list;
+  ipa_known_agg_contents_list **p = list;
   while (*p && (*p)->offset < lhs_offset)
     {
       if ((*p)->offset + (*p)->size > lhs_offset)
@@ -1670,16 +1670,16 @@ get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
    is ARG_OFFSET and store it into JFUNC.  */
 
 static void
-build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
+build_agg_jump_func_from_list (ipa_known_agg_contents_list *list,
 			       int const_count, HOST_WIDE_INT arg_offset,
-			       struct ipa_jump_func *jfunc)
+			       ipa_jump_func *jfunc)
 {
   vec_alloc (jfunc->agg.items, const_count);
   while (list)
     {
       if (list->constant)
 	{
-	  struct ipa_agg_jf_item item;
+	  ipa_agg_jf_item item;
 	  item.offset = list->offset - arg_offset;
 	  gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
 	  item.value = unshare_expr_without_location (list->constant);
@@ -1697,9 +1697,9 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
 
 static void
 determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
-					 struct ipa_jump_func *jfunc)
+					 ipa_jump_func *jfunc)
 {
-  struct ipa_known_agg_contents_list *list = NULL;
+  ipa_known_agg_contents_list *list = NULL;
   int item_count = 0, const_count = 0;
   HOST_WIDE_INT arg_offset, arg_size;
   gimple_stmt_iterator gsi;
@@ -1774,7 +1774,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
   gsi_prev (&gsi);
   for (; !gsi_end_p (gsi); gsi_prev (&gsi))
     {
-      struct ipa_known_agg_contents_list *n, **p;
+      ipa_known_agg_contents_list *n, **p;
       gimple stmt = gsi_stmt (gsi);
       HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
       tree lhs, rhs, lhs_base;
@@ -1821,7 +1821,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
 	continue;
 
       rhs = get_ssa_def_if_simple_copy (rhs);
-      n = XALLOCA (struct ipa_known_agg_contents_list);
+      n = XALLOCA (ipa_known_agg_contents_list);
       n->size = lhs_size;
       n->offset = lhs_offset;
       if (is_gimple_ip_invariant (rhs))
@@ -1852,7 +1852,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
 }
 
 static tree
-ipa_get_callee_param_type (struct cgraph_edge *e, int i)
+ipa_get_callee_param_type (cgraph_edge *e, int i)
 {
   int n;
   tree type = (e->callee
@@ -1887,11 +1887,11 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
    to this callsite.  */
 
 static void
-ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
-				     struct cgraph_edge *cs)
+ipa_compute_jump_functions_for_edge (func_body_info *fbi,
+				     cgraph_edge *cs)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
-  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
+  ipa_node_params *info = IPA_NODE_REF (cs->caller);
+  ipa_edge_args *args = IPA_EDGE_REF (cs);
   gimple call = cs->call_stmt;
   int n, arg_num = gimple_call_num_args (call);
   bool useful_context = false;
@@ -1909,13 +1909,13 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
 
   for (n = 0; n < arg_num; n++)
     {
-      struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
+      ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
       tree arg = gimple_call_arg (call, n);
       tree param_type = ipa_get_callee_param_type (cs, n);
       if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
 	  tree instance;
-	  struct ipa_polymorphic_call_context context (cs->caller->decl,
+	  ipa_polymorphic_call_context context (cs->caller->decl,
 						       arg, cs->call_stmt,
 						       &instance);
 	  context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
@@ -2003,15 +2003,15 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
    from BB.  */
 
 static void
-ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
+ipa_compute_jump_functions_for_bb (func_body_info *fbi, basic_block bb)
 {
-  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   int i;
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
     {
-      struct cgraph_node *callee = cs->callee;
+      cgraph_node *callee = cs->callee;
 
       if (callee)
 	{
@@ -2093,10 +2093,10 @@ ipa_is_ssa_with_stmt_def (tree t)
    call to a parameter number PARAM_INDEX.  NODE is the caller.  Return the
    indirect call graph edge.  */
 
-static struct cgraph_edge *
-ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
+static cgraph_edge *
+ipa_note_param_call (cgraph_node *node, int param_index, gimple stmt)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   cs = node->get_edge (stmt);
   cs->indirect_info->param_index = param_index;
@@ -2165,10 +2165,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
    passed by value or reference.  */
 
 static void
-ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
+ipa_analyze_indirect_call_uses (func_body_info *fbi, gimple call,
 				tree target)
 {
-  struct ipa_node_params *info = fbi->info;
+  ipa_node_params *info = fbi->info;
   HOST_WIDE_INT offset;
   bool by_ref;
 
@@ -2188,7 +2188,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
 				   gimple_assign_rhs1 (def), &index, &offset,
 				   NULL, &by_ref))
     {
-      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
       cs->indirect_info->agg_contents = 1;
       cs->indirect_info->by_ref = by_ref;
@@ -2288,7 +2288,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
   if (index >= 0
       && parm_preserved_before_stmt_p (fbi, index, call, rec))
     {
-      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
       cs->indirect_info->agg_contents = 1;
       cs->indirect_info->member_ptr = 1;
@@ -2303,7 +2303,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
    statement.  */
 
 static void
-ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
+ipa_analyze_virtual_call_uses (func_body_info *fbi,
 			       gimple call, tree target)
 {
   tree obj = OBJ_TYPE_REF_OBJECT (target);
@@ -2316,10 +2316,10 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
   if (TREE_CODE (obj) != SSA_NAME)
     return;
 
-  struct ipa_node_params *info = fbi->info;
+  ipa_node_params *info = fbi->info;
   if (SSA_NAME_IS_DEFAULT_DEF (obj))
     {
-      struct ipa_jump_func jfunc;
+      ipa_jump_func jfunc;
       if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
 	return;
 
@@ -2332,7 +2332,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
     }
   else
     {
-      struct ipa_jump_func jfunc;
+      ipa_jump_func jfunc;
       gimple stmt = SSA_NAME_DEF_STMT (obj);
       tree expr;
 
@@ -2347,8 +2347,8 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
 	return;
     }
 
-  struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
+  cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+  cgraph_indirect_call_info *ii = cs->indirect_info;
   ii->offset = anc_offset;
   ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
   ii->otr_type = obj_type_ref_class (target);
@@ -2360,7 +2360,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
    containing intermediate information about each formal parameter.  */
 
 static void
-ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
+ipa_analyze_call_uses (func_body_info *fbi, gimple call)
 {
   tree target = gimple_call_fn (call);
 
@@ -2369,7 +2369,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
           && !virtual_method_call_p (target)))
     return;
 
-  struct cgraph_edge *cs = fbi->node->get_edge (call);
+  cgraph_edge *cs = fbi->node->get_edge (call);
   /* If we previously turned the call into a direct call, there is
      no need to analyze.  */
   if (cs && !cs->indirect_unknown_callee)
@@ -2406,7 +2406,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
    formal parameters are called.  */
 
 static void
-ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
+ipa_analyze_stmt_uses (func_body_info *fbi, gimple stmt)
 {
   if (is_gimple_call (stmt))
     ipa_analyze_call_uses (fbi, stmt);
@@ -2419,7 +2419,7 @@ ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
 static bool
 visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
 {
-  struct ipa_node_params *info = (struct ipa_node_params *) data;
+  ipa_node_params *info = (ipa_node_params *) data;
 
   op = get_base_address (op);
   if (op
@@ -2439,7 +2439,7 @@ visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
    the function being analyzed.  */
 
 static void
-ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
+ipa_analyze_params_uses_in_bb (func_body_info *fbi, basic_block bb)
 {
   gimple_stmt_iterator gsi;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -2465,9 +2465,9 @@ ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
 /* Calculate controlled uses of parameters of NODE.  */
 
 static void
-ipa_analyze_controlled_uses (struct cgraph_node *node)
+ipa_analyze_controlled_uses (cgraph_node *node)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   for (int i = 0; i < ipa_get_param_count (info); i++)
     {
@@ -2510,7 +2510,7 @@ ipa_analyze_controlled_uses (struct cgraph_node *node)
 /* Free stuff in BI.  */
 
 static void
-free_ipa_bb_info (struct ipa_bb_info *bi)
+free_ipa_bb_info (ipa_bb_info *bi)
 {
   bi->cg_edges.release ();
   bi->param_aa_statuses.release ();
@@ -2521,13 +2521,13 @@ free_ipa_bb_info (struct ipa_bb_info *bi)
 class analysis_dom_walker : public dom_walker
 {
 public:
-  analysis_dom_walker (struct func_body_info *fbi)
+  analysis_dom_walker (func_body_info *fbi)
     : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
 
   virtual void before_dom_children (basic_block);
 
 private:
-  struct func_body_info *m_fbi;
+  func_body_info *m_fbi;
 };
 
 void
@@ -2542,10 +2542,10 @@ analysis_dom_walker::before_dom_children (basic_block bb)
    with actual arguments of calls from within NODE.  */
 
 void
-ipa_analyze_node (struct cgraph_node *node)
+ipa_analyze_node (cgraph_node *node)
 {
-  struct func_body_info fbi;
-  struct ipa_node_params *info;
+  func_body_info fbi;
+  ipa_node_params *info;
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
@@ -2565,7 +2565,7 @@ ipa_analyze_node (struct cgraph_node *node)
       return;
     }
 
-  struct function *func = DECL_STRUCT_FUNCTION (node->decl);
+  function *func = DECL_STRUCT_FUNCTION (node->decl);
   push_cfun (func);
   calculate_dominance_info (CDI_DOMINATORS);
   ipa_initialize_node_params (node);
@@ -2578,13 +2578,13 @@ ipa_analyze_node (struct cgraph_node *node)
   fbi.param_count = ipa_get_param_count (info);
   fbi.aa_walked = 0;
 
-  for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
       bi->cg_edges.safe_push (cs);
     }
 
-  for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
+  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
       bi->cg_edges.safe_push (cs);
@@ -2593,7 +2593,7 @@ ipa_analyze_node (struct cgraph_node *node)
   analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
   int i;
-  struct ipa_bb_info *bi;
+  ipa_bb_info *bi;
   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
     free_ipa_bb_info (bi);
   fbi.bb_infos.release ();
@@ -2606,8 +2606,8 @@ ipa_analyze_node (struct cgraph_node *node)
    type.  */
 
 static void
-combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
-				     struct ipa_jump_func *dst)
+combine_known_type_and_ancestor_jfs (ipa_jump_func *src,
+				     ipa_jump_func *dst)
 {
   HOST_WIDE_INT combined_offset;
   tree combined_type;
@@ -2632,25 +2632,25 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
    indirectly) inlined into CS->callee and that E has not been inlined.  */
 
 static void
-update_jump_functions_after_inlining (struct cgraph_edge *cs,
-				      struct cgraph_edge *e)
+update_jump_functions_after_inlining (cgraph_edge *cs,
+				      cgraph_edge *e)
 {
-  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
-  struct ipa_edge_args *args = IPA_EDGE_REF (e);
+  ipa_edge_args *top = IPA_EDGE_REF (cs);
+  ipa_edge_args *args = IPA_EDGE_REF (e);
   int count = ipa_get_cs_argument_count (args);
   int i;
 
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
-      struct ipa_polymorphic_call_context *dst_ctx
+      ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
+      ipa_polymorphic_call_context *dst_ctx
 	= ipa_get_ith_polymorhic_call_context (args, i);
 
       if (dst->type == IPA_JF_ANCESTOR)
 	{
-	  struct ipa_jump_func *src;
+	  ipa_jump_func *src;
 	  int dst_fid = dst->value.ancestor.formal_id;
-	  struct ipa_polymorphic_call_context *src_ctx
+	  ipa_polymorphic_call_context *src_ctx
 	    = ipa_get_ith_polymorhic_call_context (top, dst_fid);
 
 	  /* Variable number of arguments can cause havoc if we try to access
@@ -2666,7 +2666,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 
 	  if (src_ctx && !src_ctx->useless_p ())
 	    {
-	      struct ipa_polymorphic_call_context ctx = *src_ctx;
+	      ipa_polymorphic_call_context ctx = *src_ctx;
 
 	      /* TODO: Make type preserved safe WRT contexts.  */
 	      if (!dst->value.ancestor.agg_preserved)
@@ -2683,7 +2683,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	  if (src->agg.items
 	      && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
 	    {
-	      struct ipa_agg_jf_item *item;
+	      ipa_agg_jf_item *item;
 	      int j;
 
 	      /* Currently we do not produce clobber aggregate jump functions,
@@ -2721,7 +2721,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	}
       else if (dst->type == IPA_JF_PASS_THROUGH)
 	{
-	  struct ipa_jump_func *src;
+	  ipa_jump_func *src;
 	  /* We must check range due to calls with variable number of arguments
 	     and we cannot combine jump functions with operations.  */
 	  if (dst->value.pass_through.operation == NOP_EXPR
@@ -2731,12 +2731,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	      int dst_fid = dst->value.pass_through.formal_id;
 	      src = ipa_get_ith_jump_func (top, dst_fid);
 	      bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
-	      struct ipa_polymorphic_call_context *src_ctx
+	      ipa_polymorphic_call_context *src_ctx
 		= ipa_get_ith_polymorhic_call_context (top, dst_fid);
 
 	      if (src_ctx && !src_ctx->useless_p ())
 		{
-		  struct ipa_polymorphic_call_context ctx = *src_ctx;
+		  ipa_polymorphic_call_context ctx = *src_ctx;
 
 		  /* TODO: Make type preserved safe WRT contexts.  */
 		  if (!dst->value.ancestor.agg_preserved)
@@ -2833,11 +2833,11 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
    (SPECULATIVE)destination of an indirect edge IE and return the edge.
    Otherwise, return NULL.  */
 
-struct cgraph_edge *
-ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
+cgraph_edge *
+ipa_make_edge_direct_to_target (cgraph_edge *ie, tree target,
 				bool speculative)
 {
-  struct cgraph_node *callee;
+  cgraph_node *callee;
   struct inline_edge_summary *es = inline_edge_summary (ie);
   bool unreachable = false;
 
@@ -2898,8 +2898,8 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
   /* If the edge is already speculated.  */
   if (speculative && ie->speculative)
     {
-      struct cgraph_edge *e2;
-      struct ipa_ref *ref;
+      cgraph_edge *e2;
+      ipa_ref *ref;
       ie->speculative_call_info (e2, ie, ref);
       if (e2->callee->ultimate_alias_target ()
 	  != callee->ultimate_alias_target ())
@@ -2987,10 +2987,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
    be passed by reference or by value.  */
 
 tree
-ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
+ipa_find_agg_cst_for_param (ipa_agg_jump_function *agg,
 			    HOST_WIDE_INT offset, bool by_ref)
 {
-  struct ipa_agg_jf_item *item;
+  ipa_agg_jf_item *item;
   int i;
 
   if (by_ref != agg->by_ref)
@@ -3012,10 +3012,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
    successfully found and removed.  */
 
 static bool
-remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
+remove_described_reference (symtab_node *symbol, ipa_cst_ref_desc *rdesc)
 {
-  struct ipa_ref *to_del;
-  struct cgraph_edge *origin;
+  ipa_ref *to_del;
+  cgraph_edge *origin;
 
   origin = rdesc->cs;
   if (!origin)
@@ -3037,10 +3037,10 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
    IPA_UNDESCRIBED_USE, return the reference description, otherwise return
    NULL.  JFUNC must be a constant jump function.  */
 
-static struct ipa_cst_ref_desc *
-jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
+static ipa_cst_ref_desc *
+jfunc_rdesc_usable (ipa_jump_func *jfunc)
 {
-  struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
+  ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
   if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
     return rdesc;
   else
@@ -3052,7 +3052,7 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
    NULL.  */
 
 static cgraph_node *
-cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
+cgraph_node_for_jfunc (ipa_jump_func *jfunc)
 {
   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
   tree cst = ipa_get_jf_constant (jfunc);
@@ -3070,9 +3070,9 @@ cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
    reference could not be found, otherwise return true.  */
 
 static bool
-try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
+try_decrement_rdesc_refcount (ipa_jump_func *jfunc)
 {
-  struct ipa_cst_ref_desc *rdesc;
+  ipa_cst_ref_desc *rdesc;
   if (jfunc->type == IPA_JF_CONST
       && (rdesc = jfunc_rdesc_usable (jfunc))
       && --rdesc->refcount == 0)
@@ -3092,12 +3092,12 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
    determined, return the newly direct edge, otherwise return NULL.
    NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
 
-static struct cgraph_edge *
-try_make_edge_direct_simple_call (struct cgraph_edge *ie,
-				  struct ipa_jump_func *jfunc,
-				  struct ipa_node_params *new_root_info)
+static cgraph_edge *
+try_make_edge_direct_simple_call (cgraph_edge *ie,
+				  ipa_jump_func *jfunc,
+				  ipa_node_params *new_root_info)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   tree target;
   bool agg_contents = ie->indirect_info->agg_contents;
 
@@ -3130,7 +3130,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
    and target (the latter can be NULL) are dumped when dumping is enabled.  */
 
 tree
-ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
+ipa_impossible_devirt_target (cgraph_edge *ie, tree target)
 {
   if (dump_file)
     {
@@ -3155,11 +3155,11 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
    Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
    are relative to.  */
 
-static struct cgraph_edge *
-try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
-				   struct ipa_jump_func *jfunc,
-				   struct ipa_node_params *new_root_info,
-				   struct ipa_polymorphic_call_context *ctx_ptr)
+static cgraph_edge *
+try_make_edge_direct_virtual_call (cgraph_edge *ie,
+				   ipa_jump_func *jfunc,
+				   ipa_node_params *new_root_info,
+				   ipa_polymorphic_call_context *ctx_ptr)
 {
   tree binfo, target = NULL;
   bool speculative = false;
@@ -3172,7 +3172,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
      based on knowlede of the context.  */
   if (ctx_ptr && !ie->indirect_info->by_ref)
     {
-      struct ipa_polymorphic_call_context ctx = *ctx_ptr;
+      ipa_polymorphic_call_context ctx = *ctx_ptr;
 
       ctx.offset_by (ie->indirect_info->offset);
 
@@ -3221,7 +3221,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
 
   if (binfo && TREE_CODE (binfo) != TREE_BINFO)
     {
-      struct ipa_polymorphic_call_context ctx (binfo,
+      ipa_polymorphic_call_context ctx (binfo,
 					       ie->indirect_info->otr_type,
 					       ie->indirect_info->offset);
       updated |= ie->indirect_info->context.combine_with
@@ -3296,13 +3296,13 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
    unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
 
 static bool
-update_indirect_edges_after_inlining (struct cgraph_edge *cs,
-				      struct cgraph_node *node,
+update_indirect_edges_after_inlining (cgraph_edge *cs,
+				      cgraph_node *node,
 				      vec<cgraph_edge *> *new_edges)
 {
-  struct ipa_edge_args *top;
-  struct cgraph_edge *ie, *next_ie, *new_direct_edge;
-  struct ipa_node_params *new_root_info;
+  ipa_edge_args *top;
+  cgraph_edge *ie, *next_ie, *new_direct_edge;
+  ipa_node_params *new_root_info;
   bool res = false;
 
   ipa_check_create_edge_args ();
@@ -3313,8 +3313,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
   for (ie = node->indirect_calls; ie; ie = next_ie)
     {
-      struct cgraph_indirect_call_info *ici = ie->indirect_info;
-      struct ipa_jump_func *jfunc;
+      cgraph_indirect_call_info *ici = ie->indirect_info;
+      ipa_jump_func *jfunc;
       int param_index;
 
       next_ie = ie->next_callee;
@@ -3408,11 +3408,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
    created.  */
 
 static bool
-propagate_info_to_inlined_callees (struct cgraph_edge *cs,
-				   struct cgraph_node *node,
+propagate_info_to_inlined_callees (cgraph_edge *cs,
+				   cgraph_node *node,
 				   vec<cgraph_edge *> *new_edges)
 {
-  struct cgraph_edge *e;
+  cgraph_edge *e;
   bool res;
 
   res = update_indirect_edges_after_inlining (cs, node, new_edges);
@@ -3443,21 +3443,21 @@ combine_controlled_uses_counters (int c, int d)
    tree of inlined nodes.  */
 
 static void
-propagate_controlled_uses (struct cgraph_edge *cs)
+propagate_controlled_uses (cgraph_edge *cs)
 {
-  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
-  struct cgraph_node *new_root = cs->caller->global.inlined_to
+  ipa_edge_args *args = IPA_EDGE_REF (cs);
+  cgraph_node *new_root = cs->caller->global.inlined_to
     ? cs->caller->global.inlined_to : cs->caller;
-  struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
-  struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
+  ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
+  ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
   int count, i;
 
   count = MIN (ipa_get_cs_argument_count (args),
 	       ipa_get_param_count (old_root_info));
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
-      struct ipa_cst_ref_desc *rdesc;
+      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
+      ipa_cst_ref_desc *rdesc;
 
       if (jf->type == IPA_JF_PASS_THROUGH)
 	{
@@ -3472,8 +3472,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  ipa_set_controlled_uses (new_root_info, src_idx, c);
 	  if (c == 0 && new_root_info->ipcp_orig_node)
 	    {
-	      struct cgraph_node *n;
-	      struct ipa_ref *ref;
+	      cgraph_node *n;
+	      ipa_ref *ref;
 	      tree t = new_root_info->known_vals[src_idx];
 
 	      if (t && TREE_CODE (t) == ADDR_EXPR
@@ -3500,14 +3500,14 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  if (rdesc->refcount == 0)
 	    {
 	      tree cst = ipa_get_jf_constant (jf);
-	      struct cgraph_node *n;
+	      cgraph_node *n;
 	      gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
 				   && TREE_CODE (TREE_OPERAND (cst, 0))
 				   == FUNCTION_DECL);
 	      n = cgraph_node::get (TREE_OPERAND (cst, 0));
 	      if (n)
 		{
-		  struct cgraph_node *clone;
+		  cgraph_node *clone;
 		  bool ok;
 		  ok = remove_described_reference (n, rdesc);
 		  gcc_checking_assert (ok);
@@ -3517,7 +3517,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 			 && clone != rdesc->cs->caller
 			 && IPA_NODE_REF (clone)->ipcp_orig_node)
 		    {
-		      struct ipa_ref *ref;
+		      ipa_ref *ref;
 		      ref = clone->find_reference (n, NULL, 0);
 		      if (ref)
 			{
@@ -3542,11 +3542,11 @@ propagate_controlled_uses (struct cgraph_edge *cs)
        i < ipa_get_cs_argument_count (args);
        i++)
     {
-      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
+      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
 
       if (jf->type == IPA_JF_CONST)
 	{
-	  struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
+	  ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
 	  if (rdesc)
 	    rdesc->refcount = IPA_UNDESCRIBED_USE;
 	}
@@ -3564,13 +3564,13 @@ propagate_controlled_uses (struct cgraph_edge *cs)
    created.  */
 
 bool
-ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
+ipa_propagate_indirect_call_infos (cgraph_edge *cs,
 				   vec<cgraph_edge *> *new_edges)
 {
   bool changed;
   /* Do nothing if the preparation phase has not been carried out yet
      (i.e. during early inlining).  */
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_summary)
     return false;
   gcc_assert (ipa_edge_args_vector);
 
@@ -3584,7 +3584,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
    to.  */
 
 void
-ipa_free_edge_args_substructures (struct ipa_edge_args *args)
+ipa_free_edge_args_substructures (ipa_edge_args *args)
 {
   vec_free (args->jump_functions);
   memset (args, 0, sizeof (*args));
@@ -3596,7 +3596,7 @@ void
 ipa_free_all_edge_args (void)
 {
   int i;
-  struct ipa_edge_args *args;
+  ipa_edge_args *args;
 
   if (!ipa_edge_args_vector)
     return;
@@ -3610,15 +3610,21 @@ ipa_free_all_edge_args (void)
 /* Frees all dynamically allocated structures that the param info points
    to.  */
 
-void
-ipa_free_node_params_substructures (struct ipa_node_params *info)
+ipa_node_params::~ipa_node_params ()
 {
-  info->descriptors.release ();
-  free (info->lattices);
+  descriptors.release ();
+  free (lattices);
   /* Lattice values and their sources are deallocated with their alocation
      pool.  */
-  info->known_vals.release ();
-  memset (info, 0, sizeof (*info));
+  known_vals.release ();
+
+  lattices = NULL;
+  ipcp_orig_node = NULL;
+  analysis_done = 0;
+  node_enqueued = 0;
+  do_clone_for_all_contexts = 0;
+  is_all_contexts_clone = 0;
+  node_dead = 0;
 }
 
 /* Free all ipa_node_params structures.  */
@@ -3626,11 +3632,8 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
 void
 ipa_free_all_node_params (void)
 {
-  int i;
-  struct ipa_node_params *info;
-
-  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
-    ipa_free_node_params_substructures (info);
+  delete ipa_node_params_summary;
+  ipa_node_params_summary = NULL;
 
   ipa_node_params_vector.release ();
 }
@@ -3638,8 +3641,8 @@ ipa_free_all_node_params (void)
 /* Set the aggregate replacements of NODE to be AGGVALS.  */
 
 void
-ipa_set_node_agg_value_chain (struct cgraph_node *node,
-			      struct ipa_agg_replacement_value *aggvals)
+ipa_set_node_agg_value_chain (const cgraph_node *node,
+			      ipa_agg_replacement_value *aggvals)
 {
   if (vec_safe_length (ipa_node_agg_replacements)
       <= (unsigned) symtab->cgraph_max_uid)
@@ -3652,9 +3655,9 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
 /* Hook that is called by cgraph.c when an edge is removed.  */
 
 static void
-ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
+ipa_edge_removal_hook (cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_edge_args *args;
+  ipa_edge_args *args;
 
   /* During IPA-CP updating we can be called on not-yet analyzed clones.  */
   if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
@@ -3663,11 +3666,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   args = IPA_EDGE_REF (cs);
   if (args->jump_functions)
     {
-      struct ipa_jump_func *jf;
+      ipa_jump_func *jf;
       int i;
       FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
 	{
-	  struct ipa_cst_ref_desc *rdesc;
+	  ipa_cst_ref_desc *rdesc;
 	  try_decrement_rdesc_refcount (jf);
 	  if (jf->type == IPA_JF_CONST
 	      && (rdesc = ipa_get_jf_constant_rdesc (jf))
@@ -3679,25 +3682,13 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
 }
 
-/* Hook that is called by cgraph.c when a node is removed.  */
-
-static void
-ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
-  if (ipa_node_params_vector.length () > (unsigned)node->uid)
-    ipa_free_node_params_substructures (IPA_NODE_REF (node));
-  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
-    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
-}
-
 /* Hook that is called by cgraph.c when an edge is duplicated.  */
 
 static void
-ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
+ipa_edge_duplication_hook (cgraph_edge *src, cgraph_edge *dst,
 			   __attribute__((unused)) void *data)
 {
-  struct ipa_edge_args *old_args, *new_args;
+  ipa_edge_args *old_args, *new_args;
   unsigned int i;
 
   ipa_check_create_edge_args ();
@@ -3712,20 +3703,20 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 
   for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
     {
-      struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
-      struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
+      ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
+      ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
 
       dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
 
       if (src_jf->type == IPA_JF_CONST)
 	{
-	  struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
+	  ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
 
 	  if (!src_rdesc)
 	    dst_jf->value.constant.rdesc = NULL;
 	  else if (src->caller == dst->caller)
 	    {
-	      struct ipa_ref *ref;
+	      ipa_ref *ref;
 	      symtab_node *n = cgraph_node_for_jfunc (src_jf);
 	      gcc_checking_assert (n);
 	      ref = src->caller->find_reference (n, src->call_stmt,
@@ -3734,8 +3725,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	      dst->caller->clone_reference (ref, ref->stmt);
 
 	      gcc_checking_assert (ipa_refdesc_pool);
-	      struct ipa_cst_ref_desc *dst_rdesc
-		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+	      ipa_cst_ref_desc *dst_rdesc
+		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
 	      dst_rdesc->cs = dst;
 	      dst_rdesc->refcount = src_rdesc->refcount;
 	      dst_rdesc->next_duplicate = NULL;
@@ -3743,10 +3734,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	    }
 	  else if (src_rdesc->cs == src)
 	    {
-	      struct ipa_cst_ref_desc *dst_rdesc;
+	      ipa_cst_ref_desc *dst_rdesc;
 	      gcc_checking_assert (ipa_refdesc_pool);
 	      dst_rdesc
-		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
 	      dst_rdesc->cs = dst;
 	      dst_rdesc->refcount = src_rdesc->refcount;
 	      dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
@@ -3755,7 +3746,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	    }
 	  else
 	    {
-	      struct ipa_cst_ref_desc *dst_rdesc;
+	      ipa_cst_ref_desc *dst_rdesc;
 	      /* This can happen during inlining, when a JFUNC can refer to a
 		 reference taken in a function up in the tree of inline clones.
 		 We need to find the duplicate that refers to our tree of
@@ -3766,7 +3757,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 		   dst_rdesc;
 		   dst_rdesc = dst_rdesc->next_duplicate)
 		{
-		  struct cgraph_node *top;
+		  cgraph_node *top;
 		  top = dst_rdesc->cs->caller->global.inlined_to
 		    ? dst_rdesc->cs->caller->global.inlined_to
 		    : dst_rdesc->cs->caller;
@@ -3780,9 +3771,9 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
       else if (dst_jf->type == IPA_JF_PASS_THROUGH
 	       && src->caller == dst->caller)
 	{
-	  struct cgraph_node *inline_root = dst->caller->global.inlined_to
+	  cgraph_node *inline_root = dst->caller->global.inlined_to
 	    ? dst->caller->global.inlined_to : dst->caller;
-	  struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
+	  ipa_node_params *root_info = IPA_NODE_REF (inline_root);
 	  int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
 
 	  int c = ipa_get_controlled_uses (root_info, idx);
@@ -3795,18 +3786,24 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
     }
 }
 
-/* Hook that is called by cgraph.c when a node is duplicated.  */
+/* Analyze newly added function into callgraph.  */
 
 static void
-ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
-			   ATTRIBUTE_UNUSED void *data)
+ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_node_params *old_info, *new_info;
-  struct ipa_agg_replacement_value *old_av, *new_av;
+  if (node->has_gimple_body_p ())
+    ipa_analyze_node (node);
+}
 
-  ipa_check_create_node_params ();
-  old_info = IPA_NODE_REF (src);
-  new_info = IPA_NODE_REF (dst);
+/* Hook that is called by summary when a node is duplicated.  */
+
+void
+ipa_node_params_cgraph_summary::duplication_hook(cgraph_node *src,
+						    cgraph_node *dst,
+						    ipa_node_params *old_info,
+						    ipa_node_params *new_info)
+{
+  ipa_agg_replacement_value *old_av, *new_av;
 
   new_info->descriptors = old_info->descriptors.copy ();
   new_info->lattices = NULL;
@@ -3822,7 +3819,7 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   new_av = NULL;
   while (old_av)
     {
-      struct ipa_agg_replacement_value *v;
+      ipa_agg_replacement_value *v;
 
       v = ggc_alloc<ipa_agg_replacement_value> ();
       memcpy (v, old_av, sizeof (*v));
@@ -3833,33 +3830,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   ipa_set_node_agg_value_chain (dst, new_av);
 }
 
-
-/* Analyze newly added function into callgraph.  */
-
-static void
-ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  if (node->has_gimple_body_p ())
-    ipa_analyze_node (node);
-}
-
 /* Register our cgraph hooks if they are not already there.  */
 
 void
 ipa_register_cgraph_hooks (void)
 {
+  ipa_check_create_node_params ();
+
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
   function_insertion_hook_holder =
       symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
 }
@@ -3871,12 +3854,8 @@ ipa_unregister_cgraph_hooks (void)
 {
   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
   symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
 }
@@ -3923,10 +3902,10 @@ ipa_free_all_structures_after_iinln (void)
    callgraph to F.  */
 
 void
-ipa_print_node_params (FILE *f, struct cgraph_node *node)
+ipa_print_node_params (FILE *f, cgraph_node *node)
 {
   int i, count;
-  struct ipa_node_params *info;
+  ipa_node_params *info;
 
   if (!node->definition)
     return;
@@ -3957,7 +3936,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
 void
 ipa_print_all_params (FILE * f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "\nFunction parameters:\n");
   FOR_EACH_FUNCTION (node)
@@ -4040,7 +4019,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
   tree new_arg_types = NULL;
   for (int i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       gcc_assert (link);
 
       adj = &adjustments[i];
@@ -4158,10 +4137,10 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
    contain the corresponding call graph edge.  */
 
 void
-ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
+ipa_modify_call_arguments (cgraph_edge *cs, gimple stmt,
 			   ipa_parm_adjustment_vec adjustments)
 {
-  struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
+  cgraph_node *current_node = cgraph_node::get (current_function_decl);
   vec<tree> vargs;
   vec<tree, va_gc> **debug_args = NULL;
   gimple new_stmt;
@@ -4179,7 +4158,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
   gsi_prev (&prev_gsi);
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
 
       adj = &adjustments[i];
 
@@ -4412,7 +4391,7 @@ bool
 ipa_modify_expr (tree *expr, bool convert,
 		 ipa_parm_adjustment_vec adjustments)
 {
-  struct ipa_parm_adjustment *cand
+  ipa_parm_adjustment *cand
     = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
   if (!cand)
     return false;
@@ -4500,11 +4479,11 @@ ipa_get_adjustment_candidate (tree **expr, bool *convert,
   if (!base || TREE_CODE (base) != PARM_DECL)
     return NULL;
 
-  struct ipa_parm_adjustment *cand = NULL;
+  ipa_parm_adjustment *cand = NULL;
   unsigned int len = adjustments.length ();
   for (unsigned i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj = &adjustments[i];
+      ipa_parm_adjustment *adj = &adjustments[i];
 
       if (adj->base == base
 	  && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
@@ -4530,7 +4509,7 @@ index_in_adjustments_multiple_times_p (int base_index,
 
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       adj = &adjustments[i];
 
       if (adj->base_index == base_index)
@@ -4561,7 +4540,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
   tmp.create (inlen);
   for (i = 0; i < inlen; i++)
     {
-      struct ipa_parm_adjustment *n;
+      ipa_parm_adjustment *n;
       n = &inner[i];
 
       if (n->op == IPA_PARM_OP_REMOVE)
@@ -4577,9 +4556,9 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
   adjustments.create (outlen + removals);
   for (i = 0; i < outlen; i++)
     {
-      struct ipa_parm_adjustment r;
-      struct ipa_parm_adjustment *out = &outer[i];
-      struct ipa_parm_adjustment *in = &tmp[out->base_index];
+      ipa_parm_adjustment r;
+      ipa_parm_adjustment *out = &outer[i];
+      ipa_parm_adjustment *in = &tmp[out->base_index];
 
       memset (&r, 0, sizeof (r));
       gcc_assert (in->op != IPA_PARM_OP_REMOVE);
@@ -4616,7 +4595,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
 
   for (i = 0; i < inlen; i++)
     {
-      struct ipa_parm_adjustment *n = &inner[i];
+      ipa_parm_adjustment *n = &inner[i];
 
       if (n->op == IPA_PARM_OP_REMOVE)
 	adjustments.quick_push (*n);
@@ -4640,7 +4619,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
   fprintf (file, "IPA param adjustments: ");
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       adj = &adjustments[i];
 
       if (!first)
@@ -4683,7 +4662,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
 /* Dump the AV linked list.  */
 
 void
-ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
+ipa_dump_agg_replacement_values (FILE *f, ipa_agg_replacement_value *av)
 {
   bool comma = false;
   fprintf (f, "     Aggregate replacements:");
@@ -4700,11 +4679,11 @@ ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
 /* Stream out jump function JUMP_FUNC to OB.  */
 
 static void
-ipa_write_jump_function (struct output_block *ob,
-			 struct ipa_jump_func *jump_func)
+ipa_write_jump_function (output_block *ob,
+			 ipa_jump_func *jump_func)
 {
-  struct ipa_agg_jf_item *item;
-  struct bitpack_d bp;
+  ipa_agg_jf_item *item;
+  bitpack_d bp;
   int i, count;
 
   streamer_write_uhwi (ob, jump_func->type);
@@ -4768,10 +4747,10 @@ ipa_write_jump_function (struct output_block *ob,
 /* Read in jump function JUMP_FUNC from IB.  */
 
 static void
-ipa_read_jump_function (struct lto_input_block *ib,
-			struct ipa_jump_func *jump_func,
-			struct cgraph_edge *cs,
-			struct data_in *data_in)
+ipa_read_jump_function (lto_input_block *ib,
+			ipa_jump_func *jump_func,
+			cgraph_edge *cs,
+			data_in *data_in)
 {
   enum jump_func_type jftype;
   enum tree_code operation;
@@ -4800,7 +4779,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
       if (operation == NOP_EXPR)
 	{
 	  int formal_id =  streamer_read_uhwi (ib);
-	  struct bitpack_d bp = streamer_read_bitpack (ib);
+	  bitpack_d bp = streamer_read_bitpack (ib);
 	  bool agg_preserved = bp_unpack_value (&bp, 1);
 	  bool type_preserved = bp_unpack_value (&bp, 1);
 	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
@@ -4819,7 +4798,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
 	HOST_WIDE_INT offset = streamer_read_uhwi (ib);
 	tree type = stream_read_tree (ib, data_in);
 	int formal_id = streamer_read_uhwi (ib);
-	struct bitpack_d bp = streamer_read_bitpack (ib);
+	bitpack_d bp = streamer_read_bitpack (ib);
 	bool agg_preserved = bp_unpack_value (&bp, 1);
 	bool type_preserved = bp_unpack_value (&bp, 1);
 
@@ -4833,12 +4812,12 @@ ipa_read_jump_function (struct lto_input_block *ib,
   vec_alloc (jump_func->agg.items, count);
   if (count)
     {
-      struct bitpack_d bp = streamer_read_bitpack (ib);
+      bitpack_d bp = streamer_read_bitpack (ib);
       jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
     }
   for (i = 0; i < count; i++)
     {
-      struct ipa_agg_jf_item item;
+      ipa_agg_jf_item item;
       item.offset = streamer_read_uhwi (ib);
       item.value = stream_read_tree (ib, data_in);
       jump_func->agg.items->quick_push (item);
@@ -4849,11 +4828,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
    relevant to indirect inlining to OB.  */
 
 static void
-ipa_write_indirect_edge_info (struct output_block *ob,
-			      struct cgraph_edge *cs)
+ipa_write_indirect_edge_info (output_block *ob,
+			      cgraph_edge *cs)
 {
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
-  struct bitpack_d bp;
+  cgraph_indirect_call_info *ii = cs->indirect_info;
+  bitpack_d bp;
 
   streamer_write_hwi (ob, ii->param_index);
   bp = bitpack_create (ob->main_stream);
@@ -4880,12 +4859,12 @@ ipa_write_indirect_edge_info (struct output_block *ob,
    relevant to indirect inlining from IB.  */
 
 static void
-ipa_read_indirect_edge_info (struct lto_input_block *ib,
-			     struct data_in *data_in,
-			     struct cgraph_edge *cs)
+ipa_read_indirect_edge_info (lto_input_block *ib,
+			     data_in *data_in,
+			     cgraph_edge *cs)
 {
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
-  struct bitpack_d bp;
+  cgraph_indirect_call_info *ii = cs->indirect_info;
+  bitpack_d bp;
 
   ii->param_index = (int) streamer_read_hwi (ib);
   bp = streamer_read_bitpack (ib);
@@ -4909,14 +4888,14 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
 /* Stream out NODE info to OB.  */
 
 static void
-ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
+ipa_write_node_info (output_block *ob, cgraph_node *node)
 {
   int node_ref;
   lto_symtab_encoder_t encoder;
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
   int j;
-  struct cgraph_edge *e;
-  struct bitpack_d bp;
+  cgraph_edge *e;
+  bitpack_d bp;
 
   encoder = ob->decl_state->symtab_node_encoder;
   node_ref = lto_symtab_encoder_encode (encoder, node);
@@ -4937,7 +4916,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
     streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
   for (e = node->callees; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
 
       streamer_write_uhwi (ob,
 			   ipa_get_cs_argument_count (args) * 2
@@ -4951,7 +4930,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
 
       streamer_write_uhwi (ob,
 			   ipa_get_cs_argument_count (args) * 2
@@ -4969,13 +4948,13 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
 /* Stream in NODE info from IB.  */
 
 static void
-ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
-		    struct data_in *data_in)
+ipa_read_node_info (lto_input_block *ib, cgraph_node *node,
+		    data_in *data_in)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
   int k;
-  struct cgraph_edge *e;
-  struct bitpack_d bp;
+  cgraph_edge *e;
+  bitpack_d bp;
 
   ipa_alloc_node_params (node, streamer_read_uhwi (ib));
 
@@ -4992,7 +4971,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
     ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
   for (e = node->callees; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
       int count = streamer_read_uhwi (ib);
       bool contexts_computed = count & 1;
       count /= 2;
@@ -5013,7 +4992,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
       int count = streamer_read_uhwi (ib);
       bool contexts_computed = count & 1;
       count /= 2;
@@ -5040,14 +5019,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
 void
 ipa_prop_write_jump_functions (void)
 {
-  struct cgraph_node *node;
-  struct output_block *ob;
+  cgraph_node *node;
+  output_block *ob;
   unsigned int count = 0;
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
 
-
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_summary)
     return;
 
   ob = create_output_block (LTO_section_jump_functions);
@@ -5081,15 +5059,15 @@ ipa_prop_write_jump_functions (void)
 /* Read section in file FILE_DATA of length LEN with data DATA.  */
 
 static void
-ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
+ipa_prop_read_section (lto_file_decl_data *file_data, const char *data,
 		       size_t len)
 {
-  const struct lto_function_header *header =
-    (const struct lto_function_header *) data;
-  const int cfg_offset = sizeof (struct lto_function_header);
+  const lto_function_header *header =
+    (const lto_function_header *) data;
+  const int cfg_offset = sizeof (lto_function_header);
   const int main_offset = cfg_offset + header->cfg_size;
   const int string_offset = main_offset + header->main_size;
-  struct data_in *data_in;
+  data_in *data_in;
   unsigned int i;
   unsigned int count;
 
@@ -5104,7 +5082,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
   for (i = 0; i < count; i++)
     {
       unsigned int index;
-      struct cgraph_node *node;
+      cgraph_node *node;
       lto_symtab_encoder_t encoder;
 
       index = streamer_read_uhwi (&ib_main);
@@ -5124,8 +5102,8 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
 void
 ipa_prop_read_jump_functions (void)
 {
-  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  lto_file_decl_data *file_data;
   unsigned int j = 0;
 
   ipa_check_create_node_params ();
@@ -5154,12 +5132,12 @@ ipa_update_after_lto_read (void)
 }
 
 void
-write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
+write_agg_replacement_chain (output_block *ob, cgraph_node *node)
 {
   int node_ref;
   unsigned int count = 0;
   lto_symtab_encoder_t encoder;
-  struct ipa_agg_replacement_value *aggvals, *av;
+  ipa_agg_replacement_value *aggvals, *av;
 
   aggvals = ipa_get_agg_replacements_for_node (node);
   encoder = ob->decl_state->symtab_node_encoder;
@@ -5172,7 +5150,7 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
 
   for (av = aggvals; av; av = av->next)
     {
-      struct bitpack_d bp;
+      bitpack_d bp;
 
       streamer_write_uhwi (ob, av->offset);
       streamer_write_uhwi (ob, av->index);
@@ -5187,18 +5165,18 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
 /* Stream in the aggregate value replacement chain for NODE from IB.  */
 
 static void
-read_agg_replacement_chain (struct lto_input_block *ib,
-			    struct cgraph_node *node,
-			    struct data_in *data_in)
+read_agg_replacement_chain (lto_input_block *ib,
+			    cgraph_node *node,
+			    data_in *data_in)
 {
-  struct ipa_agg_replacement_value *aggvals = NULL;
+  ipa_agg_replacement_value *aggvals = NULL;
   unsigned int count, i;
 
   count = streamer_read_uhwi (ib);
   for (i = 0; i <count; i++)
     {
-      struct ipa_agg_replacement_value *av;
-      struct bitpack_d bp;
+      ipa_agg_replacement_value *av;
+      bitpack_d bp;
 
       av = ggc_alloc<ipa_agg_replacement_value> ();
       av->offset = streamer_read_uhwi (ib);
@@ -5217,8 +5195,8 @@ read_agg_replacement_chain (struct lto_input_block *ib,
 void
 ipa_prop_write_all_agg_replacement (void)
 {
-  struct cgraph_node *node;
-  struct output_block *ob;
+  cgraph_node *node;
+  output_block *ob;
   unsigned int count = 0;
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
@@ -5257,16 +5235,16 @@ ipa_prop_write_all_agg_replacement (void)
    DATA.  */
 
 static void
-read_replacements_section (struct lto_file_decl_data *file_data,
+read_replacements_section (lto_file_decl_data *file_data,
 			   const char *data,
 			   size_t len)
 {
-  const struct lto_function_header *header =
-    (const struct lto_function_header *) data;
-  const int cfg_offset = sizeof (struct lto_function_header);
+  const lto_function_header *header =
+    (const lto_function_header *) data;
+  const int cfg_offset = sizeof (lto_function_header);
   const int main_offset = cfg_offset + header->cfg_size;
   const int string_offset = main_offset + header->main_size;
-  struct data_in *data_in;
+  data_in *data_in;
   unsigned int i;
   unsigned int count;
 
@@ -5280,7 +5258,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
   for (i = 0; i < count; i++)
     {
       unsigned int index;
-      struct cgraph_node *node;
+      cgraph_node *node;
       lto_symtab_encoder_t encoder;
 
       index = streamer_read_uhwi (&ib_main);
@@ -5300,8 +5278,8 @@ read_replacements_section (struct lto_file_decl_data *file_data,
 void
 ipa_prop_read_all_agg_replacement (void)
 {
-  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  lto_file_decl_data *file_data;
   unsigned int j = 0;
 
   while ((file_data = file_data_vec[j++]))
@@ -5319,10 +5297,10 @@ ipa_prop_read_all_agg_replacement (void)
    NODE.  */
 
 static void
-adjust_agg_replacement_values (struct cgraph_node *node,
-			       struct ipa_agg_replacement_value *aggval)
+adjust_agg_replacement_values (cgraph_node *node,
+			       ipa_agg_replacement_value *aggval)
 {
-  struct ipa_agg_replacement_value *v;
+  ipa_agg_replacement_value *v;
   int i, c = 0, d = 0, *adj;
 
   if (!node->clone.combined_args_to_skip)
@@ -5355,9 +5333,9 @@ adjust_agg_replacement_values (struct cgraph_node *node,
 class ipcp_modif_dom_walker : public dom_walker
 {
 public:
-  ipcp_modif_dom_walker (struct func_body_info *fbi,
+  ipcp_modif_dom_walker (func_body_info *fbi,
 			 vec<ipa_param_descriptor> descs,
-			 struct ipa_agg_replacement_value *av,
+			 ipa_agg_replacement_value *av,
 			 bool *sc, bool *cc)
     : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
       m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
@@ -5365,9 +5343,9 @@ public:
   virtual void before_dom_children (basic_block);
 
 private:
-  struct func_body_info *m_fbi;
+  func_body_info *m_fbi;
   vec<ipa_param_descriptor> m_descriptors;
-  struct ipa_agg_replacement_value *m_aggval;
+  ipa_agg_replacement_value *m_aggval;
   bool *m_something_changed, *m_cfg_changed;
 };
 
@@ -5377,7 +5355,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
   gimple_stmt_iterator gsi;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      struct ipa_agg_replacement_value *v;
+      ipa_agg_replacement_value *v;
       gimple stmt = gsi_stmt (gsi);
       tree rhs, val, t;
       HOST_WIDE_INT offset, size;
@@ -5468,11 +5446,11 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
 /* IPCP transformation phase doing propagation of aggregate values.  */
 
 unsigned int
-ipcp_transform_function (struct cgraph_node *node)
+ipcp_transform_function (cgraph_node *node)
 {
   vec<ipa_param_descriptor> descriptors = vNULL;
-  struct func_body_info fbi;
-  struct ipa_agg_replacement_value *aggval;
+  func_body_info fbi;
+  ipa_agg_replacement_value *aggval;
   int param_count;
   bool cfg_changed = false, something_changed = false;
 
@@ -5507,7 +5485,7 @@ ipcp_transform_function (struct cgraph_node *node)
 			 &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
   int i;
-  struct ipa_bb_info *bi;
+  ipa_bb_info *bi;
   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
     free_ipa_bb_info (bi);
   fbi.bb_infos.release ();
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 165fc1a..6c3b31f 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef IPA_PROP_H
 #define IPA_PROP_H
 
-
 /* The following definitions and interfaces are used by
    interprocedural analyses or parameters.  */
 
@@ -356,6 +355,8 @@ struct ipcp_lattice;
 
 struct ipa_node_params
 {
+  ~ipa_node_params ();
+
   /* Information about individual formal parameters that are gathered when
      summaries are generated. */
   vec<ipa_param_descriptor> descriptors;
@@ -364,7 +365,7 @@ struct ipa_node_params
   struct ipcp_param_lattices *lattices;
   /* Only for versioned nodes this field would not be NULL,
      it points to the node that IPA cp cloned from.  */
-  struct cgraph_node *ipcp_orig_node;
+  cgraph_node *ipcp_orig_node;
   /* If this node is an ipa-cp clone, these are the known values that describe
      what it has been specialized for.  */
   vec<tree> known_vals;
@@ -470,7 +471,7 @@ struct GTY(()) ipa_agg_replacement_value
 
 typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
 
-void ipa_set_node_agg_value_chain (struct cgraph_node *node,
+void ipa_set_node_agg_value_chain (const cgraph_node *node,
 				   struct ipa_agg_replacement_value *aggvals);
 
 /* ipa_edge_args stores information related to a callsite and particularly its
@@ -513,10 +514,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Types of vectors holding the infos.  */
+/* Callgraph summary for ipa_node_params.  */
+class ipa_node_params_cgraph_summary: public cgraph_summary <ipa_node_params *>
+{
+public:
+  ipa_node_params_cgraph_summary (symbol_table *table):
+    cgraph_summary <ipa_node_params *> (table) { }
+
+  /* Hook that is called by summary when a node is duplicated.  */
+  virtual void duplication_hook (cgraph_node *node,
+				 cgraph_node *node2,
+				 ipa_node_params *data,
+				 ipa_node_params *data2);
+};
 
 /* Vector where the parameter infos are actually stored. */
-extern vec<ipa_node_params> ipa_node_params_vector;
+extern ipa_node_params_cgraph_summary *ipa_node_params_summary;
 /* Vector of known aggregate values in cloned nodes.  */
 extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
@@ -524,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Return the associated parameter/argument info corresponding to the given
    node/edge.  */
-#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
+#define IPA_NODE_REF(NODE) ((*ipa_node_params_summary)[NODE])
 #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
 /* This macro checks validity of index returned by
    ipa_get_param_decl_index function.  */
@@ -534,11 +547,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 void ipa_create_all_node_params (void);
 void ipa_create_all_edge_args (void);
 void ipa_free_edge_args_substructures (struct ipa_edge_args *);
-void ipa_free_node_params_substructures (struct ipa_node_params *);
 void ipa_free_all_node_params (void);
 void ipa_free_all_edge_args (void);
 void ipa_free_all_structures_after_ipa_cp (void);
 void ipa_free_all_structures_after_iinln (void);
+
 void ipa_register_cgraph_hooks (void);
 int count_formal_params (tree fndecl);
 
@@ -548,11 +561,8 @@ int count_formal_params (tree fndecl);
 static inline void
 ipa_check_create_node_params (void)
 {
-  if (!ipa_node_params_vector.exists ())
-    ipa_node_params_vector.create (symtab->cgraph_max_uid);
-
-  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
-    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
+  if (!ipa_node_params_summary)
+    ipa_node_params_summary = new ipa_node_params_cgraph_summary (symtab);
 }
 
 /* This function ensures the array of edge arguments infos is big enough to
@@ -579,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
 /* Return the aggregate replacements for NODE, if there are any.  */
 
 static inline struct ipa_agg_replacement_value *
-ipa_get_agg_replacements_for_node (struct cgraph_node *node)
+ipa_get_agg_replacements_for_node (const cgraph_node *node)
 {
   if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
     return NULL;
@@ -587,7 +597,7 @@ ipa_get_agg_replacements_for_node (struct cgraph_node *node)
 }
 
 /* Function formal parameters related computations.  */
-void ipa_initialize_node_params (struct cgraph_node *node);
+void ipa_initialize_node_params (const cgraph_node *node);
 bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
 					vec<cgraph_edge *> *new_edges);
 
@@ -602,7 +612,7 @@ tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
 tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
 
 /* Functions related to both.  */
-void ipa_analyze_node (struct cgraph_node *);
+void ipa_analyze_node (cgraph_node *);
 
 /* Aggregate jump function related functions.  */
 tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
@@ -611,9 +621,9 @@ bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
 			     HOST_WIDE_INT *, bool *);
 
 /* Debugging interface.  */
-void ipa_print_node_params (FILE *, struct cgraph_node *node);
+void ipa_print_node_params (FILE *, cgraph_node *node);
 void ipa_print_all_params (FILE *);
-void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
+void ipa_print_node_jump_functions (FILE *f, cgraph_node *node);
 void ipa_print_all_jump_functions (FILE * f);
 void ipcp_verify_propagated_values (void);
 
@@ -717,7 +727,7 @@ void ipa_update_after_lto_read (void);
 int ipa_get_param_decl_index (struct ipa_node_params *, tree);
 tree ipa_value_from_jfunc (struct ipa_node_params *info,
 			   struct ipa_jump_func *jfunc);
-unsigned int ipcp_transform_function (struct cgraph_node *node);
+unsigned int ipcp_transform_function (cgraph_node *node);
 void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
 bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
 ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 98dbc63..0a7ca53 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "gimple-ssa.h"
 #include "tree-cfg.h"
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 22900cc..83111bc 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa.c b/gcc/ipa.c
index a6086d8..aded512 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-iterator.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 0e1a95b..37d0f39 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "ipa-utils.h"
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 4c4e48a..ee97d06 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "builtins.h"
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index d8519d9..c99dbdf 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "inchash.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "common.h"
 #include "debug.h"
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b59d069..707379a 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfgcleanup.h"
 #include "pretty-print.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "tree-nested.h"
 #include "tree-eh.h"
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 8cb9510..a8e3561 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "value-prof.h"
 #include "tree-pass.h"
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 1e629bc..99b19b8 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "statistics.h"
 #include "params.h"
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ea99198..b526cc9 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "tree-ssa-propagate.h"
 #include "ipa-utils.h"
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 1/4] cgraph_summary data structure introduction.
@ 2014-11-13 14:23 mliska
  2014-11-13 14:23 ` [PATCH 4/4] Data structure is used for inline_summary struct mliska
                   ` (3 more replies)
  0 siblings, 4 replies; 40+ messages in thread
From: mliska @ 2014-11-13 14:23 UTC (permalink / raw)
  To: gcc-patches

Following patchset introduces cgraph_summary template class that
should replace custom implementation of cgraph related summaries.

Idea behind the patch is to provide a generic interface one can use
to register custom summary related to a cgraph_node. As you know,
symbol_table provides hooks for creation, deletion and duplication
of a cgraph_node. If you have a pass, you need to handle all these
hooks and store custom data in your data structure.

Patchset can boostrap on x86_64-linux-pc and no regression was
observed.

Ready for trunk?
Thank you,
Martin
---
 gcc/ChangeLog | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2eb6f35..ad3c2bf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,4 @@
+
 2014-11-12  Alan Lawrence  <alan.lawrence@arm.com>
 
 	* config/aarch64/aarch64.c (aarch64_simd_lane_bounds): Display indices.
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-13 14:23 [PATCH 1/4] cgraph_summary data structure introduction mliska
@ 2014-11-13 14:23 ` mliska
  2014-11-13 16:04   ` Jan Hubicka
  2014-11-13 14:23 ` [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass mliska
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 40+ messages in thread
From: mliska @ 2014-11-13 14:23 UTC (permalink / raw)
  To: gcc-patches

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* cgraphunit.c (symbol_table::process_new_functions):
	inline_summary_vec is replaced with inline_summary_summary.
	* ipa-cp.c (ipcp_cloning_candidate_p): Usage of get_inline_summary.
	(devirtualization_time_bonus): Likewise.
	(estimate_local_effects): Likewise.
	(ipcp_propagate_stage): Likewise.
	* ipa-inline-analysis.c (evaluate_conditions_for_known_args): Likewise.
	(evaluate_properties_for_edge): Likewise.
	(inline_summary_alloc): Deletion of old hook holders.
	(reset_inline_summary): inline_summary is added as argument.
	(inline_summary_cgraph_summary::removal_hook): New function.
	(inline_summary_cgraph_summary::duplication_hook): Likewise.
	(dump_inline_edge_summary): Struct keyword removed.
	(dump_inline_summary): Likewise.
	(estimate_function_body_sizes): Usage of get_inline_summary.
	(compute_inline_parameters): Likewise.
	(estimate_edge_devirt_benefit): Struct keyword removed.
	(estimate_node_size_and_time): Likewise.
	(inline_update_callee_summaries): Likewise.
	(inline_merge_summary): Usage of get_inline_summary.
	(inline_update_overall_summary): Likewise.
	(simple_edge_hints): Likewise.
	(do_estimate_edge_time): Likewise.
	(estimate_time_after_inlining): Likewise.
	(estimate_size_after_inlining): Likewise.
	(do_estimate_growth): Likewise.
	(growth_likely_positive): Likewise.
	(inline_generate_summary): inline_summary_summary is registered.
	(inline_read_section): Struct keyword removed.
	(inline_read_summary): Likewise.
	(inline_write_summary): Likewise.
	(inline_free_summary): Removal of old hook holders.
	* ipa-inline-transform.c (clone_inlined_nodes): Usage of
	get_inline_summary.
	(inline_call): Likewise.
	* ipa-inline.c (caller_growth_limits): Struct keyword is removed.
	(can_inline_edge_p): Usage of get_inline_summary.
	(want_early_inline_function_p): Struct keyword removed.
	(compute_uninlined_call_time): Usage of get_inline_summary.
	(compute_inlined_call_time): Likewise.
	(big_speedup_p): Likewise.
	(want_inline_small_function_p): Likewise.
	(edge_badness): Likewise.
	(update_caller_keys): Likewise.
	(update_callee_keys): Likewise.
	(recursive_inlining): Likewise.
	(inline_small_functions): Likewise.
	(inline_to_all_callers): Likewise.
	(dump_overall_stats): Likewise.
	(early_inline_small_functions): Likewise.
	* ipa-inline.h (get_inline_summary): New function.
	* ipa-split.c (execute_split_functions): Usage of get_inline_summary.
	* ipa.c (walk_polymorphic_call_targets): inline_summary_vec is replaced with inline_summary_summary.
	* tree-sra.c (ipa_sra_preliminary_function_checks): Usage of get_inline_summary.

gcc/lto/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* lto-partition.c (add_symbol_to_partition_1): Usage of
	get_inline_summary.
	(undo_partition): Likewise.
	(lto_balanced_map): Likewise.
---
 gcc/cgraphunit.c           |   2 +-
 gcc/ipa-cp.c               |  10 +--
 gcc/ipa-inline-analysis.c  | 193 ++++++++++++++++++++-------------------------
 gcc/ipa-inline-transform.c |   6 +-
 gcc/ipa-inline.c           |  61 +++++++-------
 gcc/ipa-inline.h           |  30 +++++--
 gcc/ipa-split.c            |   2 +-
 gcc/ipa.c                  |   2 +-
 gcc/lto/lto-partition.c    |  10 +--
 gcc/tree-sra.c             |   2 +-
 10 files changed, 154 insertions(+), 164 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index dbbdc44..de032c1 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -338,7 +338,7 @@ symbol_table::process_new_functions (void)
 	  if (state == IPA_SSA
 	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
 	    g->get_passes ()->execute_early_local_passes ();
-	  else if (inline_summary_vec != NULL)
+	  else if (inline_summary_summary != NULL)
 	    compute_inline_parameters (node, true);
 	  free_dominance_info (CDI_POST_DOMINATORS);
 	  free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index da589af..f721e72 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -552,7 +552,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
   init_caller_stats (&stats);
   node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
 
-  if (inline_summary (node)->self_size < stats.n_calls)
+  if (get_inline_summary (node)->self_size < stats.n_calls)
     {
       if (dump_file)
         fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
@@ -1718,7 +1718,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
     {
       struct cgraph_node *callee;
-      struct inline_summary *isummary;
+      inline_summary *isummary;
       enum availability avail;
       tree target;
 
@@ -1735,7 +1735,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
       callee = callee->function_symbol (&avail);
       if (avail < AVAIL_AVAILABLE)
 	continue;
-      isummary = inline_summary (callee);
+      isummary = get_inline_summary (callee);
       if (!isummary->inlinable)
 	continue;
 
@@ -1945,7 +1945,7 @@ estimate_local_effects (struct cgraph_node *node)
   vec<ipa_agg_jump_function> known_aggs;
   vec<ipa_agg_jump_function_p> known_aggs_ptrs;
   bool always_const;
-  int base_time = inline_summary (node)->time;
+  int base_time = get_inline_summary (node)->time;
   int removable_params_cost;
 
   if (!count || !ipcp_versionable_function_p (node))
@@ -2357,7 +2357,7 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
 	initialize_node_lattices (node);
       }
     if (node->definition && !node->alias)
-      overall_size += inline_summary (node)->self_size;
+      overall_size += get_inline_summary (node)->self_size;
     if (node->count > max_count)
       max_count = node->count;
   }
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index c7a52d2..b3dbd5b 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -148,21 +148,15 @@ enum predicate_conditions
 #define CHANGED IDENTIFIER_NODE
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static void inline_node_removal_hook (struct cgraph_node *, void *);
-static void inline_node_duplication_hook (struct cgraph_node *,
-					  struct cgraph_node *, void *);
 static void inline_edge_removal_hook (struct cgraph_edge *, void *);
 static void inline_edge_duplication_hook (struct cgraph_edge *,
 					  struct cgraph_edge *, void *);
 
 /* VECtor holding inline summaries.  
    In GGC memory because conditions might point to constant trees.  */
-vec<inline_summary_t, va_gc> *inline_summary_vec;
+cgraph_summary <inline_summary *> *inline_summary_summary;
 vec<inline_edge_summary_t> inline_edge_summary_vec;
 
 /* Cached node/edge growths.  */
@@ -699,7 +693,7 @@ dump_inline_hints (FILE *f, inline_hints hints)
 /* Record SIZE and TIME under condition PRED into the inline summary.  */
 
 static void
-account_size_time (struct inline_summary *summary, int size, int time,
+account_size_time (inline_summary *summary, int size, int time,
 		   struct predicate *pred)
 {
   size_time_entry *e;
@@ -829,7 +823,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 				    known_aggs)
 {
   clause_t clause = inline_p ? 0 : 1 << predicate_not_inlined_condition;
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = get_inline_summary (node);
   int i;
   struct condition *c;
 
@@ -900,7 +894,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 			      vec<ipa_agg_jump_function_p> *known_aggs_ptr)
 {
   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-  struct inline_summary *info = inline_summary (callee);
+  inline_summary *info = get_inline_summary (callee);
   vec<tree> known_vals = vNULL;
   vec<ipa_agg_jump_function_p> known_aggs = vNULL;
 
@@ -974,21 +968,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 static void
 inline_summary_alloc (void)
 {
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&inline_node_removal_hook, NULL);
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&inline_node_duplication_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
 
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) symtab->cgraph_max_uid)
-    vec_safe_grow_cleared (inline_summary_vec, symtab->cgraph_max_uid + 1);
+  if (!inline_summary_summary)
+    inline_summary_summary = (inline_summary_cgraph_summary *) inline_summary_cgraph_summary::create_ggc (symtab);
+
   if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid)
     inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
   if (!edge_predicate_pool)
@@ -1018,9 +1007,9 @@ reset_inline_edge_summary (struct cgraph_edge *e)
    data from previous run so they are not cumulated.  */
 
 static void
-reset_inline_summary (struct cgraph_node *node)
+reset_inline_summary (const struct cgraph_node *node,
+		      inline_summary *info)
 {
-  struct inline_summary *info = inline_summary (node);
   struct cgraph_edge *e;
 
   info->self_size = info->self_time = 0;
@@ -1056,16 +1045,10 @@ reset_inline_summary (struct cgraph_node *node)
 
 /* Hook that is called by cgraph.c when a node is removed.  */
 
-static void
-inline_node_removal_hook (struct cgraph_node *node,
-			  void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_cgraph_summary::removal_hook (cgraph_node *node, inline_summary *info)
 {
-  struct inline_summary *info;
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) node->uid)
-    return;
-  info = inline_summary (node);
-  reset_inline_summary (node);
-  memset (info, 0, sizeof (inline_summary_t));
+  reset_inline_summary (node, info);
 }
 
 /* Remap predicate P of former function to be predicate of duplicated function.
@@ -1075,7 +1058,7 @@ inline_node_removal_hook (struct cgraph_node *node,
 static struct predicate
 remap_predicate_after_duplication (struct predicate *p,
 				   clause_t possible_truths,
-				   struct inline_summary *info)
+				   inline_summary *info)
 {
   struct predicate new_predicate = true_predicate ();
   int j;
@@ -1099,7 +1082,7 @@ remap_predicate_after_duplication (struct predicate *p,
 static void
 remap_hint_predicate_after_duplication (struct predicate **p,
 					clause_t possible_truths,
-					struct inline_summary *info)
+					inline_summary *info)
 {
   struct predicate new_predicate;
 
@@ -1115,16 +1098,14 @@ remap_hint_predicate_after_duplication (struct predicate **p,
 
 
 /* Hook that is called by cgraph.c when a node is duplicated.  */
-
-static void
-inline_node_duplication_hook (struct cgraph_node *src,
-			      struct cgraph_node *dst,
-			      ATTRIBUTE_UNUSED void *data)
+void
+inline_summary_cgraph_summary::duplication_hook (cgraph_node *src,
+			      cgraph_node *dst,
+			      inline_summary *,
+			      inline_summary *info)
 {
-  struct inline_summary *info;
   inline_summary_alloc ();
-  info = inline_summary (dst);
-  memcpy (info, inline_summary (src), sizeof (struct inline_summary));
+  memcpy (info, get_inline_summary (src), sizeof (inline_summary));
   /* TODO: as an optimization, we may avoid copying conditions
      that are known to be false or true.  */
   info->conds = vec_safe_copy (info->conds);
@@ -1328,7 +1309,7 @@ free_growth_caches (void)
 
 static void
 dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
-			  struct inline_summary *info)
+			  inline_summary *info)
 {
   struct cgraph_edge *edge;
   for (edge = node->callees; edge; edge = edge->next_callee)
@@ -1345,8 +1326,8 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
 	       indent, "", es->loop_depth, edge->frequency,
 	       es->call_stmt_size, es->call_stmt_time,
-	       (int) inline_summary (callee)->size / INLINE_SIZE_SCALE,
-	       (int) inline_summary (callee)->estimated_stack_size);
+	       (int) get_inline_summary (callee)->size / INLINE_SIZE_SCALE,
+	       (int) get_inline_summary (callee)->estimated_stack_size);
 
       if (es->predicate)
 	{
@@ -1372,9 +1353,9 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
 		   " callee size %i\n",
 		   indent + 2, "",
-		   (int) inline_summary (callee)->stack_frame_offset,
-		   (int) inline_summary (callee)->estimated_self_stack_size,
-		   (int) inline_summary (callee)->estimated_stack_size);
+		   (int) get_inline_summary (callee)->stack_frame_offset,
+		   (int) get_inline_summary (callee)->estimated_self_stack_size,
+		   (int) get_inline_summary (callee)->estimated_stack_size);
 	  dump_inline_edge_summary (f, indent + 2, callee, info);
 	}
     }
@@ -1402,7 +1383,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
 {
   if (node->definition)
     {
-      struct inline_summary *s = inline_summary (node);
+      inline_summary *s = get_inline_summary (node);
       size_time_entry *e;
       int i;
       fprintf (f, "Inline summary for %s/%i", node->name (),
@@ -1725,7 +1706,7 @@ eliminated_by_inlining_prob (gimple stmt)
 
 static void
 set_cond_stmt_execution_predicate (struct ipa_node_params *info,
-				   struct inline_summary *summary,
+				   inline_summary *summary,
 				   basic_block bb)
 {
   gimple last;
@@ -1810,7 +1791,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
 
 static void
 set_switch_stmt_execution_predicate (struct ipa_node_params *info,
-				     struct inline_summary *summary,
+				     inline_summary *summary,
 				     basic_block bb)
 {
   gimple last;
@@ -1871,7 +1852,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
 static void
 compute_bb_predicates (struct cgraph_node *node,
 		       struct ipa_node_params *parms_info,
-		       struct inline_summary *summary)
+		       inline_summary *summary)
 {
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   bool done = false;
@@ -1950,7 +1931,7 @@ typedef struct predicate predicate_t;
 
 static struct predicate
 will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
-				    struct inline_summary *summary,
+				    inline_summary *summary,
 				    tree expr,
 				    vec<predicate_t> nonconstant_names)
 {
@@ -2013,7 +1994,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
 
 static struct predicate
 will_be_nonconstant_predicate (struct ipa_node_params *info,
-			       struct inline_summary *summary,
+			       inline_summary *summary,
 			       gimple stmt,
 			       vec<predicate_t> nonconstant_names)
 {
@@ -2215,7 +2196,7 @@ param_change_prob (gimple stmt, int i)
 
 static bool
 phi_result_unknown_predicate (struct ipa_node_params *info,
-			      struct inline_summary *summary, basic_block bb,
+			      inline_summary *summary, basic_block bb,
 			      struct predicate *p,
 			      vec<predicate_t> nonconstant_names)
 {
@@ -2274,7 +2255,7 @@ phi_result_unknown_predicate (struct ipa_node_params *info,
    NONCONSTANT_NAMES, if possible.  */
 
 static void
-predicate_for_phi_result (struct inline_summary *summary, gimple phi,
+predicate_for_phi_result (inline_summary *summary, gimple phi,
 			  struct predicate *p,
 			  vec<predicate_t> nonconstant_names)
 {
@@ -2304,7 +2285,7 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
 /* Return predicate specifying when array index in access OP becomes non-constant.  */
 
 static struct predicate
-array_index_predicate (struct inline_summary *info,
+array_index_predicate (inline_summary *info,
 		       vec< predicate_t> nonconstant_names, tree op)
 {
   struct predicate p = false_predicate ();
@@ -2460,7 +2441,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   gimple_stmt_iterator bsi;
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   int freq;
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = get_inline_summary (node);
   struct predicate bb_predicate;
   struct ipa_node_params *parms_info = NULL;
   vec<predicate_t> nonconstant_names = vNULL;
@@ -2702,7 +2683,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	}
     }
-  set_hint_predicate (&inline_summary (node)->array_index, array_index);
+  set_hint_predicate (&get_inline_summary (node)->array_index, array_index);
   time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
   if (time > MAX_TIME)
     time = MAX_TIME;
@@ -2790,9 +2771,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	  free (body);
 	}
-      set_hint_predicate (&inline_summary (node)->loop_iterations,
+      set_hint_predicate (&get_inline_summary (node)->loop_iterations,
 			  loop_iterations);
-      set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
+      set_hint_predicate (&get_inline_summary (node)->loop_stride, loop_stride);
       scev_finalize ();
     }
   FOR_ALL_BB_FN (bb, my_function)
@@ -2810,8 +2791,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	  e->aux = NULL;
 	}
     }
-  inline_summary (node)->self_time = time;
-  inline_summary (node)->self_size = size;
+  get_inline_summary (node)->self_time = time;
+  get_inline_summary (node)->self_size = size;
   nonconstant_names.release ();
   if (optimize && !early)
     {
@@ -2834,14 +2815,14 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
 {
   HOST_WIDE_INT self_stack_size;
   struct cgraph_edge *e;
-  struct inline_summary *info;
+  inline_summary *info;
 
   gcc_assert (!node->global.inlined_to);
 
   inline_summary_alloc ();
 
-  info = inline_summary (node);
-  reset_inline_summary (node);
+  info = get_inline_summary (node);
+  reset_inline_summary (node, info);
 
   /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
      Once this happen, we will need to more curefully predict call
@@ -2982,7 +2963,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
 {
   tree target;
   struct cgraph_node *callee;
-  struct inline_summary *isummary;
+  inline_summary *isummary;
   enum availability avail;
 
   if (!known_vals.exists () && !known_binfos.exists ())
@@ -3007,7 +2988,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
   callee = callee->function_symbol (&avail);
   if (avail < AVAIL_AVAILABLE)
     return false;
-  isummary = inline_summary (callee);
+  isummary = get_inline_summary (callee);
   return isummary->inlinable;
 }
 
@@ -3120,7 +3101,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
 			     vec<inline_param_summary>
 			     inline_param_summary)
 {
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = get_inline_summary (node);
   size_time_entry *e;
   int size = 0;
   int time = 0;
@@ -3246,8 +3227,8 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
    for other purposes).  */
 
 static struct predicate
-remap_predicate (struct inline_summary *info,
-		 struct inline_summary *callee_info,
+remap_predicate (inline_summary *info,
+		 inline_summary *callee_info,
 		 struct predicate *p,
 		 vec<int> operand_map,
 		 vec<int> offset_map,
@@ -3336,8 +3317,8 @@ static void
 inline_update_callee_summaries (struct cgraph_node *node, int depth)
 {
   struct cgraph_edge *e;
-  struct inline_summary *callee_info = inline_summary (node);
-  struct inline_summary *caller_info = inline_summary (node->callers->caller);
+  inline_summary *callee_info = get_inline_summary (node);
+  inline_summary *caller_info = get_inline_summary (node->callers->caller);
   HOST_WIDE_INT peak;
 
   callee_info->stack_frame_offset
@@ -3345,8 +3326,8 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
     + caller_info->estimated_self_stack_size;
   peak = callee_info->stack_frame_offset
     + callee_info->estimated_self_stack_size;
-  if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
-      inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
+  if (get_inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
+      get_inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
   ipa_propagate_frequency (node);
   for (e = node->callees; e; e = e->next_callee)
     {
@@ -3407,8 +3388,8 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 static void
 remap_edge_summaries (struct cgraph_edge *inlined_edge,
 		      struct cgraph_node *node,
-		      struct inline_summary *info,
-		      struct inline_summary *callee_info,
+		      inline_summary *info,
+		      inline_summary *callee_info,
 		      vec<int> operand_map,
 		      vec<int> offset_map,
 		      clause_t possible_truths,
@@ -3476,8 +3457,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
 /* Same as remap_predicate, but set result into hint *HINT.  */
 
 static void
-remap_hint_predicate (struct inline_summary *info,
-		      struct inline_summary *callee_info,
+remap_hint_predicate (inline_summary *info,
+		      inline_summary *callee_info,
 		      struct predicate **hint,
 		      vec<int> operand_map,
 		      vec<int> offset_map,
@@ -3506,10 +3487,10 @@ remap_hint_predicate (struct inline_summary *info,
 void
 inline_merge_summary (struct cgraph_edge *edge)
 {
-  struct inline_summary *callee_info = inline_summary (edge->callee);
+  inline_summary *callee_info = get_inline_summary (edge->callee);
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  struct inline_summary *info = inline_summary (to);
+  inline_summary *info = get_inline_summary (to);
   clause_t clause = 0;		/* not_inline is known to be false.  */
   size_time_entry *e;
   vec<int> operand_map = vNULL;
@@ -3618,7 +3599,7 @@ inline_merge_summary (struct cgraph_edge *edge)
 void
 inline_update_overall_summary (struct cgraph_node *node)
 {
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = get_inline_summary (node);
   size_time_entry *e;
   int i;
 
@@ -3645,8 +3626,8 @@ simple_edge_hints (struct cgraph_edge *edge)
   int hints = 0;
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  if (inline_summary (to)->scc_no
-      && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
+  if (get_inline_summary (to)->scc_no
+      && get_inline_summary (to)->scc_no == get_inline_summary (edge->callee)->scc_no
       && !edge->recursive_p ())
     hints |= INLINE_HINT_same_scc;
 
@@ -3706,7 +3687,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
   /* When caching, update the cache entry.  */
   if (edge_growth_cache.exists ())
     {
-      inline_summary (edge->callee)->min_size = min_size;
+      get_inline_summary (edge->callee)->min_size = min_size;
       if ((int) edge_growth_cache.length () <= edge->uid)
 	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
       edge_growth_cache[edge->uid].time = time + (time >= 0);
@@ -3808,14 +3789,14 @@ estimate_time_after_inlining (struct cgraph_node *node,
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
       gcov_type time =
-	inline_summary (node)->time + estimate_edge_time (edge);
+	get_inline_summary (node)->time + estimate_edge_time (edge);
       if (time < 0)
 	time = 0;
       if (time > MAX_TIME)
 	time = MAX_TIME;
       return time;
     }
-  return inline_summary (node)->time;
+  return get_inline_summary (node)->time;
 }
 
 
@@ -3829,11 +3810,11 @@ estimate_size_after_inlining (struct cgraph_node *node,
   struct inline_edge_summary *es = inline_edge_summary (edge);
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
-      int size = inline_summary (node)->size + estimate_edge_growth (edge);
+      int size = get_inline_summary (node)->size + estimate_edge_growth (edge);
       gcc_assert (size >= 0);
       return size;
     }
-  return inline_summary (node)->size;
+  return get_inline_summary (node)->size;
 }
 
 
@@ -3873,7 +3854,7 @@ int
 do_estimate_growth (struct cgraph_node *node)
 {
   struct growth_data d = { node, 0, false };
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = get_inline_summary (node);
 
   node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
 
@@ -3946,7 +3927,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
       && (!DECL_COMDAT (node->decl)
 	  || !node->can_remove_if_no_direct_calls_p ()))
     return true;
-  max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
+  max_callers = get_inline_summary (node)->size * 4 / edge_growth + 2;
 
   for (e = node->callers; e; e = e->next_caller)
     {
@@ -4009,13 +3990,12 @@ inline_analyze_function (struct cgraph_node *node)
 
 /* Called when new function is inserted to callgraph late.  */
 
-static void
-add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_cgraph_summary::insertion_hook (cgraph_node *node, inline_summary *)
 {
   inline_analyze_function (node);
 }
 
-
 /* Note function body size.  */
 
 void
@@ -4028,8 +4008,10 @@ inline_generate_summary (void)
   if (!optimize && !flag_lto && !flag_wpa)
     return;
 
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+  if (!inline_summary_summary)
+    inline_summary_summary = (inline_summary_cgraph_summary *) inline_summary_cgraph_summary::create_ggc (symtab);
+
+  inline_summary_summary->enable_insertion_hook ();
 
   ipa_register_cgraph_hooks ();
   inline_free_summary ();
@@ -4113,7 +4095,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
     {
       unsigned int index;
       struct cgraph_node *node;
-      struct inline_summary *info;
+      inline_summary *info;
       lto_symtab_encoder_t encoder;
       struct bitpack_d bp;
       struct cgraph_edge *e;
@@ -4123,7 +4105,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
       encoder = file_data->symtab_node_encoder;
       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
 								index));
-      info = inline_summary (node);
+      info = get_inline_summary (node);
 
       info->estimated_stack_size
 	= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
@@ -4212,8 +4194,9 @@ inline_read_summary (void)
       if (!flag_ipa_cp)
 	ipa_prop_read_jump_functions ();
     }
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+
+  gcc_assert (inline_summary_summary);
+  inline_summary_summary->enable_insertion_hook ();
 }
 
 
@@ -4279,7 +4262,7 @@ inline_write_summary (void)
       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
       if (cnode && (node = cnode)->definition && !node->alias)
 	{
-	  struct inline_summary *info = inline_summary (node);
+	  inline_summary *info = get_inline_summary (node);
 	  struct bitpack_d bp;
 	  struct cgraph_edge *edge;
 	  int i;
@@ -4344,23 +4327,15 @@ inline_free_summary (void)
     return;
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->alias)
-      reset_inline_summary (node);
-  if (function_insertion_hook_holder)
-    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
-  function_insertion_hook_holder = NULL;
-  if (node_removal_hook_holder)
-    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
+      reset_inline_summary (node, get_inline_summary (node));
   if (edge_removal_hook_holder)
     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  if (node_duplication_hook_holder)
-    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   if (edge_duplication_hook_holder)
     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  vec_free (inline_summary_vec);
+  inline_summary_summary->destroy ();
+  inline_summary_summary = NULL;
   inline_edge_summary_vec.release ();
   if (edge_predicate_pool)
     free_alloc_pool (edge_predicate_pool);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index fd700ff..5e990ef 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
 	  if (e->callee->definition && !DECL_EXTERNAL (e->callee->decl))
 	    {
 	      if (overall_size)
-	        *overall_size -= inline_summary (e->callee)->size;
+	        *overall_size -= get_inline_summary (e->callee)->size;
 	      nfunctions_inlined++;
 	    }
 	  duplicate = false;
@@ -309,13 +309,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   gcc_assert (curr->callee->global.inlined_to == to);
 
-  old_size = inline_summary (to)->size;
+  old_size = get_inline_summary (to)->size;
   inline_merge_summary (e);
   if (optimize)
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   if (update_overall_summary)
    inline_update_overall_summary (to);
-  new_size = inline_summary (to)->size;
+  new_size = get_inline_summary (to)->size;
 
   if (callee->calls_comdat_local)
     to->calls_comdat_local = true;
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 8a08cd4..f29e0e0 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -167,7 +167,7 @@ caller_growth_limits (struct cgraph_edge *e)
   int newsize;
   int limit = 0;
   HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
-  struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
+  inline_summary *info, *what_info, *outer_info = get_inline_summary (to);
 
   /* Look for function e->caller is inlined to.  While doing
      so work out the largest function body on the way.  As
@@ -179,7 +179,7 @@ caller_growth_limits (struct cgraph_edge *e)
      too much in order to prevent compiler from exploding".  */
   while (true)
     {
-      info = inline_summary (to);
+      info = get_inline_summary (to);
       if (limit < info->self_size)
 	limit = info->self_size;
       if (stack_size_limit < info->estimated_self_stack_size)
@@ -190,7 +190,7 @@ caller_growth_limits (struct cgraph_edge *e)
 	break;
     }
 
-  what_info = inline_summary (what);
+  what_info = get_inline_summary (what);
 
   if (limit < what_info->self_size)
     limit = what_info->self_size;
@@ -304,7 +304,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_USES_COMDAT_LOCAL;
       inlinable = false;
     }
-  else if (!inline_summary (callee)->inlinable 
+  else if (!get_inline_summary (callee)->inlinable 
 	   || (caller_fun && fn_contains_cilk_spawn_p (caller_fun)))
     {
       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
@@ -458,7 +458,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     ;
-  /* For AutoFDO, we need to make sure that before profile annotation, all
+  /* For AutoFDO, we need to make sure that before profile summary, all
      hot paths' IR look exactly the same as profiled binary. As a result,
      in einliner, we will disregard size limit and inline those callsites
      that are:
@@ -524,13 +524,12 @@ want_early_inline_function_p (struct cgraph_edge *e)
    does not happen.  */
 
 inline gcov_type
-compute_uninlined_call_time (struct inline_summary *callee_info,
-			     struct cgraph_edge *edge)
+compute_uninlined_call_time (inline_summary *callee_info, cgraph_edge *edge)
 {
   gcov_type uninlined_call_time =
     RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
 	  CGRAPH_FREQ_BASE);
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = get_inline_summary (edge->caller->global.inlined_to
 				          ? edge->caller->global.inlined_to
 				          : edge->caller)->time;
   return uninlined_call_time + caller_time;
@@ -543,7 +542,7 @@ inline gcov_type
 compute_inlined_call_time (struct cgraph_edge *edge,
 			   int edge_time)
 {
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = get_inline_summary (edge->caller->global.inlined_to
 					  ? edge->caller->global.inlined_to
 					  : edge->caller)->time;
   gcov_type time = (caller_time
@@ -563,7 +562,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
 static bool
 big_speedup_p (struct cgraph_edge *e)
 {
-  gcov_type time = compute_uninlined_call_time (inline_summary (e->callee),
+  gcov_type time = compute_uninlined_call_time (get_inline_summary (e->callee),
 					  	e);
   gcov_type inlined_time = compute_inlined_call_time (e,
 					              estimate_edge_time (e));
@@ -596,7 +595,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
      MAX_INLINE_INSNS_SINGLE 16-fold for inline functions.  */
   else if ((!DECL_DECLARED_INLINE_P (callee->decl)
 	   && (!e->count || !e->maybe_hot_p ()))
-	   && inline_summary (callee)->min_size
+	   && get_inline_summary (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
     {
@@ -604,7 +603,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
       want_inline = false;
     }
   else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
-	   && inline_summary (callee)->min_size
+	   && get_inline_summary (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > 16 * MAX_INLINE_INSNS_SINGLE)
     {
@@ -867,8 +866,8 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
    1...RELATIVE_TIME_BENEFIT_RANGE  */
 
 static inline int
-relative_time_benefit (struct inline_summary *callee_info,
-		       struct cgraph_edge *edge,
+relative_time_benefit (inline_summary *callee_info,
+		       cgraph_edge *edge,
 		       int edge_time)
 {
   gcov_type relbenefit;
@@ -913,7 +912,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   gcov_type badness;
   int growth, edge_time;
   struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
-  struct inline_summary *callee_info = inline_summary (callee);
+  inline_summary *callee_info = get_inline_summary (callee);
   inline_hints hints;
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
@@ -1188,7 +1187,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
   struct cgraph_edge *edge;
   struct ipa_ref *ref;
 
-  if ((!node->alias && !inline_summary (node)->inlinable)
+  if ((!node->alias && !get_inline_summary (node)->inlinable)
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->uid))
@@ -1246,7 +1245,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
            don't need updating.  */
 	if (e->inline_failed
 	    && (callee = e->callee->ultimate_alias_target (&avail))
-	    && inline_summary (callee)->inlinable
+	    && get_inline_summary (callee)->inlinable
 	    && avail >= AVAIL_AVAILABLE
 	    && !bitmap_bit_p (updated_nodes, callee->uid))
 	  {
@@ -1424,8 +1423,8 @@ recursive_inlining (struct cgraph_edge *edge,
     fprintf (dump_file,
 	     "\n   Inlined %i times, "
 	     "body grown from size %i to %i, time %i to %i\n", n,
-	     inline_summary (master_clone)->size, inline_summary (node)->size,
-	     inline_summary (master_clone)->time, inline_summary (node)->time);
+	     get_inline_summary (master_clone)->size, get_inline_summary (node)->size,
+	     get_inline_summary (master_clone)->time, get_inline_summary (node)->time);
 
   /* Remove master clone we used for inlining.  We rely that clones inlined
      into master clone gets queued just before master clone so we don't
@@ -1599,8 +1598,8 @@ inline_small_functions (void)
 	if (node->has_gimple_body_p ()
 	    || node->thunk.thunk_p)
 	  {
-	    struct inline_summary *info = inline_summary (node);
-	    struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
+	    inline_summary *info = get_inline_summary (node);
+	    ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
 
 	    /* Do not account external functions, they will be optimized out
 	       if not inlined.  Also only count the non-cold portion of program.  */
@@ -1610,12 +1609,12 @@ inline_small_functions (void)
 	    info->growth = estimate_growth (node);
 	    if (dfs && dfs->next_cycle)
 	      {
-		struct cgraph_node *n2;
+		cgraph_node *n2;
 		int id = dfs->scc_no + 1;
 		for (n2 = node; n2;
 		     n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
 		  {
-		    struct inline_summary *info2 = inline_summary (n2);
+		    inline_summary *info2 = get_inline_summary (n2);
 		    if (info2->scc_no)
 		      break;
 		    info2->scc_no = id;
@@ -1735,7 +1734,7 @@ inline_small_functions (void)
 	  fprintf (dump_file,
 		   "\nConsidering %s/%i with %i size\n",
 		   callee->name (), callee->order,
-		   inline_summary (callee)->size);
+		   get_inline_summary (callee)->size);
 	  fprintf (dump_file,
 		   " to be inlined into %s/%i in %s:%i\n"
 		   " Estimated badness is %i, frequency %.2f.\n",
@@ -1853,8 +1852,8 @@ inline_small_functions (void)
 		   " Inlined into %s which now has time %i and size %i,"
 		   "net change of %+i.\n",
 		   edge->caller->name (),
-		   inline_summary (edge->caller)->time,
-		   inline_summary (edge->caller)->size,
+		   get_inline_summary (edge->caller)->time,
+		   get_inline_summary (edge->caller)->size,
 		   overall_size - old_size);
 	}
       if (min_size > overall_size)
@@ -1992,11 +1991,11 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	  fprintf (dump_file,
 		   "\nInlining %s size %i.\n",
 		   node->name (),
-		   inline_summary (node)->size);
+		   get_inline_summary (node)->size);
 	  fprintf (dump_file,
 		   " Called once from %s %i insns.\n",
 		   node->callers->caller->name (),
-		   inline_summary (node->callers->caller)->size);
+		   get_inline_summary (node->callers->caller)->size);
 	}
 
       inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
@@ -2004,7 +2003,7 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	fprintf (dump_file,
 		 " Inlined into %s which now has %i size\n",
 		 caller->name (),
-		 inline_summary (caller)->size);
+		 get_inline_summary (caller)->size);
       if (!(*num_calls)--)
 	{
 	  if (dump_file)
@@ -2028,7 +2027,7 @@ dump_overall_stats (void)
     if (!node->global.inlined_to
 	&& !node->alias)
       {
-	int time = inline_summary (node)->time;
+	int time = get_inline_summary (node)->time;
 	sum += time;
 	sum_weighted += time * node->count;
       }
@@ -2345,7 +2344,7 @@ early_inline_small_functions (struct cgraph_node *node)
   for (e = node->callees; e; e = e->next_callee)
     {
       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-      if (!inline_summary (callee)->inlinable
+      if (!get_inline_summary (callee)->inlinable
 	  || !e->inline_failed)
 	continue;
 
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index 2ac6e4e..bcbcd05 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -162,10 +162,26 @@ struct GTY(()) inline_summary
   int scc_no;
 };
 
-/* Need a typedef for inline_summary because of inline function
-   'inline_summary' below.  */
-typedef struct inline_summary inline_summary_t;
-extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
+class GTY((user)) inline_summary_cgraph_summary: public cgraph_summary <inline_summary *>
+{
+public:
+  inline_summary_cgraph_summary (symbol_table *symtab, bool ggc):
+    cgraph_summary <inline_summary *> (symtab, ggc) {}
+  
+  static inline_summary_cgraph_summary *create_ggc (symbol_table *symtab)
+  {
+    inline_summary_cgraph_summary *summary = new (ggc_cleared_alloc <inline_summary_cgraph_summary> ()) inline_summary_cgraph_summary(symtab, true);
+    summary->disable_insertion_hook ();
+    return summary;
+  }
+
+
+  virtual void insertion_hook (cgraph_node *, inline_summary *);
+  virtual void removal_hook (cgraph_node *node, inline_summary *);
+  virtual void duplication_hook (cgraph_node *src, cgraph_node *dst, inline_summary *src_data, inline_summary *dst_data);
+};
+
+extern GTY(()) cgraph_summary <inline_summary *> *inline_summary_summary;
 
 /* Information kept about parameter of call site.  */
 struct inline_param_summary
@@ -249,10 +265,10 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
 extern int ncalls_inlined;
 extern int nfunctions_inlined;
 
-static inline struct inline_summary *
-inline_summary (struct cgraph_node *node)
+static inline inline_summary *
+get_inline_summary (const struct cgraph_node *node)
 {
-  return &(*inline_summary_vec)[node->uid];
+  return (*inline_summary_summary)[node->summary_uid];
 }
 
 static inline struct inline_edge_summary *
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 0a7ca53..5c84810 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1669,7 +1669,7 @@ execute_split_functions (void)
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
   if (inline_edge_summary_vec.exists ()
-      && !inline_summary (node)->inlinable)
+      && !get_inline_summary (node)->inlinable)
     {
       if (dump_file)
 	fprintf (dump_file, "Not splitting: not inlinable.\n");
diff --git a/gcc/ipa.c b/gcc/ipa.c
index aded512..ca6d540 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -224,7 +224,7 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
                                target->order);
 	    }
 	  edge = edge->make_direct (target);
-	  if (inline_summary_vec)
+	  if (inline_summary_summary)
 	    inline_update_overall_summary (node);
 	  else if (edge->call_stmt)
 	    {
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 37d0f39..4495ee6 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -165,7 +165,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
     {
       struct cgraph_edge *e;
       if (!node->alias)
-        part->insns += inline_summary (cnode)->self_size;
+        part->insns += get_inline_summary (cnode)->self_size;
 
       /* Add all inline clones and callees that are duplicated.  */
       for (e = cnode->callees; e; e = e->next_callee)
@@ -274,7 +274,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
       partition->initializers_visited = NULL;
 
       if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
-        partition->insns -= inline_summary (cnode)->self_size;
+        partition->insns -= get_inline_summary (cnode)->self_size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->aux = (void *)((size_t)node->aux - 1);
     }
@@ -477,7 +477,7 @@ lto_balanced_map (int n_lto_partitions)
 	else
 	  order[n_nodes++] = node;
 	if (!node->alias)
-	  total_size += inline_summary (node)->size;
+	  total_size += get_inline_summary (node)->size;
       }
 
   /* Streaming works best when the source units do not cross partition
@@ -534,14 +534,14 @@ lto_balanced_map (int n_lto_partitions)
 	     && noreorder[noreorder_pos]->order < current_order)
 	{
 	  if (!noreorder[noreorder_pos]->alias)
-	    total_size -= inline_summary (noreorder[noreorder_pos])->size;
+	    total_size -= get_inline_summary (noreorder[noreorder_pos])->size;
 	  next_nodes.safe_push (noreorder[noreorder_pos++]);
 	}
       add_sorted_nodes (next_nodes, partition);
 
       add_symbol_to_partition (partition, order[i]);
       if (!order[i]->alias)
-        total_size -= inline_summary (order[i])->size;
+        total_size -= get_inline_summary (order[i])->size;
 	  
 
       /* Once we added a new node to the partition, we also want to add
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 99b19b8..86dbc9d 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -4991,7 +4991,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
     }
 
   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
-      && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
+      && get_inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
     {
       if (dump_file)
 	fprintf (dump_file, "Function too big to be made truly local.\n");
-- 
2.1.2

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 14:23 [PATCH 1/4] cgraph_summary data structure introduction mliska
  2014-11-13 14:23 ` [PATCH 4/4] Data structure is used for inline_summary struct mliska
  2014-11-13 14:23 ` [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass mliska
@ 2014-11-13 14:24 ` mliska
  2014-11-13 14:52   ` Markus Trippelsdorf
  2014-11-13 15:57   ` Jan Hubicka
  2014-11-13 14:34 ` [PATCH 1/4] cgraph_summary data structure introduction Richard Biener
  3 siblings, 2 replies; 40+ messages in thread
From: mliska @ 2014-11-13 14:24 UTC (permalink / raw)
  To: gcc-patches

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* Makefile.in: New object file is added.
	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
	is filled up.
	* cgraph_summary.c: New file.
	* cgraph_summary.h: New file.
	* gengtype.c (open_base_files): Add cgraph_summary.h.
	* toplev.c (general_init): Call constructor of symbol_table.
---
 gcc/Makefile.in      |   1 +
 gcc/cgraph.h         |   8 ++
 gcc/cgraph_summary.c |  34 ++++++
 gcc/cgraph_summary.h | 301 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/gengtype.c       |   4 +-
 gcc/toplev.c         |   3 +-
 6 files changed, 348 insertions(+), 3 deletions(-)
 create mode 100644 gcc/cgraph_summary.c
 create mode 100644 gcc/cgraph_summary.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3d671c2..bf11277 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1175,6 +1175,7 @@ OBJS = \
 	cfgrtl.o \
 	symtab.o \
 	cgraph.o \
+	cgraph_summary.o \
 	cgraphbuild.o \
 	cgraphunit.o \
 	cgraphclones.o \
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index e2becb9..588b6d5 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1225,6 +1225,8 @@ public:
   int count_materialization_scale;
   /* Unique id of the node.  */
   int uid;
+  /* Summary unique id of the node.  */
+  int summary_uid;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
   /* Time profiler: first run of function.  */
@@ -1786,6 +1788,10 @@ public:
   friend class cgraph_node;
   friend class cgraph_edge;
 
+  symbol_table (): cgraph_max_summary_uid (1)
+  {
+  }
+
   /* Initialize callgraph dump file.  */
   void initialize (void);
 
@@ -1982,6 +1988,7 @@ public:
 
   int cgraph_count;
   int cgraph_max_uid;
+  int cgraph_max_summary_uid;
 
   int edges_count;
   int edges_max_uid;
@@ -2310,6 +2317,7 @@ symbol_table::allocate_cgraph_symbol (void)
       node->uid = cgraph_max_uid++;
     }
 
+  node->summary_uid = cgraph_max_summary_uid++;
   return node;
 }
 
diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
new file mode 100644
index 0000000..9af1d7e
--- /dev/null
+++ b/gcc/cgraph_summary.c
@@ -0,0 +1,34 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "predict.h"
+#include "vec.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "input.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "tree-inline.h"
+#include "dumpfile.h"
+#include "langhooks.h"
+#include "splay-tree.h"
+#include "hash-map.h"
+#include "plugin-api.h"
+#include "ipa-ref.h"
+#include "cgraph.h"
+#include "ipa-utils.h"
+#include "alloc-pool.h"
+#include "cgraph_summary.h"
+#include "ipa-prop.h"
+#include "hash-map.h"
diff --git a/gcc/cgraph_summary.h b/gcc/cgraph_summary.h
new file mode 100644
index 0000000..dd2b649
--- /dev/null
+++ b/gcc/cgraph_summary.h
@@ -0,0 +1,301 @@
+/* Callgraph summary data structure.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Contributed by Martin Liska
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_CGRAPH_SUMMARY_H
+#define GCC_CGRAPH_SUMMARY_H
+
+#define CGRAPH_SUMMARY_DELETED_VALUE -1
+#define CGRAPH_SUMMARY_EMPTY_VALUE 0
+
+template <class T>
+class cgraph_summary
+{
+  private:
+    cgraph_summary();
+};
+
+template <class T>
+class GTY((user)) cgraph_summary <T *>
+{
+public:
+  /* Default construction takes SYMTAB as an argument.  */
+  cgraph_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
+    m_insertion_enabled (true), m_symtab (symtab)
+  {
+    cgraph_node *node;
+
+    FOR_EACH_FUNCTION (node)
+    {
+      gcc_assert (node->summary_uid > 0);
+    }
+
+    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
+
+    m_symtab_insertion_hook =
+      symtab->add_cgraph_insertion_hook
+      (cgraph_summary::symtab_insertion, this);
+
+    m_symtab_removal_hook =
+      symtab->add_cgraph_removal_hook
+      (cgraph_summary::symtab_removal, this);
+    m_symtab_duplication_hook =
+      symtab->add_cgraph_duplication_hook
+      (cgraph_summary::symtab_duplication, this);
+  }
+
+  /* Destructor.  */
+  virtual ~cgraph_summary ()
+  {
+    destroy ();
+  }
+
+  /* Destruction method that can be called for GGT purpose.  */
+  void destroy ()
+  {
+    if (m_symtab_insertion_hook)
+      m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
+
+    if (m_symtab_removal_hook)
+      m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
+
+    if (m_symtab_duplication_hook)
+      m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
+
+    m_symtab_insertion_hook = NULL;
+    m_symtab_removal_hook = NULL;
+    m_symtab_duplication_hook = NULL;
+
+    if (!m_ggc)
+      m_map->traverse <void *, cgraph_summary::release> (NULL);
+  }
+
+  /* Traverses all summarys with a function F called with
+     ARG as argument.  */
+  template<typename Arg, bool (*f)(const T &, Arg)>
+  void traverse (Arg a) const
+  {
+    m_map->traverse <f> (a);
+  }
+
+  /* Basic implementation of insertion hook.  */
+  virtual void insertion_hook (cgraph_node *, T *) {}
+
+  /* Basic implementation of removal hook.  */
+  virtual void removal_hook (cgraph_node *, T *) {}
+
+  /* Basic implementation of duplication hook.  */
+  virtual void duplication_hook (cgraph_node *,
+				 cgraph_node *, T *, T *) {}
+
+  /* Allocates new data that are stored within map.  */
+  inline T* allocate_new ()
+  {
+    return m_ggc ? new (ggc_alloc <T> ()) T() : new T () ;
+  }
+
+  /* Getter for summary callgraph ID.  */
+  inline T* operator[] (int uid)
+  {
+    T **v = m_map->get (uid);
+    if (!v)
+      {
+	T *new_value = allocate_new ();
+	m_map->put (uid, new_value);
+
+	v = &new_value;
+      }
+
+    return *v;
+  }
+
+  /* Getter for summary callgraph node pointer.  */
+  inline T * operator[] (cgraph_node *node)
+  {
+    return operator[] (node->summary_uid);
+  }
+
+  /* Return number of elements handled by data structure.  */
+  size_t elements ()
+  {
+    return m_map->elements ();
+  }
+
+  /* Enable insertin hook invocation.  */
+  inline void enable_insertion_hook ()
+  {
+    m_insertion_enabled = true;
+  }
+
+  /* Enable insertin hook invocation.  */
+  inline void disable_insertion_hook ()
+  {
+    m_insertion_enabled = false;
+  }
+
+  /* Symbol insertion hook that is registered to symbol table.  */
+  static void symtab_insertion (cgraph_node *node, void *data)
+  {
+    cgraph_summary *summary = (cgraph_summary <T *> *) (data);
+
+    if (summary->m_insertion_enabled)
+      summary->insertion_hook (node, (*summary)[node]);
+  }
+
+  /* Symbol removal hook that is registered to symbol table.  */
+  static void symtab_removal (cgraph_node *node, void *data)
+  {
+    gcc_assert (node->summary_uid);
+    cgraph_summary *summary = (cgraph_summary <T *> *) (data);
+
+    int summary_uid = node->summary_uid;
+    T **v = summary->m_map->get (summary_uid);
+
+    if (v)
+      {
+	summary->removal_hook (node, *v);
+
+	if (!summary->m_ggc)
+	  delete (*v);
+      }
+
+    if (summary->m_map->get (summary_uid))
+      summary->m_map->remove (summary_uid);
+  }
+
+  /* Symbol duplication hook that is registered to symbol table.  */
+  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
+				  void *data)
+  {
+    cgraph_summary *summary = (cgraph_summary <T *> *) (data);
+    T **v = summary->m_map->get (node->summary_uid);
+
+    gcc_assert (node2->summary_uid > 0);
+
+    if (v)
+      {
+	T *data = *v;
+	T *duplicate = summary->allocate_new ();
+	summary->m_map->put (node2->summary_uid, duplicate);
+	summary->duplication_hook (node, node2, data, (*summary)[node2]);
+      }
+  }
+
+protected:
+  /* Indicatation if we use ggc summary.  */
+  bool m_ggc;
+
+private:
+  struct summary_hashmap_traits: default_hashmap_traits
+  {
+    static inline
+    hashval_t hash (const int v)
+    {
+      return (hashval_t)v;
+    }
+
+    template<typename Type>
+    static inline
+    bool is_deleted (Type &e)
+    {
+      return e.m_key == CGRAPH_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static inline
+    bool is_empty (Type &e)
+    {
+      return e.m_key == CGRAPH_SUMMARY_EMPTY_VALUE;
+    }
+
+    template<typename Type>
+    static inline
+    void mark_deleted (Type &e)
+    {
+      e.m_key = CGRAPH_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static inline
+    void mark_empty (Type &e)
+    {
+      e.m_key = CGRAPH_SUMMARY_EMPTY_VALUE;
+    }
+  };
+
+  /* Remove summary for summary UID.  */
+  inline void remove (int uid)
+  {
+    T *v = m_map->get (uid);
+
+    if (v)
+      m_map->erase (uid);
+  }
+
+  /* Summary class release function called by traverse method.  */
+  static bool release (int const &, T * const &v, void *)
+  {
+    delete (v);
+    return true;
+  }
+
+  /* Main summary store, where summary ID is used as key.  */
+  hash_map <int, T *, summary_hashmap_traits> *m_map;
+  /* Internal summary insertion hook pointer.  */
+  cgraph_node_hook_list *m_symtab_insertion_hook;
+  /* Internal summary removal hook pointer.  */
+  cgraph_node_hook_list *m_symtab_removal_hook;
+  /* Internal summary duplication hook pointer.  */
+  cgraph_2node_hook_list *m_symtab_duplication_hook;
+  /* Indicates if insertion hook is enabled.  */
+  bool m_insertion_enabled;
+  /* Symbol table the summary is registered to.  */
+  symbol_table *m_symtab;
+
+  template <typename U> friend void gt_ggc_mx (cgraph_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (cgraph_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (cgraph_summary <U *> * const &,
+					       gt_pointer_operator, void *);
+};
+
+template <typename T>
+void
+gt_ggc_mx(cgraph_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_ggc_mx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(cgraph_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_pch_nx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(cgraph_summary<T *>* const& summary, gt_pointer_operator op, void *cookie)
+{
+  if (summary->m_map)
+    gt_pch_nx (summary->m_map, op, cookie);
+}
+
+#endif  /* GCC_CGRAPH_SUMMARY_H  */
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index fac83ee..91c5c91 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1842,8 +1842,8 @@ open_base_files (void)
       "tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h", 
       "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
-      "target-globals.h", "ipa-ref.h", "cgraph.h", "ipa-prop.h", 
-      "ipa-inline.h", "dwarf2out.h", NULL
+      "target-globals.h", "ipa-ref.h", "cgraph.h", "cgraph_summary.h",
+      "ipa-prop.h", "ipa-inline.h", "dwarf2out.h", NULL
     };
     const char *const *ifp;
     outf_p gtype_desc_c;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index aa1653e..e6c5159 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -93,6 +93,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "bitmap.h"
 #include "ipa-reference.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "gcse.h"
 #include "insn-codes.h"
@@ -1209,7 +1210,7 @@ general_init (const char *argv0)
   /* Create the singleton holder for global state.
      Doing so also creates the pass manager and with it the passes.  */
   g = new gcc::context ();
-  symtab = ggc_cleared_alloc <symbol_table> ();
+  symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table ();
 
   statistics_early_init ();
   finish_params ();
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/4] cgraph_summary data structure introduction.
  2014-11-13 14:23 [PATCH 1/4] cgraph_summary data structure introduction mliska
                   ` (2 preceding siblings ...)
  2014-11-13 14:24 ` [PATCH 2/4] New data structure for cgraph_summary introduced mliska
@ 2014-11-13 14:34 ` Richard Biener
  2014-11-13 14:45   ` Martin Liška
  3 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2014-11-13 14:34 UTC (permalink / raw)
  To: mliska; +Cc: GCC Patches

On Thu, Nov 13, 2014 at 3:10 PM, mliska <mliska@suse.cz> wrote:
> Following patchset introduces cgraph_summary template class that
> should replace custom implementation of cgraph related summaries.
>
> Idea behind the patch is to provide a generic interface one can use
> to register custom summary related to a cgraph_node. As you know,
> symbol_table provides hooks for creation, deletion and duplication
> of a cgraph_node. If you have a pass, you need to handle all these
> hooks and store custom data in your data structure.
>
> Patchset can boostrap on x86_64-linux-pc and no regression was
> observed.
>
> Ready for trunk?
> Thank you,
> Martin
> ---
>  gcc/ChangeLog | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 2eb6f35..ad3c2bf 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,4 @@
> +
>  2014-11-12  Alan Lawrence  <alan.lawrence@arm.com>
>
>         * config/aarch64/aarch64.c (aarch64_simd_lane_bounds): Display indices.

huh?

> --
> 2.1.2
>
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/4] cgraph_summary data structure introduction.
  2014-11-13 14:34 ` [PATCH 1/4] cgraph_summary data structure introduction Richard Biener
@ 2014-11-13 14:45   ` Martin Liška
  0 siblings, 0 replies; 40+ messages in thread
From: Martin Liška @ 2014-11-13 14:45 UTC (permalink / raw)
  To: gcc-patches

On 11/13/2014 03:33 PM, Richard Biener wrote:
> On Thu, Nov 13, 2014 at 3:10 PM, mliska <mliska@suse.cz> wrote:
>> Following patchset introduces cgraph_summary template class that
>> should replace custom implementation of cgraph related summaries.
>>
>> Idea behind the patch is to provide a generic interface one can use
>> to register custom summary related to a cgraph_node. As you know,
>> symbol_table provides hooks for creation, deletion and duplication
>> of a cgraph_node. If you have a pass, you need to handle all these
>> hooks and store custom data in your data structure.
>>
>> Patchset can boostrap on x86_64-linux-pc and no regression was
>> observed.
>>
>> Ready for trunk?
>> Thank you,
>> Martin
>> ---
>>   gcc/ChangeLog | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>> index 2eb6f35..ad3c2bf 100644
>> --- a/gcc/ChangeLog
>> +++ b/gcc/ChangeLog
>> @@ -1,3 +1,4 @@
>> +
>>   2014-11-12  Alan Lawrence  <alan.lawrence@arm.com>
>>
>>          * config/aarch64/aarch64.c (aarch64_simd_lane_bounds): Display indices.
>
> huh?

Please ignore this modification, I forgot to remove it from the email patchset.
I've just introduced the change to be able to introduce git commit.

Thank you for understanding,
Martin

>
>> --
>> 2.1.2
>>
>>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 14:24 ` [PATCH 2/4] New data structure for cgraph_summary introduced mliska
@ 2014-11-13 14:52   ` Markus Trippelsdorf
  2014-11-13 15:04     ` Martin Liška
  2014-11-13 21:35     ` Trevor Saunders
  2014-11-13 15:57   ` Jan Hubicka
  1 sibling, 2 replies; 40+ messages in thread
From: Markus Trippelsdorf @ 2014-11-13 14:52 UTC (permalink / raw)
  To: mliska; +Cc: gcc-patches

On 2014.11.13 at 15:11 +0100, mliska wrote:

Just two remarks:

> +template <class T>
> +class GTY((user)) cgraph_summary <T *>
> +{
> +public:
> +  /* Default construction takes SYMTAB as an argument.  */
> +  cgraph_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
> +    m_insertion_enabled (true), m_symtab (symtab)
> +  {
> +    cgraph_node *node;
> +
> +    FOR_EACH_FUNCTION (node)
> +    {
> +      gcc_assert (node->summary_uid > 0);
> +    }
> +
> +    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
> +
> +    m_symtab_insertion_hook =
> +      symtab->add_cgraph_insertion_hook
> +      (cgraph_summary::symtab_insertion, this);
> +
> +    m_symtab_removal_hook =
> +      symtab->add_cgraph_removal_hook
> +      (cgraph_summary::symtab_removal, this);
> +    m_symtab_duplication_hook =
> +      symtab->add_cgraph_duplication_hook
> +      (cgraph_summary::symtab_duplication, this);
> +  }
> +
> +  /* Destructor.  */
> +  virtual ~cgraph_summary ()
> +  {
> +    destroy ();
> +  }

From https://gcc.gnu.org/wiki/CppConventions:

Constructors and destructors are often much larger than programmers
expect. Prefer non-inline versions unless you have evidence that the
inline version is needed.

>...
> +  inline T* operator[] (int uid)
> +  {
> +    T **v = m_map->get (uid);

The inline keyword is redundant for members inside a class definition.
Please drop it.

-- 
Markus

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 14:52   ` Markus Trippelsdorf
@ 2014-11-13 15:04     ` Martin Liška
  2014-11-13 21:35     ` Trevor Saunders
  1 sibling, 0 replies; 40+ messages in thread
From: Martin Liška @ 2014-11-13 15:04 UTC (permalink / raw)
  To: Markus Trippelsdorf; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1607 bytes --]

On 11/13/2014 03:48 PM, Markus Trippelsdorf wrote:
> On 2014.11.13 at 15:11 +0100, mliska wrote:
>
> Just two remarks:
>
>> +template <class T>
>> +class GTY((user)) cgraph_summary <T *>
>> +{
>> +public:
>> +  /* Default construction takes SYMTAB as an argument.  */
>> +  cgraph_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
>> +    m_insertion_enabled (true), m_symtab (symtab)
>> +  {
>> +    cgraph_node *node;
>> +
>> +    FOR_EACH_FUNCTION (node)
>> +    {
>> +      gcc_assert (node->summary_uid > 0);
>> +    }
>> +
>> +    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
>> +
>> +    m_symtab_insertion_hook =
>> +      symtab->add_cgraph_insertion_hook
>> +      (cgraph_summary::symtab_insertion, this);
>> +
>> +    m_symtab_removal_hook =
>> +      symtab->add_cgraph_removal_hook
>> +      (cgraph_summary::symtab_removal, this);
>> +    m_symtab_duplication_hook =
>> +      symtab->add_cgraph_duplication_hook
>> +      (cgraph_summary::symtab_duplication, this);
>> +  }
>> +
>> +  /* Destructor.  */
>> +  virtual ~cgraph_summary ()
>> +  {
>> +    destroy ();
>> +  }
>
>  From https://gcc.gnu.org/wiki/CppConventions:
>
> Constructors and destructors are often much larger than programmers
> expect. Prefer non-inline versions unless you have evidence that the
> inline version is needed.
>
>> ...
>> +  inline T* operator[] (int uid)
>> +  {
>> +    T **v = m_map->get (uid);
>
> The inline keyword is redundant for members inside a class definition.
> Please drop it.
>

Hi.

Thank you for remarks. There's new version of the patch.

Thanks,
Martin

[-- Attachment #2: cgraph_annotation_2-v2.patch --]
[-- Type: text/x-patch, Size: 11605 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3d671c2..bf11277 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1175,6 +1175,7 @@ OBJS = \
 	cfgrtl.o \
 	symtab.o \
 	cgraph.o \
+	cgraph_summary.o \
 	cgraphbuild.o \
 	cgraphunit.o \
 	cgraphclones.o \
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index e2becb9..588b6d5 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1225,6 +1225,8 @@ public:
   int count_materialization_scale;
   /* Unique id of the node.  */
   int uid;
+  /* Summary unique id of the node.  */
+  int summary_uid;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
   /* Time profiler: first run of function.  */
@@ -1786,6 +1788,10 @@ public:
   friend class cgraph_node;
   friend class cgraph_edge;
 
+  symbol_table (): cgraph_max_summary_uid (1)
+  {
+  }
+
   /* Initialize callgraph dump file.  */
   void initialize (void);
 
@@ -1982,6 +1988,7 @@ public:
 
   int cgraph_count;
   int cgraph_max_uid;
+  int cgraph_max_summary_uid;
 
   int edges_count;
   int edges_max_uid;
@@ -2310,6 +2317,7 @@ symbol_table::allocate_cgraph_symbol (void)
       node->uid = cgraph_max_uid++;
     }
 
+  node->summary_uid = cgraph_max_summary_uid++;
   return node;
 }
 
diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
new file mode 100644
index 0000000..9af1d7e
--- /dev/null
+++ b/gcc/cgraph_summary.c
@@ -0,0 +1,34 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "predict.h"
+#include "vec.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "input.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "tree-inline.h"
+#include "dumpfile.h"
+#include "langhooks.h"
+#include "splay-tree.h"
+#include "hash-map.h"
+#include "plugin-api.h"
+#include "ipa-ref.h"
+#include "cgraph.h"
+#include "ipa-utils.h"
+#include "alloc-pool.h"
+#include "cgraph_summary.h"
+#include "ipa-prop.h"
+#include "hash-map.h"
diff --git a/gcc/cgraph_summary.h b/gcc/cgraph_summary.h
new file mode 100644
index 0000000..d89b679
--- /dev/null
+++ b/gcc/cgraph_summary.h
@@ -0,0 +1,301 @@
+/* Callgraph summary data structure.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Contributed by Martin Liska
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_CGRAPH_SUMMARY_H
+#define GCC_CGRAPH_SUMMARY_H
+
+#define CGRAPH_SUMMARY_DELETED_VALUE -1
+#define CGRAPH_SUMMARY_EMPTY_VALUE 0
+
+template <class T>
+class cgraph_summary
+{
+  private:
+    cgraph_summary();
+};
+
+template <class T>
+class GTY((user)) cgraph_summary <T *>
+{
+public:
+  /* Default construction takes SYMTAB as an argument.  */
+  cgraph_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
+    m_insertion_enabled (true), m_symtab (symtab)
+  {
+    cgraph_node *node;
+
+    FOR_EACH_FUNCTION (node)
+    {
+      gcc_assert (node->summary_uid > 0);
+    }
+
+    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
+
+    m_symtab_insertion_hook =
+      symtab->add_cgraph_insertion_hook
+      (cgraph_summary::symtab_insertion, this);
+
+    m_symtab_removal_hook =
+      symtab->add_cgraph_removal_hook
+      (cgraph_summary::symtab_removal, this);
+    m_symtab_duplication_hook =
+      symtab->add_cgraph_duplication_hook
+      (cgraph_summary::symtab_duplication, this);
+  }
+
+  /* Destructor.  */
+  virtual ~cgraph_summary ()
+  {
+    destroy ();
+  }
+
+  /* Destruction method that can be called for GGT purpose.  */
+  void destroy ()
+  {
+    if (m_symtab_insertion_hook)
+      m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
+
+    if (m_symtab_removal_hook)
+      m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
+
+    if (m_symtab_duplication_hook)
+      m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
+
+    m_symtab_insertion_hook = NULL;
+    m_symtab_removal_hook = NULL;
+    m_symtab_duplication_hook = NULL;
+
+    if (!m_ggc)
+      m_map->traverse <void *, cgraph_summary::release> (NULL);
+  }
+
+  /* Traverses all summarys with a function F called with
+     ARG as argument.  */
+  template<typename Arg, bool (*f)(const T &, Arg)>
+  void traverse (Arg a) const
+  {
+    m_map->traverse <f> (a);
+  }
+
+  /* Basic implementation of insertion hook.  */
+  virtual void insertion_hook (cgraph_node *, T *) {}
+
+  /* Basic implementation of removal hook.  */
+  virtual void removal_hook (cgraph_node *, T *) {}
+
+  /* Basic implementation of duplication hook.  */
+  virtual void duplication_hook (cgraph_node *,
+				 cgraph_node *, T *, T *) {}
+
+  /* Allocates new data that are stored within map.  */
+  T* allocate_new ()
+  {
+    return m_ggc ? new (ggc_alloc <T> ()) T() : new T () ;
+  }
+
+  /* Getter for summary callgraph ID.  */
+  T* operator[] (int uid)
+  {
+    T **v = m_map->get (uid);
+    if (!v)
+      {
+	T *new_value = allocate_new ();
+	m_map->put (uid, new_value);
+
+	v = &new_value;
+      }
+
+    return *v;
+  }
+
+  /* Getter for summary callgraph node pointer.  */
+  T * operator[] (cgraph_node *node)
+  {
+    return operator[] (node->summary_uid);
+  }
+
+  /* Return number of elements handled by data structure.  */
+  size_t elements ()
+  {
+    return m_map->elements ();
+  }
+
+  /* Enable insertin hook invocation.  */
+  void enable_insertion_hook ()
+  {
+    m_insertion_enabled = true;
+  }
+
+  /* Enable insertin hook invocation.  */
+  void disable_insertion_hook ()
+  {
+    m_insertion_enabled = false;
+  }
+
+  /* Symbol insertion hook that is registered to symbol table.  */
+  static void symtab_insertion (cgraph_node *node, void *data)
+  {
+    cgraph_summary *summary = (cgraph_summary <T *> *) (data);
+
+    if (summary->m_insertion_enabled)
+      summary->insertion_hook (node, (*summary)[node]);
+  }
+
+  /* Symbol removal hook that is registered to symbol table.  */
+  static void symtab_removal (cgraph_node *node, void *data)
+  {
+    gcc_assert (node->summary_uid);
+    cgraph_summary *summary = (cgraph_summary <T *> *) (data);
+
+    int summary_uid = node->summary_uid;
+    T **v = summary->m_map->get (summary_uid);
+
+    if (v)
+      {
+	summary->removal_hook (node, *v);
+
+	if (!summary->m_ggc)
+	  delete (*v);
+      }
+
+    if (summary->m_map->get (summary_uid))
+      summary->m_map->remove (summary_uid);
+  }
+
+  /* Symbol duplication hook that is registered to symbol table.  */
+  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
+				  void *data)
+  {
+    cgraph_summary *summary = (cgraph_summary <T *> *) (data);
+    T **v = summary->m_map->get (node->summary_uid);
+
+    gcc_assert (node2->summary_uid > 0);
+
+    if (v)
+      {
+	T *data = *v;
+	T *duplicate = summary->allocate_new ();
+	summary->m_map->put (node2->summary_uid, duplicate);
+	summary->duplication_hook (node, node2, data, (*summary)[node2]);
+      }
+  }
+
+protected:
+  /* Indicatation if we use ggc summary.  */
+  bool m_ggc;
+
+private:
+  struct summary_hashmap_traits: default_hashmap_traits
+  {
+    static
+    hashval_t hash (const int v)
+    {
+      return (hashval_t)v;
+    }
+
+    template<typename Type>
+    static
+    bool is_deleted (Type &e)
+    {
+      return e.m_key == CGRAPH_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static
+    bool is_empty (Type &e)
+    {
+      return e.m_key == CGRAPH_SUMMARY_EMPTY_VALUE;
+    }
+
+    template<typename Type>
+    static
+    void mark_deleted (Type &e)
+    {
+      e.m_key = CGRAPH_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static
+    void mark_empty (Type &e)
+    {
+      e.m_key = CGRAPH_SUMMARY_EMPTY_VALUE;
+    }
+  };
+
+  /* Remove summary for summary UID.  */
+  void remove (int uid)
+  {
+    T *v = m_map->get (uid);
+
+    if (v)
+      m_map->erase (uid);
+  }
+
+  /* Summary class release function called by traverse method.  */
+  static bool release (int const &, T * const &v, void *)
+  {
+    delete (v);
+    return true;
+  }
+
+  /* Main summary store, where summary ID is used as key.  */
+  hash_map <int, T *, summary_hashmap_traits> *m_map;
+  /* Internal summary insertion hook pointer.  */
+  cgraph_node_hook_list *m_symtab_insertion_hook;
+  /* Internal summary removal hook pointer.  */
+  cgraph_node_hook_list *m_symtab_removal_hook;
+  /* Internal summary duplication hook pointer.  */
+  cgraph_2node_hook_list *m_symtab_duplication_hook;
+  /* Indicates if insertion hook is enabled.  */
+  bool m_insertion_enabled;
+  /* Symbol table the summary is registered to.  */
+  symbol_table *m_symtab;
+
+  template <typename U> friend void gt_ggc_mx (cgraph_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (cgraph_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (cgraph_summary <U *> * const &,
+					       gt_pointer_operator, void *);
+};
+
+template <typename T>
+void
+gt_ggc_mx(cgraph_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_ggc_mx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(cgraph_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_pch_nx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(cgraph_summary<T *>* const& summary, gt_pointer_operator op, void *cookie)
+{
+  if (summary->m_map)
+    gt_pch_nx (summary->m_map, op, cookie);
+}
+
+#endif  /* GCC_CGRAPH_SUMMARY_H  */
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index fac83ee..91c5c91 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1842,8 +1842,8 @@ open_base_files (void)
       "tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h", 
       "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
-      "target-globals.h", "ipa-ref.h", "cgraph.h", "ipa-prop.h", 
-      "ipa-inline.h", "dwarf2out.h", NULL
+      "target-globals.h", "ipa-ref.h", "cgraph.h", "cgraph_summary.h",
+      "ipa-prop.h", "ipa-inline.h", "dwarf2out.h", NULL
     };
     const char *const *ifp;
     outf_p gtype_desc_c;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index aa1653e..e6c5159 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -93,6 +93,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "bitmap.h"
 #include "ipa-reference.h"
+#include "cgraph_summary.h"
 #include "ipa-prop.h"
 #include "gcse.h"
 #include "insn-codes.h"
@@ -1209,7 +1210,7 @@ general_init (const char *argv0)
   /* Create the singleton holder for global state.
      Doing so also creates the pass manager and with it the passes.  */
   g = new gcc::context ();
-  symtab = ggc_cleared_alloc <symbol_table> ();
+  symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table ();
 
   statistics_early_init ();
   finish_params ();

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 14:24 ` [PATCH 2/4] New data structure for cgraph_summary introduced mliska
  2014-11-13 14:52   ` Markus Trippelsdorf
@ 2014-11-13 15:57   ` Jan Hubicka
  2014-11-14 10:22     ` Richard Biener
  2014-11-14 14:11     ` Martin Liška
  1 sibling, 2 replies; 40+ messages in thread
From: Jan Hubicka @ 2014-11-13 15:57 UTC (permalink / raw)
  To: mliska; +Cc: gcc-patches

> gcc/ChangeLog:
> 
> 2014-11-12  Martin Liska  <mliska@suse.cz>
> 
> 	* Makefile.in: New object file is added.
> 	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
> 	is filled up.
> 	* cgraph_summary.c: New file.
> 	* cgraph_summary.h: New file.

Since I am trying to get rid of the cgraph prefixes for symbols (keep it for
the graph only) and the summaries can be annotated to variables too. Even if it
not necessarily supported by your current implementation, lets keep API
prepared for it. So I would call it symtab-summary.* for source files and
symtab_summary for base type  (probably function_summary for annotating
functions/cgraph_edge_summary for annotating edges?)


> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index e2becb9..588b6d5 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -1225,6 +1225,8 @@ public:
>    int count_materialization_scale;
>    /* Unique id of the node.  */
>    int uid;
> +  /* Summary unique id of the node.  */
> +  int summary_uid;

What makes summary_uid better than uid?

> diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
> new file mode 100644
> index 0000000..9af1d7e
> --- /dev/null
> +++ b/gcc/cgraph_summary.c

And why do we need this file?  It will need license header if really needed.

The implementation seems sane - I will check the actual uses :)
Please send the updated patch though.

Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-13 14:23 ` [PATCH 4/4] Data structure is used for inline_summary struct mliska
@ 2014-11-13 16:04   ` Jan Hubicka
  2014-11-14 14:13     ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2014-11-13 16:04 UTC (permalink / raw)
  To: mliska; +Cc: gcc-patches

> +  if (!inline_summary_summary)
> +    inline_summary_summary = (inline_summary_cgraph_summary *) inline_summary_cgraph_summary::create_ggc (symtab);

Hehe, this is funny naming scheme.
Peraps inline_summary_d and inline_summary_t for the data and type?
> -
> -static void
> -inline_node_duplication_hook (struct cgraph_node *src,
> -			      struct cgraph_node *dst,
> -			      ATTRIBUTE_UNUSED void *data)
> +void
> +inline_summary_cgraph_summary::duplication_hook (cgraph_node *src,
> +			      cgraph_node *dst,
> +			      inline_summary *,
> +			      inline_summary *info)

Becuase those are no longer "hooks" but virtual function, I guess we could call them
simply duplicate/insert/remove.

In a way I would like to see these to be methods of the underlying type rather than
virtual methods of the summary, becuase these are operations on the data themselves.
I was thinking to model these by specual constructor and copy constructor
(taking the extra node pointer parameters) and standard destructor.  I am not sure this
would be more understandable this way?
> -/* Need a typedef for inline_summary because of inline function
> -   'inline_summary' below.  */
> -typedef struct inline_summary inline_summary_t;
> -extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
> +class GTY((user)) inline_summary_cgraph_summary: public cgraph_summary <inline_summary *>
> +{
> +public:
> +  inline_summary_cgraph_summary (symbol_table *symtab, bool ggc):
> +    cgraph_summary <inline_summary *> (symtab, ggc) {}
> +  
> +  static inline_summary_cgraph_summary *create_ggc (symbol_table *symtab)
> +  {
> +    inline_summary_cgraph_summary *summary = new (ggc_cleared_alloc <inline_summary_cgraph_summary> ()) inline_summary_cgraph_summary(symtab, true);
> +    summary->disable_insertion_hook ();
> +    return summary;
> +  }
> +
> +
> +  virtual void insertion_hook (cgraph_node *, inline_summary *);
> +  virtual void removal_hook (cgraph_node *node, inline_summary *);
> +  virtual void duplication_hook (cgraph_node *src, cgraph_node *dst, inline_summary *src_data, inline_summary *dst_data);
> +};
> +
> +extern GTY(()) cgraph_summary <inline_summary *> *inline_summary_summary;

All in all it looks better than original code.  If we moved insert/
>  
>  /* Information kept about parameter of call site.  */
>  struct inline_param_summary
> @@ -249,10 +265,10 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
>  extern int ncalls_inlined;
>  extern int nfunctions_inlined;
>  
> -static inline struct inline_summary *
> -inline_summary (struct cgraph_node *node)
> +static inline inline_summary *
> +get_inline_summary (const struct cgraph_node *node)
>  {
> -  return &(*inline_summary_vec)[node->uid];
> +  return (*inline_summary_summary)[node->summary_uid];

Hmm, i guess there is no way to avoid the (*...)? Otherwise it would be cleaner
to use inline_summary[...] instead of get_inline_summary IMO.

Thanks for working on this!
Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 14:52   ` Markus Trippelsdorf
  2014-11-13 15:04     ` Martin Liška
@ 2014-11-13 21:35     ` Trevor Saunders
  2014-11-13 22:30       ` Markus Trippelsdorf
  1 sibling, 1 reply; 40+ messages in thread
From: Trevor Saunders @ 2014-11-13 21:35 UTC (permalink / raw)
  To: gcc-patches

On Thu, Nov 13, 2014 at 03:48:34PM +0100, Markus Trippelsdorf wrote:
> On 2014.11.13 at 15:11 +0100, mliska wrote:
> 
> Just two remarks:
> 
> > +template <class T>
> > +class GTY((user)) cgraph_summary <T *>
> > +{
> > +public:
> > +  /* Default construction takes SYMTAB as an argument.  */
> > +  cgraph_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
> > +    m_insertion_enabled (true), m_symtab (symtab)
> > +  {
> > +    cgraph_node *node;
> > +
> > +    FOR_EACH_FUNCTION (node)
> > +    {
> > +      gcc_assert (node->summary_uid > 0);
> > +    }
> > +
> > +    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
> > +
> > +    m_symtab_insertion_hook =
> > +      symtab->add_cgraph_insertion_hook
> > +      (cgraph_summary::symtab_insertion, this);
> > +
> > +    m_symtab_removal_hook =
> > +      symtab->add_cgraph_removal_hook
> > +      (cgraph_summary::symtab_removal, this);
> > +    m_symtab_duplication_hook =
> > +      symtab->add_cgraph_duplication_hook
> > +      (cgraph_summary::symtab_duplication, this);
> > +  }
> > +
> > +  /* Destructor.  */
> > +  virtual ~cgraph_summary ()
> > +  {
> > +    destroy ();
> > +  }
> 
> From https://gcc.gnu.org/wiki/CppConventions:
> 
> Constructors and destructors are often much larger than programmers
> expect. Prefer non-inline versions unless you have evidence that the
> inline version is needed.

I never really agreed with that, and we don't really follow it.  However
it really doesn't matter in this case since its virtual.
Trev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 21:35     ` Trevor Saunders
@ 2014-11-13 22:30       ` Markus Trippelsdorf
  2014-11-13 23:15         ` Trevor Saunders
  0 siblings, 1 reply; 40+ messages in thread
From: Markus Trippelsdorf @ 2014-11-13 22:30 UTC (permalink / raw)
  To: Trevor Saunders; +Cc: gcc-patches

On 2014.11.14 at 01:19 -0500, Trevor Saunders wrote:
> On Thu, Nov 13, 2014 at 03:48:34PM +0100, Markus Trippelsdorf wrote:
> > On 2014.11.13 at 15:11 +0100, mliska wrote:
> > 
> > > +  /* Destructor.  */
> > > +  virtual ~cgraph_summary ()
> > > +  {
> > > +    destroy ();
> > > +  }
> > 
> > From https://gcc.gnu.org/wiki/CppConventions:
> > 
> > Constructors and destructors are often much larger than programmers
> > expect. Prefer non-inline versions unless you have evidence that the
> > inline version is needed.
> 
> I never really agreed with that, and we don't really follow it.  However
> it really doesn't matter in this case since its virtual.

It doesn't really matter if the destructor is virtual or not, because the same
bloat can happen.

Consider a trivial example that I've found on the web and compare the assembly
output with "virtual ~A ()" defined inline vs. out-of-line:

#include <string>

using namespace std;

class A
{
  string name;
  string address;
  string telephone;

public:
  A (){};
  virtual void
  function ()
  {
  }
  virtual ~A () {}
};

//A::~A (){};

class B : public A
{
public:
  B (){};
  void
  function ()
  {
  }
  ~B () {}
};

void
abc ()
{
  B b;
  b.function ();
}

int
main ()
{
  B b;
  b.function ();
  abc ();
}

-- 
Markus

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 22:30       ` Markus Trippelsdorf
@ 2014-11-13 23:15         ` Trevor Saunders
  0 siblings, 0 replies; 40+ messages in thread
From: Trevor Saunders @ 2014-11-13 23:15 UTC (permalink / raw)
  To: Markus Trippelsdorf; +Cc: gcc-patches

On Thu, Nov 13, 2014 at 11:23:31PM +0100, Markus Trippelsdorf wrote:
> On 2014.11.14 at 01:19 -0500, Trevor Saunders wrote:
> > On Thu, Nov 13, 2014 at 03:48:34PM +0100, Markus Trippelsdorf wrote:
> > > On 2014.11.13 at 15:11 +0100, mliska wrote:
> > > 
> > > > +  /* Destructor.  */
> > > > +  virtual ~cgraph_summary ()
> > > > +  {
> > > > +    destroy ();
> > > > +  }
> > > 
> > > From https://gcc.gnu.org/wiki/CppConventions:
> > > 
> > > Constructors and destructors are often much larger than programmers
> > > expect. Prefer non-inline versions unless you have evidence that the
> > > inline version is needed.
> > 
> > I never really agreed with that, and we don't really follow it.  However
> > it really doesn't matter in this case since its virtual.
> 
> It doesn't really matter if the destructor is virtual or not, because the same
> bloat can happen.
> 
> Consider a trivial example that I've found on the web and compare the assembly
> output with "virtual ~A ()" defined inline vs. out-of-line:

I do see different assembly, but with gcc 4.9.2-1 (Debian) and -O2 what
I get with the inline dtor looks much better than with the out of line
one.  So your example isn't very convincing, and if it did cause worse
code I'd probably call that a compiler bug.

Trev

> 
> #include <string>
> 
> using namespace std;
> 
> class A
> {
>   string name;
>   string address;
>   string telephone;
> 
> public:
>   A (){};
>   virtual void
>   function ()
>   {
>   }
>   virtual ~A () {}
> };
> 
> //A::~A (){};
> 
> class B : public A
> {
> public:
>   B (){};
>   void
>   function ()
>   {
>   }
>   ~B () {}
> };
> 
> void
> abc ()
> {
>   B b;
>   b.function ();
> }
> 
> int
> main ()
> {
>   B b;
>   b.function ();
>   abc ();
> }
> 
> -- 
> Markus

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 15:57   ` Jan Hubicka
@ 2014-11-14 10:22     ` Richard Biener
  2014-11-14 14:11     ` Martin Liška
  1 sibling, 0 replies; 40+ messages in thread
From: Richard Biener @ 2014-11-14 10:22 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: mliska, GCC Patches

On Thu, Nov 13, 2014 at 4:50 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> gcc/ChangeLog:
>>
>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>
>>       * Makefile.in: New object file is added.
>>       * cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
>>       is filled up.
>>       * cgraph_summary.c: New file.
>>       * cgraph_summary.h: New file.
>
> Since I am trying to get rid of the cgraph prefixes for symbols (keep it for
> the graph only) and the summaries can be annotated to variables too. Even if it
> not necessarily supported by your current implementation, lets keep API
> prepared for it. So I would call it symtab-summary.* for source files and
> symtab_summary for base type  (probably function_summary for annotating
> functions/cgraph_edge_summary for annotating edges?)

Also please don't use underscores in filenames but dashes, thus
cgraph-summary.[ch], not cgraph_summary.[ch].

Richard.


>> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
>> index e2becb9..588b6d5 100644
>> --- a/gcc/cgraph.h
>> +++ b/gcc/cgraph.h
>> @@ -1225,6 +1225,8 @@ public:
>>    int count_materialization_scale;
>>    /* Unique id of the node.  */
>>    int uid;
>> +  /* Summary unique id of the node.  */
>> +  int summary_uid;
>
> What makes summary_uid better than uid?
>
>> diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
>> new file mode 100644
>> index 0000000..9af1d7e
>> --- /dev/null
>> +++ b/gcc/cgraph_summary.c
>
> And why do we need this file?  It will need license header if really needed.
>
> The implementation seems sane - I will check the actual uses :)
> Please send the updated patch though.
>
> Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-13 15:57   ` Jan Hubicka
  2014-11-14 10:22     ` Richard Biener
@ 2014-11-14 14:11     ` Martin Liška
  2014-11-14 15:31       ` Martin Liška
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-11-14 14:11 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2111 bytes --]

On 11/13/2014 04:50 PM, Jan Hubicka wrote:
>> gcc/ChangeLog:
>>
>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>
>> 	* Makefile.in: New object file is added.
>> 	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
>> 	is filled up.
>> 	* cgraph_summary.c: New file.
>> 	* cgraph_summary.h: New file.
>
> Since I am trying to get rid of the cgraph prefixes for symbols (keep it for
> the graph only) and the summaries can be annotated to variables too. Even if it
> not necessarily supported by your current implementation, lets keep API
> prepared for it. So I would call it symtab-summary.* for source files and
> symtab_summary for base type  (probably function_summary for annotating
> functions/cgraph_edge_summary for annotating edges?)

Hello.

I followed your remarks, new class is called function_summary and is located
in symbol-summary.h.
>
>
>> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
>> index e2becb9..588b6d5 100644
>> --- a/gcc/cgraph.h
>> +++ b/gcc/cgraph.h
>> @@ -1225,6 +1225,8 @@ public:
>>     int count_materialization_scale;
>>     /* Unique id of the node.  */
>>     int uid;
>> +  /* Summary unique id of the node.  */
>> +  int summary_uid;
>
> What makes summary_uid better than uid?

Because cgraph_node::uid is not a unique ID, it's recycled. As I can see,
there are two remaining usages of the fact that cgraph::uid are quite consecutive:

a) node_growth_cache vector is resized according to cgraph_max_uid
b) lto-partition.c: lto_balanced_map

If we change ipa-related stuff to annotations and lto_balanced_map with be rewritten,
we can finally unify uid and summary_uid. As Martin correctly pointed out, we should
unify cgraph_node dumps, we combine uid and order.

>
>> diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
>> new file mode 100644
>> index 0000000..9af1d7e
>> --- /dev/null
>> +++ b/gcc/cgraph_summary.c
>
> And why do we need this file?  It will need license header if really needed.

Sure, the file can be removed.

Martin

>
> The implementation seems sane - I will check the actual uses :)
> Please send the updated patch though.
>
> Honza
>


[-- Attachment #2: 0001-New-data-structure-for-function_summary-introduced.patch --]
[-- Type: text/x-patch, Size: 11437 bytes --]

From d7c149edea20850e95fde2e2e332895f5b5a8594 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Thu, 13 Nov 2014 15:11:05 +0100
Subject: [PATCH 1/3] New data structure for function_summary introduced.

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
	is filled up.
	* symbol-summary.h: New file.
	* gengtype.c (open_base_files): Add symbol-summary.h.
	* toplev.c (general_init): Call constructor of symbol_table.
---
 gcc/cgraph.h         |   8 ++
 gcc/gengtype.c       |   4 +-
 gcc/symbol-summary.h | 313 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/toplev.c         |   3 +-
 4 files changed, 325 insertions(+), 3 deletions(-)
 create mode 100644 gcc/symbol-summary.h

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index e2becb9..588b6d5 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1225,6 +1225,8 @@ public:
   int count_materialization_scale;
   /* Unique id of the node.  */
   int uid;
+  /* Summary unique id of the node.  */
+  int summary_uid;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
   /* Time profiler: first run of function.  */
@@ -1786,6 +1788,10 @@ public:
   friend class cgraph_node;
   friend class cgraph_edge;
 
+  symbol_table (): cgraph_max_summary_uid (1)
+  {
+  }
+
   /* Initialize callgraph dump file.  */
   void initialize (void);
 
@@ -1982,6 +1988,7 @@ public:
 
   int cgraph_count;
   int cgraph_max_uid;
+  int cgraph_max_summary_uid;
 
   int edges_count;
   int edges_max_uid;
@@ -2310,6 +2317,7 @@ symbol_table::allocate_cgraph_symbol (void)
       node->uid = cgraph_max_uid++;
     }
 
+  node->summary_uid = cgraph_max_summary_uid++;
   return node;
 }
 
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index fac83ee..1e2db27 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1842,8 +1842,8 @@ open_base_files (void)
       "tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h", 
       "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
-      "target-globals.h", "ipa-ref.h", "cgraph.h", "ipa-prop.h", 
-      "ipa-inline.h", "dwarf2out.h", NULL
+      "target-globals.h", "ipa-ref.h", "cgraph.h", "function-summary.h",
+      "ipa-prop.h", "ipa-inline.h", "dwarf2out.h", NULL
     };
     const char *const *ifp;
     outf_p gtype_desc_c;
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
new file mode 100644
index 0000000..893f065
--- /dev/null
+++ b/gcc/symbol-summary.h
@@ -0,0 +1,313 @@
+/* Callgraph summary data structure.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Contributed by Martin Liska
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_SYMBOL_SUMMARY_H
+#define GCC_SYMBOL_SUMMARY_H
+
+#define SYMBOL_SUMMARY_DELETED_VALUE -1
+#define SYMBOL_SUMMARY_EMPTY_VALUE 0
+
+template <class T>
+class function_summary
+{
+private:
+  function_summary();
+};
+
+template <class T>
+class GTY((user)) function_summary <T *>
+{
+public:
+  /* Default construction takes SYMTAB as an argument.  */
+  function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
+    m_insertion_enabled (true), m_symtab (symtab)
+  {
+    cgraph_node *node;
+
+    FOR_EACH_FUNCTION (node)
+    {
+      gcc_assert (node->summary_uid > 0);
+    }
+
+    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
+
+    m_symtab_insertion_hook =
+      symtab->add_cgraph_insertion_hook
+      (function_summary::symtab_insertion, this);
+
+    m_symtab_removal_hook =
+      symtab->add_cgraph_removal_hook
+      (function_summary::symtab_removal, this);
+    m_symtab_duplication_hook =
+      symtab->add_cgraph_duplication_hook
+      (function_summary::symtab_duplication, this);
+  }
+
+  /* Destructor.  */
+  virtual ~function_summary ()
+  {
+    destroy ();
+  }
+
+  /* Destruction method that can be called for GGT purpose.  */
+  void destroy ()
+  {
+    if (m_symtab_insertion_hook)
+      m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
+
+    if (m_symtab_removal_hook)
+      m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
+
+    if (m_symtab_duplication_hook)
+      m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
+
+    m_symtab_insertion_hook = NULL;
+    m_symtab_removal_hook = NULL;
+    m_symtab_duplication_hook = NULL;
+
+    if (!m_ggc)
+      m_map->traverse <void *, function_summary::release> (NULL);
+  }
+
+  /* Traverses all summarys with a function F called with
+     ARG as argument.  */
+  template<typename Arg, bool (*f)(const T &, Arg)>
+  void traverse (Arg a) const
+  {
+    m_map->traverse <f> (a);
+  }
+
+  /* Basic implementation of insert operation.  */
+  virtual void insert (cgraph_node *, T *) {}
+
+  /* Basic implementation of removal operation.  */
+  virtual void remove (cgraph_node *, T *) {}
+
+  /* Basic implementation of duplication operation.  */
+  virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
+
+  /* Allocates new data that are stored within map.  */
+  T* allocate_new ()
+  {
+    return m_ggc ? new (ggc_alloc <T> ()) T() : new T () ;
+  }
+
+  /* Getter for summary callgraph ID.  */
+  T* get (int uid)
+  {
+    T **v = m_map->get (uid);
+    if (!v)
+      {
+	T *new_value = allocate_new ();
+	m_map->put (uid, new_value);
+
+	v = &new_value;
+      }
+
+    return *v;
+  }
+
+  /* Getter for summary callgraph node pointer.  */
+  T* get (cgraph_node *node)
+  {
+    return operator[] (node->summary_uid);
+  }
+
+  /* Getter operator for summary callgraph ID.  */
+  T* operator[] (int uid)
+  {
+    return get (uid);
+  }
+
+  /* Getter operator for summary callgraph node pointer.  */
+  T* operator[] (cgraph_node *node)
+  {
+    return get (node);
+  }
+
+  /* Return number of elements handled by data structure.  */
+  size_t elements ()
+  {
+    return m_map->elements ();
+  }
+
+  /* Enable insertin hook invocation.  */
+  void enable_insertion_hook ()
+  {
+    m_insertion_enabled = true;
+  }
+
+  /* Enable insertin hook invocation.  */
+  void disable_insertion_hook ()
+  {
+    m_insertion_enabled = false;
+  }
+
+  /* Symbol insertion hook that is registered to symbol table.  */
+  static void symtab_insertion (cgraph_node *node, void *data)
+  {
+    function_summary *summary = (function_summary <T *> *) (data);
+
+    if (summary->m_insertion_enabled)
+      summary->insertion_hook (node, (*summary)[node]);
+  }
+
+  /* Symbol removal hook that is registered to symbol table.  */
+  static void symtab_removal (cgraph_node *node, void *data)
+  {
+    gcc_assert (node->summary_uid);
+    function_summary *summary = (function_summary <T *> *) (data);
+
+    int summary_uid = node->summary_uid;
+    T **v = summary->m_map->get (summary_uid);
+
+    if (v)
+      {
+	summary->removal_hook (node, *v);
+
+	if (!summary->m_ggc)
+	  delete (*v);
+      }
+
+    if (summary->m_map->get (summary_uid))
+      summary->m_map->remove (summary_uid);
+  }
+
+  /* Symbol duplication hook that is registered to symbol table.  */
+  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
+				  void *data)
+  {
+    function_summary *summary = (function_summary <T *> *) (data);
+    T **v = summary->m_map->get (node->summary_uid);
+
+    gcc_assert (node2->summary_uid > 0);
+
+    if (v)
+      {
+	T *data = *v;
+	T *duplicate = summary->allocate_new ();
+	summary->m_map->put (node2->summary_uid, duplicate);
+	summary->duplication_hook (node, node2, data, (*summary)[node2]);
+      }
+  }
+
+protected:
+  /* Indicatation if we use ggc summary.  */
+  bool m_ggc;
+
+private:
+  struct summary_hashmap_traits: default_hashmap_traits
+  {
+    static
+    hashval_t hash (const int v)
+    {
+      return (hashval_t)v;
+    }
+
+    template<typename Type>
+    static
+    bool is_deleted (Type &e)
+    {
+      return e.m_key == SYMBOL_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static
+    bool is_empty (Type &e)
+    {
+      return e.m_key == SYMBOL_SUMMARY_EMPTY_VALUE;
+    }
+
+    template<typename Type>
+    static
+    void mark_deleted (Type &e)
+    {
+      e.m_key = SYMBOL_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static
+    void mark_empty (Type &e)
+    {
+      e.m_key = SYMBOL_SUMMARY_EMPTY_VALUE;
+    }
+  };
+
+  /* Remove summary for summary UID.  */
+  void remove (int uid)
+  {
+    T *v = m_map->get (uid);
+
+    if (v)
+      m_map->erase (uid);
+  }
+
+  /* Summary class release function called by traverse method.  */
+  static bool release (int const &, T * const &v, void *)
+  {
+    delete (v);
+    return true;
+  }
+
+  /* Main summary store, where summary ID is used as key.  */
+  hash_map <int, T *, summary_hashmap_traits> *m_map;
+  /* Internal summary insertion hook pointer.  */
+  cgraph_node_hook_list *m_symtab_insertion_hook;
+  /* Internal summary removal hook pointer.  */
+  cgraph_node_hook_list *m_symtab_removal_hook;
+  /* Internal summary duplication hook pointer.  */
+  cgraph_2node_hook_list *m_symtab_duplication_hook;
+  /* Indicates if insertion hook is enabled.  */
+  bool m_insertion_enabled;
+  /* Symbol table the summary is registered to.  */
+  symbol_table *m_symtab;
+
+  template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
+      gt_pointer_operator, void *);
+};
+
+template <typename T>
+void
+gt_ggc_mx(function_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_ggc_mx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(function_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_pch_nx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op,
+	  void *cookie)
+{
+  if (summary->m_map)
+    gt_pch_nx (summary->m_map, op, cookie);
+}
+
+#endif  /* GCC_SYMBOL_SUMMARY_H  */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index aa1653e..b0f5b11 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -93,6 +93,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "bitmap.h"
 #include "ipa-reference.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "gcse.h"
 #include "insn-codes.h"
@@ -1209,7 +1210,7 @@ general_init (const char *argv0)
   /* Create the singleton holder for global state.
      Doing so also creates the pass manager and with it the passes.  */
   g = new gcc::context ();
-  symtab = ggc_cleared_alloc <symbol_table> ();
+  symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table ();
 
   statistics_early_init ();
   finish_params ();
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass.
  2014-11-13 14:23 ` [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass mliska
@ 2014-11-14 14:12   ` Martin Liška
  2014-11-14 15:31     ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-11-14 14:12 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 104083 bytes --]

On 11/11/2014 01:26 PM, mliska wrote:
> gcc/ChangeLog:
>
> 2014-11-12  Martin Liska  <mliska@suse.cz>
>
> 	* auto-profile.c: Include cgraph_summary.h.
> 	* cgraph.c: Likewise.
> 	* cgraphbuild.c: Likewise.
> 	* cgraphclones.c: Likewise.
> 	* cgraphunit.c: Likewise.
> 	* ipa-cp.c: Likewise.
> 	* ipa-devirt.c: Likewise.
> 	* ipa-icf.c: Likewise.
> 	* ipa-inline-analysis.c (evaluate_properties_for_edge): Usage of
> 	ipa_node_params_vector is replaced with ipa_node_params_summary.
> 	(inline_node_duplication_hook): Likewise.
> 	(estimate_function_body_sizes): Likewise.
> 	(remap_edge_change_prob): Likewise.
> 	(inline_merge_summary): Likewise.
> 	* ipa-inline-transform.c: Include of cgraph_summary.h.
> 	* ipa-inline.c (early_inliner): Usage of
> 	ipa_node_params_vector is replaced with ipa_node_params_summary.
> 	* ipa-polymorphic-call.c: Include of cgraph_summary.h.
> 	* ipa-profile.c: Include of cgraph_summary.h.
> 	* ipa-prop.c (struct func_body_info): Struct keyword is removed.
> 	(struct ipa_cst_ref_desc): Likewise.
> 	(ipa_func_spec_opts_forbid_analysis_p): Likewise.
> 	(ipa_alloc_node_params): Likewise.
> 	(ipa_initialize_node_params): Likewise.
> 	(ipa_print_node_jump_functions_for_edge): Likewise.
> 	(ipa_print_node_jump_functions): Likewise.
> 	(ipa_print_all_jump_functions): Likewise.
> 	(ipa_set_jf_constant): Likewise.
> 	(check_stmt_for_type_change): Likewise.
> 	(detect_type_change_from_memory_writes): Likewise.
> 	(find_dominating_aa_status): Likewise.
> 	(parm_bb_aa_status_for_bb): Likewise.
> 	(parm_preserved_before_stmt_p): Likewise.
> 	(parm_ref_data_preserved_p): Likewise.
> 	(parm_ref_data_pass_through_p): Likewise.
> 	(struct ipa_known_agg_contents_list): Likewise.
> 	(get_place_in_agg_contents_list): Likewise.
> 	(build_agg_jump_func_from_list): Likewise.
> 	(determine_locally_known_aggregate_parts): Likewise.
> 	(ipa_compute_jump_functions_for_edge): Likewise.
> 	(ipa_compute_jump_functions_for_bb): Likewise.
> 	(ipa_note_param_call): Likewise.
> 	(ipa_analyze_indirect_call_uses) Likewise.:
> 	(ipa_analyze_virtual_call_uses): Likewise.
> 	(ipa_analyze_call_uses): Likewise.
> 	(visit_ref_for_mod_analysis): Likewise.
> 	(ipa_analyze_controlled_uses): Likewise.
> 	(ipa_analyze_node): Likewise.
> 	(update_jump_functions_after_inlining): Likewise.
> 	(ipa_make_edge_direct_to_target): Likewise.
> 	(ipa_find_agg_cst_for_param): Likewise.
> 	(remove_described_reference): Likewise.
> 	(jfunc_rdesc_usable): Likewise.
> 	(try_decrement_rdesc_refcount): Likewise.
> 	(try_make_edge_direct_simple_call): Likewise.
> 	(try_make_edge_direct_virtual_call): Likewise.
> 	(update_indirect_edges_after_inlining): Likewise.
> 	(propagate_info_to_inlined_callees): Likewise.
> 	(propagate_controlled_uses): Likewise.
> 	(ipa_propagate_indirect_call_infos): Likewise.
> 	(ipa_free_all_edge_args): Likewise.
> 	(ipa_node_params::~ipa_node_params): Likewise.
> 	(ipa_free_all_node_params): Likewise.
> 	(ipa_edge_removal_hook): Likewise.
> 	(ipa_node_removal_hook): Likewise.
> 	(ipa_edge_duplication_hook): Likewise.
> 	(ipa_add_new_function): Removed
> 	(ipa_node_params_cgraph_summary::duplication_hook): New function.
> 	(ipa_node_duplication_hook): Struct keyword removed.
> 	(ipa_register_cgraph_hooks): Removal of old hooks.
> 	(ipa_unregister_cgraph_hooks): Likewise.
> 	(ipa_print_node_params): Struct keyword is removed.
> 	(ipa_print_all_params): Likewise.
> 	(ipa_modify_formal_parameters): Likewise.
> 	(ipa_modify_call_arguments): Likewise.
> 	(ipa_modify_expr): Likewise.
> 	(ipa_get_adjustment_candidate): Likewise.
> 	(index_in_adjustments_multiple_times_p): Likewise.
> 	(ipa_combine_adjustments): Likewise.
> 	(ipa_dump_param_adjustments): Likewise.
> 	(ipa_write_jump_function): Likewise.
> 	(ipa_read_jump_function): Likewise.
> 	(ipa_write_indirect_edge_info): Likewise.
> 	(ipa_read_indirect_edge_info): Likewise.
> 	(ipa_write_node_info): Likewise.
> 	(ipa_read_node_info): Likewise.
> 	(ipa_prop_write_jump_functions): Likewise.
> 	(ipa_prop_read_section): Likewise.
> 	(ipa_prop_read_jump_functions): Likewise.
> 	(write_agg_replacement_chain): Likewise.
> 	(read_agg_replacement_chain): Likewise.
> 	(ipa_prop_write_all_agg_replacement): Likewise.
> 	(read_replacements_section): Likewise.
> 	(ipa_prop_read_all_agg_replacement): Likewise.
> 	(adjust_agg_replacement_values): Likewise.
> 	(ipcp_modif_dom_walker::before_dom_children): Likewise.
> 	(ipcp_transform_function): Likewise.
> 	* ipa-prop.h (struct ipa_node_params): Introduction of new class
> 	ipa_node_params_cgraph_summary.
> 	* ipa-split.c: Include cgraph_summary.h.
> 	* ipa-utils.c: Likewise.
> 	* ipa.c: Likewise.
> 	* omp-low.c: Likewise.
> 	* tree-inline.c: Likewise.
> 	* tree-sra.c: Likewise.
> 	* tree-ssa-pre.c: Likewise.
>
> gcc/lto/ChangeLog:
>
> 2014-11-12  Martin Liska  <mliska@suse.cz>
>
> 	* lto-partition.c: Include cgraph_summary.h.
> 	* lto-symtab.c: Likewise.
> 	* lto.c: Likewise.
> ---
>   gcc/auto-profile.c         |   1 +
>   gcc/cgraph.c               |   1 +
>   gcc/cgraphbuild.c          |   1 +
>   gcc/cgraphclones.c         |   1 +
>   gcc/cgraphunit.c           |   1 +
>   gcc/ipa-cp.c               |   1 +
>   gcc/ipa-devirt.c           |   1 +
>   gcc/ipa-icf.c              |   1 +
>   gcc/ipa-inline-analysis.c  |  13 +-
>   gcc/ipa-inline-transform.c |   1 +
>   gcc/ipa-inline.c           |   3 +-
>   gcc/ipa-polymorphic-call.c |   1 +
>   gcc/ipa-profile.c          |   1 +
>   gcc/ipa-prop.c             | 700 ++++++++++++++++++++++-----------------------
>   gcc/ipa-prop.h             |  46 +--
>   gcc/ipa-split.c            |   1 +
>   gcc/ipa-utils.c            |   1 +
>   gcc/ipa.c                  |   1 +
>   gcc/lto/lto-partition.c    |   1 +
>   gcc/lto/lto-symtab.c       |   1 +
>   gcc/lto/lto.c              |   1 +
>   gcc/omp-low.c              |   1 +
>   gcc/tree-inline.c          |   1 +
>   gcc/tree-sra.c             |   1 +
>   gcc/tree-ssa-pre.c         |   1 +
>   25 files changed, 397 insertions(+), 386 deletions(-)
>
> diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
> index 8c7b4ca..49f9b8c 100644
> --- a/gcc/auto-profile.c
> +++ b/gcc/auto-profile.c
> @@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "coverage.h"
>   #include "params.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "tree-inline.h"
> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
> index 7216b89..af1835a 100644
> --- a/gcc/cgraph.c
> +++ b/gcc/cgraph.c
> @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-utils.h"
>   #include "lto-streamer.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "cfgloop.h"
> diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
> index c72ceab..a93b0aa 100644
> --- a/gcc/cgraphbuild.c
> +++ b/gcc/cgraphbuild.c
> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-utils.h"
>   #include "except.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>
> diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
> index c8892da..79f95ef 100644
> --- a/gcc/cgraphclones.c
> +++ b/gcc/cgraphclones.c
> @@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "tree-iterator.h"
>   #include "tree-dump.h"
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 25af234..dbbdc44 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -204,6 +204,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "tree-iterator.h"
>   #include "tree-pass.h"
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index 47f9f5c..da589af 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "bitmap.h"
>   #include "tree-pass.h"
> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
> index 32c6549..8e1f9ce 100644
> --- a/gcc/ipa-devirt.c
> +++ b/gcc/ipa-devirt.c
> @@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "gimple-expr.h"
>   #include "gimple.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "diagnostic.h"
> diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
> index 92ec82d..9778323 100644
> --- a/gcc/ipa-icf.c
> +++ b/gcc/ipa-icf.c
> @@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "cfgloop.h"
> diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
> index eb1c6ec..c7a52d2 100644
> --- a/gcc/ipa-inline-analysis.c
> +++ b/gcc/ipa-inline-analysis.c
> @@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "lto-streamer.h"
>   #include "data-streamer.h"
> @@ -910,7 +911,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
>     if (known_binfos_ptr)
>       known_binfos_ptr->create (0);
>
> -  if (ipa_node_params_vector.exists ()
> +  if (ipa_node_params_summary
>         && !e->call_stmt_cannot_inline_p
>         && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr))
>       {
> @@ -1130,7 +1131,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
>
>     /* When there are any replacements in the function body, see if we can figure
>        out that something was optimized out.  */
> -  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
> +  if (ipa_node_params_summary && dst->clone.tree_map)
>       {
>         vec<size_time_entry, va_gc> *entry = info->entry;
>         /* Use SRC parm info since it may not be copied yet.  */
> @@ -2476,7 +2477,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>         calculate_dominance_info (CDI_DOMINATORS);
>         loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
>
> -      if (ipa_node_params_vector.exists ())
> +      if (ipa_node_params_summary)
>   	{
>   	  parms_info = IPA_NODE_REF (node);
>   	  nonconstant_names.safe_grow_cleared
> @@ -2624,7 +2625,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>   		  nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
>   		    = false_p;
>   		}
> -	      if (ipa_node_params_vector.exists ())
> +	      if (ipa_node_params_summary)
>   		{
>   		  int count = gimple_call_num_args (stmt);
>   		  int i;
> @@ -3367,7 +3368,7 @@ static void
>   remap_edge_change_prob (struct cgraph_edge *inlined_edge,
>   			struct cgraph_edge *edge)
>   {
> -  if (ipa_node_params_vector.exists ())
> +  if (ipa_node_params_summary)
>       {
>         int i;
>         struct ipa_edge_args *args = IPA_EDGE_REF (edge);
> @@ -3523,7 +3524,7 @@ inline_merge_summary (struct cgraph_edge *edge)
>     else
>       toplev_predicate = true_predicate ();
>
> -  if (ipa_node_params_vector.exists () && callee_info->conds)
> +  if (ipa_node_params_summary && callee_info->conds)
>       {
>         struct ipa_edge_args *args = IPA_EDGE_REF (edge);
>         int count = ipa_get_cs_argument_count (args);
> diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
> index dbc56c5..fd700ff 100644
> --- a/gcc/ipa-inline-transform.c
> +++ b/gcc/ipa-inline-transform.c
> @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "tree-inline.h"
> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
> index 5c97815..8a08cd4 100644
> --- a/gcc/ipa-inline.c
> +++ b/gcc/ipa-inline.c
> @@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "except.h"
>   #include "target.h"
> @@ -2400,7 +2401,7 @@ early_inliner (function *fun)
>        it.  This may confuse ourself when early inliner decide to inline call to
>        function clone, because function clones don't have parameter list in
>        ipa-prop matching their signature.  */
> -  if (ipa_node_params_vector.exists ())
> +  if (ipa_node_params_summary)
>       return 0;
>
>   #ifdef ENABLE_CHECKING
> diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
> index 33dd1a8..e0555f2 100644
> --- a/gcc/ipa-polymorphic-call.c
> +++ b/gcc/ipa-polymorphic-call.c
> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "gimple-expr.h"
>   #include "gimple.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "diagnostic.h"
> diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
> index b83d1cf..4fdee09 100644
> --- a/gcc/ipa-profile.c
> +++ b/gcc/ipa-profile.c
> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "tree-inline.h"
>   #include "lto-streamer.h"
>   #include "data-streamer.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index db85c7d..ce9745e 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "bitmap.h"
>   #include "gimple-ssa.h"
> @@ -119,7 +120,7 @@ struct func_body_info
>     cgraph_node *node;
>
>     /* Its info.  */
> -  struct ipa_node_params *info;
> +  ipa_node_params *info;
>
>     /* Information about individual BBs. */
>     vec<ipa_bb_info> bb_infos;
> @@ -131,7 +132,8 @@ struct func_body_info
>     unsigned int aa_walked;
>   };
>
> -/* Vector where the parameter infos are actually stored. */
> +/* Callgraph summary where the parameter infos are actually stored. */
> +ipa_node_params_cgraph_summary *ipa_node_params_summary = NULL;
>   vec<ipa_node_params> ipa_node_params_vector;
>   /* Vector of known aggregate values in cloned nodes.  */
>   vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
> @@ -139,19 +141,17 @@ vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>   vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>
>   /* Holders of ipa cgraph hooks: */
> -static struct cgraph_edge_hook_list *edge_removal_hook_holder;
> -static struct cgraph_node_hook_list *node_removal_hook_holder;
> -static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
> -static struct cgraph_2node_hook_list *node_duplication_hook_holder;
> -static struct cgraph_node_hook_list *function_insertion_hook_holder;
> +static cgraph_edge_hook_list *edge_removal_hook_holder;
> +static cgraph_2edge_hook_list *edge_duplication_hook_holder;
> +static cgraph_node_hook_list *function_insertion_hook_holder;
>
>   /* Description of a reference to an IPA constant.  */
>   struct ipa_cst_ref_desc
>   {
>     /* Edge that corresponds to the statement which took the reference.  */
> -  struct cgraph_edge *cs;
> +  cgraph_edge *cs;
>     /* Linked list of duplicates created when call graph edges are cloned.  */
> -  struct ipa_cst_ref_desc *next_duplicate;
> +  ipa_cst_ref_desc *next_duplicate;
>     /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
>        if out of control.  */
>     int refcount;
> @@ -165,10 +165,10 @@ static alloc_pool ipa_refdesc_pool;
>      with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
>
>   static bool
> -ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
> +ipa_func_spec_opts_forbid_analysis_p (cgraph_node *node)
>   {
>     tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
> -  struct cl_optimization *os;
> +  cl_optimization *os;
>
>     if (!fs_opts)
>       return false;
> @@ -196,7 +196,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
>      to INFO.  */
>
>   int
> -ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
> +ipa_get_param_decl_index (ipa_node_params *info, tree ptree)
>   {
>     return ipa_get_param_decl_index_1 (info->descriptors, ptree);
>   }
> @@ -205,7 +205,7 @@ ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
>      NODE.  */
>
>   static void
> -ipa_populate_param_decls (struct cgraph_node *node,
> +ipa_populate_param_decls (cgraph_node *node,
>   			  vec<ipa_param_descriptor> &descriptors)
>   {
>     tree fndecl;
> @@ -246,7 +246,7 @@ count_formal_params (tree fndecl)
>      using ipa_initialize_node_params. */
>
>   void
> -ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
> +ipa_dump_param (FILE *file, ipa_node_params *info, int i)
>   {
>     fprintf (file, "param #%i", i);
>     if (info->descriptors[i].decl)
> @@ -260,9 +260,9 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
>      to hold PARAM_COUNT parameters.  */
>
>   void
> -ipa_alloc_node_params (struct cgraph_node *node, int param_count)
> +ipa_alloc_node_params (cgraph_node *node, int param_count)
>   {
> -  struct ipa_node_params *info = IPA_NODE_REF (node);
> +  ipa_node_params *info = IPA_NODE_REF (node);
>
>     if (!info->descriptors.exists () && param_count)
>       info->descriptors.safe_grow_cleared (param_count);
> @@ -273,9 +273,9 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
>      param_decls.  */
>
>   void
> -ipa_initialize_node_params (struct cgraph_node *node)
> +ipa_initialize_node_params (cgraph_node *node)
>   {
> -  struct ipa_node_params *info = IPA_NODE_REF (node);
> +  ipa_node_params *info = IPA_NODE_REF (node);
>
>     if (!info->descriptors.exists ())
>       {
> @@ -287,14 +287,14 @@ ipa_initialize_node_params (struct cgraph_node *node)
>   /* Print the jump functions associated with call graph edge CS to file F.  */
>
>   static void
> -ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
> +ipa_print_node_jump_functions_for_edge (FILE *f, cgraph_edge *cs)
>   {
>     int i, count;
>
>     count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
>     for (i = 0; i < count; i++)
>       {
> -      struct ipa_jump_func *jump_func;
> +      ipa_jump_func *jump_func;
>         enum jump_func_type type;
>
>         jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
> @@ -360,7 +360,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>
>         if (jump_func->agg.items)
>   	{
> -	  struct ipa_agg_jf_item *item;
> +	  ipa_agg_jf_item *item;
>   	  int j;
>
>   	  fprintf (f, "         Aggregate passed by %s:\n",
> @@ -390,9 +390,9 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>      NODE to file F.  */
>
>   void
> -ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
> +ipa_print_node_jump_functions (FILE *f, cgraph_node *node)
>   {
> -  struct cgraph_edge *cs;
> +  cgraph_edge *cs;
>
>     fprintf (f, "  Jump functions of caller  %s/%i:\n", node->name (),
>   	   node->order);
> @@ -410,7 +410,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>
>     for (cs = node->indirect_calls; cs; cs = cs->next_callee)
>       {
> -      struct cgraph_indirect_call_info *ii;
> +      cgraph_indirect_call_info *ii;
>         if (!ipa_edge_args_info_available_for_edge_p (cs))
>   	continue;
>
> @@ -445,7 +445,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>   void
>   ipa_print_all_jump_functions (FILE *f)
>   {
> -  struct cgraph_node *node;
> +  cgraph_node *node;
>
>     fprintf (f, "\nJump functions:\n");
>     FOR_EACH_FUNCTION (node)
> @@ -457,7 +457,7 @@ ipa_print_all_jump_functions (FILE *f)
>   /* Set JFUNC to be a known type jump function.  */
>
>   static void
> -ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
> +ipa_set_jf_known_type (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>   		       tree base_type, tree component_type)
>   {
>     /* Recording and propagating main variants increases change that types
> @@ -480,8 +480,8 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>      combination code).  The two functions will share their rdesc.  */
>
>   static void
> -ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
> -		     struct ipa_jump_func *src)
> +ipa_set_jf_cst_copy (ipa_jump_func *dst,
> +		     ipa_jump_func *src)
>
>   {
>     gcc_checking_assert (src->type == IPA_JF_CONST);
> @@ -492,8 +492,8 @@ ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
>   /* Set JFUNC to be a constant jmp function.  */
>
>   static void
> -ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
> -		     struct cgraph_edge *cs)
> +ipa_set_jf_constant (ipa_jump_func *jfunc, tree constant,
> +		     cgraph_edge *cs)
>   {
>     constant = unshare_expr (constant);
>     if (constant && EXPR_P (constant))
> @@ -504,12 +504,12 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>     if (TREE_CODE (constant) == ADDR_EXPR
>         && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
>       {
> -      struct ipa_cst_ref_desc *rdesc;
> +      ipa_cst_ref_desc *rdesc;
>         if (!ipa_refdesc_pool)
>   	ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
> -					sizeof (struct ipa_cst_ref_desc), 32);
> +					sizeof (ipa_cst_ref_desc), 32);
>
> -      rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
> +      rdesc = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>         rdesc->cs = cs;
>         rdesc->next_duplicate = NULL;
>         rdesc->refcount = 1;
> @@ -521,7 +521,7 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>
>   /* Set JFUNC to be a simple pass-through jump function.  */
>   static void
> -ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
> +ipa_set_jf_simple_pass_through (ipa_jump_func *jfunc, int formal_id,
>   				bool agg_preserved, bool type_preserved)
>   {
>     jfunc->type = IPA_JF_PASS_THROUGH;
> @@ -535,7 +535,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>   /* Set JFUNC to be an arithmetic pass through jump function.  */
>
>   static void
> -ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
> +ipa_set_jf_arith_pass_through (ipa_jump_func *jfunc, int formal_id,
>   			       tree operand, enum tree_code operation)
>   {
>     jfunc->type = IPA_JF_PASS_THROUGH;
> @@ -549,7 +549,7 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>   /* Set JFUNC to be an ancestor jump function.  */
>
>   static void
> -ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
> +ipa_set_ancestor_jf (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>   		     tree type, int formal_id, bool agg_preserved,
>   		     bool type_preserved)
>   {
> @@ -572,7 +572,7 @@ ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>      jump function.  */
>
>   tree
> -ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
> +ipa_binfo_from_known_type_jfunc (ipa_jump_func *jfunc)
>   {
>     if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
>       return NULL_TREE;
> @@ -602,8 +602,8 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
>   /* Get IPA BB information about the given BB.  FBI is the context of analyzis
>      of this function body.  */
>
> -static struct ipa_bb_info *
> -ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
> +static ipa_bb_info *
> +ipa_get_bb_info (func_body_info *fbi, basic_block bb)
>   {
>     gcc_checking_assert (fbi);
>     return &fbi->bb_infos[bb->index];
> @@ -700,7 +700,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
>      identified, return the type.  Otherwise return NULL_TREE.  */
>
>   static tree
> -extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
> +extr_type_from_vtbl_ptr_store (gimple stmt, prop_type_change_info *tci)
>   {
>     HOST_WIDE_INT offset, size, max_size;
>     tree lhs, rhs, base, binfo;
> @@ -752,7 +752,7 @@ static bool
>   check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
>   {
>     gimple stmt = SSA_NAME_DEF_STMT (vdef);
> -  struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
> +  prop_type_change_info *tci = (prop_type_change_info *) data;
>
>     if (stmt_may_be_vtbl_ptr_store (stmt))
>       {
> @@ -847,10 +847,10 @@ param_type_may_change_p (tree function, tree arg, gimple call)
>
>   static bool
>   detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
> -				       gimple call, struct ipa_jump_func *jfunc,
> +				       gimple call, ipa_jump_func *jfunc,
>   				       HOST_WIDE_INT offset)
>   {
> -  struct prop_type_change_info tci;
> +  prop_type_change_info tci;
>     ao_ref ao;
>     bool entry_reached = false;
>
> @@ -908,7 +908,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
>
>   static bool
>   detect_type_change (tree arg, tree base, tree comp_type, gimple call,
> -		    struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
> +		    ipa_jump_func *jfunc, HOST_WIDE_INT offset)
>   {
>     if (!flag_devirtualize)
>       return false;
> @@ -928,7 +928,7 @@ detect_type_change (tree arg, tree base, tree comp_type, gimple call,
>
>   static bool
>   detect_type_change_ssa (tree arg, tree comp_type,
> -			gimple call, struct ipa_jump_func *jfunc)
> +			gimple call, ipa_jump_func *jfunc)
>   {
>     gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
>     if (!flag_devirtualize
> @@ -961,7 +961,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
>      should really just start giving up.  */
>
>   static bool
> -aa_overwalked (struct func_body_info *fbi)
> +aa_overwalked (func_body_info *fbi)
>   {
>     gcc_checking_assert (fbi);
>     return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
> @@ -970,8 +970,8 @@ aa_overwalked (struct func_body_info *fbi)
>   /* Find the nearest valid aa status for parameter specified by INDEX that
>      dominates BB.  */
>
> -static struct param_aa_status *
> -find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
> +static param_aa_status *
> +find_dominating_aa_status (func_body_info *fbi, basic_block bb,
>   			   int index)
>   {
>     while (true)
> @@ -979,7 +979,7 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>         bb = get_immediate_dominator (CDI_DOMINATORS, bb);
>         if (!bb)
>   	return NULL;
> -      struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
> +      ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>         if (!bi->param_aa_statuses.is_empty ()
>   	  && bi->param_aa_statuses[index].valid)
>   	return &bi->param_aa_statuses[index];
> @@ -990,21 +990,21 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>      structures and/or intialize the result with a dominating description as
>      necessary.  */
>
> -static struct param_aa_status *
> -parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
> +static param_aa_status *
> +parm_bb_aa_status_for_bb (func_body_info *fbi, basic_block bb,
>   			  int index)
>   {
>     gcc_checking_assert (fbi);
> -  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
> +  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>     if (bi->param_aa_statuses.is_empty ())
>       bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
> -  struct param_aa_status *paa = &bi->param_aa_statuses[index];
> +  param_aa_status *paa = &bi->param_aa_statuses[index];
>     if (!paa->valid)
>       {
>         gcc_checking_assert (!paa->parm_modified
>   			   && !paa->ref_modified
>   			   && !paa->pt_modified);
> -      struct param_aa_status *dom_paa;
> +      param_aa_status *dom_paa;
>         dom_paa = find_dominating_aa_status (fbi, bb, index);
>         if (dom_paa)
>   	*paa = *dom_paa;
> @@ -1021,10 +1021,10 @@ parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
>      gathered but do not survive the summary building stage.  */
>
>   static bool
> -parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
> +parm_preserved_before_stmt_p (func_body_info *fbi, int index,
>   			      gimple stmt, tree parm_load)
>   {
> -  struct param_aa_status *paa;
> +  param_aa_status *paa;
>     bool modified = false;
>     ao_ref refd;
>
> @@ -1060,7 +1060,7 @@ parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
>      modified.  Otherwise return -1.  */
>
>   static int
> -load_from_unmodified_param (struct func_body_info *fbi,
> +load_from_unmodified_param (func_body_info *fbi,
>   			    vec<ipa_param_descriptor> descriptors,
>   			    gimple stmt)
>   {
> @@ -1087,10 +1087,10 @@ load_from_unmodified_param (struct func_body_info *fbi,
>      before reaching statement STMT.  */
>
>   static bool
> -parm_ref_data_preserved_p (struct func_body_info *fbi,
> +parm_ref_data_preserved_p (func_body_info *fbi,
>   			   int index, gimple stmt, tree ref)
>   {
> -  struct param_aa_status *paa;
> +  param_aa_status *paa;
>     bool modified = false;
>     ao_ref refd;
>
> @@ -1126,7 +1126,7 @@ parm_ref_data_preserved_p (struct func_body_info *fbi,
>      CALL into which it is passed.  FBI describes the function body.  */
>
>   static bool
> -parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
> +parm_ref_data_pass_through_p (func_body_info *fbi, int index,
>   			      gimple call, tree parm)
>   {
>     bool modified = false;
> @@ -1140,7 +1140,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>         || aa_overwalked (fbi))
>       return false;
>
> -  struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
> +  param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
>   							  index);
>     if (paa->pt_modified)
>       return false;
> @@ -1165,7 +1165,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>      reference respectively.  */
>
>   static bool
> -ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
> +ipa_load_from_parm_agg_1 (func_body_info *fbi,
>   			  vec<ipa_param_descriptor> descriptors,
>   			  gimple stmt, tree op, int *index_p,
>   			  HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
> @@ -1240,7 +1240,7 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
>      pointer, for users outside of this file.  */
>
>   bool
> -ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
> +ipa_load_from_parm_agg (ipa_node_params *info, gimple stmt,
>   			tree op, int *index_p, HOST_WIDE_INT *offset_p,
>   			bool *by_ref_p)
>   {
> @@ -1302,9 +1302,9 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
>      only needed for intraprocedural analysis.  */
>
>   static void
> -compute_complex_assign_jump_func (struct func_body_info *fbi,
> -				  struct ipa_node_params *info,
> -				  struct ipa_jump_func *jfunc,
> +compute_complex_assign_jump_func (func_body_info *fbi,
> +				  ipa_node_params *info,
> +				  ipa_jump_func *jfunc,
>   				  gimple call, gimple stmt, tree name,
>   				  tree param_type)
>   {
> @@ -1458,9 +1458,9 @@ get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
>        return D.1879_6;  */
>
>   static void
> -compute_complex_ancestor_jump_func (struct func_body_info *fbi,
> -				    struct ipa_node_params *info,
> -				    struct ipa_jump_func *jfunc,
> +compute_complex_ancestor_jump_func (func_body_info *fbi,
> +				    ipa_node_params *info,
> +				    ipa_jump_func *jfunc,
>   				    gimple call, gimple phi, tree param_type)
>   {
>     HOST_WIDE_INT offset;
> @@ -1531,7 +1531,7 @@ compute_complex_ancestor_jump_func (struct func_body_info *fbi,
>      EXPECTED_TYPE represents a type the argument should be in  */
>
>   static void
> -compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
> +compute_known_type_jump_func (tree op, ipa_jump_func *jfunc,
>   			      gimple call, tree expected_type)
>   {
>     HOST_WIDE_INT offset, size, max_size;
> @@ -1629,7 +1629,7 @@ struct ipa_known_agg_contents_list
>     /* Known constant value or NULL if the contents is known to be unknown.  */
>     tree constant;
>     /* Pointer to the next structure in the list.  */
> -  struct ipa_known_agg_contents_list *next;
> +  ipa_known_agg_contents_list *next;
>   };
>
>   /* Find the proper place in linked list of ipa_known_agg_contents_list
> @@ -1637,13 +1637,13 @@ struct ipa_known_agg_contents_list
>      unless there is a partial overlap, in which case return NULL, or such
>      element is already there, in which case set *ALREADY_THERE to true.  */
>
> -static struct ipa_known_agg_contents_list **
> -get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
> +static ipa_known_agg_contents_list **
> +get_place_in_agg_contents_list (ipa_known_agg_contents_list **list,
>   				HOST_WIDE_INT lhs_offset,
>   				HOST_WIDE_INT lhs_size,
>   				bool *already_there)
>   {
> -  struct ipa_known_agg_contents_list **p = list;
> +  ipa_known_agg_contents_list **p = list;
>     while (*p && (*p)->offset < lhs_offset)
>       {
>         if ((*p)->offset + (*p)->size > lhs_offset)
> @@ -1670,16 +1670,16 @@ get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
>      is ARG_OFFSET and store it into JFUNC.  */
>
>   static void
> -build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
> +build_agg_jump_func_from_list (ipa_known_agg_contents_list *list,
>   			       int const_count, HOST_WIDE_INT arg_offset,
> -			       struct ipa_jump_func *jfunc)
> +			       ipa_jump_func *jfunc)
>   {
>     vec_alloc (jfunc->agg.items, const_count);
>     while (list)
>       {
>         if (list->constant)
>   	{
> -	  struct ipa_agg_jf_item item;
> +	  ipa_agg_jf_item item;
>   	  item.offset = list->offset - arg_offset;
>   	  gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
>   	  item.value = unshare_expr_without_location (list->constant);
> @@ -1697,9 +1697,9 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
>
>   static void
>   determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
> -					 struct ipa_jump_func *jfunc)
> +					 ipa_jump_func *jfunc)
>   {
> -  struct ipa_known_agg_contents_list *list = NULL;
> +  ipa_known_agg_contents_list *list = NULL;
>     int item_count = 0, const_count = 0;
>     HOST_WIDE_INT arg_offset, arg_size;
>     gimple_stmt_iterator gsi;
> @@ -1774,7 +1774,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>     gsi_prev (&gsi);
>     for (; !gsi_end_p (gsi); gsi_prev (&gsi))
>       {
> -      struct ipa_known_agg_contents_list *n, **p;
> +      ipa_known_agg_contents_list *n, **p;
>         gimple stmt = gsi_stmt (gsi);
>         HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
>         tree lhs, rhs, lhs_base;
> @@ -1821,7 +1821,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>   	continue;
>
>         rhs = get_ssa_def_if_simple_copy (rhs);
> -      n = XALLOCA (struct ipa_known_agg_contents_list);
> +      n = XALLOCA (ipa_known_agg_contents_list);
>         n->size = lhs_size;
>         n->offset = lhs_offset;
>         if (is_gimple_ip_invariant (rhs))
> @@ -1852,7 +1852,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>   }
>
>   static tree
> -ipa_get_callee_param_type (struct cgraph_edge *e, int i)
> +ipa_get_callee_param_type (cgraph_edge *e, int i)
>   {
>     int n;
>     tree type = (e->callee
> @@ -1887,11 +1887,11 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>      to this callsite.  */
>
>   static void
> -ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
> -				     struct cgraph_edge *cs)
> +ipa_compute_jump_functions_for_edge (func_body_info *fbi,
> +				     cgraph_edge *cs)
>   {
> -  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
> -  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
> +  ipa_node_params *info = IPA_NODE_REF (cs->caller);
> +  ipa_edge_args *args = IPA_EDGE_REF (cs);
>     gimple call = cs->call_stmt;
>     int n, arg_num = gimple_call_num_args (call);
>     bool useful_context = false;
> @@ -1909,13 +1909,13 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>
>     for (n = 0; n < arg_num; n++)
>       {
> -      struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
> +      ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
>         tree arg = gimple_call_arg (call, n);
>         tree param_type = ipa_get_callee_param_type (cs, n);
>         if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
>   	{
>   	  tree instance;
> -	  struct ipa_polymorphic_call_context context (cs->caller->decl,
> +	  ipa_polymorphic_call_context context (cs->caller->decl,
>   						       arg, cs->call_stmt,
>   						       &instance);
>   	  context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
> @@ -2003,15 +2003,15 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>      from BB.  */
>
>   static void
> -ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
> +ipa_compute_jump_functions_for_bb (func_body_info *fbi, basic_block bb)
>   {
> -  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
> +  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>     int i;
> -  struct cgraph_edge *cs;
> +  cgraph_edge *cs;
>
>     FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
>       {
> -      struct cgraph_node *callee = cs->callee;
> +      cgraph_node *callee = cs->callee;
>
>         if (callee)
>   	{
> @@ -2093,10 +2093,10 @@ ipa_is_ssa_with_stmt_def (tree t)
>      call to a parameter number PARAM_INDEX.  NODE is the caller.  Return the
>      indirect call graph edge.  */
>
> -static struct cgraph_edge *
> -ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
> +static cgraph_edge *
> +ipa_note_param_call (cgraph_node *node, int param_index, gimple stmt)
>   {
> -  struct cgraph_edge *cs;
> +  cgraph_edge *cs;
>
>     cs = node->get_edge (stmt);
>     cs->indirect_info->param_index = param_index;
> @@ -2165,10 +2165,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
>      passed by value or reference.  */
>
>   static void
> -ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
> +ipa_analyze_indirect_call_uses (func_body_info *fbi, gimple call,
>   				tree target)
>   {
> -  struct ipa_node_params *info = fbi->info;
> +  ipa_node_params *info = fbi->info;
>     HOST_WIDE_INT offset;
>     bool by_ref;
>
> @@ -2188,7 +2188,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>   				   gimple_assign_rhs1 (def), &index, &offset,
>   				   NULL, &by_ref))
>       {
> -      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
> +      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>         cs->indirect_info->offset = offset;
>         cs->indirect_info->agg_contents = 1;
>         cs->indirect_info->by_ref = by_ref;
> @@ -2288,7 +2288,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>     if (index >= 0
>         && parm_preserved_before_stmt_p (fbi, index, call, rec))
>       {
> -      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
> +      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>         cs->indirect_info->offset = offset;
>         cs->indirect_info->agg_contents = 1;
>         cs->indirect_info->member_ptr = 1;
> @@ -2303,7 +2303,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>      statement.  */
>
>   static void
> -ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
> +ipa_analyze_virtual_call_uses (func_body_info *fbi,
>   			       gimple call, tree target)
>   {
>     tree obj = OBJ_TYPE_REF_OBJECT (target);
> @@ -2316,10 +2316,10 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>     if (TREE_CODE (obj) != SSA_NAME)
>       return;
>
> -  struct ipa_node_params *info = fbi->info;
> +  ipa_node_params *info = fbi->info;
>     if (SSA_NAME_IS_DEFAULT_DEF (obj))
>       {
> -      struct ipa_jump_func jfunc;
> +      ipa_jump_func jfunc;
>         if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
>   	return;
>
> @@ -2332,7 +2332,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>       }
>     else
>       {
> -      struct ipa_jump_func jfunc;
> +      ipa_jump_func jfunc;
>         gimple stmt = SSA_NAME_DEF_STMT (obj);
>         tree expr;
>
> @@ -2347,8 +2347,8 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>   	return;
>       }
>
> -  struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
> +  cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>     ii->offset = anc_offset;
>     ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
>     ii->otr_type = obj_type_ref_class (target);
> @@ -2360,7 +2360,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>      containing intermediate information about each formal parameter.  */
>
>   static void
> -ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
> +ipa_analyze_call_uses (func_body_info *fbi, gimple call)
>   {
>     tree target = gimple_call_fn (call);
>
> @@ -2369,7 +2369,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>             && !virtual_method_call_p (target)))
>       return;
>
> -  struct cgraph_edge *cs = fbi->node->get_edge (call);
> +  cgraph_edge *cs = fbi->node->get_edge (call);
>     /* If we previously turned the call into a direct call, there is
>        no need to analyze.  */
>     if (cs && !cs->indirect_unknown_callee)
> @@ -2406,7 +2406,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>      formal parameters are called.  */
>
>   static void
> -ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
> +ipa_analyze_stmt_uses (func_body_info *fbi, gimple stmt)
>   {
>     if (is_gimple_call (stmt))
>       ipa_analyze_call_uses (fbi, stmt);
> @@ -2419,7 +2419,7 @@ ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
>   static bool
>   visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
>   {
> -  struct ipa_node_params *info = (struct ipa_node_params *) data;
> +  ipa_node_params *info = (ipa_node_params *) data;
>
>     op = get_base_address (op);
>     if (op
> @@ -2439,7 +2439,7 @@ visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
>      the function being analyzed.  */
>
>   static void
> -ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
> +ipa_analyze_params_uses_in_bb (func_body_info *fbi, basic_block bb)
>   {
>     gimple_stmt_iterator gsi;
>     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
> @@ -2465,9 +2465,9 @@ ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
>   /* Calculate controlled uses of parameters of NODE.  */
>
>   static void
> -ipa_analyze_controlled_uses (struct cgraph_node *node)
> +ipa_analyze_controlled_uses (cgraph_node *node)
>   {
> -  struct ipa_node_params *info = IPA_NODE_REF (node);
> +  ipa_node_params *info = IPA_NODE_REF (node);
>
>     for (int i = 0; i < ipa_get_param_count (info); i++)
>       {
> @@ -2510,7 +2510,7 @@ ipa_analyze_controlled_uses (struct cgraph_node *node)
>   /* Free stuff in BI.  */
>
>   static void
> -free_ipa_bb_info (struct ipa_bb_info *bi)
> +free_ipa_bb_info (ipa_bb_info *bi)
>   {
>     bi->cg_edges.release ();
>     bi->param_aa_statuses.release ();
> @@ -2521,13 +2521,13 @@ free_ipa_bb_info (struct ipa_bb_info *bi)
>   class analysis_dom_walker : public dom_walker
>   {
>   public:
> -  analysis_dom_walker (struct func_body_info *fbi)
> +  analysis_dom_walker (func_body_info *fbi)
>       : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
>
>     virtual void before_dom_children (basic_block);
>
>   private:
> -  struct func_body_info *m_fbi;
> +  func_body_info *m_fbi;
>   };
>
>   void
> @@ -2542,10 +2542,10 @@ analysis_dom_walker::before_dom_children (basic_block bb)
>      with actual arguments of calls from within NODE.  */
>
>   void
> -ipa_analyze_node (struct cgraph_node *node)
> +ipa_analyze_node (cgraph_node *node)
>   {
> -  struct func_body_info fbi;
> -  struct ipa_node_params *info;
> +  func_body_info fbi;
> +  ipa_node_params *info;
>
>     ipa_check_create_node_params ();
>     ipa_check_create_edge_args ();
> @@ -2565,7 +2565,7 @@ ipa_analyze_node (struct cgraph_node *node)
>         return;
>       }
>
> -  struct function *func = DECL_STRUCT_FUNCTION (node->decl);
> +  function *func = DECL_STRUCT_FUNCTION (node->decl);
>     push_cfun (func);
>     calculate_dominance_info (CDI_DOMINATORS);
>     ipa_initialize_node_params (node);
> @@ -2578,13 +2578,13 @@ ipa_analyze_node (struct cgraph_node *node)
>     fbi.param_count = ipa_get_param_count (info);
>     fbi.aa_walked = 0;
>
> -  for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
> +  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
>       {
>         ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
>         bi->cg_edges.safe_push (cs);
>       }
>
> -  for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
> +  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
>       {
>         ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
>         bi->cg_edges.safe_push (cs);
> @@ -2593,7 +2593,7 @@ ipa_analyze_node (struct cgraph_node *node)
>     analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
>
>     int i;
> -  struct ipa_bb_info *bi;
> +  ipa_bb_info *bi;
>     FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
>       free_ipa_bb_info (bi);
>     fbi.bb_infos.release ();
> @@ -2606,8 +2606,8 @@ ipa_analyze_node (struct cgraph_node *node)
>      type.  */
>
>   static void
> -combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
> -				     struct ipa_jump_func *dst)
> +combine_known_type_and_ancestor_jfs (ipa_jump_func *src,
> +				     ipa_jump_func *dst)
>   {
>     HOST_WIDE_INT combined_offset;
>     tree combined_type;
> @@ -2632,25 +2632,25 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
>      indirectly) inlined into CS->callee and that E has not been inlined.  */
>
>   static void
> -update_jump_functions_after_inlining (struct cgraph_edge *cs,
> -				      struct cgraph_edge *e)
> +update_jump_functions_after_inlining (cgraph_edge *cs,
> +				      cgraph_edge *e)
>   {
> -  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
> -  struct ipa_edge_args *args = IPA_EDGE_REF (e);
> +  ipa_edge_args *top = IPA_EDGE_REF (cs);
> +  ipa_edge_args *args = IPA_EDGE_REF (e);
>     int count = ipa_get_cs_argument_count (args);
>     int i;
>
>     for (i = 0; i < count; i++)
>       {
> -      struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
> -      struct ipa_polymorphic_call_context *dst_ctx
> +      ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
> +      ipa_polymorphic_call_context *dst_ctx
>   	= ipa_get_ith_polymorhic_call_context (args, i);
>
>         if (dst->type == IPA_JF_ANCESTOR)
>   	{
> -	  struct ipa_jump_func *src;
> +	  ipa_jump_func *src;
>   	  int dst_fid = dst->value.ancestor.formal_id;
> -	  struct ipa_polymorphic_call_context *src_ctx
> +	  ipa_polymorphic_call_context *src_ctx
>   	    = ipa_get_ith_polymorhic_call_context (top, dst_fid);
>
>   	  /* Variable number of arguments can cause havoc if we try to access
> @@ -2666,7 +2666,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>
>   	  if (src_ctx && !src_ctx->useless_p ())
>   	    {
> -	      struct ipa_polymorphic_call_context ctx = *src_ctx;
> +	      ipa_polymorphic_call_context ctx = *src_ctx;
>
>   	      /* TODO: Make type preserved safe WRT contexts.  */
>   	      if (!dst->value.ancestor.agg_preserved)
> @@ -2683,7 +2683,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>   	  if (src->agg.items
>   	      && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
>   	    {
> -	      struct ipa_agg_jf_item *item;
> +	      ipa_agg_jf_item *item;
>   	      int j;
>
>   	      /* Currently we do not produce clobber aggregate jump functions,
> @@ -2721,7 +2721,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>   	}
>         else if (dst->type == IPA_JF_PASS_THROUGH)
>   	{
> -	  struct ipa_jump_func *src;
> +	  ipa_jump_func *src;
>   	  /* We must check range due to calls with variable number of arguments
>   	     and we cannot combine jump functions with operations.  */
>   	  if (dst->value.pass_through.operation == NOP_EXPR
> @@ -2731,12 +2731,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>   	      int dst_fid = dst->value.pass_through.formal_id;
>   	      src = ipa_get_ith_jump_func (top, dst_fid);
>   	      bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
> -	      struct ipa_polymorphic_call_context *src_ctx
> +	      ipa_polymorphic_call_context *src_ctx
>   		= ipa_get_ith_polymorhic_call_context (top, dst_fid);
>
>   	      if (src_ctx && !src_ctx->useless_p ())
>   		{
> -		  struct ipa_polymorphic_call_context ctx = *src_ctx;
> +		  ipa_polymorphic_call_context ctx = *src_ctx;
>
>   		  /* TODO: Make type preserved safe WRT contexts.  */
>   		  if (!dst->value.ancestor.agg_preserved)
> @@ -2833,11 +2833,11 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>      (SPECULATIVE)destination of an indirect edge IE and return the edge.
>      Otherwise, return NULL.  */
>
> -struct cgraph_edge *
> -ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
> +cgraph_edge *
> +ipa_make_edge_direct_to_target (cgraph_edge *ie, tree target,
>   				bool speculative)
>   {
> -  struct cgraph_node *callee;
> +  cgraph_node *callee;
>     struct inline_edge_summary *es = inline_edge_summary (ie);
>     bool unreachable = false;
>
> @@ -2898,8 +2898,8 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>     /* If the edge is already speculated.  */
>     if (speculative && ie->speculative)
>       {
> -      struct cgraph_edge *e2;
> -      struct ipa_ref *ref;
> +      cgraph_edge *e2;
> +      ipa_ref *ref;
>         ie->speculative_call_info (e2, ie, ref);
>         if (e2->callee->ultimate_alias_target ()
>   	  != callee->ultimate_alias_target ())
> @@ -2987,10 +2987,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>      be passed by reference or by value.  */
>
>   tree
> -ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
> +ipa_find_agg_cst_for_param (ipa_agg_jump_function *agg,
>   			    HOST_WIDE_INT offset, bool by_ref)
>   {
> -  struct ipa_agg_jf_item *item;
> +  ipa_agg_jf_item *item;
>     int i;
>
>     if (by_ref != agg->by_ref)
> @@ -3012,10 +3012,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
>      successfully found and removed.  */
>
>   static bool
> -remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
> +remove_described_reference (symtab_node *symbol, ipa_cst_ref_desc *rdesc)
>   {
> -  struct ipa_ref *to_del;
> -  struct cgraph_edge *origin;
> +  ipa_ref *to_del;
> +  cgraph_edge *origin;
>
>     origin = rdesc->cs;
>     if (!origin)
> @@ -3037,10 +3037,10 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
>      IPA_UNDESCRIBED_USE, return the reference description, otherwise return
>      NULL.  JFUNC must be a constant jump function.  */
>
> -static struct ipa_cst_ref_desc *
> -jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
> +static ipa_cst_ref_desc *
> +jfunc_rdesc_usable (ipa_jump_func *jfunc)
>   {
> -  struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
> +  ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
>     if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
>       return rdesc;
>     else
> @@ -3052,7 +3052,7 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
>      NULL.  */
>
>   static cgraph_node *
> -cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
> +cgraph_node_for_jfunc (ipa_jump_func *jfunc)
>   {
>     gcc_checking_assert (jfunc->type == IPA_JF_CONST);
>     tree cst = ipa_get_jf_constant (jfunc);
> @@ -3070,9 +3070,9 @@ cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
>      reference could not be found, otherwise return true.  */
>
>   static bool
> -try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
> +try_decrement_rdesc_refcount (ipa_jump_func *jfunc)
>   {
> -  struct ipa_cst_ref_desc *rdesc;
> +  ipa_cst_ref_desc *rdesc;
>     if (jfunc->type == IPA_JF_CONST
>         && (rdesc = jfunc_rdesc_usable (jfunc))
>         && --rdesc->refcount == 0)
> @@ -3092,12 +3092,12 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
>      determined, return the newly direct edge, otherwise return NULL.
>      NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
>
> -static struct cgraph_edge *
> -try_make_edge_direct_simple_call (struct cgraph_edge *ie,
> -				  struct ipa_jump_func *jfunc,
> -				  struct ipa_node_params *new_root_info)
> +static cgraph_edge *
> +try_make_edge_direct_simple_call (cgraph_edge *ie,
> +				  ipa_jump_func *jfunc,
> +				  ipa_node_params *new_root_info)
>   {
> -  struct cgraph_edge *cs;
> +  cgraph_edge *cs;
>     tree target;
>     bool agg_contents = ie->indirect_info->agg_contents;
>
> @@ -3130,7 +3130,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
>      and target (the latter can be NULL) are dumped when dumping is enabled.  */
>
>   tree
> -ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
> +ipa_impossible_devirt_target (cgraph_edge *ie, tree target)
>   {
>     if (dump_file)
>       {
> @@ -3155,11 +3155,11 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
>      Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
>      are relative to.  */
>
> -static struct cgraph_edge *
> -try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
> -				   struct ipa_jump_func *jfunc,
> -				   struct ipa_node_params *new_root_info,
> -				   struct ipa_polymorphic_call_context *ctx_ptr)
> +static cgraph_edge *
> +try_make_edge_direct_virtual_call (cgraph_edge *ie,
> +				   ipa_jump_func *jfunc,
> +				   ipa_node_params *new_root_info,
> +				   ipa_polymorphic_call_context *ctx_ptr)
>   {
>     tree binfo, target = NULL;
>     bool speculative = false;
> @@ -3172,7 +3172,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>        based on knowlede of the context.  */
>     if (ctx_ptr && !ie->indirect_info->by_ref)
>       {
> -      struct ipa_polymorphic_call_context ctx = *ctx_ptr;
> +      ipa_polymorphic_call_context ctx = *ctx_ptr;
>
>         ctx.offset_by (ie->indirect_info->offset);
>
> @@ -3221,7 +3221,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>
>     if (binfo && TREE_CODE (binfo) != TREE_BINFO)
>       {
> -      struct ipa_polymorphic_call_context ctx (binfo,
> +      ipa_polymorphic_call_context ctx (binfo,
>   					       ie->indirect_info->otr_type,
>   					       ie->indirect_info->offset);
>         updated |= ie->indirect_info->context.combine_with
> @@ -3296,13 +3296,13 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>      unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
>
>   static bool
> -update_indirect_edges_after_inlining (struct cgraph_edge *cs,
> -				      struct cgraph_node *node,
> +update_indirect_edges_after_inlining (cgraph_edge *cs,
> +				      cgraph_node *node,
>   				      vec<cgraph_edge *> *new_edges)
>   {
> -  struct ipa_edge_args *top;
> -  struct cgraph_edge *ie, *next_ie, *new_direct_edge;
> -  struct ipa_node_params *new_root_info;
> +  ipa_edge_args *top;
> +  cgraph_edge *ie, *next_ie, *new_direct_edge;
> +  ipa_node_params *new_root_info;
>     bool res = false;
>
>     ipa_check_create_edge_args ();
> @@ -3313,8 +3313,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>
>     for (ie = node->indirect_calls; ie; ie = next_ie)
>       {
> -      struct cgraph_indirect_call_info *ici = ie->indirect_info;
> -      struct ipa_jump_func *jfunc;
> +      cgraph_indirect_call_info *ici = ie->indirect_info;
> +      ipa_jump_func *jfunc;
>         int param_index;
>
>         next_ie = ie->next_callee;
> @@ -3408,11 +3408,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>      created.  */
>
>   static bool
> -propagate_info_to_inlined_callees (struct cgraph_edge *cs,
> -				   struct cgraph_node *node,
> +propagate_info_to_inlined_callees (cgraph_edge *cs,
> +				   cgraph_node *node,
>   				   vec<cgraph_edge *> *new_edges)
>   {
> -  struct cgraph_edge *e;
> +  cgraph_edge *e;
>     bool res;
>
>     res = update_indirect_edges_after_inlining (cs, node, new_edges);
> @@ -3443,21 +3443,21 @@ combine_controlled_uses_counters (int c, int d)
>      tree of inlined nodes.  */
>
>   static void
> -propagate_controlled_uses (struct cgraph_edge *cs)
> +propagate_controlled_uses (cgraph_edge *cs)
>   {
> -  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
> -  struct cgraph_node *new_root = cs->caller->global.inlined_to
> +  ipa_edge_args *args = IPA_EDGE_REF (cs);
> +  cgraph_node *new_root = cs->caller->global.inlined_to
>       ? cs->caller->global.inlined_to : cs->caller;
> -  struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
> -  struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
> +  ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
> +  ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
>     int count, i;
>
>     count = MIN (ipa_get_cs_argument_count (args),
>   	       ipa_get_param_count (old_root_info));
>     for (i = 0; i < count; i++)
>       {
> -      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
> -      struct ipa_cst_ref_desc *rdesc;
> +      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
> +      ipa_cst_ref_desc *rdesc;
>
>         if (jf->type == IPA_JF_PASS_THROUGH)
>   	{
> @@ -3472,8 +3472,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>   	  ipa_set_controlled_uses (new_root_info, src_idx, c);
>   	  if (c == 0 && new_root_info->ipcp_orig_node)
>   	    {
> -	      struct cgraph_node *n;
> -	      struct ipa_ref *ref;
> +	      cgraph_node *n;
> +	      ipa_ref *ref;
>   	      tree t = new_root_info->known_vals[src_idx];
>
>   	      if (t && TREE_CODE (t) == ADDR_EXPR
> @@ -3500,14 +3500,14 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>   	  if (rdesc->refcount == 0)
>   	    {
>   	      tree cst = ipa_get_jf_constant (jf);
> -	      struct cgraph_node *n;
> +	      cgraph_node *n;
>   	      gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
>   				   && TREE_CODE (TREE_OPERAND (cst, 0))
>   				   == FUNCTION_DECL);
>   	      n = cgraph_node::get (TREE_OPERAND (cst, 0));
>   	      if (n)
>   		{
> -		  struct cgraph_node *clone;
> +		  cgraph_node *clone;
>   		  bool ok;
>   		  ok = remove_described_reference (n, rdesc);
>   		  gcc_checking_assert (ok);
> @@ -3517,7 +3517,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>   			 && clone != rdesc->cs->caller
>   			 && IPA_NODE_REF (clone)->ipcp_orig_node)
>   		    {
> -		      struct ipa_ref *ref;
> +		      ipa_ref *ref;
>   		      ref = clone->find_reference (n, NULL, 0);
>   		      if (ref)
>   			{
> @@ -3542,11 +3542,11 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>          i < ipa_get_cs_argument_count (args);
>          i++)
>       {
> -      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
> +      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>
>         if (jf->type == IPA_JF_CONST)
>   	{
> -	  struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
> +	  ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
>   	  if (rdesc)
>   	    rdesc->refcount = IPA_UNDESCRIBED_USE;
>   	}
> @@ -3564,13 +3564,13 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>      created.  */
>
>   bool
> -ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
> +ipa_propagate_indirect_call_infos (cgraph_edge *cs,
>   				   vec<cgraph_edge *> *new_edges)
>   {
>     bool changed;
>     /* Do nothing if the preparation phase has not been carried out yet
>        (i.e. during early inlining).  */
> -  if (!ipa_node_params_vector.exists ())
> +  if (!ipa_node_params_summary)
>       return false;
>     gcc_assert (ipa_edge_args_vector);
>
> @@ -3584,7 +3584,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>      to.  */
>
>   void
> -ipa_free_edge_args_substructures (struct ipa_edge_args *args)
> +ipa_free_edge_args_substructures (ipa_edge_args *args)
>   {
>     vec_free (args->jump_functions);
>     memset (args, 0, sizeof (*args));
> @@ -3596,7 +3596,7 @@ void
>   ipa_free_all_edge_args (void)
>   {
>     int i;
> -  struct ipa_edge_args *args;
> +  ipa_edge_args *args;
>
>     if (!ipa_edge_args_vector)
>       return;
> @@ -3610,15 +3610,21 @@ ipa_free_all_edge_args (void)
>   /* Frees all dynamically allocated structures that the param info points
>      to.  */
>
> -void
> -ipa_free_node_params_substructures (struct ipa_node_params *info)
> +ipa_node_params::~ipa_node_params ()
>   {
> -  info->descriptors.release ();
> -  free (info->lattices);
> +  descriptors.release ();
> +  free (lattices);
>     /* Lattice values and their sources are deallocated with their alocation
>        pool.  */
> -  info->known_vals.release ();
> -  memset (info, 0, sizeof (*info));
> +  known_vals.release ();
> +
> +  lattices = NULL;
> +  ipcp_orig_node = NULL;
> +  analysis_done = 0;
> +  node_enqueued = 0;
> +  do_clone_for_all_contexts = 0;
> +  is_all_contexts_clone = 0;
> +  node_dead = 0;
>   }
>
>   /* Free all ipa_node_params structures.  */
> @@ -3626,11 +3632,8 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
>   void
>   ipa_free_all_node_params (void)
>   {
> -  int i;
> -  struct ipa_node_params *info;
> -
> -  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
> -    ipa_free_node_params_substructures (info);
> +  delete ipa_node_params_summary;
> +  ipa_node_params_summary = NULL;
>
>     ipa_node_params_vector.release ();
>   }
> @@ -3638,8 +3641,8 @@ ipa_free_all_node_params (void)
>   /* Set the aggregate replacements of NODE to be AGGVALS.  */
>
>   void
> -ipa_set_node_agg_value_chain (struct cgraph_node *node,
> -			      struct ipa_agg_replacement_value *aggvals)
> +ipa_set_node_agg_value_chain (const cgraph_node *node,
> +			      ipa_agg_replacement_value *aggvals)
>   {
>     if (vec_safe_length (ipa_node_agg_replacements)
>         <= (unsigned) symtab->cgraph_max_uid)
> @@ -3652,9 +3655,9 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
>   /* Hook that is called by cgraph.c when an edge is removed.  */
>
>   static void
> -ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
> +ipa_edge_removal_hook (cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>   {
> -  struct ipa_edge_args *args;
> +  ipa_edge_args *args;
>
>     /* During IPA-CP updating we can be called on not-yet analyzed clones.  */
>     if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
> @@ -3663,11 +3666,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>     args = IPA_EDGE_REF (cs);
>     if (args->jump_functions)
>       {
> -      struct ipa_jump_func *jf;
> +      ipa_jump_func *jf;
>         int i;
>         FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
>   	{
> -	  struct ipa_cst_ref_desc *rdesc;
> +	  ipa_cst_ref_desc *rdesc;
>   	  try_decrement_rdesc_refcount (jf);
>   	  if (jf->type == IPA_JF_CONST
>   	      && (rdesc = ipa_get_jf_constant_rdesc (jf))
> @@ -3679,25 +3682,13 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>     ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
>   }
>
> -/* Hook that is called by cgraph.c when a node is removed.  */
> -
> -static void
> -ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
> -{
> -  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
> -  if (ipa_node_params_vector.length () > (unsigned)node->uid)
> -    ipa_free_node_params_substructures (IPA_NODE_REF (node));
> -  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
> -    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
> -}
> -
>   /* Hook that is called by cgraph.c when an edge is duplicated.  */
>
>   static void
> -ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
> +ipa_edge_duplication_hook (cgraph_edge *src, cgraph_edge *dst,
>   			   __attribute__((unused)) void *data)
>   {
> -  struct ipa_edge_args *old_args, *new_args;
> +  ipa_edge_args *old_args, *new_args;
>     unsigned int i;
>
>     ipa_check_create_edge_args ();
> @@ -3712,20 +3703,20 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>
>     for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
>       {
> -      struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
> -      struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
> +      ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
> +      ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
>
>         dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
>
>         if (src_jf->type == IPA_JF_CONST)
>   	{
> -	  struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
> +	  ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
>
>   	  if (!src_rdesc)
>   	    dst_jf->value.constant.rdesc = NULL;
>   	  else if (src->caller == dst->caller)
>   	    {
> -	      struct ipa_ref *ref;
> +	      ipa_ref *ref;
>   	      symtab_node *n = cgraph_node_for_jfunc (src_jf);
>   	      gcc_checking_assert (n);
>   	      ref = src->caller->find_reference (n, src->call_stmt,
> @@ -3734,8 +3725,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>   	      dst->caller->clone_reference (ref, ref->stmt);
>
>   	      gcc_checking_assert (ipa_refdesc_pool);
> -	      struct ipa_cst_ref_desc *dst_rdesc
> -		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
> +	      ipa_cst_ref_desc *dst_rdesc
> +		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>   	      dst_rdesc->cs = dst;
>   	      dst_rdesc->refcount = src_rdesc->refcount;
>   	      dst_rdesc->next_duplicate = NULL;
> @@ -3743,10 +3734,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>   	    }
>   	  else if (src_rdesc->cs == src)
>   	    {
> -	      struct ipa_cst_ref_desc *dst_rdesc;
> +	      ipa_cst_ref_desc *dst_rdesc;
>   	      gcc_checking_assert (ipa_refdesc_pool);
>   	      dst_rdesc
> -		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
> +		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>   	      dst_rdesc->cs = dst;
>   	      dst_rdesc->refcount = src_rdesc->refcount;
>   	      dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
> @@ -3755,7 +3746,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>   	    }
>   	  else
>   	    {
> -	      struct ipa_cst_ref_desc *dst_rdesc;
> +	      ipa_cst_ref_desc *dst_rdesc;
>   	      /* This can happen during inlining, when a JFUNC can refer to a
>   		 reference taken in a function up in the tree of inline clones.
>   		 We need to find the duplicate that refers to our tree of
> @@ -3766,7 +3757,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>   		   dst_rdesc;
>   		   dst_rdesc = dst_rdesc->next_duplicate)
>   		{
> -		  struct cgraph_node *top;
> +		  cgraph_node *top;
>   		  top = dst_rdesc->cs->caller->global.inlined_to
>   		    ? dst_rdesc->cs->caller->global.inlined_to
>   		    : dst_rdesc->cs->caller;
> @@ -3780,9 +3771,9 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>         else if (dst_jf->type == IPA_JF_PASS_THROUGH
>   	       && src->caller == dst->caller)
>   	{
> -	  struct cgraph_node *inline_root = dst->caller->global.inlined_to
> +	  cgraph_node *inline_root = dst->caller->global.inlined_to
>   	    ? dst->caller->global.inlined_to : dst->caller;
> -	  struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
> +	  ipa_node_params *root_info = IPA_NODE_REF (inline_root);
>   	  int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
>
>   	  int c = ipa_get_controlled_uses (root_info, idx);
> @@ -3795,18 +3786,24 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>       }
>   }
>
> -/* Hook that is called by cgraph.c when a node is duplicated.  */
> +/* Analyze newly added function into callgraph.  */
>
>   static void
> -ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
> -			   ATTRIBUTE_UNUSED void *data)
> +ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>   {
> -  struct ipa_node_params *old_info, *new_info;
> -  struct ipa_agg_replacement_value *old_av, *new_av;
> +  if (node->has_gimple_body_p ())
> +    ipa_analyze_node (node);
> +}
>
> -  ipa_check_create_node_params ();
> -  old_info = IPA_NODE_REF (src);
> -  new_info = IPA_NODE_REF (dst);
> +/* Hook that is called by summary when a node is duplicated.  */
> +
> +void
> +ipa_node_params_cgraph_summary::duplication_hook(cgraph_node *src,
> +						    cgraph_node *dst,
> +						    ipa_node_params *old_info,
> +						    ipa_node_params *new_info)
> +{
> +  ipa_agg_replacement_value *old_av, *new_av;
>
>     new_info->descriptors = old_info->descriptors.copy ();
>     new_info->lattices = NULL;
> @@ -3822,7 +3819,7 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>     new_av = NULL;
>     while (old_av)
>       {
> -      struct ipa_agg_replacement_value *v;
> +      ipa_agg_replacement_value *v;
>
>         v = ggc_alloc<ipa_agg_replacement_value> ();
>         memcpy (v, old_av, sizeof (*v));
> @@ -3833,33 +3830,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>     ipa_set_node_agg_value_chain (dst, new_av);
>   }
>
> -
> -/* Analyze newly added function into callgraph.  */
> -
> -static void
> -ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
> -{
> -  if (node->has_gimple_body_p ())
> -    ipa_analyze_node (node);
> -}
> -
>   /* Register our cgraph hooks if they are not already there.  */
>
>   void
>   ipa_register_cgraph_hooks (void)
>   {
> +  ipa_check_create_node_params ();
> +
>     if (!edge_removal_hook_holder)
>       edge_removal_hook_holder =
>         symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
> -  if (!node_removal_hook_holder)
> -    node_removal_hook_holder =
> -      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
>     if (!edge_duplication_hook_holder)
>       edge_duplication_hook_holder =
>         symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
> -  if (!node_duplication_hook_holder)
> -    node_duplication_hook_holder =
> -      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
>     function_insertion_hook_holder =
>         symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
>   }
> @@ -3871,12 +3854,8 @@ ipa_unregister_cgraph_hooks (void)
>   {
>     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
>     edge_removal_hook_holder = NULL;
> -  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
> -  node_removal_hook_holder = NULL;
>     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
>     edge_duplication_hook_holder = NULL;
> -  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
> -  node_duplication_hook_holder = NULL;
>     symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
>     function_insertion_hook_holder = NULL;
>   }
> @@ -3923,10 +3902,10 @@ ipa_free_all_structures_after_iinln (void)
>      callgraph to F.  */
>
>   void
> -ipa_print_node_params (FILE *f, struct cgraph_node *node)
> +ipa_print_node_params (FILE *f, cgraph_node *node)
>   {
>     int i, count;
> -  struct ipa_node_params *info;
> +  ipa_node_params *info;
>
>     if (!node->definition)
>       return;
> @@ -3957,7 +3936,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
>   void
>   ipa_print_all_params (FILE * f)
>   {
> -  struct cgraph_node *node;
> +  cgraph_node *node;
>
>     fprintf (f, "\nFunction parameters:\n");
>     FOR_EACH_FUNCTION (node)
> @@ -4040,7 +4019,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
>     tree new_arg_types = NULL;
>     for (int i = 0; i < len; i++)
>       {
> -      struct ipa_parm_adjustment *adj;
> +      ipa_parm_adjustment *adj;
>         gcc_assert (link);
>
>         adj = &adjustments[i];
> @@ -4158,10 +4137,10 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
>      contain the corresponding call graph edge.  */
>
>   void
> -ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
> +ipa_modify_call_arguments (cgraph_edge *cs, gimple stmt,
>   			   ipa_parm_adjustment_vec adjustments)
>   {
> -  struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
> +  cgraph_node *current_node = cgraph_node::get (current_function_decl);
>     vec<tree> vargs;
>     vec<tree, va_gc> **debug_args = NULL;
>     gimple new_stmt;
> @@ -4179,7 +4158,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
>     gsi_prev (&prev_gsi);
>     for (i = 0; i < len; i++)
>       {
> -      struct ipa_parm_adjustment *adj;
> +      ipa_parm_adjustment *adj;
>
>         adj = &adjustments[i];
>
> @@ -4412,7 +4391,7 @@ bool
>   ipa_modify_expr (tree *expr, bool convert,
>   		 ipa_parm_adjustment_vec adjustments)
>   {
> -  struct ipa_parm_adjustment *cand
> +  ipa_parm_adjustment *cand
>       = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
>     if (!cand)
>       return false;
> @@ -4500,11 +4479,11 @@ ipa_get_adjustment_candidate (tree **expr, bool *convert,
>     if (!base || TREE_CODE (base) != PARM_DECL)
>       return NULL;
>
> -  struct ipa_parm_adjustment *cand = NULL;
> +  ipa_parm_adjustment *cand = NULL;
>     unsigned int len = adjustments.length ();
>     for (unsigned i = 0; i < len; i++)
>       {
> -      struct ipa_parm_adjustment *adj = &adjustments[i];
> +      ipa_parm_adjustment *adj = &adjustments[i];
>
>         if (adj->base == base
>   	  && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
> @@ -4530,7 +4509,7 @@ index_in_adjustments_multiple_times_p (int base_index,
>
>     for (i = 0; i < len; i++)
>       {
> -      struct ipa_parm_adjustment *adj;
> +      ipa_parm_adjustment *adj;
>         adj = &adjustments[i];
>
>         if (adj->base_index == base_index)
> @@ -4561,7 +4540,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>     tmp.create (inlen);
>     for (i = 0; i < inlen; i++)
>       {
> -      struct ipa_parm_adjustment *n;
> +      ipa_parm_adjustment *n;
>         n = &inner[i];
>
>         if (n->op == IPA_PARM_OP_REMOVE)
> @@ -4577,9 +4556,9 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>     adjustments.create (outlen + removals);
>     for (i = 0; i < outlen; i++)
>       {
> -      struct ipa_parm_adjustment r;
> -      struct ipa_parm_adjustment *out = &outer[i];
> -      struct ipa_parm_adjustment *in = &tmp[out->base_index];
> +      ipa_parm_adjustment r;
> +      ipa_parm_adjustment *out = &outer[i];
> +      ipa_parm_adjustment *in = &tmp[out->base_index];
>
>         memset (&r, 0, sizeof (r));
>         gcc_assert (in->op != IPA_PARM_OP_REMOVE);
> @@ -4616,7 +4595,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>
>     for (i = 0; i < inlen; i++)
>       {
> -      struct ipa_parm_adjustment *n = &inner[i];
> +      ipa_parm_adjustment *n = &inner[i];
>
>         if (n->op == IPA_PARM_OP_REMOVE)
>   	adjustments.quick_push (*n);
> @@ -4640,7 +4619,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
>     fprintf (file, "IPA param adjustments: ");
>     for (i = 0; i < len; i++)
>       {
> -      struct ipa_parm_adjustment *adj;
> +      ipa_parm_adjustment *adj;
>         adj = &adjustments[i];
>
>         if (!first)
> @@ -4683,7 +4662,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
>   /* Dump the AV linked list.  */
>
>   void
> -ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
> +ipa_dump_agg_replacement_values (FILE *f, ipa_agg_replacement_value *av)
>   {
>     bool comma = false;
>     fprintf (f, "     Aggregate replacements:");
> @@ -4700,11 +4679,11 @@ ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
>   /* Stream out jump function JUMP_FUNC to OB.  */
>
>   static void
> -ipa_write_jump_function (struct output_block *ob,
> -			 struct ipa_jump_func *jump_func)
> +ipa_write_jump_function (output_block *ob,
> +			 ipa_jump_func *jump_func)
>   {
> -  struct ipa_agg_jf_item *item;
> -  struct bitpack_d bp;
> +  ipa_agg_jf_item *item;
> +  bitpack_d bp;
>     int i, count;
>
>     streamer_write_uhwi (ob, jump_func->type);
> @@ -4768,10 +4747,10 @@ ipa_write_jump_function (struct output_block *ob,
>   /* Read in jump function JUMP_FUNC from IB.  */
>
>   static void
> -ipa_read_jump_function (struct lto_input_block *ib,
> -			struct ipa_jump_func *jump_func,
> -			struct cgraph_edge *cs,
> -			struct data_in *data_in)
> +ipa_read_jump_function (lto_input_block *ib,
> +			ipa_jump_func *jump_func,
> +			cgraph_edge *cs,
> +			data_in *data_in)
>   {
>     enum jump_func_type jftype;
>     enum tree_code operation;
> @@ -4800,7 +4779,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>         if (operation == NOP_EXPR)
>   	{
>   	  int formal_id =  streamer_read_uhwi (ib);
> -	  struct bitpack_d bp = streamer_read_bitpack (ib);
> +	  bitpack_d bp = streamer_read_bitpack (ib);
>   	  bool agg_preserved = bp_unpack_value (&bp, 1);
>   	  bool type_preserved = bp_unpack_value (&bp, 1);
>   	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
> @@ -4819,7 +4798,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>   	HOST_WIDE_INT offset = streamer_read_uhwi (ib);
>   	tree type = stream_read_tree (ib, data_in);
>   	int formal_id = streamer_read_uhwi (ib);
> -	struct bitpack_d bp = streamer_read_bitpack (ib);
> +	bitpack_d bp = streamer_read_bitpack (ib);
>   	bool agg_preserved = bp_unpack_value (&bp, 1);
>   	bool type_preserved = bp_unpack_value (&bp, 1);
>
> @@ -4833,12 +4812,12 @@ ipa_read_jump_function (struct lto_input_block *ib,
>     vec_alloc (jump_func->agg.items, count);
>     if (count)
>       {
> -      struct bitpack_d bp = streamer_read_bitpack (ib);
> +      bitpack_d bp = streamer_read_bitpack (ib);
>         jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
>       }
>     for (i = 0; i < count; i++)
>       {
> -      struct ipa_agg_jf_item item;
> +      ipa_agg_jf_item item;
>         item.offset = streamer_read_uhwi (ib);
>         item.value = stream_read_tree (ib, data_in);
>         jump_func->agg.items->quick_push (item);
> @@ -4849,11 +4828,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
>      relevant to indirect inlining to OB.  */
>
>   static void
> -ipa_write_indirect_edge_info (struct output_block *ob,
> -			      struct cgraph_edge *cs)
> +ipa_write_indirect_edge_info (output_block *ob,
> +			      cgraph_edge *cs)
>   {
> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
> -  struct bitpack_d bp;
> +  cgraph_indirect_call_info *ii = cs->indirect_info;
> +  bitpack_d bp;
>
>     streamer_write_hwi (ob, ii->param_index);
>     bp = bitpack_create (ob->main_stream);
> @@ -4880,12 +4859,12 @@ ipa_write_indirect_edge_info (struct output_block *ob,
>      relevant to indirect inlining from IB.  */
>
>   static void
> -ipa_read_indirect_edge_info (struct lto_input_block *ib,
> -			     struct data_in *data_in,
> -			     struct cgraph_edge *cs)
> +ipa_read_indirect_edge_info (lto_input_block *ib,
> +			     data_in *data_in,
> +			     cgraph_edge *cs)
>   {
> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
> -  struct bitpack_d bp;
> +  cgraph_indirect_call_info *ii = cs->indirect_info;
> +  bitpack_d bp;
>
>     ii->param_index = (int) streamer_read_hwi (ib);
>     bp = streamer_read_bitpack (ib);
> @@ -4909,14 +4888,14 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
>   /* Stream out NODE info to OB.  */
>
>   static void
> -ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
> +ipa_write_node_info (output_block *ob, cgraph_node *node)
>   {
>     int node_ref;
>     lto_symtab_encoder_t encoder;
> -  struct ipa_node_params *info = IPA_NODE_REF (node);
> +  ipa_node_params *info = IPA_NODE_REF (node);
>     int j;
> -  struct cgraph_edge *e;
> -  struct bitpack_d bp;
> +  cgraph_edge *e;
> +  bitpack_d bp;
>
>     encoder = ob->decl_state->symtab_node_encoder;
>     node_ref = lto_symtab_encoder_encode (encoder, node);
> @@ -4937,7 +4916,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>       streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
>     for (e = node->callees; e; e = e->next_callee)
>       {
> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>
>         streamer_write_uhwi (ob,
>   			   ipa_get_cs_argument_count (args) * 2
> @@ -4951,7 +4930,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>       }
>     for (e = node->indirect_calls; e; e = e->next_callee)
>       {
> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>
>         streamer_write_uhwi (ob,
>   			   ipa_get_cs_argument_count (args) * 2
> @@ -4969,13 +4948,13 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>   /* Stream in NODE info from IB.  */
>
>   static void
> -ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
> -		    struct data_in *data_in)
> +ipa_read_node_info (lto_input_block *ib, cgraph_node *node,
> +		    data_in *data_in)
>   {
> -  struct ipa_node_params *info = IPA_NODE_REF (node);
> +  ipa_node_params *info = IPA_NODE_REF (node);
>     int k;
> -  struct cgraph_edge *e;
> -  struct bitpack_d bp;
> +  cgraph_edge *e;
> +  bitpack_d bp;
>
>     ipa_alloc_node_params (node, streamer_read_uhwi (ib));
>
> @@ -4992,7 +4971,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>       ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
>     for (e = node->callees; e; e = e->next_callee)
>       {
> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>         int count = streamer_read_uhwi (ib);
>         bool contexts_computed = count & 1;
>         count /= 2;
> @@ -5013,7 +4992,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>       }
>     for (e = node->indirect_calls; e; e = e->next_callee)
>       {
> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>         int count = streamer_read_uhwi (ib);
>         bool contexts_computed = count & 1;
>         count /= 2;
> @@ -5040,14 +5019,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>   void
>   ipa_prop_write_jump_functions (void)
>   {
> -  struct cgraph_node *node;
> -  struct output_block *ob;
> +  cgraph_node *node;
> +  output_block *ob;
>     unsigned int count = 0;
>     lto_symtab_encoder_iterator lsei;
>     lto_symtab_encoder_t encoder;
>
> -
> -  if (!ipa_node_params_vector.exists ())
> +  if (!ipa_node_params_summary)
>       return;
>
>     ob = create_output_block (LTO_section_jump_functions);
> @@ -5081,15 +5059,15 @@ ipa_prop_write_jump_functions (void)
>   /* Read section in file FILE_DATA of length LEN with data DATA.  */
>
>   static void
> -ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
> +ipa_prop_read_section (lto_file_decl_data *file_data, const char *data,
>   		       size_t len)
>   {
> -  const struct lto_function_header *header =
> -    (const struct lto_function_header *) data;
> -  const int cfg_offset = sizeof (struct lto_function_header);
> +  const lto_function_header *header =
> +    (const lto_function_header *) data;
> +  const int cfg_offset = sizeof (lto_function_header);
>     const int main_offset = cfg_offset + header->cfg_size;
>     const int string_offset = main_offset + header->main_size;
> -  struct data_in *data_in;
> +  data_in *data_in;
>     unsigned int i;
>     unsigned int count;
>
> @@ -5104,7 +5082,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>     for (i = 0; i < count; i++)
>       {
>         unsigned int index;
> -      struct cgraph_node *node;
> +      cgraph_node *node;
>         lto_symtab_encoder_t encoder;
>
>         index = streamer_read_uhwi (&ib_main);
> @@ -5124,8 +5102,8 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>   void
>   ipa_prop_read_jump_functions (void)
>   {
> -  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
> -  struct lto_file_decl_data *file_data;
> +  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
> +  lto_file_decl_data *file_data;
>     unsigned int j = 0;
>
>     ipa_check_create_node_params ();
> @@ -5154,12 +5132,12 @@ ipa_update_after_lto_read (void)
>   }
>
>   void
> -write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
> +write_agg_replacement_chain (output_block *ob, cgraph_node *node)
>   {
>     int node_ref;
>     unsigned int count = 0;
>     lto_symtab_encoder_t encoder;
> -  struct ipa_agg_replacement_value *aggvals, *av;
> +  ipa_agg_replacement_value *aggvals, *av;
>
>     aggvals = ipa_get_agg_replacements_for_node (node);
>     encoder = ob->decl_state->symtab_node_encoder;
> @@ -5172,7 +5150,7 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>
>     for (av = aggvals; av; av = av->next)
>       {
> -      struct bitpack_d bp;
> +      bitpack_d bp;
>
>         streamer_write_uhwi (ob, av->offset);
>         streamer_write_uhwi (ob, av->index);
> @@ -5187,18 +5165,18 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>   /* Stream in the aggregate value replacement chain for NODE from IB.  */
>
>   static void
> -read_agg_replacement_chain (struct lto_input_block *ib,
> -			    struct cgraph_node *node,
> -			    struct data_in *data_in)
> +read_agg_replacement_chain (lto_input_block *ib,
> +			    cgraph_node *node,
> +			    data_in *data_in)
>   {
> -  struct ipa_agg_replacement_value *aggvals = NULL;
> +  ipa_agg_replacement_value *aggvals = NULL;
>     unsigned int count, i;
>
>     count = streamer_read_uhwi (ib);
>     for (i = 0; i <count; i++)
>       {
> -      struct ipa_agg_replacement_value *av;
> -      struct bitpack_d bp;
> +      ipa_agg_replacement_value *av;
> +      bitpack_d bp;
>
>         av = ggc_alloc<ipa_agg_replacement_value> ();
>         av->offset = streamer_read_uhwi (ib);
> @@ -5217,8 +5195,8 @@ read_agg_replacement_chain (struct lto_input_block *ib,
>   void
>   ipa_prop_write_all_agg_replacement (void)
>   {
> -  struct cgraph_node *node;
> -  struct output_block *ob;
> +  cgraph_node *node;
> +  output_block *ob;
>     unsigned int count = 0;
>     lto_symtab_encoder_iterator lsei;
>     lto_symtab_encoder_t encoder;
> @@ -5257,16 +5235,16 @@ ipa_prop_write_all_agg_replacement (void)
>      DATA.  */
>
>   static void
> -read_replacements_section (struct lto_file_decl_data *file_data,
> +read_replacements_section (lto_file_decl_data *file_data,
>   			   const char *data,
>   			   size_t len)
>   {
> -  const struct lto_function_header *header =
> -    (const struct lto_function_header *) data;
> -  const int cfg_offset = sizeof (struct lto_function_header);
> +  const lto_function_header *header =
> +    (const lto_function_header *) data;
> +  const int cfg_offset = sizeof (lto_function_header);
>     const int main_offset = cfg_offset + header->cfg_size;
>     const int string_offset = main_offset + header->main_size;
> -  struct data_in *data_in;
> +  data_in *data_in;
>     unsigned int i;
>     unsigned int count;
>
> @@ -5280,7 +5258,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
>     for (i = 0; i < count; i++)
>       {
>         unsigned int index;
> -      struct cgraph_node *node;
> +      cgraph_node *node;
>         lto_symtab_encoder_t encoder;
>
>         index = streamer_read_uhwi (&ib_main);
> @@ -5300,8 +5278,8 @@ read_replacements_section (struct lto_file_decl_data *file_data,
>   void
>   ipa_prop_read_all_agg_replacement (void)
>   {
> -  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
> -  struct lto_file_decl_data *file_data;
> +  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
> +  lto_file_decl_data *file_data;
>     unsigned int j = 0;
>
>     while ((file_data = file_data_vec[j++]))
> @@ -5319,10 +5297,10 @@ ipa_prop_read_all_agg_replacement (void)
>      NODE.  */
>
>   static void
> -adjust_agg_replacement_values (struct cgraph_node *node,
> -			       struct ipa_agg_replacement_value *aggval)
> +adjust_agg_replacement_values (cgraph_node *node,
> +			       ipa_agg_replacement_value *aggval)
>   {
> -  struct ipa_agg_replacement_value *v;
> +  ipa_agg_replacement_value *v;
>     int i, c = 0, d = 0, *adj;
>
>     if (!node->clone.combined_args_to_skip)
> @@ -5355,9 +5333,9 @@ adjust_agg_replacement_values (struct cgraph_node *node,
>   class ipcp_modif_dom_walker : public dom_walker
>   {
>   public:
> -  ipcp_modif_dom_walker (struct func_body_info *fbi,
> +  ipcp_modif_dom_walker (func_body_info *fbi,
>   			 vec<ipa_param_descriptor> descs,
> -			 struct ipa_agg_replacement_value *av,
> +			 ipa_agg_replacement_value *av,
>   			 bool *sc, bool *cc)
>       : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
>         m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
> @@ -5365,9 +5343,9 @@ public:
>     virtual void before_dom_children (basic_block);
>
>   private:
> -  struct func_body_info *m_fbi;
> +  func_body_info *m_fbi;
>     vec<ipa_param_descriptor> m_descriptors;
> -  struct ipa_agg_replacement_value *m_aggval;
> +  ipa_agg_replacement_value *m_aggval;
>     bool *m_something_changed, *m_cfg_changed;
>   };
>
> @@ -5377,7 +5355,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
>     gimple_stmt_iterator gsi;
>     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>       {
> -      struct ipa_agg_replacement_value *v;
> +      ipa_agg_replacement_value *v;
>         gimple stmt = gsi_stmt (gsi);
>         tree rhs, val, t;
>         HOST_WIDE_INT offset, size;
> @@ -5468,11 +5446,11 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
>   /* IPCP transformation phase doing propagation of aggregate values.  */
>
>   unsigned int
> -ipcp_transform_function (struct cgraph_node *node)
> +ipcp_transform_function (cgraph_node *node)
>   {
>     vec<ipa_param_descriptor> descriptors = vNULL;
> -  struct func_body_info fbi;
> -  struct ipa_agg_replacement_value *aggval;
> +  func_body_info fbi;
> +  ipa_agg_replacement_value *aggval;
>     int param_count;
>     bool cfg_changed = false, something_changed = false;
>
> @@ -5507,7 +5485,7 @@ ipcp_transform_function (struct cgraph_node *node)
>   			 &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
>
>     int i;
> -  struct ipa_bb_info *bi;
> +  ipa_bb_info *bi;
>     FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
>       free_ipa_bb_info (bi);
>     fbi.bb_infos.release ();
> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
> index 165fc1a..6c3b31f 100644
> --- a/gcc/ipa-prop.h
> +++ b/gcc/ipa-prop.h
> @@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
>   #ifndef IPA_PROP_H
>   #define IPA_PROP_H
>
> -
>   /* The following definitions and interfaces are used by
>      interprocedural analyses or parameters.  */
>
> @@ -356,6 +355,8 @@ struct ipcp_lattice;
>
>   struct ipa_node_params
>   {
> +  ~ipa_node_params ();
> +
>     /* Information about individual formal parameters that are gathered when
>        summaries are generated. */
>     vec<ipa_param_descriptor> descriptors;
> @@ -364,7 +365,7 @@ struct ipa_node_params
>     struct ipcp_param_lattices *lattices;
>     /* Only for versioned nodes this field would not be NULL,
>        it points to the node that IPA cp cloned from.  */
> -  struct cgraph_node *ipcp_orig_node;
> +  cgraph_node *ipcp_orig_node;
>     /* If this node is an ipa-cp clone, these are the known values that describe
>        what it has been specialized for.  */
>     vec<tree> known_vals;
> @@ -470,7 +471,7 @@ struct GTY(()) ipa_agg_replacement_value
>
>   typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
>
> -void ipa_set_node_agg_value_chain (struct cgraph_node *node,
> +void ipa_set_node_agg_value_chain (const cgraph_node *node,
>   				   struct ipa_agg_replacement_value *aggvals);
>
>   /* ipa_edge_args stores information related to a callsite and particularly its
> @@ -513,10 +514,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
>     return &(*args->polymorphic_call_contexts)[i];
>   }
>
> -/* Types of vectors holding the infos.  */
> +/* Callgraph summary for ipa_node_params.  */
> +class ipa_node_params_cgraph_summary: public cgraph_summary <ipa_node_params *>
> +{
> +public:
> +  ipa_node_params_cgraph_summary (symbol_table *table):
> +    cgraph_summary <ipa_node_params *> (table) { }
> +
> +  /* Hook that is called by summary when a node is duplicated.  */
> +  virtual void duplication_hook (cgraph_node *node,
> +				 cgraph_node *node2,
> +				 ipa_node_params *data,
> +				 ipa_node_params *data2);
> +};
>
>   /* Vector where the parameter infos are actually stored. */
> -extern vec<ipa_node_params> ipa_node_params_vector;
> +extern ipa_node_params_cgraph_summary *ipa_node_params_summary;
>   /* Vector of known aggregate values in cloned nodes.  */
>   extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>   /* Vector where the parameter infos are actually stored. */
> @@ -524,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>
>   /* Return the associated parameter/argument info corresponding to the given
>      node/edge.  */
> -#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
> +#define IPA_NODE_REF(NODE) ((*ipa_node_params_summary)[NODE])
>   #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
>   /* This macro checks validity of index returned by
>      ipa_get_param_decl_index function.  */
> @@ -534,11 +547,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>   void ipa_create_all_node_params (void);
>   void ipa_create_all_edge_args (void);
>   void ipa_free_edge_args_substructures (struct ipa_edge_args *);
> -void ipa_free_node_params_substructures (struct ipa_node_params *);
>   void ipa_free_all_node_params (void);
>   void ipa_free_all_edge_args (void);
>   void ipa_free_all_structures_after_ipa_cp (void);
>   void ipa_free_all_structures_after_iinln (void);
> +
>   void ipa_register_cgraph_hooks (void);
>   int count_formal_params (tree fndecl);
>
> @@ -548,11 +561,8 @@ int count_formal_params (tree fndecl);
>   static inline void
>   ipa_check_create_node_params (void)
>   {
> -  if (!ipa_node_params_vector.exists ())
> -    ipa_node_params_vector.create (symtab->cgraph_max_uid);
> -
> -  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
> -    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
> +  if (!ipa_node_params_summary)
> +    ipa_node_params_summary = new ipa_node_params_cgraph_summary (symtab);
>   }
>
>   /* This function ensures the array of edge arguments infos is big enough to
> @@ -579,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
>   /* Return the aggregate replacements for NODE, if there are any.  */
>
>   static inline struct ipa_agg_replacement_value *
> -ipa_get_agg_replacements_for_node (struct cgraph_node *node)
> +ipa_get_agg_replacements_for_node (const cgraph_node *node)
>   {
>     if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
>       return NULL;
> @@ -587,7 +597,7 @@ ipa_get_agg_replacements_for_node (struct cgraph_node *node)
>   }
>
>   /* Function formal parameters related computations.  */
> -void ipa_initialize_node_params (struct cgraph_node *node);
> +void ipa_initialize_node_params (const cgraph_node *node);
>   bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>   					vec<cgraph_edge *> *new_edges);
>
> @@ -602,7 +612,7 @@ tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
>   tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
>
>   /* Functions related to both.  */
> -void ipa_analyze_node (struct cgraph_node *);
> +void ipa_analyze_node (cgraph_node *);
>
>   /* Aggregate jump function related functions.  */
>   tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
> @@ -611,9 +621,9 @@ bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
>   			     HOST_WIDE_INT *, bool *);
>
>   /* Debugging interface.  */
> -void ipa_print_node_params (FILE *, struct cgraph_node *node);
> +void ipa_print_node_params (FILE *, cgraph_node *node);
>   void ipa_print_all_params (FILE *);
> -void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
> +void ipa_print_node_jump_functions (FILE *f, cgraph_node *node);
>   void ipa_print_all_jump_functions (FILE * f);
>   void ipcp_verify_propagated_values (void);
>
> @@ -717,7 +727,7 @@ void ipa_update_after_lto_read (void);
>   int ipa_get_param_decl_index (struct ipa_node_params *, tree);
>   tree ipa_value_from_jfunc (struct ipa_node_params *info,
>   			   struct ipa_jump_func *jfunc);
> -unsigned int ipcp_transform_function (struct cgraph_node *node);
> +unsigned int ipcp_transform_function (cgraph_node *node);
>   void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
>   bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
>   ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
> index 98dbc63..0a7ca53 100644
> --- a/gcc/ipa-split.c
> +++ b/gcc/ipa-split.c
> @@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "gimple-ssa.h"
>   #include "tree-cfg.h"
> diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
> index 22900cc..83111bc 100644
> --- a/gcc/ipa-utils.c
> +++ b/gcc/ipa-utils.c
> @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "langhooks.h"
>   #include "lto-streamer.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>
> diff --git a/gcc/ipa.c b/gcc/ipa.c
> index a6086d8..aded512 100644
> --- a/gcc/ipa.c
> +++ b/gcc/ipa.c
> @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "tree-iterator.h"
>   #include "ipa-utils.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "tree-inline.h"
> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
> index 0e1a95b..37d0f39 100644
> --- a/gcc/lto/lto-partition.c
> +++ b/gcc/lto/lto-partition.c
> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "timevar.h"
>   #include "params.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "ipa-utils.h"
> diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
> index 4c4e48a..ee97d06 100644
> --- a/gcc/lto/lto-symtab.c
> +++ b/gcc/lto/lto-symtab.c
> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "lto-streamer.h"
>   #include "ipa-utils.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "ipa-inline.h"
>   #include "builtins.h"
> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
> index d8519d9..c99dbdf 100644
> --- a/gcc/lto/lto.c
> +++ b/gcc/lto/lto.c
> @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "bitmap.h"
>   #include "inchash.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "common.h"
>   #include "debug.h"
> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
> index b59d069..707379a 100644
> --- a/gcc/omp-low.c
> +++ b/gcc/omp-low.c
> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "tree-cfgcleanup.h"
>   #include "pretty-print.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "tree-nested.h"
>   #include "tree-eh.h"
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index 8cb9510..a8e3561 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "ipa-ref.h"
>   #include "cgraph.h"
>   #include "alloc-pool.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "value-prof.h"
>   #include "tree-pass.h"
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index 1e629bc..99b19b8 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "plugin-api.h"
>   #include "ipa-ref.h"
>   #include "cgraph.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "statistics.h"
>   #include "params.h"
> diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
> index ea99198..b526cc9 100644
> --- a/gcc/tree-ssa-pre.c
> +++ b/gcc/tree-ssa-pre.c
> @@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
>   #include "plugin-api.h"
>   #include "ipa-ref.h"
>   #include "cgraph.h"
> +#include "cgraph_summary.h"
>   #include "ipa-prop.h"
>   #include "tree-ssa-propagate.h"
>   #include "ipa-utils.h"
>

Patch v2.

Martin

[-- Attachment #2: 0002-First-usage-of-cgraph_summary-in-ipa-prop-pass.patch --]
[-- Type: text/x-patch, Size: 99482 bytes --]

From 1016bec95eac5eebb5303d2d118bc4a095a73574 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Tue, 11 Nov 2014 13:26:07 +0100
Subject: [PATCH 2/3] First usage of cgraph_summary in ipa-prop pass.

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* auto-profile.c: Include symbol-summary.h.
	* cgraph.c: Likewise.
	* cgraphbuild.c: Likewise.
	* cgraphclones.c: Likewise.
	* cgraphunit.c: Likewise.
	* ipa-cp.c: Likewise.
	* ipa-devirt.c: Likewise.
	* ipa-icf.c: Likewise.
	* ipa-inline-analysis.c (evaluate_properties_for_edge): Usage of
	ipa_node_params_vector is replaced with ipa_node_params_t.
	(inline_node_duplication_hook): Likewise.
	(estimate_function_body_sizes): Likewise.
	(remap_edge_change_prob): Likewise.
	(inline_merge_summary): Likewise.
	* ipa-inline-transform.c: Include of symbol-summary.h.
	* ipa-inline.c (early_inliner): Usage of
	ipa_node_params_vector is replaced with ipa_node_params_t.
	* ipa-polymorphic-call.c: Include of symbol-summary.h.
	* ipa-profile.c: Include of symbol-summary.h.
	* ipa-prop.c (struct func_body_info): Struct keyword is removed.
	(struct ipa_cst_ref_desc): Likewise.
	(ipa_func_spec_opts_forbid_analysis_p): Likewise.
	(ipa_alloc_node_params): Likewise.
	(ipa_initialize_node_params): Likewise.
	(ipa_print_node_jump_functions_for_edge): Likewise.
	(ipa_print_node_jump_functions): Likewise.
	(ipa_print_all_jump_functions): Likewise.
	(ipa_set_jf_constant): Likewise.
	(check_stmt_for_type_change): Likewise.
	(detect_type_change_from_memory_writes): Likewise.
	(find_dominating_aa_status): Likewise.
	(parm_bb_aa_status_for_bb): Likewise.
	(parm_preserved_before_stmt_p): Likewise.
	(parm_ref_data_preserved_p): Likewise.
	(parm_ref_data_pass_through_p): Likewise.
	(struct ipa_known_agg_contents_list): Likewise.
	(get_place_in_agg_contents_list): Likewise.
	(build_agg_jump_func_from_list): Likewise.
	(determine_locally_known_aggregate_parts): Likewise.
	(ipa_compute_jump_functions_for_edge): Likewise.
	(ipa_compute_jump_functions_for_bb): Likewise.
	(ipa_note_param_call): Likewise.
	(ipa_analyze_indirect_call_uses) Likewise.:
	(ipa_analyze_virtual_call_uses): Likewise.
	(ipa_analyze_call_uses): Likewise.
	(visit_ref_for_mod_analysis): Likewise.
	(ipa_analyze_controlled_uses): Likewise.
	(ipa_analyze_node): Likewise.
	(update_jump_functions_after_inlining): Likewise.
	(ipa_make_edge_direct_to_target): Likewise.
	(ipa_find_agg_cst_for_param): Likewise.
	(remove_described_reference): Likewise.
	(jfunc_rdesc_usable): Likewise.
	(try_decrement_rdesc_refcount): Likewise.
	(try_make_edge_direct_simple_call): Likewise.
	(try_make_edge_direct_virtual_call): Likewise.
	(update_indirect_edges_after_inlining): Likewise.
	(propagate_info_to_inlined_callees): Likewise.
	(propagate_controlled_uses): Likewise.
	(ipa_propagate_indirect_call_infos): Likewise.
	(ipa_free_all_edge_args): Likewise.
	(ipa_node_params::~ipa_node_params): Likewise.
	(ipa_free_all_node_params): Likewise.
	(ipa_edge_removal_hook): Likewise.
	(ipa_node_removal_hook): Likewise.
	(ipa_edge_duplication_hook): Likewise.
	(ipa_add_new_function): Removed
	(ipa_node_params_t::duplicate): New function.
	(ipa_node_duplication_hook): Struct keyword removed.
	(ipa_register_cgraph_hooks): Removal of old hooks.
	(ipa_unregister_cgraph_hooks): Likewise.
	(ipa_print_node_params): Struct keyword is removed.
	(ipa_print_all_params): Likewise.
	(ipa_modify_formal_parameters): Likewise.
	(ipa_modify_call_arguments): Likewise.
	(ipa_modify_expr): Likewise.
	(ipa_get_adjustment_candidate): Likewise.
	(index_in_adjustments_multiple_times_p): Likewise.
	(ipa_combine_adjustments): Likewise.
	(ipa_dump_param_adjustments): Likewise.
	(ipa_write_jump_function): Likewise.
	(ipa_read_jump_function): Likewise.
	(ipa_write_indirect_edge_info): Likewise.
	(ipa_read_indirect_edge_info): Likewise.
	(ipa_write_node_info): Likewise.
	(ipa_read_node_info): Likewise.
	(ipa_prop_write_jump_functions): Likewise.
	(ipa_prop_read_section): Likewise.
	(ipa_prop_read_jump_functions): Likewise.
	(write_agg_replacement_chain): Likewise.
	(read_agg_replacement_chain): Likewise.
	(ipa_prop_write_all_agg_replacement): Likewise.
	(read_replacements_section): Likewise.
	(ipa_prop_read_all_agg_replacement): Likewise.
	(adjust_agg_replacement_values): Likewise.
	(ipcp_modif_dom_walker::before_dom_children): Likewise.
	(ipcp_transform_function): Likewise.
	* ipa-prop.h (struct ipa_node_params): Introduction of new class
	ipa_node_params_t.
	* ipa-split.c: Include symbol-summary.h.
	* ipa-utils.c: Likewise.
	* ipa.c: Likewise.
	* omp-low.c: Likewise.
	* tree-inline.c: Likewise.
	* tree-sra.c: Likewise.
	* tree-ssa-pre.c: Likewise.

gcc/lto/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* lto-partition.c: Include symbol-summary.h.
	* lto-symtab.c: Likewise.
	* lto.c: Likewise.
---
 gcc/auto-profile.c         |   1 +
 gcc/cgraph.c               |   1 +
 gcc/cgraphbuild.c          |   1 +
 gcc/cgraphclones.c         |   1 +
 gcc/cgraphunit.c           |   1 +
 gcc/gengtype.c             |   2 +-
 gcc/ipa-cp.c               |   1 +
 gcc/ipa-devirt.c           |   1 +
 gcc/ipa-icf.c              |   1 +
 gcc/ipa-inline-analysis.c  |  13 +-
 gcc/ipa-inline-transform.c |   1 +
 gcc/ipa-inline.c           |   3 +-
 gcc/ipa-polymorphic-call.c |   1 +
 gcc/ipa-profile.c          |   1 +
 gcc/ipa-prop.c             | 702 ++++++++++++++++++++++-----------------------
 gcc/ipa-prop.h             |  48 ++--
 gcc/ipa-split.c            |   1 +
 gcc/ipa-utils.c            |   1 +
 gcc/ipa.c                  |   1 +
 gcc/lto/lto-partition.c    |   1 +
 gcc/lto/lto-symtab.c       |   1 +
 gcc/lto/lto.c              |   1 +
 gcc/omp-low.c              |   1 +
 gcc/symbol-summary.h       |   6 +-
 gcc/tree-inline.c          |   1 +
 gcc/tree-sra.c             |   1 +
 gcc/tree-ssa-pre.c         |   1 +
 27 files changed, 401 insertions(+), 394 deletions(-)

diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index 8c7b4ca..3119d04 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coverage.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 7216b89..d60c610 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index c72ceab..007c386 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "except.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index c8892da..5091b3b 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-dump.h"
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 25af234..93f8d91 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -204,6 +204,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-pass.h"
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 1e2db27..0161004 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1842,7 +1842,7 @@ open_base_files (void)
       "tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h", 
       "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
-      "target-globals.h", "ipa-ref.h", "cgraph.h", "function-summary.h",
+      "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h",
       "ipa-prop.h", "ipa-inline.h", "dwarf2out.h", NULL
     };
     const char *const *ifp;
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 47f9f5c..56d1ae9 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 32c6549..0be721b 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 92ec82d..e8892d4 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index eb1c6ec..84da4dc 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
@@ -910,7 +911,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
   if (known_binfos_ptr)
     known_binfos_ptr->create (0);
 
-  if (ipa_node_params_vector.exists ()
+  if (ipa_node_params_d
       && !e->call_stmt_cannot_inline_p
       && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr))
     {
@@ -1130,7 +1131,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
 
   /* When there are any replacements in the function body, see if we can figure
      out that something was optimized out.  */
-  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
+  if (ipa_node_params_d && dst->clone.tree_map)
     {
       vec<size_time_entry, va_gc> *entry = info->entry;
       /* Use SRC parm info since it may not be copied yet.  */
@@ -2476,7 +2477,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
       calculate_dominance_info (CDI_DOMINATORS);
       loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
 
-      if (ipa_node_params_vector.exists ())
+      if (ipa_node_params_d)
 	{
 	  parms_info = IPA_NODE_REF (node);
 	  nonconstant_names.safe_grow_cleared
@@ -2624,7 +2625,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 		  nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
 		    = false_p;
 		}
-	      if (ipa_node_params_vector.exists ())
+	      if (ipa_node_params_d)
 		{
 		  int count = gimple_call_num_args (stmt);
 		  int i;
@@ -3367,7 +3368,7 @@ static void
 remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 			struct cgraph_edge *edge)
 {
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_d)
     {
       int i;
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
@@ -3523,7 +3524,7 @@ inline_merge_summary (struct cgraph_edge *edge)
   else
     toplev_predicate = true_predicate ();
 
-  if (ipa_node_params_vector.exists () && callee_info->conds)
+  if (ipa_node_params_d && callee_info->conds)
     {
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
       int count = ipa_get_cs_argument_count (args);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index dbc56c5..49c2679 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 5c97815..a8e94e2 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "except.h"
 #include "target.h"
@@ -2400,7 +2401,7 @@ early_inliner (function *fun)
      it.  This may confuse ourself when early inliner decide to inline call to
      function clone, because function clones don't have parameter list in
      ipa-prop matching their signature.  */
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_d)
     return 0;
 
 #ifdef ENABLE_CHECKING
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 33dd1a8..ea7f9a6 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index b83d1cf..ddbc17a 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index db85c7d..c356845 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "gimple-ssa.h"
@@ -119,7 +120,7 @@ struct func_body_info
   cgraph_node *node;
 
   /* Its info.  */
-  struct ipa_node_params *info;
+  ipa_node_params *info;
 
   /* Information about individual BBs. */
   vec<ipa_bb_info> bb_infos;
@@ -131,27 +132,25 @@ struct func_body_info
   unsigned int aa_walked;
 };
 
-/* Vector where the parameter infos are actually stored. */
-vec<ipa_node_params> ipa_node_params_vector;
+/* Function summary where the parameter infos are actually stored. */
+ipa_node_params_t *ipa_node_params_d = NULL;
 /* Vector of known aggregate values in cloned nodes.  */
 vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
 vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
+static cgraph_edge_hook_list *edge_removal_hook_holder;
+static cgraph_2edge_hook_list *edge_duplication_hook_holder;
+static cgraph_node_hook_list *function_insertion_hook_holder;
 
 /* Description of a reference to an IPA constant.  */
 struct ipa_cst_ref_desc
 {
   /* Edge that corresponds to the statement which took the reference.  */
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   /* Linked list of duplicates created when call graph edges are cloned.  */
-  struct ipa_cst_ref_desc *next_duplicate;
+  ipa_cst_ref_desc *next_duplicate;
   /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
      if out of control.  */
   int refcount;
@@ -165,10 +164,10 @@ static alloc_pool ipa_refdesc_pool;
    with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
 
 static bool
-ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
+ipa_func_spec_opts_forbid_analysis_p (cgraph_node *node)
 {
   tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
-  struct cl_optimization *os;
+  cl_optimization *os;
 
   if (!fs_opts)
     return false;
@@ -196,7 +195,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
    to INFO.  */
 
 int
-ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
+ipa_get_param_decl_index (ipa_node_params *info, tree ptree)
 {
   return ipa_get_param_decl_index_1 (info->descriptors, ptree);
 }
@@ -205,7 +204,7 @@ ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
    NODE.  */
 
 static void
-ipa_populate_param_decls (struct cgraph_node *node,
+ipa_populate_param_decls (cgraph_node *node,
 			  vec<ipa_param_descriptor> &descriptors)
 {
   tree fndecl;
@@ -246,7 +245,7 @@ count_formal_params (tree fndecl)
    using ipa_initialize_node_params. */
 
 void
-ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
+ipa_dump_param (FILE *file, ipa_node_params *info, int i)
 {
   fprintf (file, "param #%i", i);
   if (info->descriptors[i].decl)
@@ -260,9 +259,9 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
    to hold PARAM_COUNT parameters.  */
 
 void
-ipa_alloc_node_params (struct cgraph_node *node, int param_count)
+ipa_alloc_node_params (cgraph_node *node, int param_count)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   if (!info->descriptors.exists () && param_count)
     info->descriptors.safe_grow_cleared (param_count);
@@ -273,9 +272,9 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
    param_decls.  */
 
 void
-ipa_initialize_node_params (struct cgraph_node *node)
+ipa_initialize_node_params (cgraph_node *node)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   if (!info->descriptors.exists ())
     {
@@ -287,14 +286,14 @@ ipa_initialize_node_params (struct cgraph_node *node)
 /* Print the jump functions associated with call graph edge CS to file F.  */
 
 static void
-ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
+ipa_print_node_jump_functions_for_edge (FILE *f, cgraph_edge *cs)
 {
   int i, count;
 
   count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *jump_func;
+      ipa_jump_func *jump_func;
       enum jump_func_type type;
 
       jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
@@ -360,7 +359,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 
       if (jump_func->agg.items)
 	{
-	  struct ipa_agg_jf_item *item;
+	  ipa_agg_jf_item *item;
 	  int j;
 
 	  fprintf (f, "         Aggregate passed by %s:\n",
@@ -390,9 +389,9 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
    NODE to file F.  */
 
 void
-ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
+ipa_print_node_jump_functions (FILE *f, cgraph_node *node)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   fprintf (f, "  Jump functions of caller  %s/%i:\n", node->name (),
 	   node->order);
@@ -410,7 +409,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 
   for (cs = node->indirect_calls; cs; cs = cs->next_callee)
     {
-      struct cgraph_indirect_call_info *ii;
+      cgraph_indirect_call_info *ii;
       if (!ipa_edge_args_info_available_for_edge_p (cs))
 	continue;
 
@@ -445,7 +444,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 void
 ipa_print_all_jump_functions (FILE *f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "\nJump functions:\n");
   FOR_EACH_FUNCTION (node)
@@ -457,7 +456,7 @@ ipa_print_all_jump_functions (FILE *f)
 /* Set JFUNC to be a known type jump function.  */
 
 static void
-ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
+ipa_set_jf_known_type (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
 		       tree base_type, tree component_type)
 {
   /* Recording and propagating main variants increases change that types
@@ -480,8 +479,8 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
    combination code).  The two functions will share their rdesc.  */
 
 static void
-ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
-		     struct ipa_jump_func *src)
+ipa_set_jf_cst_copy (ipa_jump_func *dst,
+		     ipa_jump_func *src)
 
 {
   gcc_checking_assert (src->type == IPA_JF_CONST);
@@ -492,8 +491,8 @@ ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
 /* Set JFUNC to be a constant jmp function.  */
 
 static void
-ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
-		     struct cgraph_edge *cs)
+ipa_set_jf_constant (ipa_jump_func *jfunc, tree constant,
+		     cgraph_edge *cs)
 {
   constant = unshare_expr (constant);
   if (constant && EXPR_P (constant))
@@ -504,12 +503,12 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
   if (TREE_CODE (constant) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
     {
-      struct ipa_cst_ref_desc *rdesc;
+      ipa_cst_ref_desc *rdesc;
       if (!ipa_refdesc_pool)
 	ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
-					sizeof (struct ipa_cst_ref_desc), 32);
+					sizeof (ipa_cst_ref_desc), 32);
 
-      rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+      rdesc = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
       rdesc->cs = cs;
       rdesc->next_duplicate = NULL;
       rdesc->refcount = 1;
@@ -521,7 +520,7 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
 
 /* Set JFUNC to be a simple pass-through jump function.  */
 static void
-ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+ipa_set_jf_simple_pass_through (ipa_jump_func *jfunc, int formal_id,
 				bool agg_preserved, bool type_preserved)
 {
   jfunc->type = IPA_JF_PASS_THROUGH;
@@ -535,7 +534,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 /* Set JFUNC to be an arithmetic pass through jump function.  */
 
 static void
-ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+ipa_set_jf_arith_pass_through (ipa_jump_func *jfunc, int formal_id,
 			       tree operand, enum tree_code operation)
 {
   jfunc->type = IPA_JF_PASS_THROUGH;
@@ -549,7 +548,7 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 /* Set JFUNC to be an ancestor jump function.  */
 
 static void
-ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
+ipa_set_ancestor_jf (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
 		     tree type, int formal_id, bool agg_preserved,
 		     bool type_preserved)
 {
@@ -572,7 +571,7 @@ ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
    jump function.  */
 
 tree
-ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
+ipa_binfo_from_known_type_jfunc (ipa_jump_func *jfunc)
 {
   if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
     return NULL_TREE;
@@ -602,8 +601,8 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
 /* Get IPA BB information about the given BB.  FBI is the context of analyzis
    of this function body.  */
 
-static struct ipa_bb_info *
-ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
+static ipa_bb_info *
+ipa_get_bb_info (func_body_info *fbi, basic_block bb)
 {
   gcc_checking_assert (fbi);
   return &fbi->bb_infos[bb->index];
@@ -700,7 +699,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
    identified, return the type.  Otherwise return NULL_TREE.  */
 
 static tree
-extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
+extr_type_from_vtbl_ptr_store (gimple stmt, prop_type_change_info *tci)
 {
   HOST_WIDE_INT offset, size, max_size;
   tree lhs, rhs, base, binfo;
@@ -752,7 +751,7 @@ static bool
 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
 {
   gimple stmt = SSA_NAME_DEF_STMT (vdef);
-  struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
+  prop_type_change_info *tci = (prop_type_change_info *) data;
 
   if (stmt_may_be_vtbl_ptr_store (stmt))
     {
@@ -847,10 +846,10 @@ param_type_may_change_p (tree function, tree arg, gimple call)
 
 static bool
 detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
-				       gimple call, struct ipa_jump_func *jfunc,
+				       gimple call, ipa_jump_func *jfunc,
 				       HOST_WIDE_INT offset)
 {
-  struct prop_type_change_info tci;
+  prop_type_change_info tci;
   ao_ref ao;
   bool entry_reached = false;
 
@@ -908,7 +907,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
 
 static bool
 detect_type_change (tree arg, tree base, tree comp_type, gimple call,
-		    struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
+		    ipa_jump_func *jfunc, HOST_WIDE_INT offset)
 {
   if (!flag_devirtualize)
     return false;
@@ -928,7 +927,7 @@ detect_type_change (tree arg, tree base, tree comp_type, gimple call,
 
 static bool
 detect_type_change_ssa (tree arg, tree comp_type,
-			gimple call, struct ipa_jump_func *jfunc)
+			gimple call, ipa_jump_func *jfunc)
 {
   gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
   if (!flag_devirtualize
@@ -961,7 +960,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
    should really just start giving up.  */
 
 static bool
-aa_overwalked (struct func_body_info *fbi)
+aa_overwalked (func_body_info *fbi)
 {
   gcc_checking_assert (fbi);
   return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
@@ -970,8 +969,8 @@ aa_overwalked (struct func_body_info *fbi)
 /* Find the nearest valid aa status for parameter specified by INDEX that
    dominates BB.  */
 
-static struct param_aa_status *
-find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
+static param_aa_status *
+find_dominating_aa_status (func_body_info *fbi, basic_block bb,
 			   int index)
 {
   while (true)
@@ -979,7 +978,7 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
       bb = get_immediate_dominator (CDI_DOMINATORS, bb);
       if (!bb)
 	return NULL;
-      struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+      ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
       if (!bi->param_aa_statuses.is_empty ()
 	  && bi->param_aa_statuses[index].valid)
 	return &bi->param_aa_statuses[index];
@@ -990,21 +989,21 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
    structures and/or intialize the result with a dominating description as
    necessary.  */
 
-static struct param_aa_status *
-parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
+static param_aa_status *
+parm_bb_aa_status_for_bb (func_body_info *fbi, basic_block bb,
 			  int index)
 {
   gcc_checking_assert (fbi);
-  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   if (bi->param_aa_statuses.is_empty ())
     bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
-  struct param_aa_status *paa = &bi->param_aa_statuses[index];
+  param_aa_status *paa = &bi->param_aa_statuses[index];
   if (!paa->valid)
     {
       gcc_checking_assert (!paa->parm_modified
 			   && !paa->ref_modified
 			   && !paa->pt_modified);
-      struct param_aa_status *dom_paa;
+      param_aa_status *dom_paa;
       dom_paa = find_dominating_aa_status (fbi, bb, index);
       if (dom_paa)
 	*paa = *dom_paa;
@@ -1021,10 +1020,10 @@ parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
    gathered but do not survive the summary building stage.  */
 
 static bool
-parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
+parm_preserved_before_stmt_p (func_body_info *fbi, int index,
 			      gimple stmt, tree parm_load)
 {
-  struct param_aa_status *paa;
+  param_aa_status *paa;
   bool modified = false;
   ao_ref refd;
 
@@ -1060,7 +1059,7 @@ parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
    modified.  Otherwise return -1.  */
 
 static int
-load_from_unmodified_param (struct func_body_info *fbi,
+load_from_unmodified_param (func_body_info *fbi,
 			    vec<ipa_param_descriptor> descriptors,
 			    gimple stmt)
 {
@@ -1087,10 +1086,10 @@ load_from_unmodified_param (struct func_body_info *fbi,
    before reaching statement STMT.  */
 
 static bool
-parm_ref_data_preserved_p (struct func_body_info *fbi,
+parm_ref_data_preserved_p (func_body_info *fbi,
 			   int index, gimple stmt, tree ref)
 {
-  struct param_aa_status *paa;
+  param_aa_status *paa;
   bool modified = false;
   ao_ref refd;
 
@@ -1126,7 +1125,7 @@ parm_ref_data_preserved_p (struct func_body_info *fbi,
    CALL into which it is passed.  FBI describes the function body.  */
 
 static bool
-parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
+parm_ref_data_pass_through_p (func_body_info *fbi, int index,
 			      gimple call, tree parm)
 {
   bool modified = false;
@@ -1140,7 +1139,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
       || aa_overwalked (fbi))
     return false;
 
-  struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
+  param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
 							  index);
   if (paa->pt_modified)
     return false;
@@ -1165,7 +1164,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
    reference respectively.  */
 
 static bool
-ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
+ipa_load_from_parm_agg_1 (func_body_info *fbi,
 			  vec<ipa_param_descriptor> descriptors,
 			  gimple stmt, tree op, int *index_p,
 			  HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
@@ -1240,7 +1239,7 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
    pointer, for users outside of this file.  */
 
 bool
-ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
+ipa_load_from_parm_agg (ipa_node_params *info, gimple stmt,
 			tree op, int *index_p, HOST_WIDE_INT *offset_p,
 			bool *by_ref_p)
 {
@@ -1302,9 +1301,9 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
    only needed for intraprocedural analysis.  */
 
 static void
-compute_complex_assign_jump_func (struct func_body_info *fbi,
-				  struct ipa_node_params *info,
-				  struct ipa_jump_func *jfunc,
+compute_complex_assign_jump_func (func_body_info *fbi,
+				  ipa_node_params *info,
+				  ipa_jump_func *jfunc,
 				  gimple call, gimple stmt, tree name,
 				  tree param_type)
 {
@@ -1458,9 +1457,9 @@ get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
      return D.1879_6;  */
 
 static void
-compute_complex_ancestor_jump_func (struct func_body_info *fbi,
-				    struct ipa_node_params *info,
-				    struct ipa_jump_func *jfunc,
+compute_complex_ancestor_jump_func (func_body_info *fbi,
+				    ipa_node_params *info,
+				    ipa_jump_func *jfunc,
 				    gimple call, gimple phi, tree param_type)
 {
   HOST_WIDE_INT offset;
@@ -1531,7 +1530,7 @@ compute_complex_ancestor_jump_func (struct func_body_info *fbi,
    EXPECTED_TYPE represents a type the argument should be in  */
 
 static void
-compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
+compute_known_type_jump_func (tree op, ipa_jump_func *jfunc,
 			      gimple call, tree expected_type)
 {
   HOST_WIDE_INT offset, size, max_size;
@@ -1629,7 +1628,7 @@ struct ipa_known_agg_contents_list
   /* Known constant value or NULL if the contents is known to be unknown.  */
   tree constant;
   /* Pointer to the next structure in the list.  */
-  struct ipa_known_agg_contents_list *next;
+  ipa_known_agg_contents_list *next;
 };
 
 /* Find the proper place in linked list of ipa_known_agg_contents_list
@@ -1637,13 +1636,13 @@ struct ipa_known_agg_contents_list
    unless there is a partial overlap, in which case return NULL, or such
    element is already there, in which case set *ALREADY_THERE to true.  */
 
-static struct ipa_known_agg_contents_list **
-get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
+static ipa_known_agg_contents_list **
+get_place_in_agg_contents_list (ipa_known_agg_contents_list **list,
 				HOST_WIDE_INT lhs_offset,
 				HOST_WIDE_INT lhs_size,
 				bool *already_there)
 {
-  struct ipa_known_agg_contents_list **p = list;
+  ipa_known_agg_contents_list **p = list;
   while (*p && (*p)->offset < lhs_offset)
     {
       if ((*p)->offset + (*p)->size > lhs_offset)
@@ -1670,16 +1669,16 @@ get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
    is ARG_OFFSET and store it into JFUNC.  */
 
 static void
-build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
+build_agg_jump_func_from_list (ipa_known_agg_contents_list *list,
 			       int const_count, HOST_WIDE_INT arg_offset,
-			       struct ipa_jump_func *jfunc)
+			       ipa_jump_func *jfunc)
 {
   vec_alloc (jfunc->agg.items, const_count);
   while (list)
     {
       if (list->constant)
 	{
-	  struct ipa_agg_jf_item item;
+	  ipa_agg_jf_item item;
 	  item.offset = list->offset - arg_offset;
 	  gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
 	  item.value = unshare_expr_without_location (list->constant);
@@ -1697,9 +1696,9 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
 
 static void
 determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
-					 struct ipa_jump_func *jfunc)
+					 ipa_jump_func *jfunc)
 {
-  struct ipa_known_agg_contents_list *list = NULL;
+  ipa_known_agg_contents_list *list = NULL;
   int item_count = 0, const_count = 0;
   HOST_WIDE_INT arg_offset, arg_size;
   gimple_stmt_iterator gsi;
@@ -1774,7 +1773,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
   gsi_prev (&gsi);
   for (; !gsi_end_p (gsi); gsi_prev (&gsi))
     {
-      struct ipa_known_agg_contents_list *n, **p;
+      ipa_known_agg_contents_list *n, **p;
       gimple stmt = gsi_stmt (gsi);
       HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
       tree lhs, rhs, lhs_base;
@@ -1821,7 +1820,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
 	continue;
 
       rhs = get_ssa_def_if_simple_copy (rhs);
-      n = XALLOCA (struct ipa_known_agg_contents_list);
+      n = XALLOCA (ipa_known_agg_contents_list);
       n->size = lhs_size;
       n->offset = lhs_offset;
       if (is_gimple_ip_invariant (rhs))
@@ -1852,7 +1851,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
 }
 
 static tree
-ipa_get_callee_param_type (struct cgraph_edge *e, int i)
+ipa_get_callee_param_type (cgraph_edge *e, int i)
 {
   int n;
   tree type = (e->callee
@@ -1887,11 +1886,11 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
    to this callsite.  */
 
 static void
-ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
-				     struct cgraph_edge *cs)
+ipa_compute_jump_functions_for_edge (func_body_info *fbi,
+				     cgraph_edge *cs)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
-  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
+  ipa_node_params *info = IPA_NODE_REF (cs->caller);
+  ipa_edge_args *args = IPA_EDGE_REF (cs);
   gimple call = cs->call_stmt;
   int n, arg_num = gimple_call_num_args (call);
   bool useful_context = false;
@@ -1909,13 +1908,13 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
 
   for (n = 0; n < arg_num; n++)
     {
-      struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
+      ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
       tree arg = gimple_call_arg (call, n);
       tree param_type = ipa_get_callee_param_type (cs, n);
       if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
 	  tree instance;
-	  struct ipa_polymorphic_call_context context (cs->caller->decl,
+	  ipa_polymorphic_call_context context (cs->caller->decl,
 						       arg, cs->call_stmt,
 						       &instance);
 	  context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
@@ -2003,15 +2002,15 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
    from BB.  */
 
 static void
-ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
+ipa_compute_jump_functions_for_bb (func_body_info *fbi, basic_block bb)
 {
-  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   int i;
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
     {
-      struct cgraph_node *callee = cs->callee;
+      cgraph_node *callee = cs->callee;
 
       if (callee)
 	{
@@ -2093,10 +2092,10 @@ ipa_is_ssa_with_stmt_def (tree t)
    call to a parameter number PARAM_INDEX.  NODE is the caller.  Return the
    indirect call graph edge.  */
 
-static struct cgraph_edge *
-ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
+static cgraph_edge *
+ipa_note_param_call (cgraph_node *node, int param_index, gimple stmt)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   cs = node->get_edge (stmt);
   cs->indirect_info->param_index = param_index;
@@ -2165,10 +2164,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
    passed by value or reference.  */
 
 static void
-ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
+ipa_analyze_indirect_call_uses (func_body_info *fbi, gimple call,
 				tree target)
 {
-  struct ipa_node_params *info = fbi->info;
+  ipa_node_params *info = fbi->info;
   HOST_WIDE_INT offset;
   bool by_ref;
 
@@ -2188,7 +2187,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
 				   gimple_assign_rhs1 (def), &index, &offset,
 				   NULL, &by_ref))
     {
-      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
       cs->indirect_info->agg_contents = 1;
       cs->indirect_info->by_ref = by_ref;
@@ -2288,7 +2287,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
   if (index >= 0
       && parm_preserved_before_stmt_p (fbi, index, call, rec))
     {
-      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
       cs->indirect_info->agg_contents = 1;
       cs->indirect_info->member_ptr = 1;
@@ -2303,7 +2302,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
    statement.  */
 
 static void
-ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
+ipa_analyze_virtual_call_uses (func_body_info *fbi,
 			       gimple call, tree target)
 {
   tree obj = OBJ_TYPE_REF_OBJECT (target);
@@ -2316,10 +2315,10 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
   if (TREE_CODE (obj) != SSA_NAME)
     return;
 
-  struct ipa_node_params *info = fbi->info;
+  ipa_node_params *info = fbi->info;
   if (SSA_NAME_IS_DEFAULT_DEF (obj))
     {
-      struct ipa_jump_func jfunc;
+      ipa_jump_func jfunc;
       if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
 	return;
 
@@ -2332,7 +2331,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
     }
   else
     {
-      struct ipa_jump_func jfunc;
+      ipa_jump_func jfunc;
       gimple stmt = SSA_NAME_DEF_STMT (obj);
       tree expr;
 
@@ -2347,8 +2346,8 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
 	return;
     }
 
-  struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
+  cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+  cgraph_indirect_call_info *ii = cs->indirect_info;
   ii->offset = anc_offset;
   ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
   ii->otr_type = obj_type_ref_class (target);
@@ -2360,7 +2359,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
    containing intermediate information about each formal parameter.  */
 
 static void
-ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
+ipa_analyze_call_uses (func_body_info *fbi, gimple call)
 {
   tree target = gimple_call_fn (call);
 
@@ -2369,7 +2368,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
           && !virtual_method_call_p (target)))
     return;
 
-  struct cgraph_edge *cs = fbi->node->get_edge (call);
+  cgraph_edge *cs = fbi->node->get_edge (call);
   /* If we previously turned the call into a direct call, there is
      no need to analyze.  */
   if (cs && !cs->indirect_unknown_callee)
@@ -2406,7 +2405,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
    formal parameters are called.  */
 
 static void
-ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
+ipa_analyze_stmt_uses (func_body_info *fbi, gimple stmt)
 {
   if (is_gimple_call (stmt))
     ipa_analyze_call_uses (fbi, stmt);
@@ -2419,7 +2418,7 @@ ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
 static bool
 visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
 {
-  struct ipa_node_params *info = (struct ipa_node_params *) data;
+  ipa_node_params *info = (ipa_node_params *) data;
 
   op = get_base_address (op);
   if (op
@@ -2439,7 +2438,7 @@ visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
    the function being analyzed.  */
 
 static void
-ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
+ipa_analyze_params_uses_in_bb (func_body_info *fbi, basic_block bb)
 {
   gimple_stmt_iterator gsi;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -2465,9 +2464,9 @@ ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
 /* Calculate controlled uses of parameters of NODE.  */
 
 static void
-ipa_analyze_controlled_uses (struct cgraph_node *node)
+ipa_analyze_controlled_uses (cgraph_node *node)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   for (int i = 0; i < ipa_get_param_count (info); i++)
     {
@@ -2510,7 +2509,7 @@ ipa_analyze_controlled_uses (struct cgraph_node *node)
 /* Free stuff in BI.  */
 
 static void
-free_ipa_bb_info (struct ipa_bb_info *bi)
+free_ipa_bb_info (ipa_bb_info *bi)
 {
   bi->cg_edges.release ();
   bi->param_aa_statuses.release ();
@@ -2521,13 +2520,13 @@ free_ipa_bb_info (struct ipa_bb_info *bi)
 class analysis_dom_walker : public dom_walker
 {
 public:
-  analysis_dom_walker (struct func_body_info *fbi)
+  analysis_dom_walker (func_body_info *fbi)
     : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
 
   virtual void before_dom_children (basic_block);
 
 private:
-  struct func_body_info *m_fbi;
+  func_body_info *m_fbi;
 };
 
 void
@@ -2542,10 +2541,10 @@ analysis_dom_walker::before_dom_children (basic_block bb)
    with actual arguments of calls from within NODE.  */
 
 void
-ipa_analyze_node (struct cgraph_node *node)
+ipa_analyze_node (cgraph_node *node)
 {
-  struct func_body_info fbi;
-  struct ipa_node_params *info;
+  func_body_info fbi;
+  ipa_node_params *info;
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
@@ -2565,7 +2564,7 @@ ipa_analyze_node (struct cgraph_node *node)
       return;
     }
 
-  struct function *func = DECL_STRUCT_FUNCTION (node->decl);
+  function *func = DECL_STRUCT_FUNCTION (node->decl);
   push_cfun (func);
   calculate_dominance_info (CDI_DOMINATORS);
   ipa_initialize_node_params (node);
@@ -2578,13 +2577,13 @@ ipa_analyze_node (struct cgraph_node *node)
   fbi.param_count = ipa_get_param_count (info);
   fbi.aa_walked = 0;
 
-  for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
       bi->cg_edges.safe_push (cs);
     }
 
-  for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
+  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
       bi->cg_edges.safe_push (cs);
@@ -2593,7 +2592,7 @@ ipa_analyze_node (struct cgraph_node *node)
   analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
   int i;
-  struct ipa_bb_info *bi;
+  ipa_bb_info *bi;
   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
     free_ipa_bb_info (bi);
   fbi.bb_infos.release ();
@@ -2606,8 +2605,8 @@ ipa_analyze_node (struct cgraph_node *node)
    type.  */
 
 static void
-combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
-				     struct ipa_jump_func *dst)
+combine_known_type_and_ancestor_jfs (ipa_jump_func *src,
+				     ipa_jump_func *dst)
 {
   HOST_WIDE_INT combined_offset;
   tree combined_type;
@@ -2632,25 +2631,25 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
    indirectly) inlined into CS->callee and that E has not been inlined.  */
 
 static void
-update_jump_functions_after_inlining (struct cgraph_edge *cs,
-				      struct cgraph_edge *e)
+update_jump_functions_after_inlining (cgraph_edge *cs,
+				      cgraph_edge *e)
 {
-  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
-  struct ipa_edge_args *args = IPA_EDGE_REF (e);
+  ipa_edge_args *top = IPA_EDGE_REF (cs);
+  ipa_edge_args *args = IPA_EDGE_REF (e);
   int count = ipa_get_cs_argument_count (args);
   int i;
 
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
-      struct ipa_polymorphic_call_context *dst_ctx
+      ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
+      ipa_polymorphic_call_context *dst_ctx
 	= ipa_get_ith_polymorhic_call_context (args, i);
 
       if (dst->type == IPA_JF_ANCESTOR)
 	{
-	  struct ipa_jump_func *src;
+	  ipa_jump_func *src;
 	  int dst_fid = dst->value.ancestor.formal_id;
-	  struct ipa_polymorphic_call_context *src_ctx
+	  ipa_polymorphic_call_context *src_ctx
 	    = ipa_get_ith_polymorhic_call_context (top, dst_fid);
 
 	  /* Variable number of arguments can cause havoc if we try to access
@@ -2666,7 +2665,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 
 	  if (src_ctx && !src_ctx->useless_p ())
 	    {
-	      struct ipa_polymorphic_call_context ctx = *src_ctx;
+	      ipa_polymorphic_call_context ctx = *src_ctx;
 
 	      /* TODO: Make type preserved safe WRT contexts.  */
 	      if (!dst->value.ancestor.agg_preserved)
@@ -2683,7 +2682,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	  if (src->agg.items
 	      && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
 	    {
-	      struct ipa_agg_jf_item *item;
+	      ipa_agg_jf_item *item;
 	      int j;
 
 	      /* Currently we do not produce clobber aggregate jump functions,
@@ -2721,7 +2720,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	}
       else if (dst->type == IPA_JF_PASS_THROUGH)
 	{
-	  struct ipa_jump_func *src;
+	  ipa_jump_func *src;
 	  /* We must check range due to calls with variable number of arguments
 	     and we cannot combine jump functions with operations.  */
 	  if (dst->value.pass_through.operation == NOP_EXPR
@@ -2731,12 +2730,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	      int dst_fid = dst->value.pass_through.formal_id;
 	      src = ipa_get_ith_jump_func (top, dst_fid);
 	      bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
-	      struct ipa_polymorphic_call_context *src_ctx
+	      ipa_polymorphic_call_context *src_ctx
 		= ipa_get_ith_polymorhic_call_context (top, dst_fid);
 
 	      if (src_ctx && !src_ctx->useless_p ())
 		{
-		  struct ipa_polymorphic_call_context ctx = *src_ctx;
+		  ipa_polymorphic_call_context ctx = *src_ctx;
 
 		  /* TODO: Make type preserved safe WRT contexts.  */
 		  if (!dst->value.ancestor.agg_preserved)
@@ -2833,11 +2832,11 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
    (SPECULATIVE)destination of an indirect edge IE and return the edge.
    Otherwise, return NULL.  */
 
-struct cgraph_edge *
-ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
+cgraph_edge *
+ipa_make_edge_direct_to_target (cgraph_edge *ie, tree target,
 				bool speculative)
 {
-  struct cgraph_node *callee;
+  cgraph_node *callee;
   struct inline_edge_summary *es = inline_edge_summary (ie);
   bool unreachable = false;
 
@@ -2898,8 +2897,8 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
   /* If the edge is already speculated.  */
   if (speculative && ie->speculative)
     {
-      struct cgraph_edge *e2;
-      struct ipa_ref *ref;
+      cgraph_edge *e2;
+      ipa_ref *ref;
       ie->speculative_call_info (e2, ie, ref);
       if (e2->callee->ultimate_alias_target ()
 	  != callee->ultimate_alias_target ())
@@ -2987,10 +2986,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
    be passed by reference or by value.  */
 
 tree
-ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
+ipa_find_agg_cst_for_param (ipa_agg_jump_function *agg,
 			    HOST_WIDE_INT offset, bool by_ref)
 {
-  struct ipa_agg_jf_item *item;
+  ipa_agg_jf_item *item;
   int i;
 
   if (by_ref != agg->by_ref)
@@ -3012,10 +3011,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
    successfully found and removed.  */
 
 static bool
-remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
+remove_described_reference (symtab_node *symbol, ipa_cst_ref_desc *rdesc)
 {
-  struct ipa_ref *to_del;
-  struct cgraph_edge *origin;
+  ipa_ref *to_del;
+  cgraph_edge *origin;
 
   origin = rdesc->cs;
   if (!origin)
@@ -3037,10 +3036,10 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
    IPA_UNDESCRIBED_USE, return the reference description, otherwise return
    NULL.  JFUNC must be a constant jump function.  */
 
-static struct ipa_cst_ref_desc *
-jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
+static ipa_cst_ref_desc *
+jfunc_rdesc_usable (ipa_jump_func *jfunc)
 {
-  struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
+  ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
   if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
     return rdesc;
   else
@@ -3052,7 +3051,7 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
    NULL.  */
 
 static cgraph_node *
-cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
+cgraph_node_for_jfunc (ipa_jump_func *jfunc)
 {
   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
   tree cst = ipa_get_jf_constant (jfunc);
@@ -3070,9 +3069,9 @@ cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
    reference could not be found, otherwise return true.  */
 
 static bool
-try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
+try_decrement_rdesc_refcount (ipa_jump_func *jfunc)
 {
-  struct ipa_cst_ref_desc *rdesc;
+  ipa_cst_ref_desc *rdesc;
   if (jfunc->type == IPA_JF_CONST
       && (rdesc = jfunc_rdesc_usable (jfunc))
       && --rdesc->refcount == 0)
@@ -3092,12 +3091,12 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
    determined, return the newly direct edge, otherwise return NULL.
    NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
 
-static struct cgraph_edge *
-try_make_edge_direct_simple_call (struct cgraph_edge *ie,
-				  struct ipa_jump_func *jfunc,
-				  struct ipa_node_params *new_root_info)
+static cgraph_edge *
+try_make_edge_direct_simple_call (cgraph_edge *ie,
+				  ipa_jump_func *jfunc,
+				  ipa_node_params *new_root_info)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   tree target;
   bool agg_contents = ie->indirect_info->agg_contents;
 
@@ -3130,7 +3129,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
    and target (the latter can be NULL) are dumped when dumping is enabled.  */
 
 tree
-ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
+ipa_impossible_devirt_target (cgraph_edge *ie, tree target)
 {
   if (dump_file)
     {
@@ -3155,11 +3154,11 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
    Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
    are relative to.  */
 
-static struct cgraph_edge *
-try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
-				   struct ipa_jump_func *jfunc,
-				   struct ipa_node_params *new_root_info,
-				   struct ipa_polymorphic_call_context *ctx_ptr)
+static cgraph_edge *
+try_make_edge_direct_virtual_call (cgraph_edge *ie,
+				   ipa_jump_func *jfunc,
+				   ipa_node_params *new_root_info,
+				   ipa_polymorphic_call_context *ctx_ptr)
 {
   tree binfo, target = NULL;
   bool speculative = false;
@@ -3172,7 +3171,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
      based on knowlede of the context.  */
   if (ctx_ptr && !ie->indirect_info->by_ref)
     {
-      struct ipa_polymorphic_call_context ctx = *ctx_ptr;
+      ipa_polymorphic_call_context ctx = *ctx_ptr;
 
       ctx.offset_by (ie->indirect_info->offset);
 
@@ -3221,7 +3220,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
 
   if (binfo && TREE_CODE (binfo) != TREE_BINFO)
     {
-      struct ipa_polymorphic_call_context ctx (binfo,
+      ipa_polymorphic_call_context ctx (binfo,
 					       ie->indirect_info->otr_type,
 					       ie->indirect_info->offset);
       updated |= ie->indirect_info->context.combine_with
@@ -3296,13 +3295,13 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
    unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
 
 static bool
-update_indirect_edges_after_inlining (struct cgraph_edge *cs,
-				      struct cgraph_node *node,
+update_indirect_edges_after_inlining (cgraph_edge *cs,
+				      cgraph_node *node,
 				      vec<cgraph_edge *> *new_edges)
 {
-  struct ipa_edge_args *top;
-  struct cgraph_edge *ie, *next_ie, *new_direct_edge;
-  struct ipa_node_params *new_root_info;
+  ipa_edge_args *top;
+  cgraph_edge *ie, *next_ie, *new_direct_edge;
+  ipa_node_params *new_root_info;
   bool res = false;
 
   ipa_check_create_edge_args ();
@@ -3313,8 +3312,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
   for (ie = node->indirect_calls; ie; ie = next_ie)
     {
-      struct cgraph_indirect_call_info *ici = ie->indirect_info;
-      struct ipa_jump_func *jfunc;
+      cgraph_indirect_call_info *ici = ie->indirect_info;
+      ipa_jump_func *jfunc;
       int param_index;
 
       next_ie = ie->next_callee;
@@ -3408,11 +3407,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
    created.  */
 
 static bool
-propagate_info_to_inlined_callees (struct cgraph_edge *cs,
-				   struct cgraph_node *node,
+propagate_info_to_inlined_callees (cgraph_edge *cs,
+				   cgraph_node *node,
 				   vec<cgraph_edge *> *new_edges)
 {
-  struct cgraph_edge *e;
+  cgraph_edge *e;
   bool res;
 
   res = update_indirect_edges_after_inlining (cs, node, new_edges);
@@ -3443,21 +3442,21 @@ combine_controlled_uses_counters (int c, int d)
    tree of inlined nodes.  */
 
 static void
-propagate_controlled_uses (struct cgraph_edge *cs)
+propagate_controlled_uses (cgraph_edge *cs)
 {
-  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
-  struct cgraph_node *new_root = cs->caller->global.inlined_to
+  ipa_edge_args *args = IPA_EDGE_REF (cs);
+  cgraph_node *new_root = cs->caller->global.inlined_to
     ? cs->caller->global.inlined_to : cs->caller;
-  struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
-  struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
+  ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
+  ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
   int count, i;
 
   count = MIN (ipa_get_cs_argument_count (args),
 	       ipa_get_param_count (old_root_info));
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
-      struct ipa_cst_ref_desc *rdesc;
+      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
+      ipa_cst_ref_desc *rdesc;
 
       if (jf->type == IPA_JF_PASS_THROUGH)
 	{
@@ -3472,8 +3471,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  ipa_set_controlled_uses (new_root_info, src_idx, c);
 	  if (c == 0 && new_root_info->ipcp_orig_node)
 	    {
-	      struct cgraph_node *n;
-	      struct ipa_ref *ref;
+	      cgraph_node *n;
+	      ipa_ref *ref;
 	      tree t = new_root_info->known_vals[src_idx];
 
 	      if (t && TREE_CODE (t) == ADDR_EXPR
@@ -3500,14 +3499,14 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  if (rdesc->refcount == 0)
 	    {
 	      tree cst = ipa_get_jf_constant (jf);
-	      struct cgraph_node *n;
+	      cgraph_node *n;
 	      gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
 				   && TREE_CODE (TREE_OPERAND (cst, 0))
 				   == FUNCTION_DECL);
 	      n = cgraph_node::get (TREE_OPERAND (cst, 0));
 	      if (n)
 		{
-		  struct cgraph_node *clone;
+		  cgraph_node *clone;
 		  bool ok;
 		  ok = remove_described_reference (n, rdesc);
 		  gcc_checking_assert (ok);
@@ -3517,7 +3516,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 			 && clone != rdesc->cs->caller
 			 && IPA_NODE_REF (clone)->ipcp_orig_node)
 		    {
-		      struct ipa_ref *ref;
+		      ipa_ref *ref;
 		      ref = clone->find_reference (n, NULL, 0);
 		      if (ref)
 			{
@@ -3542,11 +3541,11 @@ propagate_controlled_uses (struct cgraph_edge *cs)
        i < ipa_get_cs_argument_count (args);
        i++)
     {
-      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
+      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
 
       if (jf->type == IPA_JF_CONST)
 	{
-	  struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
+	  ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
 	  if (rdesc)
 	    rdesc->refcount = IPA_UNDESCRIBED_USE;
 	}
@@ -3564,13 +3563,13 @@ propagate_controlled_uses (struct cgraph_edge *cs)
    created.  */
 
 bool
-ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
+ipa_propagate_indirect_call_infos (cgraph_edge *cs,
 				   vec<cgraph_edge *> *new_edges)
 {
   bool changed;
   /* Do nothing if the preparation phase has not been carried out yet
      (i.e. during early inlining).  */
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_d)
     return false;
   gcc_assert (ipa_edge_args_vector);
 
@@ -3584,7 +3583,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
    to.  */
 
 void
-ipa_free_edge_args_substructures (struct ipa_edge_args *args)
+ipa_free_edge_args_substructures (ipa_edge_args *args)
 {
   vec_free (args->jump_functions);
   memset (args, 0, sizeof (*args));
@@ -3596,7 +3595,7 @@ void
 ipa_free_all_edge_args (void)
 {
   int i;
-  struct ipa_edge_args *args;
+  ipa_edge_args *args;
 
   if (!ipa_edge_args_vector)
     return;
@@ -3610,15 +3609,21 @@ ipa_free_all_edge_args (void)
 /* Frees all dynamically allocated structures that the param info points
    to.  */
 
-void
-ipa_free_node_params_substructures (struct ipa_node_params *info)
+ipa_node_params::~ipa_node_params ()
 {
-  info->descriptors.release ();
-  free (info->lattices);
+  descriptors.release ();
+  free (lattices);
   /* Lattice values and their sources are deallocated with their alocation
      pool.  */
-  info->known_vals.release ();
-  memset (info, 0, sizeof (*info));
+  known_vals.release ();
+
+  lattices = NULL;
+  ipcp_orig_node = NULL;
+  analysis_done = 0;
+  node_enqueued = 0;
+  do_clone_for_all_contexts = 0;
+  is_all_contexts_clone = 0;
+  node_dead = 0;
 }
 
 /* Free all ipa_node_params structures.  */
@@ -3626,20 +3631,15 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
 void
 ipa_free_all_node_params (void)
 {
-  int i;
-  struct ipa_node_params *info;
-
-  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
-    ipa_free_node_params_substructures (info);
-
-  ipa_node_params_vector.release ();
+  delete ipa_node_params_d;
+  ipa_node_params_d = NULL;
 }
 
 /* Set the aggregate replacements of NODE to be AGGVALS.  */
 
 void
-ipa_set_node_agg_value_chain (struct cgraph_node *node,
-			      struct ipa_agg_replacement_value *aggvals)
+ipa_set_node_agg_value_chain (const cgraph_node *node,
+			      ipa_agg_replacement_value *aggvals)
 {
   if (vec_safe_length (ipa_node_agg_replacements)
       <= (unsigned) symtab->cgraph_max_uid)
@@ -3652,9 +3652,9 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
 /* Hook that is called by cgraph.c when an edge is removed.  */
 
 static void
-ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
+ipa_edge_removal_hook (cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_edge_args *args;
+  ipa_edge_args *args;
 
   /* During IPA-CP updating we can be called on not-yet analyzed clones.  */
   if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
@@ -3663,11 +3663,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   args = IPA_EDGE_REF (cs);
   if (args->jump_functions)
     {
-      struct ipa_jump_func *jf;
+      ipa_jump_func *jf;
       int i;
       FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
 	{
-	  struct ipa_cst_ref_desc *rdesc;
+	  ipa_cst_ref_desc *rdesc;
 	  try_decrement_rdesc_refcount (jf);
 	  if (jf->type == IPA_JF_CONST
 	      && (rdesc = ipa_get_jf_constant_rdesc (jf))
@@ -3679,25 +3679,13 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
 }
 
-/* Hook that is called by cgraph.c when a node is removed.  */
-
-static void
-ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
-  if (ipa_node_params_vector.length () > (unsigned)node->uid)
-    ipa_free_node_params_substructures (IPA_NODE_REF (node));
-  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
-    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
-}
-
 /* Hook that is called by cgraph.c when an edge is duplicated.  */
 
 static void
-ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
+ipa_edge_duplication_hook (cgraph_edge *src, cgraph_edge *dst,
 			   __attribute__((unused)) void *data)
 {
-  struct ipa_edge_args *old_args, *new_args;
+  ipa_edge_args *old_args, *new_args;
   unsigned int i;
 
   ipa_check_create_edge_args ();
@@ -3712,20 +3700,20 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 
   for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
     {
-      struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
-      struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
+      ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
+      ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
 
       dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
 
       if (src_jf->type == IPA_JF_CONST)
 	{
-	  struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
+	  ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
 
 	  if (!src_rdesc)
 	    dst_jf->value.constant.rdesc = NULL;
 	  else if (src->caller == dst->caller)
 	    {
-	      struct ipa_ref *ref;
+	      ipa_ref *ref;
 	      symtab_node *n = cgraph_node_for_jfunc (src_jf);
 	      gcc_checking_assert (n);
 	      ref = src->caller->find_reference (n, src->call_stmt,
@@ -3734,8 +3722,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	      dst->caller->clone_reference (ref, ref->stmt);
 
 	      gcc_checking_assert (ipa_refdesc_pool);
-	      struct ipa_cst_ref_desc *dst_rdesc
-		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+	      ipa_cst_ref_desc *dst_rdesc
+		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
 	      dst_rdesc->cs = dst;
 	      dst_rdesc->refcount = src_rdesc->refcount;
 	      dst_rdesc->next_duplicate = NULL;
@@ -3743,10 +3731,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	    }
 	  else if (src_rdesc->cs == src)
 	    {
-	      struct ipa_cst_ref_desc *dst_rdesc;
+	      ipa_cst_ref_desc *dst_rdesc;
 	      gcc_checking_assert (ipa_refdesc_pool);
 	      dst_rdesc
-		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
 	      dst_rdesc->cs = dst;
 	      dst_rdesc->refcount = src_rdesc->refcount;
 	      dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
@@ -3755,7 +3743,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	    }
 	  else
 	    {
-	      struct ipa_cst_ref_desc *dst_rdesc;
+	      ipa_cst_ref_desc *dst_rdesc;
 	      /* This can happen during inlining, when a JFUNC can refer to a
 		 reference taken in a function up in the tree of inline clones.
 		 We need to find the duplicate that refers to our tree of
@@ -3766,7 +3754,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 		   dst_rdesc;
 		   dst_rdesc = dst_rdesc->next_duplicate)
 		{
-		  struct cgraph_node *top;
+		  cgraph_node *top;
 		  top = dst_rdesc->cs->caller->global.inlined_to
 		    ? dst_rdesc->cs->caller->global.inlined_to
 		    : dst_rdesc->cs->caller;
@@ -3780,9 +3768,9 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
       else if (dst_jf->type == IPA_JF_PASS_THROUGH
 	       && src->caller == dst->caller)
 	{
-	  struct cgraph_node *inline_root = dst->caller->global.inlined_to
+	  cgraph_node *inline_root = dst->caller->global.inlined_to
 	    ? dst->caller->global.inlined_to : dst->caller;
-	  struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
+	  ipa_node_params *root_info = IPA_NODE_REF (inline_root);
 	  int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
 
 	  int c = ipa_get_controlled_uses (root_info, idx);
@@ -3795,18 +3783,23 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
     }
 }
 
-/* Hook that is called by cgraph.c when a node is duplicated.  */
+/* Analyze newly added function into callgraph.  */
 
 static void
-ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
-			   ATTRIBUTE_UNUSED void *data)
+ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_node_params *old_info, *new_info;
-  struct ipa_agg_replacement_value *old_av, *new_av;
+  if (node->has_gimple_body_p ())
+    ipa_analyze_node (node);
+}
 
-  ipa_check_create_node_params ();
-  old_info = IPA_NODE_REF (src);
-  new_info = IPA_NODE_REF (dst);
+/* Hook that is called by summary when a node is duplicated.  */
+
+void
+ipa_node_params_t::duplication_hook(cgraph_node *src, cgraph_node *dst,
+				    ipa_node_params *old_info,
+				    ipa_node_params *new_info)
+{
+  ipa_agg_replacement_value *old_av, *new_av;
 
   new_info->descriptors = old_info->descriptors.copy ();
   new_info->lattices = NULL;
@@ -3822,7 +3815,7 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   new_av = NULL;
   while (old_av)
     {
-      struct ipa_agg_replacement_value *v;
+      ipa_agg_replacement_value *v;
 
       v = ggc_alloc<ipa_agg_replacement_value> ();
       memcpy (v, old_av, sizeof (*v));
@@ -3833,33 +3826,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   ipa_set_node_agg_value_chain (dst, new_av);
 }
 
-
-/* Analyze newly added function into callgraph.  */
-
-static void
-ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  if (node->has_gimple_body_p ())
-    ipa_analyze_node (node);
-}
-
 /* Register our cgraph hooks if they are not already there.  */
 
 void
 ipa_register_cgraph_hooks (void)
 {
+  ipa_check_create_node_params ();
+
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
   function_insertion_hook_holder =
       symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
 }
@@ -3871,12 +3850,8 @@ ipa_unregister_cgraph_hooks (void)
 {
   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
   symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
 }
@@ -3923,10 +3898,10 @@ ipa_free_all_structures_after_iinln (void)
    callgraph to F.  */
 
 void
-ipa_print_node_params (FILE *f, struct cgraph_node *node)
+ipa_print_node_params (FILE *f, cgraph_node *node)
 {
   int i, count;
-  struct ipa_node_params *info;
+  ipa_node_params *info;
 
   if (!node->definition)
     return;
@@ -3957,7 +3932,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
 void
 ipa_print_all_params (FILE * f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "\nFunction parameters:\n");
   FOR_EACH_FUNCTION (node)
@@ -4040,7 +4015,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
   tree new_arg_types = NULL;
   for (int i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       gcc_assert (link);
 
       adj = &adjustments[i];
@@ -4158,10 +4133,10 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
    contain the corresponding call graph edge.  */
 
 void
-ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
+ipa_modify_call_arguments (cgraph_edge *cs, gimple stmt,
 			   ipa_parm_adjustment_vec adjustments)
 {
-  struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
+  cgraph_node *current_node = cgraph_node::get (current_function_decl);
   vec<tree> vargs;
   vec<tree, va_gc> **debug_args = NULL;
   gimple new_stmt;
@@ -4179,7 +4154,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
   gsi_prev (&prev_gsi);
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
 
       adj = &adjustments[i];
 
@@ -4412,7 +4387,7 @@ bool
 ipa_modify_expr (tree *expr, bool convert,
 		 ipa_parm_adjustment_vec adjustments)
 {
-  struct ipa_parm_adjustment *cand
+  ipa_parm_adjustment *cand
     = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
   if (!cand)
     return false;
@@ -4500,11 +4475,11 @@ ipa_get_adjustment_candidate (tree **expr, bool *convert,
   if (!base || TREE_CODE (base) != PARM_DECL)
     return NULL;
 
-  struct ipa_parm_adjustment *cand = NULL;
+  ipa_parm_adjustment *cand = NULL;
   unsigned int len = adjustments.length ();
   for (unsigned i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj = &adjustments[i];
+      ipa_parm_adjustment *adj = &adjustments[i];
 
       if (adj->base == base
 	  && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
@@ -4530,7 +4505,7 @@ index_in_adjustments_multiple_times_p (int base_index,
 
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       adj = &adjustments[i];
 
       if (adj->base_index == base_index)
@@ -4561,7 +4536,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
   tmp.create (inlen);
   for (i = 0; i < inlen; i++)
     {
-      struct ipa_parm_adjustment *n;
+      ipa_parm_adjustment *n;
       n = &inner[i];
 
       if (n->op == IPA_PARM_OP_REMOVE)
@@ -4577,9 +4552,9 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
   adjustments.create (outlen + removals);
   for (i = 0; i < outlen; i++)
     {
-      struct ipa_parm_adjustment r;
-      struct ipa_parm_adjustment *out = &outer[i];
-      struct ipa_parm_adjustment *in = &tmp[out->base_index];
+      ipa_parm_adjustment r;
+      ipa_parm_adjustment *out = &outer[i];
+      ipa_parm_adjustment *in = &tmp[out->base_index];
 
       memset (&r, 0, sizeof (r));
       gcc_assert (in->op != IPA_PARM_OP_REMOVE);
@@ -4616,7 +4591,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
 
   for (i = 0; i < inlen; i++)
     {
-      struct ipa_parm_adjustment *n = &inner[i];
+      ipa_parm_adjustment *n = &inner[i];
 
       if (n->op == IPA_PARM_OP_REMOVE)
 	adjustments.quick_push (*n);
@@ -4640,7 +4615,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
   fprintf (file, "IPA param adjustments: ");
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       adj = &adjustments[i];
 
       if (!first)
@@ -4683,7 +4658,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
 /* Dump the AV linked list.  */
 
 void
-ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
+ipa_dump_agg_replacement_values (FILE *f, ipa_agg_replacement_value *av)
 {
   bool comma = false;
   fprintf (f, "     Aggregate replacements:");
@@ -4700,11 +4675,11 @@ ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
 /* Stream out jump function JUMP_FUNC to OB.  */
 
 static void
-ipa_write_jump_function (struct output_block *ob,
-			 struct ipa_jump_func *jump_func)
+ipa_write_jump_function (output_block *ob,
+			 ipa_jump_func *jump_func)
 {
-  struct ipa_agg_jf_item *item;
-  struct bitpack_d bp;
+  ipa_agg_jf_item *item;
+  bitpack_d bp;
   int i, count;
 
   streamer_write_uhwi (ob, jump_func->type);
@@ -4768,10 +4743,10 @@ ipa_write_jump_function (struct output_block *ob,
 /* Read in jump function JUMP_FUNC from IB.  */
 
 static void
-ipa_read_jump_function (struct lto_input_block *ib,
-			struct ipa_jump_func *jump_func,
-			struct cgraph_edge *cs,
-			struct data_in *data_in)
+ipa_read_jump_function (lto_input_block *ib,
+			ipa_jump_func *jump_func,
+			cgraph_edge *cs,
+			data_in *data_in)
 {
   enum jump_func_type jftype;
   enum tree_code operation;
@@ -4800,7 +4775,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
       if (operation == NOP_EXPR)
 	{
 	  int formal_id =  streamer_read_uhwi (ib);
-	  struct bitpack_d bp = streamer_read_bitpack (ib);
+	  bitpack_d bp = streamer_read_bitpack (ib);
 	  bool agg_preserved = bp_unpack_value (&bp, 1);
 	  bool type_preserved = bp_unpack_value (&bp, 1);
 	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
@@ -4819,7 +4794,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
 	HOST_WIDE_INT offset = streamer_read_uhwi (ib);
 	tree type = stream_read_tree (ib, data_in);
 	int formal_id = streamer_read_uhwi (ib);
-	struct bitpack_d bp = streamer_read_bitpack (ib);
+	bitpack_d bp = streamer_read_bitpack (ib);
 	bool agg_preserved = bp_unpack_value (&bp, 1);
 	bool type_preserved = bp_unpack_value (&bp, 1);
 
@@ -4833,12 +4808,12 @@ ipa_read_jump_function (struct lto_input_block *ib,
   vec_alloc (jump_func->agg.items, count);
   if (count)
     {
-      struct bitpack_d bp = streamer_read_bitpack (ib);
+      bitpack_d bp = streamer_read_bitpack (ib);
       jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
     }
   for (i = 0; i < count; i++)
     {
-      struct ipa_agg_jf_item item;
+      ipa_agg_jf_item item;
       item.offset = streamer_read_uhwi (ib);
       item.value = stream_read_tree (ib, data_in);
       jump_func->agg.items->quick_push (item);
@@ -4849,11 +4824,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
    relevant to indirect inlining to OB.  */
 
 static void
-ipa_write_indirect_edge_info (struct output_block *ob,
-			      struct cgraph_edge *cs)
+ipa_write_indirect_edge_info (output_block *ob,
+			      cgraph_edge *cs)
 {
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
-  struct bitpack_d bp;
+  cgraph_indirect_call_info *ii = cs->indirect_info;
+  bitpack_d bp;
 
   streamer_write_hwi (ob, ii->param_index);
   bp = bitpack_create (ob->main_stream);
@@ -4880,12 +4855,12 @@ ipa_write_indirect_edge_info (struct output_block *ob,
    relevant to indirect inlining from IB.  */
 
 static void
-ipa_read_indirect_edge_info (struct lto_input_block *ib,
-			     struct data_in *data_in,
-			     struct cgraph_edge *cs)
+ipa_read_indirect_edge_info (lto_input_block *ib,
+			     data_in *data_in,
+			     cgraph_edge *cs)
 {
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
-  struct bitpack_d bp;
+  cgraph_indirect_call_info *ii = cs->indirect_info;
+  bitpack_d bp;
 
   ii->param_index = (int) streamer_read_hwi (ib);
   bp = streamer_read_bitpack (ib);
@@ -4909,14 +4884,14 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
 /* Stream out NODE info to OB.  */
 
 static void
-ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
+ipa_write_node_info (output_block *ob, cgraph_node *node)
 {
   int node_ref;
   lto_symtab_encoder_t encoder;
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
   int j;
-  struct cgraph_edge *e;
-  struct bitpack_d bp;
+  cgraph_edge *e;
+  bitpack_d bp;
 
   encoder = ob->decl_state->symtab_node_encoder;
   node_ref = lto_symtab_encoder_encode (encoder, node);
@@ -4937,7 +4912,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
     streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
   for (e = node->callees; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
 
       streamer_write_uhwi (ob,
 			   ipa_get_cs_argument_count (args) * 2
@@ -4951,7 +4926,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
 
       streamer_write_uhwi (ob,
 			   ipa_get_cs_argument_count (args) * 2
@@ -4969,13 +4944,13 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
 /* Stream in NODE info from IB.  */
 
 static void
-ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
-		    struct data_in *data_in)
+ipa_read_node_info (lto_input_block *ib, cgraph_node *node,
+		    data_in *data_in)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
   int k;
-  struct cgraph_edge *e;
-  struct bitpack_d bp;
+  cgraph_edge *e;
+  bitpack_d bp;
 
   ipa_alloc_node_params (node, streamer_read_uhwi (ib));
 
@@ -4992,7 +4967,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
     ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
   for (e = node->callees; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
       int count = streamer_read_uhwi (ib);
       bool contexts_computed = count & 1;
       count /= 2;
@@ -5013,7 +4988,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
       int count = streamer_read_uhwi (ib);
       bool contexts_computed = count & 1;
       count /= 2;
@@ -5040,14 +5015,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
 void
 ipa_prop_write_jump_functions (void)
 {
-  struct cgraph_node *node;
-  struct output_block *ob;
+  cgraph_node *node;
+  output_block *ob;
   unsigned int count = 0;
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
 
-
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_d)
     return;
 
   ob = create_output_block (LTO_section_jump_functions);
@@ -5081,15 +5055,15 @@ ipa_prop_write_jump_functions (void)
 /* Read section in file FILE_DATA of length LEN with data DATA.  */
 
 static void
-ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
+ipa_prop_read_section (lto_file_decl_data *file_data, const char *data,
 		       size_t len)
 {
-  const struct lto_function_header *header =
-    (const struct lto_function_header *) data;
-  const int cfg_offset = sizeof (struct lto_function_header);
+  const lto_function_header *header =
+    (const lto_function_header *) data;
+  const int cfg_offset = sizeof (lto_function_header);
   const int main_offset = cfg_offset + header->cfg_size;
   const int string_offset = main_offset + header->main_size;
-  struct data_in *data_in;
+  data_in *data_in;
   unsigned int i;
   unsigned int count;
 
@@ -5104,7 +5078,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
   for (i = 0; i < count; i++)
     {
       unsigned int index;
-      struct cgraph_node *node;
+      cgraph_node *node;
       lto_symtab_encoder_t encoder;
 
       index = streamer_read_uhwi (&ib_main);
@@ -5124,8 +5098,8 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
 void
 ipa_prop_read_jump_functions (void)
 {
-  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  lto_file_decl_data *file_data;
   unsigned int j = 0;
 
   ipa_check_create_node_params ();
@@ -5154,12 +5128,12 @@ ipa_update_after_lto_read (void)
 }
 
 void
-write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
+write_agg_replacement_chain (output_block *ob, cgraph_node *node)
 {
   int node_ref;
   unsigned int count = 0;
   lto_symtab_encoder_t encoder;
-  struct ipa_agg_replacement_value *aggvals, *av;
+  ipa_agg_replacement_value *aggvals, *av;
 
   aggvals = ipa_get_agg_replacements_for_node (node);
   encoder = ob->decl_state->symtab_node_encoder;
@@ -5172,7 +5146,7 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
 
   for (av = aggvals; av; av = av->next)
     {
-      struct bitpack_d bp;
+      bitpack_d bp;
 
       streamer_write_uhwi (ob, av->offset);
       streamer_write_uhwi (ob, av->index);
@@ -5187,18 +5161,18 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
 /* Stream in the aggregate value replacement chain for NODE from IB.  */
 
 static void
-read_agg_replacement_chain (struct lto_input_block *ib,
-			    struct cgraph_node *node,
-			    struct data_in *data_in)
+read_agg_replacement_chain (lto_input_block *ib,
+			    cgraph_node *node,
+			    data_in *data_in)
 {
-  struct ipa_agg_replacement_value *aggvals = NULL;
+  ipa_agg_replacement_value *aggvals = NULL;
   unsigned int count, i;
 
   count = streamer_read_uhwi (ib);
   for (i = 0; i <count; i++)
     {
-      struct ipa_agg_replacement_value *av;
-      struct bitpack_d bp;
+      ipa_agg_replacement_value *av;
+      bitpack_d bp;
 
       av = ggc_alloc<ipa_agg_replacement_value> ();
       av->offset = streamer_read_uhwi (ib);
@@ -5217,8 +5191,8 @@ read_agg_replacement_chain (struct lto_input_block *ib,
 void
 ipa_prop_write_all_agg_replacement (void)
 {
-  struct cgraph_node *node;
-  struct output_block *ob;
+  cgraph_node *node;
+  output_block *ob;
   unsigned int count = 0;
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
@@ -5257,16 +5231,16 @@ ipa_prop_write_all_agg_replacement (void)
    DATA.  */
 
 static void
-read_replacements_section (struct lto_file_decl_data *file_data,
+read_replacements_section (lto_file_decl_data *file_data,
 			   const char *data,
 			   size_t len)
 {
-  const struct lto_function_header *header =
-    (const struct lto_function_header *) data;
-  const int cfg_offset = sizeof (struct lto_function_header);
+  const lto_function_header *header =
+    (const lto_function_header *) data;
+  const int cfg_offset = sizeof (lto_function_header);
   const int main_offset = cfg_offset + header->cfg_size;
   const int string_offset = main_offset + header->main_size;
-  struct data_in *data_in;
+  data_in *data_in;
   unsigned int i;
   unsigned int count;
 
@@ -5280,7 +5254,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
   for (i = 0; i < count; i++)
     {
       unsigned int index;
-      struct cgraph_node *node;
+      cgraph_node *node;
       lto_symtab_encoder_t encoder;
 
       index = streamer_read_uhwi (&ib_main);
@@ -5300,8 +5274,8 @@ read_replacements_section (struct lto_file_decl_data *file_data,
 void
 ipa_prop_read_all_agg_replacement (void)
 {
-  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  lto_file_decl_data *file_data;
   unsigned int j = 0;
 
   while ((file_data = file_data_vec[j++]))
@@ -5319,10 +5293,10 @@ ipa_prop_read_all_agg_replacement (void)
    NODE.  */
 
 static void
-adjust_agg_replacement_values (struct cgraph_node *node,
-			       struct ipa_agg_replacement_value *aggval)
+adjust_agg_replacement_values (cgraph_node *node,
+			       ipa_agg_replacement_value *aggval)
 {
-  struct ipa_agg_replacement_value *v;
+  ipa_agg_replacement_value *v;
   int i, c = 0, d = 0, *adj;
 
   if (!node->clone.combined_args_to_skip)
@@ -5355,9 +5329,9 @@ adjust_agg_replacement_values (struct cgraph_node *node,
 class ipcp_modif_dom_walker : public dom_walker
 {
 public:
-  ipcp_modif_dom_walker (struct func_body_info *fbi,
+  ipcp_modif_dom_walker (func_body_info *fbi,
 			 vec<ipa_param_descriptor> descs,
-			 struct ipa_agg_replacement_value *av,
+			 ipa_agg_replacement_value *av,
 			 bool *sc, bool *cc)
     : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
       m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
@@ -5365,9 +5339,9 @@ public:
   virtual void before_dom_children (basic_block);
 
 private:
-  struct func_body_info *m_fbi;
+  func_body_info *m_fbi;
   vec<ipa_param_descriptor> m_descriptors;
-  struct ipa_agg_replacement_value *m_aggval;
+  ipa_agg_replacement_value *m_aggval;
   bool *m_something_changed, *m_cfg_changed;
 };
 
@@ -5377,7 +5351,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
   gimple_stmt_iterator gsi;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      struct ipa_agg_replacement_value *v;
+      ipa_agg_replacement_value *v;
       gimple stmt = gsi_stmt (gsi);
       tree rhs, val, t;
       HOST_WIDE_INT offset, size;
@@ -5468,11 +5442,11 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
 /* IPCP transformation phase doing propagation of aggregate values.  */
 
 unsigned int
-ipcp_transform_function (struct cgraph_node *node)
+ipcp_transform_function (cgraph_node *node)
 {
   vec<ipa_param_descriptor> descriptors = vNULL;
-  struct func_body_info fbi;
-  struct ipa_agg_replacement_value *aggval;
+  func_body_info fbi;
+  ipa_agg_replacement_value *aggval;
   int param_count;
   bool cfg_changed = false, something_changed = false;
 
@@ -5507,7 +5481,7 @@ ipcp_transform_function (struct cgraph_node *node)
 			 &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
   int i;
-  struct ipa_bb_info *bi;
+  ipa_bb_info *bi;
   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
     free_ipa_bb_info (bi);
   fbi.bb_infos.release ();
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 165fc1a..5e25fd8 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef IPA_PROP_H
 #define IPA_PROP_H
 
-
 /* The following definitions and interfaces are used by
    interprocedural analyses or parameters.  */
 
@@ -356,6 +355,8 @@ struct ipcp_lattice;
 
 struct ipa_node_params
 {
+  ~ipa_node_params ();
+
   /* Information about individual formal parameters that are gathered when
      summaries are generated. */
   vec<ipa_param_descriptor> descriptors;
@@ -364,7 +365,7 @@ struct ipa_node_params
   struct ipcp_param_lattices *lattices;
   /* Only for versioned nodes this field would not be NULL,
      it points to the node that IPA cp cloned from.  */
-  struct cgraph_node *ipcp_orig_node;
+  cgraph_node *ipcp_orig_node;
   /* If this node is an ipa-cp clone, these are the known values that describe
      what it has been specialized for.  */
   vec<tree> known_vals;
@@ -470,7 +471,7 @@ struct GTY(()) ipa_agg_replacement_value
 
 typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
 
-void ipa_set_node_agg_value_chain (struct cgraph_node *node,
+void ipa_set_node_agg_value_chain (const cgraph_node *node,
 				   struct ipa_agg_replacement_value *aggvals);
 
 /* ipa_edge_args stores information related to a callsite and particularly its
@@ -513,10 +514,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Types of vectors holding the infos.  */
+/* Callgraph summary for ipa_node_params.  */
+class ipa_node_params_t: public function_summary <ipa_node_params *>
+{
+public:
+  ipa_node_params_t (symbol_table *table):
+    function_summary<ipa_node_params *> (table) { }
 
-/* Vector where the parameter infos are actually stored. */
-extern vec<ipa_node_params> ipa_node_params_vector;
+  /* Hook that is called by summary when a node is duplicated.  */
+  virtual void duplication_hook (cgraph_node *node,
+				 cgraph_node *node2,
+				 ipa_node_params *data,
+				 ipa_node_params *data2);
+};
+
+/* Function summary where the parameter infos are actually stored. */
+extern ipa_node_params_t *ipa_node_params_d;
 /* Vector of known aggregate values in cloned nodes.  */
 extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
@@ -524,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Return the associated parameter/argument info corresponding to the given
    node/edge.  */
-#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
+#define IPA_NODE_REF(NODE) ((*ipa_node_params_d)[NODE])
 #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
 /* This macro checks validity of index returned by
    ipa_get_param_decl_index function.  */
@@ -534,11 +547,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 void ipa_create_all_node_params (void);
 void ipa_create_all_edge_args (void);
 void ipa_free_edge_args_substructures (struct ipa_edge_args *);
-void ipa_free_node_params_substructures (struct ipa_node_params *);
 void ipa_free_all_node_params (void);
 void ipa_free_all_edge_args (void);
 void ipa_free_all_structures_after_ipa_cp (void);
 void ipa_free_all_structures_after_iinln (void);
+
 void ipa_register_cgraph_hooks (void);
 int count_formal_params (tree fndecl);
 
@@ -548,11 +561,8 @@ int count_formal_params (tree fndecl);
 static inline void
 ipa_check_create_node_params (void)
 {
-  if (!ipa_node_params_vector.exists ())
-    ipa_node_params_vector.create (symtab->cgraph_max_uid);
-
-  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
-    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
+  if (!ipa_node_params_d)
+    ipa_node_params_d = new ipa_node_params_t (symtab);
 }
 
 /* This function ensures the array of edge arguments infos is big enough to
@@ -579,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
 /* Return the aggregate replacements for NODE, if there are any.  */
 
 static inline struct ipa_agg_replacement_value *
-ipa_get_agg_replacements_for_node (struct cgraph_node *node)
+ipa_get_agg_replacements_for_node (const cgraph_node *node)
 {
   if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
     return NULL;
@@ -587,7 +597,7 @@ ipa_get_agg_replacements_for_node (struct cgraph_node *node)
 }
 
 /* Function formal parameters related computations.  */
-void ipa_initialize_node_params (struct cgraph_node *node);
+void ipa_initialize_node_params (const cgraph_node *node);
 bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
 					vec<cgraph_edge *> *new_edges);
 
@@ -602,7 +612,7 @@ tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
 tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
 
 /* Functions related to both.  */
-void ipa_analyze_node (struct cgraph_node *);
+void ipa_analyze_node (cgraph_node *);
 
 /* Aggregate jump function related functions.  */
 tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
@@ -611,9 +621,9 @@ bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
 			     HOST_WIDE_INT *, bool *);
 
 /* Debugging interface.  */
-void ipa_print_node_params (FILE *, struct cgraph_node *node);
+void ipa_print_node_params (FILE *, cgraph_node *node);
 void ipa_print_all_params (FILE *);
-void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
+void ipa_print_node_jump_functions (FILE *f, cgraph_node *node);
 void ipa_print_all_jump_functions (FILE * f);
 void ipcp_verify_propagated_values (void);
 
@@ -717,7 +727,7 @@ void ipa_update_after_lto_read (void);
 int ipa_get_param_decl_index (struct ipa_node_params *, tree);
 tree ipa_value_from_jfunc (struct ipa_node_params *info,
 			   struct ipa_jump_func *jfunc);
-unsigned int ipcp_transform_function (struct cgraph_node *node);
+unsigned int ipcp_transform_function (cgraph_node *node);
 void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
 bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
 ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 98dbc63..16684e2 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "gimple-ssa.h"
 #include "tree-cfg.h"
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 22900cc..e2f8bd2 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa.c b/gcc/ipa.c
index a6086d8..80b8561 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-iterator.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 0e1a95b..3a2f9ed 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "ipa-utils.h"
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 4c4e48a..1afdf73 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "builtins.h"
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index d8519d9..d151522 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "inchash.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "common.h"
 #include "debug.h"
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b59d069..cf51306 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfgcleanup.h"
 #include "pretty-print.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-nested.h"
 #include "tree-eh.h"
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index 893f065..fa7c768 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -166,7 +166,7 @@ public:
     function_summary *summary = (function_summary <T *> *) (data);
 
     if (summary->m_insertion_enabled)
-      summary->insertion_hook (node, (*summary)[node]);
+      summary->insert (node, (*summary)[node]);
   }
 
   /* Symbol removal hook that is registered to symbol table.  */
@@ -180,7 +180,7 @@ public:
 
     if (v)
       {
-	summary->removal_hook (node, *v);
+	summary->remove (node, *v);
 
 	if (!summary->m_ggc)
 	  delete (*v);
@@ -204,7 +204,7 @@ public:
 	T *data = *v;
 	T *duplicate = summary->allocate_new ();
 	summary->m_map->put (node2->summary_uid, duplicate);
-	summary->duplication_hook (node, node2, data, (*summary)[node2]);
+	summary->duplicate (node, node2, data, (*summary)[node2]);
       }
   }
 
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 8cb9510..d49d952 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "value-prof.h"
 #include "tree-pass.h"
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 1e629bc..e0c375d 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "statistics.h"
 #include "params.h"
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ea99198..c2e5907 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-ssa-propagate.h"
 #include "ipa-utils.h"
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-13 16:04   ` Jan Hubicka
@ 2014-11-14 14:13     ` Martin Liška
  2014-11-14 15:32       ` Martin Liška
  2014-11-14 16:07       ` Jan Hubicka
  0 siblings, 2 replies; 40+ messages in thread
From: Martin Liška @ 2014-11-14 14:13 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3463 bytes --]

On 11/13/2014 05:04 PM, Jan Hubicka wrote:
>> +  if (!inline_summary_summary)
>> +    inline_summary_summary = (inline_summary_cgraph_summary *) inline_summary_cgraph_summary::create_ggc (symtab);
>
> Hehe, this is funny naming scheme.
> Peraps inline_summary_d and inline_summary_t for the data and type?

Hello.

I adopted suggested naming scheme.

>> -
>> -static void
>> -inline_node_duplication_hook (struct cgraph_node *src,
>> -			      struct cgraph_node *dst,
>> -			      ATTRIBUTE_UNUSED void *data)
>> +void
>> +inline_summary_cgraph_summary::duplication_hook (cgraph_node *src,
>> +			      cgraph_node *dst,
>> +			      inline_summary *,
>> +			      inline_summary *info)
>
> Becuase those are no longer "hooks" but virtual function, I guess we could call them
> simply duplicate/insert/remove.

Agree with the change.

>
> In a way I would like to see these to be methods of the underlying type rather than
> virtual methods of the summary, becuase these are operations on the data themselves.
> I was thinking to model these by specual constructor and copy constructor
> (taking the extra node pointer parameters) and standard destructor.  I am not sure this
> would be more understandable this way?

Motivation for this implementation is:
a) it's useful to have an access to cgraph_node that is associated with a sumary
b) with GTY, we cannot call destructors

>> -/* Need a typedef for inline_summary because of inline function
>> -   'inline_summary' below.  */
>> -typedef struct inline_summary inline_summary_t;
>> -extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
>> +class GTY((user)) inline_summary_cgraph_summary: public cgraph_summary <inline_summary *>
>> +{
>> +public:
>> +  inline_summary_cgraph_summary (symbol_table *symtab, bool ggc):
>> +    cgraph_summary <inline_summary *> (symtab, ggc) {}
>> +
>> +  static inline_summary_cgraph_summary *create_ggc (symbol_table *symtab)
>> +  {
>> +    inline_summary_cgraph_summary *summary = new (ggc_cleared_alloc <inline_summary_cgraph_summary> ()) inline_summary_cgraph_summary(symtab, true);
>> +    summary->disable_insertion_hook ();
>> +    return summary;
>> +  }
>> +
>> +
>> +  virtual void insertion_hook (cgraph_node *, inline_summary *);
>> +  virtual void removal_hook (cgraph_node *node, inline_summary *);
>> +  virtual void duplication_hook (cgraph_node *src, cgraph_node *dst, inline_summary *src_data, inline_summary *dst_data);
>> +};
>> +
>> +extern GTY(()) cgraph_summary <inline_summary *> *inline_summary_summary;
>
> All in all it looks better than original code.  If we moved insert/
>>
>>   /* Information kept about parameter of call site.  */
>>   struct inline_param_summary
>> @@ -249,10 +265,10 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
>>   extern int ncalls_inlined;
>>   extern int nfunctions_inlined;
>>
>> -static inline struct inline_summary *
>> -inline_summary (struct cgraph_node *node)
>> +static inline inline_summary *
>> +get_inline_summary (const struct cgraph_node *node)
>>   {
>> -  return &(*inline_summary_vec)[node->uid];
>> +  return (*inline_summary_summary)[node->summary_uid];
>
> Hmm, i guess there is no way to avoid the (*...)? Otherwise it would be cleaner
> to use inline_summary[...] instead of get_inline_summary IMO.

I added function_summary::get method, where the usage looks cleaner:
inline_summary_d->get (node).

Thanks,
Martin
  
> Thanks for working on this!
> Honza
>


[-- Attachment #2: 0003-Data-structure-is-used-for-inline_summary-struct.patch --]
[-- Type: text/x-patch, Size: 46103 bytes --]

From 6e8531d8d3659524e337c7c1d96596952c3ff0e8 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 14 Nov 2014 14:54:12 +0100
Subject: [PATCH 3/3] Data structure is used for inline_summary struct.

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* cgraphunit.c (symbol_table::process_new_functions):
	inline_summary_vec is replaced with inline_summary_t.
	* ipa-cp.c (ipcp_cloning_candidate_p): Usage of inline_summary_d::get.
	(devirtualization_time_bonus): Likewise.
	(estimate_local_effects): Likewise.
	(ipcp_propagate_stage): Likewise.
	* ipa-inline-analysis.c (evaluate_conditions_for_known_args): Likewise.
	(evaluate_properties_for_edge): Likewise.
	(inline_summary_alloc): Deletion of old hook holders.
	(reset_inline_summary): inline_summary is added as argument.
	(inline_summary_cgraph_summary::removal_hook): New function.
	(inline_summary_cgraph_summary::duplication_hook): Likewise.
	(dump_inline_edge_summary): Struct keyword removed.
	(dump_inline_summary): Likewise.
	(estimate_function_body_sizes): Usage of inline_summary_d::get.
	(compute_inline_parameters): Likewise.
	(estimate_edge_devirt_benefit): Struct keyword removed.
	(estimate_node_size_and_time): Likewise.
	(inline_update_callee_summaries): Likewise.
	(inline_merge_summary): Usage of inline_summary_d::get.
	(inline_update_overall_summary): Likewise.
	(simple_edge_hints): Likewise.
	(do_estimate_edge_time): Likewise.
	(estimate_time_after_inlining): Likewise.
	(estimate_size_after_inlining): Likewise.
	(do_estimate_growth): Likewise.
	(growth_likely_positive): Likewise.
	(inline_generate_summary): inline_summary_t is registered.
	(inline_read_section): Struct keyword removed.
	(inline_read_summary): Likewise.
	(inline_write_summary): Likewise.
	(inline_free_summary): Removal of old hook holders.
	* ipa-inline-transform.c (clone_inlined_nodes): Usage of
	inline_summary_d::get.
	(inline_call): Likewise.
	* ipa-inline.c (caller_growth_limits): Struct keyword is removed.
	(can_inline_edge_p): Usage of inline_summary_d::get.
	(want_early_inline_function_p): Struct keyword removed.
	(compute_uninlined_call_time): Usage of inline_summary_d::get.
	(compute_inlined_call_time): Likewise.
	(big_speedup_p): Likewise.
	(want_inline_small_function_p): Likewise.
	(edge_badness): Likewise.
	(update_caller_keys): Likewise.
	(update_callee_keys): Likewise.
	(recursive_inlining): Likewise.
	(inline_small_functions): Likewise.
	(inline_to_all_callers): Likewise.
	(dump_overall_stats): Likewise.
	(early_inline_small_functions): Likewise.
	* ipa-inline.h (inline_summary_d::get): New function.
	* ipa-split.c (execute_split_functions): Usage of inline_summary_d::get.
	* ipa.c (walk_polymorphic_call_targets): inline_summary_vec is replaced with inline_summary_t.
	* tree-sra.c (ipa_sra_preliminary_function_checks): Usage of inline_summary_d::get.

gcc/lto/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* lto-partition.c (add_symbol_to_partition_1): Usage of
	inline_summary_d::get.
	(undo_partition): Likewise.
	(lto_balanced_map): Likewise.
---
 gcc/cgraphunit.c           |   2 +-
 gcc/ipa-cp.c               |  10 +--
 gcc/ipa-inline-analysis.c  | 193 ++++++++++++++++++++-------------------------
 gcc/ipa-inline-transform.c |   6 +-
 gcc/ipa-inline.c           |  61 +++++++-------
 gcc/ipa-inline.h           |  32 +++++---
 gcc/ipa-prop.h             |   4 +-
 gcc/ipa-split.c            |   2 +-
 gcc/ipa.c                  |   2 +-
 gcc/lto/lto-partition.c    |  10 +--
 gcc/tree-sra.c             |   2 +-
 11 files changed, 155 insertions(+), 169 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 93f8d91..7486f2a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -338,7 +338,7 @@ symbol_table::process_new_functions (void)
 	  if (state == IPA_SSA
 	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
 	    g->get_passes ()->execute_early_local_passes ();
-	  else if (inline_summary_vec != NULL)
+	  else if (inline_summary_d != NULL)
 	    compute_inline_parameters (node, true);
 	  free_dominance_info (CDI_POST_DOMINATORS);
 	  free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 56d1ae9..14684de 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -552,7 +552,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
   init_caller_stats (&stats);
   node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
 
-  if (inline_summary (node)->self_size < stats.n_calls)
+  if (inline_summary_d->get (node)->self_size < stats.n_calls)
     {
       if (dump_file)
         fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
@@ -1718,7 +1718,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
     {
       struct cgraph_node *callee;
-      struct inline_summary *isummary;
+      inline_summary *isummary;
       enum availability avail;
       tree target;
 
@@ -1735,7 +1735,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
       callee = callee->function_symbol (&avail);
       if (avail < AVAIL_AVAILABLE)
 	continue;
-      isummary = inline_summary (callee);
+      isummary = inline_summary_d->get (callee);
       if (!isummary->inlinable)
 	continue;
 
@@ -1945,7 +1945,7 @@ estimate_local_effects (struct cgraph_node *node)
   vec<ipa_agg_jump_function> known_aggs;
   vec<ipa_agg_jump_function_p> known_aggs_ptrs;
   bool always_const;
-  int base_time = inline_summary (node)->time;
+  int base_time = inline_summary_d->get (node)->time;
   int removable_params_cost;
 
   if (!count || !ipcp_versionable_function_p (node))
@@ -2357,7 +2357,7 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
 	initialize_node_lattices (node);
       }
     if (node->definition && !node->alias)
-      overall_size += inline_summary (node)->self_size;
+      overall_size += inline_summary_d->get (node)->self_size;
     if (node->count > max_count)
       max_count = node->count;
   }
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 84da4dc..f0a343a 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -148,21 +148,15 @@ enum predicate_conditions
 #define CHANGED IDENTIFIER_NODE
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static void inline_node_removal_hook (struct cgraph_node *, void *);
-static void inline_node_duplication_hook (struct cgraph_node *,
-					  struct cgraph_node *, void *);
 static void inline_edge_removal_hook (struct cgraph_edge *, void *);
 static void inline_edge_duplication_hook (struct cgraph_edge *,
 					  struct cgraph_edge *, void *);
 
 /* VECtor holding inline summaries.  
    In GGC memory because conditions might point to constant trees.  */
-vec<inline_summary_t, va_gc> *inline_summary_vec;
+function_summary <inline_summary *> *inline_summary_d;
 vec<inline_edge_summary_t> inline_edge_summary_vec;
 
 /* Cached node/edge growths.  */
@@ -699,7 +693,7 @@ dump_inline_hints (FILE *f, inline_hints hints)
 /* Record SIZE and TIME under condition PRED into the inline summary.  */
 
 static void
-account_size_time (struct inline_summary *summary, int size, int time,
+account_size_time (inline_summary *summary, int size, int time,
 		   struct predicate *pred)
 {
   size_time_entry *e;
@@ -829,7 +823,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 				    known_aggs)
 {
   clause_t clause = inline_p ? 0 : 1 << predicate_not_inlined_condition;
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   int i;
   struct condition *c;
 
@@ -900,7 +894,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 			      vec<ipa_agg_jump_function_p> *known_aggs_ptr)
 {
   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-  struct inline_summary *info = inline_summary (callee);
+  inline_summary *info = inline_summary_d->get (callee);
   vec<tree> known_vals = vNULL;
   vec<ipa_agg_jump_function_p> known_aggs = vNULL;
 
@@ -974,21 +968,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 static void
 inline_summary_alloc (void)
 {
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&inline_node_removal_hook, NULL);
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&inline_node_duplication_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
 
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) symtab->cgraph_max_uid)
-    vec_safe_grow_cleared (inline_summary_vec, symtab->cgraph_max_uid + 1);
+  if (!inline_summary_d)
+    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
   if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid)
     inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
   if (!edge_predicate_pool)
@@ -1018,9 +1007,9 @@ reset_inline_edge_summary (struct cgraph_edge *e)
    data from previous run so they are not cumulated.  */
 
 static void
-reset_inline_summary (struct cgraph_node *node)
+reset_inline_summary (const struct cgraph_node *node,
+		      inline_summary *info)
 {
-  struct inline_summary *info = inline_summary (node);
   struct cgraph_edge *e;
 
   info->self_size = info->self_time = 0;
@@ -1056,16 +1045,10 @@ reset_inline_summary (struct cgraph_node *node)
 
 /* Hook that is called by cgraph.c when a node is removed.  */
 
-static void
-inline_node_removal_hook (struct cgraph_node *node,
-			  void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::remove (cgraph_node *node, inline_summary *info)
 {
-  struct inline_summary *info;
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) node->uid)
-    return;
-  info = inline_summary (node);
-  reset_inline_summary (node);
-  memset (info, 0, sizeof (inline_summary_t));
+  reset_inline_summary (node, info);
 }
 
 /* Remap predicate P of former function to be predicate of duplicated function.
@@ -1075,7 +1058,7 @@ inline_node_removal_hook (struct cgraph_node *node,
 static struct predicate
 remap_predicate_after_duplication (struct predicate *p,
 				   clause_t possible_truths,
-				   struct inline_summary *info)
+				   inline_summary *info)
 {
   struct predicate new_predicate = true_predicate ();
   int j;
@@ -1099,7 +1082,7 @@ remap_predicate_after_duplication (struct predicate *p,
 static void
 remap_hint_predicate_after_duplication (struct predicate **p,
 					clause_t possible_truths,
-					struct inline_summary *info)
+					inline_summary *info)
 {
   struct predicate new_predicate;
 
@@ -1115,16 +1098,14 @@ remap_hint_predicate_after_duplication (struct predicate **p,
 
 
 /* Hook that is called by cgraph.c when a node is duplicated.  */
-
-static void
-inline_node_duplication_hook (struct cgraph_node *src,
-			      struct cgraph_node *dst,
-			      ATTRIBUTE_UNUSED void *data)
+void
+inline_summary_t::duplicate (cgraph_node *src,
+			     cgraph_node *dst,
+			     inline_summary *,
+			     inline_summary *info)
 {
-  struct inline_summary *info;
   inline_summary_alloc ();
-  info = inline_summary (dst);
-  memcpy (info, inline_summary (src), sizeof (struct inline_summary));
+  memcpy (info, inline_summary_d->get (src), sizeof (inline_summary));
   /* TODO: as an optimization, we may avoid copying conditions
      that are known to be false or true.  */
   info->conds = vec_safe_copy (info->conds);
@@ -1328,7 +1309,7 @@ free_growth_caches (void)
 
 static void
 dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
-			  struct inline_summary *info)
+			  inline_summary *info)
 {
   struct cgraph_edge *edge;
   for (edge = node->callees; edge; edge = edge->next_callee)
@@ -1345,8 +1326,8 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
 	       indent, "", es->loop_depth, edge->frequency,
 	       es->call_stmt_size, es->call_stmt_time,
-	       (int) inline_summary (callee)->size / INLINE_SIZE_SCALE,
-	       (int) inline_summary (callee)->estimated_stack_size);
+	       (int) inline_summary_d->get (callee)->size / INLINE_SIZE_SCALE,
+	       (int) inline_summary_d->get (callee)->estimated_stack_size);
 
       if (es->predicate)
 	{
@@ -1372,9 +1353,9 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
 		   " callee size %i\n",
 		   indent + 2, "",
-		   (int) inline_summary (callee)->stack_frame_offset,
-		   (int) inline_summary (callee)->estimated_self_stack_size,
-		   (int) inline_summary (callee)->estimated_stack_size);
+		   (int) inline_summary_d->get (callee)->stack_frame_offset,
+		   (int) inline_summary_d->get (callee)->estimated_self_stack_size,
+		   (int) inline_summary_d->get (callee)->estimated_stack_size);
 	  dump_inline_edge_summary (f, indent + 2, callee, info);
 	}
     }
@@ -1402,7 +1383,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
 {
   if (node->definition)
     {
-      struct inline_summary *s = inline_summary (node);
+      inline_summary *s = inline_summary_d->get (node);
       size_time_entry *e;
       int i;
       fprintf (f, "Inline summary for %s/%i", node->name (),
@@ -1725,7 +1706,7 @@ eliminated_by_inlining_prob (gimple stmt)
 
 static void
 set_cond_stmt_execution_predicate (struct ipa_node_params *info,
-				   struct inline_summary *summary,
+				   inline_summary *summary,
 				   basic_block bb)
 {
   gimple last;
@@ -1810,7 +1791,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
 
 static void
 set_switch_stmt_execution_predicate (struct ipa_node_params *info,
-				     struct inline_summary *summary,
+				     inline_summary *summary,
 				     basic_block bb)
 {
   gimple last;
@@ -1871,7 +1852,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
 static void
 compute_bb_predicates (struct cgraph_node *node,
 		       struct ipa_node_params *parms_info,
-		       struct inline_summary *summary)
+		       inline_summary *summary)
 {
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   bool done = false;
@@ -1950,7 +1931,7 @@ typedef struct predicate predicate_t;
 
 static struct predicate
 will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
-				    struct inline_summary *summary,
+				    inline_summary *summary,
 				    tree expr,
 				    vec<predicate_t> nonconstant_names)
 {
@@ -2013,7 +1994,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
 
 static struct predicate
 will_be_nonconstant_predicate (struct ipa_node_params *info,
-			       struct inline_summary *summary,
+			       inline_summary *summary,
 			       gimple stmt,
 			       vec<predicate_t> nonconstant_names)
 {
@@ -2215,7 +2196,7 @@ param_change_prob (gimple stmt, int i)
 
 static bool
 phi_result_unknown_predicate (struct ipa_node_params *info,
-			      struct inline_summary *summary, basic_block bb,
+			      inline_summary *summary, basic_block bb,
 			      struct predicate *p,
 			      vec<predicate_t> nonconstant_names)
 {
@@ -2274,7 +2255,7 @@ phi_result_unknown_predicate (struct ipa_node_params *info,
    NONCONSTANT_NAMES, if possible.  */
 
 static void
-predicate_for_phi_result (struct inline_summary *summary, gimple phi,
+predicate_for_phi_result (inline_summary *summary, gimple phi,
 			  struct predicate *p,
 			  vec<predicate_t> nonconstant_names)
 {
@@ -2304,7 +2285,7 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
 /* Return predicate specifying when array index in access OP becomes non-constant.  */
 
 static struct predicate
-array_index_predicate (struct inline_summary *info,
+array_index_predicate (inline_summary *info,
 		       vec< predicate_t> nonconstant_names, tree op)
 {
   struct predicate p = false_predicate ();
@@ -2460,7 +2441,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   gimple_stmt_iterator bsi;
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   int freq;
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   struct predicate bb_predicate;
   struct ipa_node_params *parms_info = NULL;
   vec<predicate_t> nonconstant_names = vNULL;
@@ -2702,7 +2683,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	}
     }
-  set_hint_predicate (&inline_summary (node)->array_index, array_index);
+  set_hint_predicate (&inline_summary_d->get (node)->array_index, array_index);
   time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
   if (time > MAX_TIME)
     time = MAX_TIME;
@@ -2790,9 +2771,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	  free (body);
 	}
-      set_hint_predicate (&inline_summary (node)->loop_iterations,
+      set_hint_predicate (&inline_summary_d->get (node)->loop_iterations,
 			  loop_iterations);
-      set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
+      set_hint_predicate (&inline_summary_d->get (node)->loop_stride, loop_stride);
       scev_finalize ();
     }
   FOR_ALL_BB_FN (bb, my_function)
@@ -2810,8 +2791,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	  e->aux = NULL;
 	}
     }
-  inline_summary (node)->self_time = time;
-  inline_summary (node)->self_size = size;
+  inline_summary_d->get (node)->self_time = time;
+  inline_summary_d->get (node)->self_size = size;
   nonconstant_names.release ();
   if (optimize && !early)
     {
@@ -2834,14 +2815,14 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
 {
   HOST_WIDE_INT self_stack_size;
   struct cgraph_edge *e;
-  struct inline_summary *info;
+  inline_summary *info;
 
   gcc_assert (!node->global.inlined_to);
 
   inline_summary_alloc ();
 
-  info = inline_summary (node);
-  reset_inline_summary (node);
+  info = inline_summary_d->get (node);
+  reset_inline_summary (node, info);
 
   /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
      Once this happen, we will need to more curefully predict call
@@ -2982,7 +2963,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
 {
   tree target;
   struct cgraph_node *callee;
-  struct inline_summary *isummary;
+  inline_summary *isummary;
   enum availability avail;
 
   if (!known_vals.exists () && !known_binfos.exists ())
@@ -3007,7 +2988,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
   callee = callee->function_symbol (&avail);
   if (avail < AVAIL_AVAILABLE)
     return false;
-  isummary = inline_summary (callee);
+  isummary = inline_summary_d->get (callee);
   return isummary->inlinable;
 }
 
@@ -3120,7 +3101,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
 			     vec<inline_param_summary>
 			     inline_param_summary)
 {
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   size_time_entry *e;
   int size = 0;
   int time = 0;
@@ -3246,8 +3227,8 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
    for other purposes).  */
 
 static struct predicate
-remap_predicate (struct inline_summary *info,
-		 struct inline_summary *callee_info,
+remap_predicate (inline_summary *info,
+		 inline_summary *callee_info,
 		 struct predicate *p,
 		 vec<int> operand_map,
 		 vec<int> offset_map,
@@ -3336,8 +3317,8 @@ static void
 inline_update_callee_summaries (struct cgraph_node *node, int depth)
 {
   struct cgraph_edge *e;
-  struct inline_summary *callee_info = inline_summary (node);
-  struct inline_summary *caller_info = inline_summary (node->callers->caller);
+  inline_summary *callee_info = inline_summary_d->get (node);
+  inline_summary *caller_info = inline_summary_d->get (node->callers->caller);
   HOST_WIDE_INT peak;
 
   callee_info->stack_frame_offset
@@ -3345,8 +3326,8 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
     + caller_info->estimated_self_stack_size;
   peak = callee_info->stack_frame_offset
     + callee_info->estimated_self_stack_size;
-  if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
-      inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
+  if (inline_summary_d->get (node->global.inlined_to)->estimated_stack_size < peak)
+      inline_summary_d->get (node->global.inlined_to)->estimated_stack_size = peak;
   ipa_propagate_frequency (node);
   for (e = node->callees; e; e = e->next_callee)
     {
@@ -3407,8 +3388,8 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 static void
 remap_edge_summaries (struct cgraph_edge *inlined_edge,
 		      struct cgraph_node *node,
-		      struct inline_summary *info,
-		      struct inline_summary *callee_info,
+		      inline_summary *info,
+		      inline_summary *callee_info,
 		      vec<int> operand_map,
 		      vec<int> offset_map,
 		      clause_t possible_truths,
@@ -3476,8 +3457,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
 /* Same as remap_predicate, but set result into hint *HINT.  */
 
 static void
-remap_hint_predicate (struct inline_summary *info,
-		      struct inline_summary *callee_info,
+remap_hint_predicate (inline_summary *info,
+		      inline_summary *callee_info,
 		      struct predicate **hint,
 		      vec<int> operand_map,
 		      vec<int> offset_map,
@@ -3506,10 +3487,10 @@ remap_hint_predicate (struct inline_summary *info,
 void
 inline_merge_summary (struct cgraph_edge *edge)
 {
-  struct inline_summary *callee_info = inline_summary (edge->callee);
+  inline_summary *callee_info = inline_summary_d->get (edge->callee);
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  struct inline_summary *info = inline_summary (to);
+  inline_summary *info = inline_summary_d->get (to);
   clause_t clause = 0;		/* not_inline is known to be false.  */
   size_time_entry *e;
   vec<int> operand_map = vNULL;
@@ -3618,7 +3599,7 @@ inline_merge_summary (struct cgraph_edge *edge)
 void
 inline_update_overall_summary (struct cgraph_node *node)
 {
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   size_time_entry *e;
   int i;
 
@@ -3645,8 +3626,8 @@ simple_edge_hints (struct cgraph_edge *edge)
   int hints = 0;
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  if (inline_summary (to)->scc_no
-      && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
+  if (inline_summary_d->get (to)->scc_no
+      && inline_summary_d->get (to)->scc_no == inline_summary_d->get (edge->callee)->scc_no
       && !edge->recursive_p ())
     hints |= INLINE_HINT_same_scc;
 
@@ -3706,7 +3687,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
   /* When caching, update the cache entry.  */
   if (edge_growth_cache.exists ())
     {
-      inline_summary (edge->callee)->min_size = min_size;
+      inline_summary_d->get (edge->callee)->min_size = min_size;
       if ((int) edge_growth_cache.length () <= edge->uid)
 	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
       edge_growth_cache[edge->uid].time = time + (time >= 0);
@@ -3808,14 +3789,14 @@ estimate_time_after_inlining (struct cgraph_node *node,
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
       gcov_type time =
-	inline_summary (node)->time + estimate_edge_time (edge);
+	inline_summary_d->get (node)->time + estimate_edge_time (edge);
       if (time < 0)
 	time = 0;
       if (time > MAX_TIME)
 	time = MAX_TIME;
       return time;
     }
-  return inline_summary (node)->time;
+  return inline_summary_d->get (node)->time;
 }
 
 
@@ -3829,11 +3810,11 @@ estimate_size_after_inlining (struct cgraph_node *node,
   struct inline_edge_summary *es = inline_edge_summary (edge);
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
-      int size = inline_summary (node)->size + estimate_edge_growth (edge);
+      int size = inline_summary_d->get (node)->size + estimate_edge_growth (edge);
       gcc_assert (size >= 0);
       return size;
     }
-  return inline_summary (node)->size;
+  return inline_summary_d->get (node)->size;
 }
 
 
@@ -3873,7 +3854,7 @@ int
 do_estimate_growth (struct cgraph_node *node)
 {
   struct growth_data d = { node, 0, false };
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
 
   node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
 
@@ -3946,7 +3927,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
       && (!DECL_COMDAT (node->decl)
 	  || !node->can_remove_if_no_direct_calls_p ()))
     return true;
-  max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
+  max_callers = inline_summary_d->get (node)->size * 4 / edge_growth + 2;
 
   for (e = node->callers; e; e = e->next_caller)
     {
@@ -4009,13 +3990,12 @@ inline_analyze_function (struct cgraph_node *node)
 
 /* Called when new function is inserted to callgraph late.  */
 
-static void
-add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::insert (cgraph_node *node, inline_summary *)
 {
   inline_analyze_function (node);
 }
 
-
 /* Note function body size.  */
 
 void
@@ -4028,8 +4008,10 @@ inline_generate_summary (void)
   if (!optimize && !flag_lto && !flag_wpa)
     return;
 
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+  if (!inline_summary_d)
+    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
+  inline_summary_d->enable_insertion_hook ();
 
   ipa_register_cgraph_hooks ();
   inline_free_summary ();
@@ -4113,7 +4095,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
     {
       unsigned int index;
       struct cgraph_node *node;
-      struct inline_summary *info;
+      inline_summary *info;
       lto_symtab_encoder_t encoder;
       struct bitpack_d bp;
       struct cgraph_edge *e;
@@ -4123,7 +4105,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
       encoder = file_data->symtab_node_encoder;
       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
 								index));
-      info = inline_summary (node);
+      info = inline_summary_d->get (node);
 
       info->estimated_stack_size
 	= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
@@ -4212,8 +4194,9 @@ inline_read_summary (void)
       if (!flag_ipa_cp)
 	ipa_prop_read_jump_functions ();
     }
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+
+  gcc_assert (inline_summary_d);
+  inline_summary_d->enable_insertion_hook ();
 }
 
 
@@ -4279,7 +4262,7 @@ inline_write_summary (void)
       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
       if (cnode && (node = cnode)->definition && !node->alias)
 	{
-	  struct inline_summary *info = inline_summary (node);
+	  inline_summary *info = inline_summary_d->get (node);
 	  struct bitpack_d bp;
 	  struct cgraph_edge *edge;
 	  int i;
@@ -4344,23 +4327,15 @@ inline_free_summary (void)
     return;
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->alias)
-      reset_inline_summary (node);
-  if (function_insertion_hook_holder)
-    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
-  function_insertion_hook_holder = NULL;
-  if (node_removal_hook_holder)
-    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
+      reset_inline_summary (node, inline_summary_d->get (node));
   if (edge_removal_hook_holder)
     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  if (node_duplication_hook_holder)
-    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   if (edge_duplication_hook_holder)
     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  vec_free (inline_summary_vec);
+  inline_summary_d->destroy ();
+  inline_summary_d = NULL;
   inline_edge_summary_vec.release ();
   if (edge_predicate_pool)
     free_alloc_pool (edge_predicate_pool);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 49c2679..841af60 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
 	  if (e->callee->definition && !DECL_EXTERNAL (e->callee->decl))
 	    {
 	      if (overall_size)
-	        *overall_size -= inline_summary (e->callee)->size;
+	        *overall_size -= inline_summary_d->get (e->callee)->size;
 	      nfunctions_inlined++;
 	    }
 	  duplicate = false;
@@ -309,13 +309,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   gcc_assert (curr->callee->global.inlined_to == to);
 
-  old_size = inline_summary (to)->size;
+  old_size = inline_summary_d->get (to)->size;
   inline_merge_summary (e);
   if (optimize)
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   if (update_overall_summary)
    inline_update_overall_summary (to);
-  new_size = inline_summary (to)->size;
+  new_size = inline_summary_d->get (to)->size;
 
   if (callee->calls_comdat_local)
     to->calls_comdat_local = true;
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index a8e94e2..73fb286 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -167,7 +167,7 @@ caller_growth_limits (struct cgraph_edge *e)
   int newsize;
   int limit = 0;
   HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
-  struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
+  inline_summary *info, *what_info, *outer_info = inline_summary_d->get (to);
 
   /* Look for function e->caller is inlined to.  While doing
      so work out the largest function body on the way.  As
@@ -179,7 +179,7 @@ caller_growth_limits (struct cgraph_edge *e)
      too much in order to prevent compiler from exploding".  */
   while (true)
     {
-      info = inline_summary (to);
+      info = inline_summary_d->get (to);
       if (limit < info->self_size)
 	limit = info->self_size;
       if (stack_size_limit < info->estimated_self_stack_size)
@@ -190,7 +190,7 @@ caller_growth_limits (struct cgraph_edge *e)
 	break;
     }
 
-  what_info = inline_summary (what);
+  what_info = inline_summary_d->get (what);
 
   if (limit < what_info->self_size)
     limit = what_info->self_size;
@@ -304,7 +304,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_USES_COMDAT_LOCAL;
       inlinable = false;
     }
-  else if (!inline_summary (callee)->inlinable 
+  else if (!inline_summary_d->get (callee)->inlinable 
 	   || (caller_fun && fn_contains_cilk_spawn_p (caller_fun)))
     {
       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
@@ -458,7 +458,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     ;
-  /* For AutoFDO, we need to make sure that before profile annotation, all
+  /* For AutoFDO, we need to make sure that before profile summary, all
      hot paths' IR look exactly the same as profiled binary. As a result,
      in einliner, we will disregard size limit and inline those callsites
      that are:
@@ -524,13 +524,12 @@ want_early_inline_function_p (struct cgraph_edge *e)
    does not happen.  */
 
 inline gcov_type
-compute_uninlined_call_time (struct inline_summary *callee_info,
-			     struct cgraph_edge *edge)
+compute_uninlined_call_time (inline_summary *callee_info, cgraph_edge *edge)
 {
   gcov_type uninlined_call_time =
     RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
 	  CGRAPH_FREQ_BASE);
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
 				          ? edge->caller->global.inlined_to
 				          : edge->caller)->time;
   return uninlined_call_time + caller_time;
@@ -543,7 +542,7 @@ inline gcov_type
 compute_inlined_call_time (struct cgraph_edge *edge,
 			   int edge_time)
 {
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
 					  ? edge->caller->global.inlined_to
 					  : edge->caller)->time;
   gcov_type time = (caller_time
@@ -563,7 +562,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
 static bool
 big_speedup_p (struct cgraph_edge *e)
 {
-  gcov_type time = compute_uninlined_call_time (inline_summary (e->callee),
+  gcov_type time = compute_uninlined_call_time (inline_summary_d->get (e->callee),
 					  	e);
   gcov_type inlined_time = compute_inlined_call_time (e,
 					              estimate_edge_time (e));
@@ -596,7 +595,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
      MAX_INLINE_INSNS_SINGLE 16-fold for inline functions.  */
   else if ((!DECL_DECLARED_INLINE_P (callee->decl)
 	   && (!e->count || !e->maybe_hot_p ()))
-	   && inline_summary (callee)->min_size
+	   && inline_summary_d->get (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
     {
@@ -604,7 +603,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
       want_inline = false;
     }
   else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
-	   && inline_summary (callee)->min_size
+	   && inline_summary_d->get (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > 16 * MAX_INLINE_INSNS_SINGLE)
     {
@@ -867,8 +866,8 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
    1...RELATIVE_TIME_BENEFIT_RANGE  */
 
 static inline int
-relative_time_benefit (struct inline_summary *callee_info,
-		       struct cgraph_edge *edge,
+relative_time_benefit (inline_summary *callee_info,
+		       cgraph_edge *edge,
 		       int edge_time)
 {
   gcov_type relbenefit;
@@ -913,7 +912,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   gcov_type badness;
   int growth, edge_time;
   struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
-  struct inline_summary *callee_info = inline_summary (callee);
+  inline_summary *callee_info = inline_summary_d->get (callee);
   inline_hints hints;
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
@@ -1188,7 +1187,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
   struct cgraph_edge *edge;
   struct ipa_ref *ref;
 
-  if ((!node->alias && !inline_summary (node)->inlinable)
+  if ((!node->alias && !inline_summary_d->get (node)->inlinable)
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->uid))
@@ -1246,7 +1245,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
            don't need updating.  */
 	if (e->inline_failed
 	    && (callee = e->callee->ultimate_alias_target (&avail))
-	    && inline_summary (callee)->inlinable
+	    && inline_summary_d->get (callee)->inlinable
 	    && avail >= AVAIL_AVAILABLE
 	    && !bitmap_bit_p (updated_nodes, callee->uid))
 	  {
@@ -1424,8 +1423,8 @@ recursive_inlining (struct cgraph_edge *edge,
     fprintf (dump_file,
 	     "\n   Inlined %i times, "
 	     "body grown from size %i to %i, time %i to %i\n", n,
-	     inline_summary (master_clone)->size, inline_summary (node)->size,
-	     inline_summary (master_clone)->time, inline_summary (node)->time);
+	     inline_summary_d->get (master_clone)->size, inline_summary_d->get (node)->size,
+	     inline_summary_d->get (master_clone)->time, inline_summary_d->get (node)->time);
 
   /* Remove master clone we used for inlining.  We rely that clones inlined
      into master clone gets queued just before master clone so we don't
@@ -1599,8 +1598,8 @@ inline_small_functions (void)
 	if (node->has_gimple_body_p ()
 	    || node->thunk.thunk_p)
 	  {
-	    struct inline_summary *info = inline_summary (node);
-	    struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
+	    inline_summary *info = inline_summary_d->get (node);
+	    ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
 
 	    /* Do not account external functions, they will be optimized out
 	       if not inlined.  Also only count the non-cold portion of program.  */
@@ -1610,12 +1609,12 @@ inline_small_functions (void)
 	    info->growth = estimate_growth (node);
 	    if (dfs && dfs->next_cycle)
 	      {
-		struct cgraph_node *n2;
+		cgraph_node *n2;
 		int id = dfs->scc_no + 1;
 		for (n2 = node; n2;
 		     n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
 		  {
-		    struct inline_summary *info2 = inline_summary (n2);
+		    inline_summary *info2 = inline_summary_d->get (n2);
 		    if (info2->scc_no)
 		      break;
 		    info2->scc_no = id;
@@ -1735,7 +1734,7 @@ inline_small_functions (void)
 	  fprintf (dump_file,
 		   "\nConsidering %s/%i with %i size\n",
 		   callee->name (), callee->order,
-		   inline_summary (callee)->size);
+		   inline_summary_d->get (callee)->size);
 	  fprintf (dump_file,
 		   " to be inlined into %s/%i in %s:%i\n"
 		   " Estimated badness is %i, frequency %.2f.\n",
@@ -1853,8 +1852,8 @@ inline_small_functions (void)
 		   " Inlined into %s which now has time %i and size %i,"
 		   "net change of %+i.\n",
 		   edge->caller->name (),
-		   inline_summary (edge->caller)->time,
-		   inline_summary (edge->caller)->size,
+		   inline_summary_d->get (edge->caller)->time,
+		   inline_summary_d->get (edge->caller)->size,
 		   overall_size - old_size);
 	}
       if (min_size > overall_size)
@@ -1992,11 +1991,11 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	  fprintf (dump_file,
 		   "\nInlining %s size %i.\n",
 		   node->name (),
-		   inline_summary (node)->size);
+		   inline_summary_d->get (node)->size);
 	  fprintf (dump_file,
 		   " Called once from %s %i insns.\n",
 		   node->callers->caller->name (),
-		   inline_summary (node->callers->caller)->size);
+		   inline_summary_d->get (node->callers->caller)->size);
 	}
 
       inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
@@ -2004,7 +2003,7 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	fprintf (dump_file,
 		 " Inlined into %s which now has %i size\n",
 		 caller->name (),
-		 inline_summary (caller)->size);
+		 inline_summary_d->get (caller)->size);
       if (!(*num_calls)--)
 	{
 	  if (dump_file)
@@ -2028,7 +2027,7 @@ dump_overall_stats (void)
     if (!node->global.inlined_to
 	&& !node->alias)
       {
-	int time = inline_summary (node)->time;
+	int time = inline_summary_d->get (node)->time;
 	sum += time;
 	sum_weighted += time * node->count;
       }
@@ -2345,7 +2344,7 @@ early_inline_small_functions (struct cgraph_node *node)
   for (e = node->callees; e; e = e->next_callee)
     {
       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-      if (!inline_summary (callee)->inlinable
+      if (!inline_summary_d->get (callee)->inlinable
 	  || !e->inline_failed)
 	continue;
 
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index 2ac6e4e..7a939f4 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -162,10 +162,28 @@ struct GTY(()) inline_summary
   int scc_no;
 };
 
-/* Need a typedef for inline_summary because of inline function
-   'inline_summary' below.  */
-typedef struct inline_summary inline_summary_t;
-extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
+class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
+{
+public:
+  inline_summary_t (symbol_table *symtab, bool ggc):
+    function_summary <inline_summary *> (symtab, ggc) {}
+
+  static inline_summary_t *create_ggc (symbol_table *symtab)
+  {
+    inline_summary_t *summary = new (ggc_cleared_alloc <inline_summary_t> ())
+      inline_summary_t(symtab, true);
+    summary->disable_insertion_hook ();
+    return summary;
+  }
+
+
+  virtual void insert (cgraph_node *, inline_summary *);
+  virtual void remove (cgraph_node *node, inline_summary *);
+  virtual void duplicate (cgraph_node *src, cgraph_node *dst,
+			  inline_summary *src_data, inline_summary *dst_data);
+};
+
+extern GTY(()) function_summary <inline_summary *> *inline_summary_d;
 
 /* Information kept about parameter of call site.  */
 struct inline_param_summary
@@ -249,12 +267,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
 extern int ncalls_inlined;
 extern int nfunctions_inlined;
 
-static inline struct inline_summary *
-inline_summary (struct cgraph_node *node)
-{
-  return &(*inline_summary_vec)[node->uid];
-}
-
 static inline struct inline_edge_summary *
 inline_edge_summary (struct cgraph_edge *edge)
 {
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 5e25fd8..387209b 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -514,7 +514,7 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Callgraph summary for ipa_node_params.  */
+/* Function summary for ipa_node_params.  */
 class ipa_node_params_t: public function_summary <ipa_node_params *>
 {
 public:
@@ -537,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Return the associated parameter/argument info corresponding to the given
    node/edge.  */
-#define IPA_NODE_REF(NODE) ((*ipa_node_params_d)[NODE])
+#define IPA_NODE_REF(NODE) (ipa_node_params_d->get (NODE))
 #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
 /* This macro checks validity of index returned by
    ipa_get_param_decl_index function.  */
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 16684e2..80c3aac 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1669,7 +1669,7 @@ execute_split_functions (void)
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
   if (inline_edge_summary_vec.exists ()
-      && !inline_summary (node)->inlinable)
+      && !inline_summary_d->get (node)->inlinable)
     {
       if (dump_file)
 	fprintf (dump_file, "Not splitting: not inlinable.\n");
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 80b8561..a873635 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -224,7 +224,7 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
                                target->order);
 	    }
 	  edge = edge->make_direct (target);
-	  if (inline_summary_vec)
+	  if (inline_summary_d)
 	    inline_update_overall_summary (node);
 	  else if (edge->call_stmt)
 	    {
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 3a2f9ed..343cd83 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -165,7 +165,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
     {
       struct cgraph_edge *e;
       if (!node->alias)
-        part->insns += inline_summary (cnode)->self_size;
+        part->insns += inline_summary_d->get (cnode)->self_size;
 
       /* Add all inline clones and callees that are duplicated.  */
       for (e = cnode->callees; e; e = e->next_callee)
@@ -274,7 +274,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
       partition->initializers_visited = NULL;
 
       if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
-        partition->insns -= inline_summary (cnode)->self_size;
+        partition->insns -= inline_summary_d->get (cnode)->self_size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->aux = (void *)((size_t)node->aux - 1);
     }
@@ -477,7 +477,7 @@ lto_balanced_map (int n_lto_partitions)
 	else
 	  order[n_nodes++] = node;
 	if (!node->alias)
-	  total_size += inline_summary (node)->size;
+	  total_size += inline_summary_d->get (node)->size;
       }
 
   /* Streaming works best when the source units do not cross partition
@@ -534,14 +534,14 @@ lto_balanced_map (int n_lto_partitions)
 	     && noreorder[noreorder_pos]->order < current_order)
 	{
 	  if (!noreorder[noreorder_pos]->alias)
-	    total_size -= inline_summary (noreorder[noreorder_pos])->size;
+	    total_size -= inline_summary_d->get (noreorder[noreorder_pos])->size;
 	  next_nodes.safe_push (noreorder[noreorder_pos++]);
 	}
       add_sorted_nodes (next_nodes, partition);
 
       add_symbol_to_partition (partition, order[i]);
       if (!order[i]->alias)
-        total_size -= inline_summary (order[i])->size;
+        total_size -= inline_summary_d->get (order[i])->size;
 	  
 
       /* Once we added a new node to the partition, we also want to add
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index e0c375d..980a97b 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -4991,7 +4991,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
     }
 
   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
-      && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
+      && inline_summary_d->get (node)->size >= MAX_INLINE_INSNS_AUTO)
     {
       if (dump_file)
 	fprintf (dump_file, "Function too big to be made truly local.\n");
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-14 14:11     ` Martin Liška
@ 2014-11-14 15:31       ` Martin Liška
  2014-12-08 17:01         ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-11-14 15:31 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2293 bytes --]

On 11/14/2014 03:04 PM, Martin Liška wrote:
> On 11/13/2014 04:50 PM, Jan Hubicka wrote:
>>> gcc/ChangeLog:
>>>
>>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>>
>>>     * Makefile.in: New object file is added.
>>>     * cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
>>>     is filled up.
>>>     * cgraph_summary.c: New file.
>>>     * cgraph_summary.h: New file.
>>
>> Since I am trying to get rid of the cgraph prefixes for symbols (keep it for
>> the graph only) and the summaries can be annotated to variables too. Even if it
>> not necessarily supported by your current implementation, lets keep API
>> prepared for it. So I would call it symtab-summary.* for source files and
>> symtab_summary for base type  (probably function_summary for annotating
>> functions/cgraph_edge_summary for annotating edges?)
>
> Hello.
>
> I followed your remarks, new class is called function_summary and is located
> in symbol-summary.h.
>>
>>
>>> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
>>> index e2becb9..588b6d5 100644
>>> --- a/gcc/cgraph.h
>>> +++ b/gcc/cgraph.h
>>> @@ -1225,6 +1225,8 @@ public:
>>>     int count_materialization_scale;
>>>     /* Unique id of the node.  */
>>>     int uid;
>>> +  /* Summary unique id of the node.  */
>>> +  int summary_uid;
>>
>> What makes summary_uid better than uid?
>
> Because cgraph_node::uid is not a unique ID, it's recycled. As I can see,
> there are two remaining usages of the fact that cgraph::uid are quite consecutive:
>
> a) node_growth_cache vector is resized according to cgraph_max_uid
> b) lto-partition.c: lto_balanced_map
>
> If we change ipa-related stuff to annotations and lto_balanced_map with be rewritten,
> we can finally unify uid and summary_uid. As Martin correctly pointed out, we should
> unify cgraph_node dumps, we combine uid and order.
>
>>
>>> diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
>>> new file mode 100644
>>> index 0000000..9af1d7e
>>> --- /dev/null
>>> +++ b/gcc/cgraph_summary.c
>>
>> And why do we need this file?  It will need license header if really needed.
>
> Sure, the file can be removed.
>
> Martin
>
>>
>> The implementation seems sane - I will check the actual uses :)
>> Please send the updated patch though.
>>
>> Honza
>>
>

Hello.

There's v3 of the patch.

Martin

[-- Attachment #2: 0001-New-data-structure-for-function_summary-introduced.patch --]
[-- Type: text/x-patch, Size: 11561 bytes --]

From 89b6fb0f599944b564726947b33a7be214dd0f74 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Thu, 13 Nov 2014 15:11:05 +0100
Subject: [PATCH 1/3] New data structure for function_summary introduced.

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
	is filled up.
	* symbol-summary.h: New file.
	* gengtype.c (open_base_files): Add symbol-summary.h.
	* toplev.c (general_init): Call constructor of symbol_table.
---
 gcc/cgraph.h         |   8 ++
 gcc/gengtype.c       |   4 +-
 gcc/symbol-summary.h | 317 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/toplev.c         |   3 +-
 4 files changed, 329 insertions(+), 3 deletions(-)
 create mode 100644 gcc/symbol-summary.h

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index e2becb9..588b6d5 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1225,6 +1225,8 @@ public:
   int count_materialization_scale;
   /* Unique id of the node.  */
   int uid;
+  /* Summary unique id of the node.  */
+  int summary_uid;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
   /* Time profiler: first run of function.  */
@@ -1786,6 +1788,10 @@ public:
   friend class cgraph_node;
   friend class cgraph_edge;
 
+  symbol_table (): cgraph_max_summary_uid (1)
+  {
+  }
+
   /* Initialize callgraph dump file.  */
   void initialize (void);
 
@@ -1982,6 +1988,7 @@ public:
 
   int cgraph_count;
   int cgraph_max_uid;
+  int cgraph_max_summary_uid;
 
   int edges_count;
   int edges_max_uid;
@@ -2310,6 +2317,7 @@ symbol_table::allocate_cgraph_symbol (void)
       node->uid = cgraph_max_uid++;
     }
 
+  node->summary_uid = cgraph_max_summary_uid++;
   return node;
 }
 
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index fac83ee..0161004 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1842,8 +1842,8 @@ open_base_files (void)
       "tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h", 
       "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
-      "target-globals.h", "ipa-ref.h", "cgraph.h", "ipa-prop.h", 
-      "ipa-inline.h", "dwarf2out.h", NULL
+      "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h",
+      "ipa-prop.h", "ipa-inline.h", "dwarf2out.h", NULL
     };
     const char *const *ifp;
     outf_p gtype_desc_c;
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
new file mode 100644
index 0000000..039d052
--- /dev/null
+++ b/gcc/symbol-summary.h
@@ -0,0 +1,317 @@
+/* Callgraph summary data structure.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Contributed by Martin Liska
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_SYMBOL_SUMMARY_H
+#define GCC_SYMBOL_SUMMARY_H
+
+#define SYMBOL_SUMMARY_DELETED_VALUE -1
+#define SYMBOL_SUMMARY_EMPTY_VALUE 0
+
+/* Following class enforces to use pointer type as function_summary
+   template argument.  */
+
+template <class T>
+class function_summary
+{
+private:
+  function_summary();
+};
+
+template <class T>
+class GTY((user)) function_summary <T *>
+{
+public:
+  /* Default construction takes SYMTAB as an argument.  */
+  function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
+    m_insertion_enabled (true), m_symtab (symtab)
+  {
+    cgraph_node *node;
+
+    FOR_EACH_FUNCTION (node)
+    {
+      gcc_assert (node->summary_uid > 0);
+    }
+
+    m_map = new hash_map<int, T*, summary_hashmap_traits>(13, m_ggc);
+
+    m_symtab_insertion_hook =
+      symtab->add_cgraph_insertion_hook
+      (function_summary::symtab_insertion, this);
+
+    m_symtab_removal_hook =
+      symtab->add_cgraph_removal_hook
+      (function_summary::symtab_removal, this);
+    m_symtab_duplication_hook =
+      symtab->add_cgraph_duplication_hook
+      (function_summary::symtab_duplication, this);
+  }
+
+  /* Destructor.  */
+  virtual ~function_summary ()
+  {
+    release ();
+  }
+
+  /* Release method that can be called for GTY purpose.  */
+  void release ()
+  {
+    if (m_symtab_insertion_hook)
+      m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
+
+    if (m_symtab_removal_hook)
+      m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
+
+    if (m_symtab_duplication_hook)
+      m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
+
+    m_symtab_insertion_hook = NULL;
+    m_symtab_removal_hook = NULL;
+    m_symtab_duplication_hook = NULL;
+
+    if (!m_ggc)
+      m_map->traverse <void *, function_summary::release> (NULL);
+  }
+
+  /* Traverses all summarys with a function F called with
+     ARG as argument.  */
+  template<typename Arg, bool (*f)(const T &, Arg)>
+  void traverse (Arg a) const
+  {
+    m_map->traverse <f> (a);
+  }
+
+  /* Basic implementation of insert operation.  */
+  virtual void insert (cgraph_node *, T *) {}
+
+  /* Basic implementation of removal operation.  */
+  virtual void remove (cgraph_node *, T *) {}
+
+  /* Basic implementation of duplication operation.  */
+  virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
+
+  /* Allocates new data that are stored within map.  */
+  T* allocate_new ()
+  {
+    return m_ggc ? new (ggc_alloc <T> ()) T() : new T () ;
+  }
+
+  /* Getter for summary callgraph ID.  */
+  T* get (int uid)
+  {
+    T **v = m_map->get (uid);
+    if (!v)
+      {
+	T *new_value = allocate_new ();
+	m_map->put (uid, new_value);
+
+	v = &new_value;
+      }
+
+    return *v;
+  }
+
+  /* Getter for summary callgraph node pointer.  */
+  T* get (cgraph_node *node)
+  {
+    return get (node->summary_uid);
+  }
+
+  /* Getter operator for summary callgraph ID.  */
+  T* operator[] (int uid)
+  {
+    return get (uid);
+  }
+
+  /* Getter operator for summary callgraph node pointer.  */
+  T* operator[] (cgraph_node *node)
+  {
+    return get (node);
+  }
+
+  /* Return number of elements handled by data structure.  */
+  size_t elements ()
+  {
+    return m_map->elements ();
+  }
+
+  /* Enable insertion operation that is triggered if a new
+     cgraph_node is inserted.  */
+  void enable_insertion_hook ()
+  {
+    m_insertion_enabled = true;
+  }
+
+  /* Enable insertin hook invocation.  */
+  void disable_insertion_hook ()
+  {
+    m_insertion_enabled = false;
+  }
+
+  /* Symbol insertion hook that is registered to symbol table.  */
+  static void symtab_insertion (cgraph_node *node, void *data)
+  {
+    function_summary *summary = (function_summary <T *> *) (data);
+
+    if (summary->m_insertion_enabled)
+      summary->insert (node, summary->get (node));
+  }
+
+  /* Symbol removal hook that is registered to symbol table.  */
+  static void symtab_removal (cgraph_node *node, void *data)
+  {
+    gcc_assert (node->summary_uid);
+    function_summary *summary = (function_summary <T *> *) (data);
+
+    int summary_uid = node->summary_uid;
+    T **v = summary->m_map->get (summary_uid);
+
+    if (v)
+      {
+	summary->remove (node, *v);
+
+	if (!summary->m_ggc)
+	  delete (*v);
+      }
+
+    if (summary->m_map->get (summary_uid))
+      summary->m_map->remove (summary_uid);
+  }
+
+  /* Symbol duplication hook that is registered to symbol table.  */
+  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
+				  void *data)
+  {
+    function_summary *summary = (function_summary <T *> *) (data);
+    T **v = summary->m_map->get (node->summary_uid);
+
+    gcc_assert (node2->summary_uid > 0);
+
+    if (v)
+      {
+	T *data = *v;
+	T *duplicate = summary->allocate_new ();
+	summary->m_map->put (node2->summary_uid, duplicate);
+	summary->duplicate (node, node2, data, (summary->get (node2)));
+      }
+  }
+
+protected:
+  /* Indicatation if we use ggc summary.  */
+  bool m_ggc;
+
+private:
+  struct summary_hashmap_traits: default_hashmap_traits
+  {
+    static
+    hashval_t hash (const int v)
+    {
+      return (hashval_t)v;
+    }
+
+    template<typename Type>
+    static
+    bool is_deleted (Type &e)
+    {
+      return e.m_key == SYMBOL_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static
+    bool is_empty (Type &e)
+    {
+      return e.m_key == SYMBOL_SUMMARY_EMPTY_VALUE;
+    }
+
+    template<typename Type>
+    static
+    void mark_deleted (Type &e)
+    {
+      e.m_key = SYMBOL_SUMMARY_DELETED_VALUE;
+    }
+
+    template<typename Type>
+    static
+    void mark_empty (Type &e)
+    {
+      e.m_key = SYMBOL_SUMMARY_EMPTY_VALUE;
+    }
+  };
+
+  /* Remove summary for summary UID.  */
+  void remove (int uid)
+  {
+    T *v = m_map->get (uid);
+
+    if (v)
+      m_map->erase (uid);
+  }
+
+  /* Summary class release function called by traverse method.  */
+  static bool release (int const &, T * const &v, void *)
+  {
+    delete (v);
+    return true;
+  }
+
+  /* Main summary store, where summary ID is used as key.  */
+  hash_map <int, T *, summary_hashmap_traits> *m_map;
+  /* Internal summary insertion hook pointer.  */
+  cgraph_node_hook_list *m_symtab_insertion_hook;
+  /* Internal summary removal hook pointer.  */
+  cgraph_node_hook_list *m_symtab_removal_hook;
+  /* Internal summary duplication hook pointer.  */
+  cgraph_2node_hook_list *m_symtab_duplication_hook;
+  /* Indicates if insertion hook is enabled.  */
+  bool m_insertion_enabled;
+  /* Symbol table the summary is registered to.  */
+  symbol_table *m_symtab;
+
+  template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
+      gt_pointer_operator, void *);
+};
+
+template <typename T>
+void
+gt_ggc_mx(function_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_ggc_mx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(function_summary<T *>* const &summary)
+{
+  if (summary->m_ggc)
+    gt_pch_nx (summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op,
+	  void *cookie)
+{
+  if (summary->m_map)
+    gt_pch_nx (summary->m_map, op, cookie);
+}
+
+#endif  /* GCC_SYMBOL_SUMMARY_H  */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index aa1653e..b0f5b11 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -93,6 +93,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "bitmap.h"
 #include "ipa-reference.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "gcse.h"
 #include "insn-codes.h"
@@ -1209,7 +1210,7 @@ general_init (const char *argv0)
   /* Create the singleton holder for global state.
      Doing so also creates the pass manager and with it the passes.  */
   g = new gcc::context ();
-  symtab = ggc_cleared_alloc <symbol_table> ();
+  symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table ();
 
   statistics_early_init ();
   finish_params ();
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass.
  2014-11-14 14:12   ` Martin Liška
@ 2014-11-14 15:31     ` Martin Liška
  2014-11-14 17:10       ` Martin Jambor
  2014-12-08 17:02       ` Martin Liška
  0 siblings, 2 replies; 40+ messages in thread
From: Martin Liška @ 2014-11-14 15:31 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 109343 bytes --]

On 11/14/2014 03:05 PM, Martin Liška wrote:
> On 11/11/2014 01:26 PM, mliska wrote:
>> gcc/ChangeLog:
>>
>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>
>>     * auto-profile.c: Include cgraph_summary.h.
>>     * cgraph.c: Likewise.
>>     * cgraphbuild.c: Likewise.
>>     * cgraphclones.c: Likewise.
>>     * cgraphunit.c: Likewise.
>>     * ipa-cp.c: Likewise.
>>     * ipa-devirt.c: Likewise.
>>     * ipa-icf.c: Likewise.
>>     * ipa-inline-analysis.c (evaluate_properties_for_edge): Usage of
>>     ipa_node_params_vector is replaced with ipa_node_params_summary.
>>     (inline_node_duplication_hook): Likewise.
>>     (estimate_function_body_sizes): Likewise.
>>     (remap_edge_change_prob): Likewise.
>>     (inline_merge_summary): Likewise.
>>     * ipa-inline-transform.c: Include of cgraph_summary.h.
>>     * ipa-inline.c (early_inliner): Usage of
>>     ipa_node_params_vector is replaced with ipa_node_params_summary.
>>     * ipa-polymorphic-call.c: Include of cgraph_summary.h.
>>     * ipa-profile.c: Include of cgraph_summary.h.
>>     * ipa-prop.c (struct func_body_info): Struct keyword is removed.
>>     (struct ipa_cst_ref_desc): Likewise.
>>     (ipa_func_spec_opts_forbid_analysis_p): Likewise.
>>     (ipa_alloc_node_params): Likewise.
>>     (ipa_initialize_node_params): Likewise.
>>     (ipa_print_node_jump_functions_for_edge): Likewise.
>>     (ipa_print_node_jump_functions): Likewise.
>>     (ipa_print_all_jump_functions): Likewise.
>>     (ipa_set_jf_constant): Likewise.
>>     (check_stmt_for_type_change): Likewise.
>>     (detect_type_change_from_memory_writes): Likewise.
>>     (find_dominating_aa_status): Likewise.
>>     (parm_bb_aa_status_for_bb): Likewise.
>>     (parm_preserved_before_stmt_p): Likewise.
>>     (parm_ref_data_preserved_p): Likewise.
>>     (parm_ref_data_pass_through_p): Likewise.
>>     (struct ipa_known_agg_contents_list): Likewise.
>>     (get_place_in_agg_contents_list): Likewise.
>>     (build_agg_jump_func_from_list): Likewise.
>>     (determine_locally_known_aggregate_parts): Likewise.
>>     (ipa_compute_jump_functions_for_edge): Likewise.
>>     (ipa_compute_jump_functions_for_bb): Likewise.
>>     (ipa_note_param_call): Likewise.
>>     (ipa_analyze_indirect_call_uses) Likewise.:
>>     (ipa_analyze_virtual_call_uses): Likewise.
>>     (ipa_analyze_call_uses): Likewise.
>>     (visit_ref_for_mod_analysis): Likewise.
>>     (ipa_analyze_controlled_uses): Likewise.
>>     (ipa_analyze_node): Likewise.
>>     (update_jump_functions_after_inlining): Likewise.
>>     (ipa_make_edge_direct_to_target): Likewise.
>>     (ipa_find_agg_cst_for_param): Likewise.
>>     (remove_described_reference): Likewise.
>>     (jfunc_rdesc_usable): Likewise.
>>     (try_decrement_rdesc_refcount): Likewise.
>>     (try_make_edge_direct_simple_call): Likewise.
>>     (try_make_edge_direct_virtual_call): Likewise.
>>     (update_indirect_edges_after_inlining): Likewise.
>>     (propagate_info_to_inlined_callees): Likewise.
>>     (propagate_controlled_uses): Likewise.
>>     (ipa_propagate_indirect_call_infos): Likewise.
>>     (ipa_free_all_edge_args): Likewise.
>>     (ipa_node_params::~ipa_node_params): Likewise.
>>     (ipa_free_all_node_params): Likewise.
>>     (ipa_edge_removal_hook): Likewise.
>>     (ipa_node_removal_hook): Likewise.
>>     (ipa_edge_duplication_hook): Likewise.
>>     (ipa_add_new_function): Removed
>>     (ipa_node_params_cgraph_summary::duplication_hook): New function.
>>     (ipa_node_duplication_hook): Struct keyword removed.
>>     (ipa_register_cgraph_hooks): Removal of old hooks.
>>     (ipa_unregister_cgraph_hooks): Likewise.
>>     (ipa_print_node_params): Struct keyword is removed.
>>     (ipa_print_all_params): Likewise.
>>     (ipa_modify_formal_parameters): Likewise.
>>     (ipa_modify_call_arguments): Likewise.
>>     (ipa_modify_expr): Likewise.
>>     (ipa_get_adjustment_candidate): Likewise.
>>     (index_in_adjustments_multiple_times_p): Likewise.
>>     (ipa_combine_adjustments): Likewise.
>>     (ipa_dump_param_adjustments): Likewise.
>>     (ipa_write_jump_function): Likewise.
>>     (ipa_read_jump_function): Likewise.
>>     (ipa_write_indirect_edge_info): Likewise.
>>     (ipa_read_indirect_edge_info): Likewise.
>>     (ipa_write_node_info): Likewise.
>>     (ipa_read_node_info): Likewise.
>>     (ipa_prop_write_jump_functions): Likewise.
>>     (ipa_prop_read_section): Likewise.
>>     (ipa_prop_read_jump_functions): Likewise.
>>     (write_agg_replacement_chain): Likewise.
>>     (read_agg_replacement_chain): Likewise.
>>     (ipa_prop_write_all_agg_replacement): Likewise.
>>     (read_replacements_section): Likewise.
>>     (ipa_prop_read_all_agg_replacement): Likewise.
>>     (adjust_agg_replacement_values): Likewise.
>>     (ipcp_modif_dom_walker::before_dom_children): Likewise.
>>     (ipcp_transform_function): Likewise.
>>     * ipa-prop.h (struct ipa_node_params): Introduction of new class
>>     ipa_node_params_cgraph_summary.
>>     * ipa-split.c: Include cgraph_summary.h.
>>     * ipa-utils.c: Likewise.
>>     * ipa.c: Likewise.
>>     * omp-low.c: Likewise.
>>     * tree-inline.c: Likewise.
>>     * tree-sra.c: Likewise.
>>     * tree-ssa-pre.c: Likewise.
>>
>> gcc/lto/ChangeLog:
>>
>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>
>>     * lto-partition.c: Include cgraph_summary.h.
>>     * lto-symtab.c: Likewise.
>>     * lto.c: Likewise.
>> ---
>>   gcc/auto-profile.c         |   1 +
>>   gcc/cgraph.c               |   1 +
>>   gcc/cgraphbuild.c          |   1 +
>>   gcc/cgraphclones.c         |   1 +
>>   gcc/cgraphunit.c           |   1 +
>>   gcc/ipa-cp.c               |   1 +
>>   gcc/ipa-devirt.c           |   1 +
>>   gcc/ipa-icf.c              |   1 +
>>   gcc/ipa-inline-analysis.c  |  13 +-
>>   gcc/ipa-inline-transform.c |   1 +
>>   gcc/ipa-inline.c           |   3 +-
>>   gcc/ipa-polymorphic-call.c |   1 +
>>   gcc/ipa-profile.c          |   1 +
>>   gcc/ipa-prop.c             | 700 ++++++++++++++++++++++-----------------------
>>   gcc/ipa-prop.h             |  46 +--
>>   gcc/ipa-split.c            |   1 +
>>   gcc/ipa-utils.c            |   1 +
>>   gcc/ipa.c                  |   1 +
>>   gcc/lto/lto-partition.c    |   1 +
>>   gcc/lto/lto-symtab.c       |   1 +
>>   gcc/lto/lto.c              |   1 +
>>   gcc/omp-low.c              |   1 +
>>   gcc/tree-inline.c          |   1 +
>>   gcc/tree-sra.c             |   1 +
>>   gcc/tree-ssa-pre.c         |   1 +
>>   25 files changed, 397 insertions(+), 386 deletions(-)
>>
>> diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
>> index 8c7b4ca..49f9b8c 100644
>> --- a/gcc/auto-profile.c
>> +++ b/gcc/auto-profile.c
>> @@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "coverage.h"
>>   #include "params.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "tree-inline.h"
>> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
>> index 7216b89..af1835a 100644
>> --- a/gcc/cgraph.c
>> +++ b/gcc/cgraph.c
>> @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-utils.h"
>>   #include "lto-streamer.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "cfgloop.h"
>> diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
>> index c72ceab..a93b0aa 100644
>> --- a/gcc/cgraphbuild.c
>> +++ b/gcc/cgraphbuild.c
>> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-utils.h"
>>   #include "except.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>
>> diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
>> index c8892da..79f95ef 100644
>> --- a/gcc/cgraphclones.c
>> +++ b/gcc/cgraphclones.c
>> @@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "tree-iterator.h"
>>   #include "tree-dump.h"
>> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
>> index 25af234..dbbdc44 100644
>> --- a/gcc/cgraphunit.c
>> +++ b/gcc/cgraphunit.c
>> @@ -204,6 +204,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "tree-iterator.h"
>>   #include "tree-pass.h"
>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>> index 47f9f5c..da589af 100644
>> --- a/gcc/ipa-cp.c
>> +++ b/gcc/ipa-cp.c
>> @@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "bitmap.h"
>>   #include "tree-pass.h"
>> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
>> index 32c6549..8e1f9ce 100644
>> --- a/gcc/ipa-devirt.c
>> +++ b/gcc/ipa-devirt.c
>> @@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "gimple-expr.h"
>>   #include "gimple.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "diagnostic.h"
>> diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
>> index 92ec82d..9778323 100644
>> --- a/gcc/ipa-icf.c
>> +++ b/gcc/ipa-icf.c
>> @@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "cfgloop.h"
>> diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
>> index eb1c6ec..c7a52d2 100644
>> --- a/gcc/ipa-inline-analysis.c
>> +++ b/gcc/ipa-inline-analysis.c
>> @@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "lto-streamer.h"
>>   #include "data-streamer.h"
>> @@ -910,7 +911,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
>>     if (known_binfos_ptr)
>>       known_binfos_ptr->create (0);
>>
>> -  if (ipa_node_params_vector.exists ()
>> +  if (ipa_node_params_summary
>>         && !e->call_stmt_cannot_inline_p
>>         && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr))
>>       {
>> @@ -1130,7 +1131,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
>>
>>     /* When there are any replacements in the function body, see if we can figure
>>        out that something was optimized out.  */
>> -  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
>> +  if (ipa_node_params_summary && dst->clone.tree_map)
>>       {
>>         vec<size_time_entry, va_gc> *entry = info->entry;
>>         /* Use SRC parm info since it may not be copied yet.  */
>> @@ -2476,7 +2477,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>         calculate_dominance_info (CDI_DOMINATORS);
>>         loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
>>
>> -      if (ipa_node_params_vector.exists ())
>> +      if (ipa_node_params_summary)
>>       {
>>         parms_info = IPA_NODE_REF (node);
>>         nonconstant_names.safe_grow_cleared
>> @@ -2624,7 +2625,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>             nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
>>               = false_p;
>>           }
>> -          if (ipa_node_params_vector.exists ())
>> +          if (ipa_node_params_summary)
>>           {
>>             int count = gimple_call_num_args (stmt);
>>             int i;
>> @@ -3367,7 +3368,7 @@ static void
>>   remap_edge_change_prob (struct cgraph_edge *inlined_edge,
>>               struct cgraph_edge *edge)
>>   {
>> -  if (ipa_node_params_vector.exists ())
>> +  if (ipa_node_params_summary)
>>       {
>>         int i;
>>         struct ipa_edge_args *args = IPA_EDGE_REF (edge);
>> @@ -3523,7 +3524,7 @@ inline_merge_summary (struct cgraph_edge *edge)
>>     else
>>       toplev_predicate = true_predicate ();
>>
>> -  if (ipa_node_params_vector.exists () && callee_info->conds)
>> +  if (ipa_node_params_summary && callee_info->conds)
>>       {
>>         struct ipa_edge_args *args = IPA_EDGE_REF (edge);
>>         int count = ipa_get_cs_argument_count (args);
>> diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
>> index dbc56c5..fd700ff 100644
>> --- a/gcc/ipa-inline-transform.c
>> +++ b/gcc/ipa-inline-transform.c
>> @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "tree-inline.h"
>> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
>> index 5c97815..8a08cd4 100644
>> --- a/gcc/ipa-inline.c
>> +++ b/gcc/ipa-inline.c
>> @@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "except.h"
>>   #include "target.h"
>> @@ -2400,7 +2401,7 @@ early_inliner (function *fun)
>>        it.  This may confuse ourself when early inliner decide to inline call to
>>        function clone, because function clones don't have parameter list in
>>        ipa-prop matching their signature.  */
>> -  if (ipa_node_params_vector.exists ())
>> +  if (ipa_node_params_summary)
>>       return 0;
>>
>>   #ifdef ENABLE_CHECKING
>> diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
>> index 33dd1a8..e0555f2 100644
>> --- a/gcc/ipa-polymorphic-call.c
>> +++ b/gcc/ipa-polymorphic-call.c
>> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "gimple-expr.h"
>>   #include "gimple.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "diagnostic.h"
>> diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
>> index b83d1cf..4fdee09 100644
>> --- a/gcc/ipa-profile.c
>> +++ b/gcc/ipa-profile.c
>> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "tree-inline.h"
>>   #include "lto-streamer.h"
>>   #include "data-streamer.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>
>> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
>> index db85c7d..ce9745e 100644
>> --- a/gcc/ipa-prop.c
>> +++ b/gcc/ipa-prop.c
>> @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "bitmap.h"
>>   #include "gimple-ssa.h"
>> @@ -119,7 +120,7 @@ struct func_body_info
>>     cgraph_node *node;
>>
>>     /* Its info.  */
>> -  struct ipa_node_params *info;
>> +  ipa_node_params *info;
>>
>>     /* Information about individual BBs. */
>>     vec<ipa_bb_info> bb_infos;
>> @@ -131,7 +132,8 @@ struct func_body_info
>>     unsigned int aa_walked;
>>   };
>>
>> -/* Vector where the parameter infos are actually stored. */
>> +/* Callgraph summary where the parameter infos are actually stored. */
>> +ipa_node_params_cgraph_summary *ipa_node_params_summary = NULL;
>>   vec<ipa_node_params> ipa_node_params_vector;
>>   /* Vector of known aggregate values in cloned nodes.  */
>>   vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>> @@ -139,19 +141,17 @@ vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>>   vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>
>>   /* Holders of ipa cgraph hooks: */
>> -static struct cgraph_edge_hook_list *edge_removal_hook_holder;
>> -static struct cgraph_node_hook_list *node_removal_hook_holder;
>> -static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
>> -static struct cgraph_2node_hook_list *node_duplication_hook_holder;
>> -static struct cgraph_node_hook_list *function_insertion_hook_holder;
>> +static cgraph_edge_hook_list *edge_removal_hook_holder;
>> +static cgraph_2edge_hook_list *edge_duplication_hook_holder;
>> +static cgraph_node_hook_list *function_insertion_hook_holder;
>>
>>   /* Description of a reference to an IPA constant.  */
>>   struct ipa_cst_ref_desc
>>   {
>>     /* Edge that corresponds to the statement which took the reference.  */
>> -  struct cgraph_edge *cs;
>> +  cgraph_edge *cs;
>>     /* Linked list of duplicates created when call graph edges are cloned.  */
>> -  struct ipa_cst_ref_desc *next_duplicate;
>> +  ipa_cst_ref_desc *next_duplicate;
>>     /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
>>        if out of control.  */
>>     int refcount;
>> @@ -165,10 +165,10 @@ static alloc_pool ipa_refdesc_pool;
>>      with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
>>
>>   static bool
>> -ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
>> +ipa_func_spec_opts_forbid_analysis_p (cgraph_node *node)
>>   {
>>     tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
>> -  struct cl_optimization *os;
>> +  cl_optimization *os;
>>
>>     if (!fs_opts)
>>       return false;
>> @@ -196,7 +196,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
>>      to INFO.  */
>>
>>   int
>> -ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
>> +ipa_get_param_decl_index (ipa_node_params *info, tree ptree)
>>   {
>>     return ipa_get_param_decl_index_1 (info->descriptors, ptree);
>>   }
>> @@ -205,7 +205,7 @@ ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
>>      NODE.  */
>>
>>   static void
>> -ipa_populate_param_decls (struct cgraph_node *node,
>> +ipa_populate_param_decls (cgraph_node *node,
>>                 vec<ipa_param_descriptor> &descriptors)
>>   {
>>     tree fndecl;
>> @@ -246,7 +246,7 @@ count_formal_params (tree fndecl)
>>      using ipa_initialize_node_params. */
>>
>>   void
>> -ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
>> +ipa_dump_param (FILE *file, ipa_node_params *info, int i)
>>   {
>>     fprintf (file, "param #%i", i);
>>     if (info->descriptors[i].decl)
>> @@ -260,9 +260,9 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
>>      to hold PARAM_COUNT parameters.  */
>>
>>   void
>> -ipa_alloc_node_params (struct cgraph_node *node, int param_count)
>> +ipa_alloc_node_params (cgraph_node *node, int param_count)
>>   {
>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>
>>     if (!info->descriptors.exists () && param_count)
>>       info->descriptors.safe_grow_cleared (param_count);
>> @@ -273,9 +273,9 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
>>      param_decls.  */
>>
>>   void
>> -ipa_initialize_node_params (struct cgraph_node *node)
>> +ipa_initialize_node_params (cgraph_node *node)
>>   {
>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>
>>     if (!info->descriptors.exists ())
>>       {
>> @@ -287,14 +287,14 @@ ipa_initialize_node_params (struct cgraph_node *node)
>>   /* Print the jump functions associated with call graph edge CS to file F.  */
>>
>>   static void
>> -ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>> +ipa_print_node_jump_functions_for_edge (FILE *f, cgraph_edge *cs)
>>   {
>>     int i, count;
>>
>>     count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
>>     for (i = 0; i < count; i++)
>>       {
>> -      struct ipa_jump_func *jump_func;
>> +      ipa_jump_func *jump_func;
>>         enum jump_func_type type;
>>
>>         jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
>> @@ -360,7 +360,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>>
>>         if (jump_func->agg.items)
>>       {
>> -      struct ipa_agg_jf_item *item;
>> +      ipa_agg_jf_item *item;
>>         int j;
>>
>>         fprintf (f, "         Aggregate passed by %s:\n",
>> @@ -390,9 +390,9 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>>      NODE to file F.  */
>>
>>   void
>> -ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>> +ipa_print_node_jump_functions (FILE *f, cgraph_node *node)
>>   {
>> -  struct cgraph_edge *cs;
>> +  cgraph_edge *cs;
>>
>>     fprintf (f, "  Jump functions of caller  %s/%i:\n", node->name (),
>>          node->order);
>> @@ -410,7 +410,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>>
>>     for (cs = node->indirect_calls; cs; cs = cs->next_callee)
>>       {
>> -      struct cgraph_indirect_call_info *ii;
>> +      cgraph_indirect_call_info *ii;
>>         if (!ipa_edge_args_info_available_for_edge_p (cs))
>>       continue;
>>
>> @@ -445,7 +445,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>>   void
>>   ipa_print_all_jump_functions (FILE *f)
>>   {
>> -  struct cgraph_node *node;
>> +  cgraph_node *node;
>>
>>     fprintf (f, "\nJump functions:\n");
>>     FOR_EACH_FUNCTION (node)
>> @@ -457,7 +457,7 @@ ipa_print_all_jump_functions (FILE *f)
>>   /* Set JFUNC to be a known type jump function.  */
>>
>>   static void
>> -ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>> +ipa_set_jf_known_type (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>                  tree base_type, tree component_type)
>>   {
>>     /* Recording and propagating main variants increases change that types
>> @@ -480,8 +480,8 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>      combination code).  The two functions will share their rdesc.  */
>>
>>   static void
>> -ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
>> -             struct ipa_jump_func *src)
>> +ipa_set_jf_cst_copy (ipa_jump_func *dst,
>> +             ipa_jump_func *src)
>>
>>   {
>>     gcc_checking_assert (src->type == IPA_JF_CONST);
>> @@ -492,8 +492,8 @@ ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
>>   /* Set JFUNC to be a constant jmp function.  */
>>
>>   static void
>> -ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>> -             struct cgraph_edge *cs)
>> +ipa_set_jf_constant (ipa_jump_func *jfunc, tree constant,
>> +             cgraph_edge *cs)
>>   {
>>     constant = unshare_expr (constant);
>>     if (constant && EXPR_P (constant))
>> @@ -504,12 +504,12 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>>     if (TREE_CODE (constant) == ADDR_EXPR
>>         && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
>>       {
>> -      struct ipa_cst_ref_desc *rdesc;
>> +      ipa_cst_ref_desc *rdesc;
>>         if (!ipa_refdesc_pool)
>>       ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
>> -                    sizeof (struct ipa_cst_ref_desc), 32);
>> +                    sizeof (ipa_cst_ref_desc), 32);
>>
>> -      rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>> +      rdesc = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>         rdesc->cs = cs;
>>         rdesc->next_duplicate = NULL;
>>         rdesc->refcount = 1;
>> @@ -521,7 +521,7 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>>
>>   /* Set JFUNC to be a simple pass-through jump function.  */
>>   static void
>> -ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>> +ipa_set_jf_simple_pass_through (ipa_jump_func *jfunc, int formal_id,
>>                   bool agg_preserved, bool type_preserved)
>>   {
>>     jfunc->type = IPA_JF_PASS_THROUGH;
>> @@ -535,7 +535,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>>   /* Set JFUNC to be an arithmetic pass through jump function.  */
>>
>>   static void
>> -ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>> +ipa_set_jf_arith_pass_through (ipa_jump_func *jfunc, int formal_id,
>>                      tree operand, enum tree_code operation)
>>   {
>>     jfunc->type = IPA_JF_PASS_THROUGH;
>> @@ -549,7 +549,7 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>>   /* Set JFUNC to be an ancestor jump function.  */
>>
>>   static void
>> -ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>> +ipa_set_ancestor_jf (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>                tree type, int formal_id, bool agg_preserved,
>>                bool type_preserved)
>>   {
>> @@ -572,7 +572,7 @@ ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>      jump function.  */
>>
>>   tree
>> -ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
>> +ipa_binfo_from_known_type_jfunc (ipa_jump_func *jfunc)
>>   {
>>     if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
>>       return NULL_TREE;
>> @@ -602,8 +602,8 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
>>   /* Get IPA BB information about the given BB.  FBI is the context of analyzis
>>      of this function body.  */
>>
>> -static struct ipa_bb_info *
>> -ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
>> +static ipa_bb_info *
>> +ipa_get_bb_info (func_body_info *fbi, basic_block bb)
>>   {
>>     gcc_checking_assert (fbi);
>>     return &fbi->bb_infos[bb->index];
>> @@ -700,7 +700,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
>>      identified, return the type.  Otherwise return NULL_TREE.  */
>>
>>   static tree
>> -extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
>> +extr_type_from_vtbl_ptr_store (gimple stmt, prop_type_change_info *tci)
>>   {
>>     HOST_WIDE_INT offset, size, max_size;
>>     tree lhs, rhs, base, binfo;
>> @@ -752,7 +752,7 @@ static bool
>>   check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
>>   {
>>     gimple stmt = SSA_NAME_DEF_STMT (vdef);
>> -  struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
>> +  prop_type_change_info *tci = (prop_type_change_info *) data;
>>
>>     if (stmt_may_be_vtbl_ptr_store (stmt))
>>       {
>> @@ -847,10 +847,10 @@ param_type_may_change_p (tree function, tree arg, gimple call)
>>
>>   static bool
>>   detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
>> -                       gimple call, struct ipa_jump_func *jfunc,
>> +                       gimple call, ipa_jump_func *jfunc,
>>                          HOST_WIDE_INT offset)
>>   {
>> -  struct prop_type_change_info tci;
>> +  prop_type_change_info tci;
>>     ao_ref ao;
>>     bool entry_reached = false;
>>
>> @@ -908,7 +908,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
>>
>>   static bool
>>   detect_type_change (tree arg, tree base, tree comp_type, gimple call,
>> -            struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
>> +            ipa_jump_func *jfunc, HOST_WIDE_INT offset)
>>   {
>>     if (!flag_devirtualize)
>>       return false;
>> @@ -928,7 +928,7 @@ detect_type_change (tree arg, tree base, tree comp_type, gimple call,
>>
>>   static bool
>>   detect_type_change_ssa (tree arg, tree comp_type,
>> -            gimple call, struct ipa_jump_func *jfunc)
>> +            gimple call, ipa_jump_func *jfunc)
>>   {
>>     gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
>>     if (!flag_devirtualize
>> @@ -961,7 +961,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
>>      should really just start giving up.  */
>>
>>   static bool
>> -aa_overwalked (struct func_body_info *fbi)
>> +aa_overwalked (func_body_info *fbi)
>>   {
>>     gcc_checking_assert (fbi);
>>     return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
>> @@ -970,8 +970,8 @@ aa_overwalked (struct func_body_info *fbi)
>>   /* Find the nearest valid aa status for parameter specified by INDEX that
>>      dominates BB.  */
>>
>> -static struct param_aa_status *
>> -find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>> +static param_aa_status *
>> +find_dominating_aa_status (func_body_info *fbi, basic_block bb,
>>                  int index)
>>   {
>>     while (true)
>> @@ -979,7 +979,7 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>>         bb = get_immediate_dominator (CDI_DOMINATORS, bb);
>>         if (!bb)
>>       return NULL;
>> -      struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>> +      ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>         if (!bi->param_aa_statuses.is_empty ()
>>         && bi->param_aa_statuses[index].valid)
>>       return &bi->param_aa_statuses[index];
>> @@ -990,21 +990,21 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>>      structures and/or intialize the result with a dominating description as
>>      necessary.  */
>>
>> -static struct param_aa_status *
>> -parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
>> +static param_aa_status *
>> +parm_bb_aa_status_for_bb (func_body_info *fbi, basic_block bb,
>>                 int index)
>>   {
>>     gcc_checking_assert (fbi);
>> -  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>> +  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>     if (bi->param_aa_statuses.is_empty ())
>>       bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
>> -  struct param_aa_status *paa = &bi->param_aa_statuses[index];
>> +  param_aa_status *paa = &bi->param_aa_statuses[index];
>>     if (!paa->valid)
>>       {
>>         gcc_checking_assert (!paa->parm_modified
>>                  && !paa->ref_modified
>>                  && !paa->pt_modified);
>> -      struct param_aa_status *dom_paa;
>> +      param_aa_status *dom_paa;
>>         dom_paa = find_dominating_aa_status (fbi, bb, index);
>>         if (dom_paa)
>>       *paa = *dom_paa;
>> @@ -1021,10 +1021,10 @@ parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
>>      gathered but do not survive the summary building stage.  */
>>
>>   static bool
>> -parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
>> +parm_preserved_before_stmt_p (func_body_info *fbi, int index,
>>                     gimple stmt, tree parm_load)
>>   {
>> -  struct param_aa_status *paa;
>> +  param_aa_status *paa;
>>     bool modified = false;
>>     ao_ref refd;
>>
>> @@ -1060,7 +1060,7 @@ parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
>>      modified.  Otherwise return -1.  */
>>
>>   static int
>> -load_from_unmodified_param (struct func_body_info *fbi,
>> +load_from_unmodified_param (func_body_info *fbi,
>>                   vec<ipa_param_descriptor> descriptors,
>>                   gimple stmt)
>>   {
>> @@ -1087,10 +1087,10 @@ load_from_unmodified_param (struct func_body_info *fbi,
>>      before reaching statement STMT.  */
>>
>>   static bool
>> -parm_ref_data_preserved_p (struct func_body_info *fbi,
>> +parm_ref_data_preserved_p (func_body_info *fbi,
>>                  int index, gimple stmt, tree ref)
>>   {
>> -  struct param_aa_status *paa;
>> +  param_aa_status *paa;
>>     bool modified = false;
>>     ao_ref refd;
>>
>> @@ -1126,7 +1126,7 @@ parm_ref_data_preserved_p (struct func_body_info *fbi,
>>      CALL into which it is passed.  FBI describes the function body.  */
>>
>>   static bool
>> -parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>> +parm_ref_data_pass_through_p (func_body_info *fbi, int index,
>>                     gimple call, tree parm)
>>   {
>>     bool modified = false;
>> @@ -1140,7 +1140,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>>         || aa_overwalked (fbi))
>>       return false;
>>
>> -  struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
>> +  param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
>>                                 index);
>>     if (paa->pt_modified)
>>       return false;
>> @@ -1165,7 +1165,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>>      reference respectively.  */
>>
>>   static bool
>> -ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
>> +ipa_load_from_parm_agg_1 (func_body_info *fbi,
>>                 vec<ipa_param_descriptor> descriptors,
>>                 gimple stmt, tree op, int *index_p,
>>                 HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
>> @@ -1240,7 +1240,7 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
>>      pointer, for users outside of this file.  */
>>
>>   bool
>> -ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
>> +ipa_load_from_parm_agg (ipa_node_params *info, gimple stmt,
>>               tree op, int *index_p, HOST_WIDE_INT *offset_p,
>>               bool *by_ref_p)
>>   {
>> @@ -1302,9 +1302,9 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
>>      only needed for intraprocedural analysis.  */
>>
>>   static void
>> -compute_complex_assign_jump_func (struct func_body_info *fbi,
>> -                  struct ipa_node_params *info,
>> -                  struct ipa_jump_func *jfunc,
>> +compute_complex_assign_jump_func (func_body_info *fbi,
>> +                  ipa_node_params *info,
>> +                  ipa_jump_func *jfunc,
>>                     gimple call, gimple stmt, tree name,
>>                     tree param_type)
>>   {
>> @@ -1458,9 +1458,9 @@ get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
>>        return D.1879_6;  */
>>
>>   static void
>> -compute_complex_ancestor_jump_func (struct func_body_info *fbi,
>> -                    struct ipa_node_params *info,
>> -                    struct ipa_jump_func *jfunc,
>> +compute_complex_ancestor_jump_func (func_body_info *fbi,
>> +                    ipa_node_params *info,
>> +                    ipa_jump_func *jfunc,
>>                       gimple call, gimple phi, tree param_type)
>>   {
>>     HOST_WIDE_INT offset;
>> @@ -1531,7 +1531,7 @@ compute_complex_ancestor_jump_func (struct func_body_info *fbi,
>>      EXPECTED_TYPE represents a type the argument should be in  */
>>
>>   static void
>> -compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
>> +compute_known_type_jump_func (tree op, ipa_jump_func *jfunc,
>>                     gimple call, tree expected_type)
>>   {
>>     HOST_WIDE_INT offset, size, max_size;
>> @@ -1629,7 +1629,7 @@ struct ipa_known_agg_contents_list
>>     /* Known constant value or NULL if the contents is known to be unknown.  */
>>     tree constant;
>>     /* Pointer to the next structure in the list.  */
>> -  struct ipa_known_agg_contents_list *next;
>> +  ipa_known_agg_contents_list *next;
>>   };
>>
>>   /* Find the proper place in linked list of ipa_known_agg_contents_list
>> @@ -1637,13 +1637,13 @@ struct ipa_known_agg_contents_list
>>      unless there is a partial overlap, in which case return NULL, or such
>>      element is already there, in which case set *ALREADY_THERE to true.  */
>>
>> -static struct ipa_known_agg_contents_list **
>> -get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
>> +static ipa_known_agg_contents_list **
>> +get_place_in_agg_contents_list (ipa_known_agg_contents_list **list,
>>                   HOST_WIDE_INT lhs_offset,
>>                   HOST_WIDE_INT lhs_size,
>>                   bool *already_there)
>>   {
>> -  struct ipa_known_agg_contents_list **p = list;
>> +  ipa_known_agg_contents_list **p = list;
>>     while (*p && (*p)->offset < lhs_offset)
>>       {
>>         if ((*p)->offset + (*p)->size > lhs_offset)
>> @@ -1670,16 +1670,16 @@ get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
>>      is ARG_OFFSET and store it into JFUNC.  */
>>
>>   static void
>> -build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
>> +build_agg_jump_func_from_list (ipa_known_agg_contents_list *list,
>>                      int const_count, HOST_WIDE_INT arg_offset,
>> -                   struct ipa_jump_func *jfunc)
>> +                   ipa_jump_func *jfunc)
>>   {
>>     vec_alloc (jfunc->agg.items, const_count);
>>     while (list)
>>       {
>>         if (list->constant)
>>       {
>> -      struct ipa_agg_jf_item item;
>> +      ipa_agg_jf_item item;
>>         item.offset = list->offset - arg_offset;
>>         gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
>>         item.value = unshare_expr_without_location (list->constant);
>> @@ -1697,9 +1697,9 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
>>
>>   static void
>>   determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>> -                     struct ipa_jump_func *jfunc)
>> +                     ipa_jump_func *jfunc)
>>   {
>> -  struct ipa_known_agg_contents_list *list = NULL;
>> +  ipa_known_agg_contents_list *list = NULL;
>>     int item_count = 0, const_count = 0;
>>     HOST_WIDE_INT arg_offset, arg_size;
>>     gimple_stmt_iterator gsi;
>> @@ -1774,7 +1774,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>     gsi_prev (&gsi);
>>     for (; !gsi_end_p (gsi); gsi_prev (&gsi))
>>       {
>> -      struct ipa_known_agg_contents_list *n, **p;
>> +      ipa_known_agg_contents_list *n, **p;
>>         gimple stmt = gsi_stmt (gsi);
>>         HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
>>         tree lhs, rhs, lhs_base;
>> @@ -1821,7 +1821,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>       continue;
>>
>>         rhs = get_ssa_def_if_simple_copy (rhs);
>> -      n = XALLOCA (struct ipa_known_agg_contents_list);
>> +      n = XALLOCA (ipa_known_agg_contents_list);
>>         n->size = lhs_size;
>>         n->offset = lhs_offset;
>>         if (is_gimple_ip_invariant (rhs))
>> @@ -1852,7 +1852,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>   }
>>
>>   static tree
>> -ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>> +ipa_get_callee_param_type (cgraph_edge *e, int i)
>>   {
>>     int n;
>>     tree type = (e->callee
>> @@ -1887,11 +1887,11 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>>      to this callsite.  */
>>
>>   static void
>> -ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>> -                     struct cgraph_edge *cs)
>> +ipa_compute_jump_functions_for_edge (func_body_info *fbi,
>> +                     cgraph_edge *cs)
>>   {
>> -  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
>> -  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
>> +  ipa_node_params *info = IPA_NODE_REF (cs->caller);
>> +  ipa_edge_args *args = IPA_EDGE_REF (cs);
>>     gimple call = cs->call_stmt;
>>     int n, arg_num = gimple_call_num_args (call);
>>     bool useful_context = false;
>> @@ -1909,13 +1909,13 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>>
>>     for (n = 0; n < arg_num; n++)
>>       {
>> -      struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
>> +      ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
>>         tree arg = gimple_call_arg (call, n);
>>         tree param_type = ipa_get_callee_param_type (cs, n);
>>         if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
>>       {
>>         tree instance;
>> -      struct ipa_polymorphic_call_context context (cs->caller->decl,
>> +      ipa_polymorphic_call_context context (cs->caller->decl,
>>                                  arg, cs->call_stmt,
>>                                  &instance);
>>         context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
>> @@ -2003,15 +2003,15 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>>      from BB.  */
>>
>>   static void
>> -ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
>> +ipa_compute_jump_functions_for_bb (func_body_info *fbi, basic_block bb)
>>   {
>> -  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>> +  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>     int i;
>> -  struct cgraph_edge *cs;
>> +  cgraph_edge *cs;
>>
>>     FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
>>       {
>> -      struct cgraph_node *callee = cs->callee;
>> +      cgraph_node *callee = cs->callee;
>>
>>         if (callee)
>>       {
>> @@ -2093,10 +2093,10 @@ ipa_is_ssa_with_stmt_def (tree t)
>>      call to a parameter number PARAM_INDEX.  NODE is the caller.  Return the
>>      indirect call graph edge.  */
>>
>> -static struct cgraph_edge *
>> -ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
>> +static cgraph_edge *
>> +ipa_note_param_call (cgraph_node *node, int param_index, gimple stmt)
>>   {
>> -  struct cgraph_edge *cs;
>> +  cgraph_edge *cs;
>>
>>     cs = node->get_edge (stmt);
>>     cs->indirect_info->param_index = param_index;
>> @@ -2165,10 +2165,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
>>      passed by value or reference.  */
>>
>>   static void
>> -ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>> +ipa_analyze_indirect_call_uses (func_body_info *fbi, gimple call,
>>                   tree target)
>>   {
>> -  struct ipa_node_params *info = fbi->info;
>> +  ipa_node_params *info = fbi->info;
>>     HOST_WIDE_INT offset;
>>     bool by_ref;
>>
>> @@ -2188,7 +2188,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>                      gimple_assign_rhs1 (def), &index, &offset,
>>                      NULL, &by_ref))
>>       {
>> -      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>> +      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>         cs->indirect_info->offset = offset;
>>         cs->indirect_info->agg_contents = 1;
>>         cs->indirect_info->by_ref = by_ref;
>> @@ -2288,7 +2288,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>     if (index >= 0
>>         && parm_preserved_before_stmt_p (fbi, index, call, rec))
>>       {
>> -      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>> +      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>         cs->indirect_info->offset = offset;
>>         cs->indirect_info->agg_contents = 1;
>>         cs->indirect_info->member_ptr = 1;
>> @@ -2303,7 +2303,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>      statement.  */
>>
>>   static void
>> -ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>> +ipa_analyze_virtual_call_uses (func_body_info *fbi,
>>                      gimple call, tree target)
>>   {
>>     tree obj = OBJ_TYPE_REF_OBJECT (target);
>> @@ -2316,10 +2316,10 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>     if (TREE_CODE (obj) != SSA_NAME)
>>       return;
>>
>> -  struct ipa_node_params *info = fbi->info;
>> +  ipa_node_params *info = fbi->info;
>>     if (SSA_NAME_IS_DEFAULT_DEF (obj))
>>       {
>> -      struct ipa_jump_func jfunc;
>> +      ipa_jump_func jfunc;
>>         if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
>>       return;
>>
>> @@ -2332,7 +2332,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>       }
>>     else
>>       {
>> -      struct ipa_jump_func jfunc;
>> +      ipa_jump_func jfunc;
>>         gimple stmt = SSA_NAME_DEF_STMT (obj);
>>         tree expr;
>>
>> @@ -2347,8 +2347,8 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>       return;
>>       }
>>
>> -  struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
>> +  cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>>     ii->offset = anc_offset;
>>     ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
>>     ii->otr_type = obj_type_ref_class (target);
>> @@ -2360,7 +2360,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>      containing intermediate information about each formal parameter.  */
>>
>>   static void
>> -ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>> +ipa_analyze_call_uses (func_body_info *fbi, gimple call)
>>   {
>>     tree target = gimple_call_fn (call);
>>
>> @@ -2369,7 +2369,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>>             && !virtual_method_call_p (target)))
>>       return;
>>
>> -  struct cgraph_edge *cs = fbi->node->get_edge (call);
>> +  cgraph_edge *cs = fbi->node->get_edge (call);
>>     /* If we previously turned the call into a direct call, there is
>>        no need to analyze.  */
>>     if (cs && !cs->indirect_unknown_callee)
>> @@ -2406,7 +2406,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>>      formal parameters are called.  */
>>
>>   static void
>> -ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
>> +ipa_analyze_stmt_uses (func_body_info *fbi, gimple stmt)
>>   {
>>     if (is_gimple_call (stmt))
>>       ipa_analyze_call_uses (fbi, stmt);
>> @@ -2419,7 +2419,7 @@ ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
>>   static bool
>>   visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
>>   {
>> -  struct ipa_node_params *info = (struct ipa_node_params *) data;
>> +  ipa_node_params *info = (ipa_node_params *) data;
>>
>>     op = get_base_address (op);
>>     if (op
>> @@ -2439,7 +2439,7 @@ visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
>>      the function being analyzed.  */
>>
>>   static void
>> -ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
>> +ipa_analyze_params_uses_in_bb (func_body_info *fbi, basic_block bb)
>>   {
>>     gimple_stmt_iterator gsi;
>>     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>> @@ -2465,9 +2465,9 @@ ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
>>   /* Calculate controlled uses of parameters of NODE.  */
>>
>>   static void
>> -ipa_analyze_controlled_uses (struct cgraph_node *node)
>> +ipa_analyze_controlled_uses (cgraph_node *node)
>>   {
>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>
>>     for (int i = 0; i < ipa_get_param_count (info); i++)
>>       {
>> @@ -2510,7 +2510,7 @@ ipa_analyze_controlled_uses (struct cgraph_node *node)
>>   /* Free stuff in BI.  */
>>
>>   static void
>> -free_ipa_bb_info (struct ipa_bb_info *bi)
>> +free_ipa_bb_info (ipa_bb_info *bi)
>>   {
>>     bi->cg_edges.release ();
>>     bi->param_aa_statuses.release ();
>> @@ -2521,13 +2521,13 @@ free_ipa_bb_info (struct ipa_bb_info *bi)
>>   class analysis_dom_walker : public dom_walker
>>   {
>>   public:
>> -  analysis_dom_walker (struct func_body_info *fbi)
>> +  analysis_dom_walker (func_body_info *fbi)
>>       : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
>>
>>     virtual void before_dom_children (basic_block);
>>
>>   private:
>> -  struct func_body_info *m_fbi;
>> +  func_body_info *m_fbi;
>>   };
>>
>>   void
>> @@ -2542,10 +2542,10 @@ analysis_dom_walker::before_dom_children (basic_block bb)
>>      with actual arguments of calls from within NODE.  */
>>
>>   void
>> -ipa_analyze_node (struct cgraph_node *node)
>> +ipa_analyze_node (cgraph_node *node)
>>   {
>> -  struct func_body_info fbi;
>> -  struct ipa_node_params *info;
>> +  func_body_info fbi;
>> +  ipa_node_params *info;
>>
>>     ipa_check_create_node_params ();
>>     ipa_check_create_edge_args ();
>> @@ -2565,7 +2565,7 @@ ipa_analyze_node (struct cgraph_node *node)
>>         return;
>>       }
>>
>> -  struct function *func = DECL_STRUCT_FUNCTION (node->decl);
>> +  function *func = DECL_STRUCT_FUNCTION (node->decl);
>>     push_cfun (func);
>>     calculate_dominance_info (CDI_DOMINATORS);
>>     ipa_initialize_node_params (node);
>> @@ -2578,13 +2578,13 @@ ipa_analyze_node (struct cgraph_node *node)
>>     fbi.param_count = ipa_get_param_count (info);
>>     fbi.aa_walked = 0;
>>
>> -  for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
>> +  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
>>       {
>>         ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
>>         bi->cg_edges.safe_push (cs);
>>       }
>>
>> -  for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
>> +  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
>>       {
>>         ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
>>         bi->cg_edges.safe_push (cs);
>> @@ -2593,7 +2593,7 @@ ipa_analyze_node (struct cgraph_node *node)
>>     analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
>>
>>     int i;
>> -  struct ipa_bb_info *bi;
>> +  ipa_bb_info *bi;
>>     FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
>>       free_ipa_bb_info (bi);
>>     fbi.bb_infos.release ();
>> @@ -2606,8 +2606,8 @@ ipa_analyze_node (struct cgraph_node *node)
>>      type.  */
>>
>>   static void
>> -combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
>> -                     struct ipa_jump_func *dst)
>> +combine_known_type_and_ancestor_jfs (ipa_jump_func *src,
>> +                     ipa_jump_func *dst)
>>   {
>>     HOST_WIDE_INT combined_offset;
>>     tree combined_type;
>> @@ -2632,25 +2632,25 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
>>      indirectly) inlined into CS->callee and that E has not been inlined.  */
>>
>>   static void
>> -update_jump_functions_after_inlining (struct cgraph_edge *cs,
>> -                      struct cgraph_edge *e)
>> +update_jump_functions_after_inlining (cgraph_edge *cs,
>> +                      cgraph_edge *e)
>>   {
>> -  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
>> -  struct ipa_edge_args *args = IPA_EDGE_REF (e);
>> +  ipa_edge_args *top = IPA_EDGE_REF (cs);
>> +  ipa_edge_args *args = IPA_EDGE_REF (e);
>>     int count = ipa_get_cs_argument_count (args);
>>     int i;
>>
>>     for (i = 0; i < count; i++)
>>       {
>> -      struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
>> -      struct ipa_polymorphic_call_context *dst_ctx
>> +      ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
>> +      ipa_polymorphic_call_context *dst_ctx
>>       = ipa_get_ith_polymorhic_call_context (args, i);
>>
>>         if (dst->type == IPA_JF_ANCESTOR)
>>       {
>> -      struct ipa_jump_func *src;
>> +      ipa_jump_func *src;
>>         int dst_fid = dst->value.ancestor.formal_id;
>> -      struct ipa_polymorphic_call_context *src_ctx
>> +      ipa_polymorphic_call_context *src_ctx
>>           = ipa_get_ith_polymorhic_call_context (top, dst_fid);
>>
>>         /* Variable number of arguments can cause havoc if we try to access
>> @@ -2666,7 +2666,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>
>>         if (src_ctx && !src_ctx->useless_p ())
>>           {
>> -          struct ipa_polymorphic_call_context ctx = *src_ctx;
>> +          ipa_polymorphic_call_context ctx = *src_ctx;
>>
>>             /* TODO: Make type preserved safe WRT contexts.  */
>>             if (!dst->value.ancestor.agg_preserved)
>> @@ -2683,7 +2683,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>         if (src->agg.items
>>             && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
>>           {
>> -          struct ipa_agg_jf_item *item;
>> +          ipa_agg_jf_item *item;
>>             int j;
>>
>>             /* Currently we do not produce clobber aggregate jump functions,
>> @@ -2721,7 +2721,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>       }
>>         else if (dst->type == IPA_JF_PASS_THROUGH)
>>       {
>> -      struct ipa_jump_func *src;
>> +      ipa_jump_func *src;
>>         /* We must check range due to calls with variable number of arguments
>>            and we cannot combine jump functions with operations.  */
>>         if (dst->value.pass_through.operation == NOP_EXPR
>> @@ -2731,12 +2731,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>             int dst_fid = dst->value.pass_through.formal_id;
>>             src = ipa_get_ith_jump_func (top, dst_fid);
>>             bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
>> -          struct ipa_polymorphic_call_context *src_ctx
>> +          ipa_polymorphic_call_context *src_ctx
>>           = ipa_get_ith_polymorhic_call_context (top, dst_fid);
>>
>>             if (src_ctx && !src_ctx->useless_p ())
>>           {
>> -          struct ipa_polymorphic_call_context ctx = *src_ctx;
>> +          ipa_polymorphic_call_context ctx = *src_ctx;
>>
>>             /* TODO: Make type preserved safe WRT contexts.  */
>>             if (!dst->value.ancestor.agg_preserved)
>> @@ -2833,11 +2833,11 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>      (SPECULATIVE)destination of an indirect edge IE and return the edge.
>>      Otherwise, return NULL.  */
>>
>> -struct cgraph_edge *
>> -ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>> +cgraph_edge *
>> +ipa_make_edge_direct_to_target (cgraph_edge *ie, tree target,
>>                   bool speculative)
>>   {
>> -  struct cgraph_node *callee;
>> +  cgraph_node *callee;
>>     struct inline_edge_summary *es = inline_edge_summary (ie);
>>     bool unreachable = false;
>>
>> @@ -2898,8 +2898,8 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>>     /* If the edge is already speculated.  */
>>     if (speculative && ie->speculative)
>>       {
>> -      struct cgraph_edge *e2;
>> -      struct ipa_ref *ref;
>> +      cgraph_edge *e2;
>> +      ipa_ref *ref;
>>         ie->speculative_call_info (e2, ie, ref);
>>         if (e2->callee->ultimate_alias_target ()
>>         != callee->ultimate_alias_target ())
>> @@ -2987,10 +2987,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>>      be passed by reference or by value.  */
>>
>>   tree
>> -ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
>> +ipa_find_agg_cst_for_param (ipa_agg_jump_function *agg,
>>                   HOST_WIDE_INT offset, bool by_ref)
>>   {
>> -  struct ipa_agg_jf_item *item;
>> +  ipa_agg_jf_item *item;
>>     int i;
>>
>>     if (by_ref != agg->by_ref)
>> @@ -3012,10 +3012,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
>>      successfully found and removed.  */
>>
>>   static bool
>> -remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
>> +remove_described_reference (symtab_node *symbol, ipa_cst_ref_desc *rdesc)
>>   {
>> -  struct ipa_ref *to_del;
>> -  struct cgraph_edge *origin;
>> +  ipa_ref *to_del;
>> +  cgraph_edge *origin;
>>
>>     origin = rdesc->cs;
>>     if (!origin)
>> @@ -3037,10 +3037,10 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
>>      IPA_UNDESCRIBED_USE, return the reference description, otherwise return
>>      NULL.  JFUNC must be a constant jump function.  */
>>
>> -static struct ipa_cst_ref_desc *
>> -jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
>> +static ipa_cst_ref_desc *
>> +jfunc_rdesc_usable (ipa_jump_func *jfunc)
>>   {
>> -  struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
>> +  ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
>>     if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
>>       return rdesc;
>>     else
>> @@ -3052,7 +3052,7 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
>>      NULL.  */
>>
>>   static cgraph_node *
>> -cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
>> +cgraph_node_for_jfunc (ipa_jump_func *jfunc)
>>   {
>>     gcc_checking_assert (jfunc->type == IPA_JF_CONST);
>>     tree cst = ipa_get_jf_constant (jfunc);
>> @@ -3070,9 +3070,9 @@ cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
>>      reference could not be found, otherwise return true.  */
>>
>>   static bool
>> -try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
>> +try_decrement_rdesc_refcount (ipa_jump_func *jfunc)
>>   {
>> -  struct ipa_cst_ref_desc *rdesc;
>> +  ipa_cst_ref_desc *rdesc;
>>     if (jfunc->type == IPA_JF_CONST
>>         && (rdesc = jfunc_rdesc_usable (jfunc))
>>         && --rdesc->refcount == 0)
>> @@ -3092,12 +3092,12 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
>>      determined, return the newly direct edge, otherwise return NULL.
>>      NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
>>
>> -static struct cgraph_edge *
>> -try_make_edge_direct_simple_call (struct cgraph_edge *ie,
>> -                  struct ipa_jump_func *jfunc,
>> -                  struct ipa_node_params *new_root_info)
>> +static cgraph_edge *
>> +try_make_edge_direct_simple_call (cgraph_edge *ie,
>> +                  ipa_jump_func *jfunc,
>> +                  ipa_node_params *new_root_info)
>>   {
>> -  struct cgraph_edge *cs;
>> +  cgraph_edge *cs;
>>     tree target;
>>     bool agg_contents = ie->indirect_info->agg_contents;
>>
>> @@ -3130,7 +3130,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
>>      and target (the latter can be NULL) are dumped when dumping is enabled.  */
>>
>>   tree
>> -ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
>> +ipa_impossible_devirt_target (cgraph_edge *ie, tree target)
>>   {
>>     if (dump_file)
>>       {
>> @@ -3155,11 +3155,11 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
>>      Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
>>      are relative to.  */
>>
>> -static struct cgraph_edge *
>> -try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>> -                   struct ipa_jump_func *jfunc,
>> -                   struct ipa_node_params *new_root_info,
>> -                   struct ipa_polymorphic_call_context *ctx_ptr)
>> +static cgraph_edge *
>> +try_make_edge_direct_virtual_call (cgraph_edge *ie,
>> +                   ipa_jump_func *jfunc,
>> +                   ipa_node_params *new_root_info,
>> +                   ipa_polymorphic_call_context *ctx_ptr)
>>   {
>>     tree binfo, target = NULL;
>>     bool speculative = false;
>> @@ -3172,7 +3172,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>        based on knowlede of the context.  */
>>     if (ctx_ptr && !ie->indirect_info->by_ref)
>>       {
>> -      struct ipa_polymorphic_call_context ctx = *ctx_ptr;
>> +      ipa_polymorphic_call_context ctx = *ctx_ptr;
>>
>>         ctx.offset_by (ie->indirect_info->offset);
>>
>> @@ -3221,7 +3221,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>
>>     if (binfo && TREE_CODE (binfo) != TREE_BINFO)
>>       {
>> -      struct ipa_polymorphic_call_context ctx (binfo,
>> +      ipa_polymorphic_call_context ctx (binfo,
>>                              ie->indirect_info->otr_type,
>>                              ie->indirect_info->offset);
>>         updated |= ie->indirect_info->context.combine_with
>> @@ -3296,13 +3296,13 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>      unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
>>
>>   static bool
>> -update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>> -                      struct cgraph_node *node,
>> +update_indirect_edges_after_inlining (cgraph_edge *cs,
>> +                      cgraph_node *node,
>>                         vec<cgraph_edge *> *new_edges)
>>   {
>> -  struct ipa_edge_args *top;
>> -  struct cgraph_edge *ie, *next_ie, *new_direct_edge;
>> -  struct ipa_node_params *new_root_info;
>> +  ipa_edge_args *top;
>> +  cgraph_edge *ie, *next_ie, *new_direct_edge;
>> +  ipa_node_params *new_root_info;
>>     bool res = false;
>>
>>     ipa_check_create_edge_args ();
>> @@ -3313,8 +3313,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>>
>>     for (ie = node->indirect_calls; ie; ie = next_ie)
>>       {
>> -      struct cgraph_indirect_call_info *ici = ie->indirect_info;
>> -      struct ipa_jump_func *jfunc;
>> +      cgraph_indirect_call_info *ici = ie->indirect_info;
>> +      ipa_jump_func *jfunc;
>>         int param_index;
>>
>>         next_ie = ie->next_callee;
>> @@ -3408,11 +3408,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>>      created.  */
>>
>>   static bool
>> -propagate_info_to_inlined_callees (struct cgraph_edge *cs,
>> -                   struct cgraph_node *node,
>> +propagate_info_to_inlined_callees (cgraph_edge *cs,
>> +                   cgraph_node *node,
>>                      vec<cgraph_edge *> *new_edges)
>>   {
>> -  struct cgraph_edge *e;
>> +  cgraph_edge *e;
>>     bool res;
>>
>>     res = update_indirect_edges_after_inlining (cs, node, new_edges);
>> @@ -3443,21 +3443,21 @@ combine_controlled_uses_counters (int c, int d)
>>      tree of inlined nodes.  */
>>
>>   static void
>> -propagate_controlled_uses (struct cgraph_edge *cs)
>> +propagate_controlled_uses (cgraph_edge *cs)
>>   {
>> -  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
>> -  struct cgraph_node *new_root = cs->caller->global.inlined_to
>> +  ipa_edge_args *args = IPA_EDGE_REF (cs);
>> +  cgraph_node *new_root = cs->caller->global.inlined_to
>>       ? cs->caller->global.inlined_to : cs->caller;
>> -  struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
>> -  struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
>> +  ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
>> +  ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
>>     int count, i;
>>
>>     count = MIN (ipa_get_cs_argument_count (args),
>>              ipa_get_param_count (old_root_info));
>>     for (i = 0; i < count; i++)
>>       {
>> -      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>> -      struct ipa_cst_ref_desc *rdesc;
>> +      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>> +      ipa_cst_ref_desc *rdesc;
>>
>>         if (jf->type == IPA_JF_PASS_THROUGH)
>>       {
>> @@ -3472,8 +3472,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>         ipa_set_controlled_uses (new_root_info, src_idx, c);
>>         if (c == 0 && new_root_info->ipcp_orig_node)
>>           {
>> -          struct cgraph_node *n;
>> -          struct ipa_ref *ref;
>> +          cgraph_node *n;
>> +          ipa_ref *ref;
>>             tree t = new_root_info->known_vals[src_idx];
>>
>>             if (t && TREE_CODE (t) == ADDR_EXPR
>> @@ -3500,14 +3500,14 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>         if (rdesc->refcount == 0)
>>           {
>>             tree cst = ipa_get_jf_constant (jf);
>> -          struct cgraph_node *n;
>> +          cgraph_node *n;
>>             gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
>>                      && TREE_CODE (TREE_OPERAND (cst, 0))
>>                      == FUNCTION_DECL);
>>             n = cgraph_node::get (TREE_OPERAND (cst, 0));
>>             if (n)
>>           {
>> -          struct cgraph_node *clone;
>> +          cgraph_node *clone;
>>             bool ok;
>>             ok = remove_described_reference (n, rdesc);
>>             gcc_checking_assert (ok);
>> @@ -3517,7 +3517,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>                && clone != rdesc->cs->caller
>>                && IPA_NODE_REF (clone)->ipcp_orig_node)
>>               {
>> -              struct ipa_ref *ref;
>> +              ipa_ref *ref;
>>                 ref = clone->find_reference (n, NULL, 0);
>>                 if (ref)
>>               {
>> @@ -3542,11 +3542,11 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>          i < ipa_get_cs_argument_count (args);
>>          i++)
>>       {
>> -      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>> +      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>>
>>         if (jf->type == IPA_JF_CONST)
>>       {
>> -      struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
>> +      ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
>>         if (rdesc)
>>           rdesc->refcount = IPA_UNDESCRIBED_USE;
>>       }
>> @@ -3564,13 +3564,13 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>      created.  */
>>
>>   bool
>> -ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>> +ipa_propagate_indirect_call_infos (cgraph_edge *cs,
>>                      vec<cgraph_edge *> *new_edges)
>>   {
>>     bool changed;
>>     /* Do nothing if the preparation phase has not been carried out yet
>>        (i.e. during early inlining).  */
>> -  if (!ipa_node_params_vector.exists ())
>> +  if (!ipa_node_params_summary)
>>       return false;
>>     gcc_assert (ipa_edge_args_vector);
>>
>> @@ -3584,7 +3584,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>>      to.  */
>>
>>   void
>> -ipa_free_edge_args_substructures (struct ipa_edge_args *args)
>> +ipa_free_edge_args_substructures (ipa_edge_args *args)
>>   {
>>     vec_free (args->jump_functions);
>>     memset (args, 0, sizeof (*args));
>> @@ -3596,7 +3596,7 @@ void
>>   ipa_free_all_edge_args (void)
>>   {
>>     int i;
>> -  struct ipa_edge_args *args;
>> +  ipa_edge_args *args;
>>
>>     if (!ipa_edge_args_vector)
>>       return;
>> @@ -3610,15 +3610,21 @@ ipa_free_all_edge_args (void)
>>   /* Frees all dynamically allocated structures that the param info points
>>      to.  */
>>
>> -void
>> -ipa_free_node_params_substructures (struct ipa_node_params *info)
>> +ipa_node_params::~ipa_node_params ()
>>   {
>> -  info->descriptors.release ();
>> -  free (info->lattices);
>> +  descriptors.release ();
>> +  free (lattices);
>>     /* Lattice values and their sources are deallocated with their alocation
>>        pool.  */
>> -  info->known_vals.release ();
>> -  memset (info, 0, sizeof (*info));
>> +  known_vals.release ();
>> +
>> +  lattices = NULL;
>> +  ipcp_orig_node = NULL;
>> +  analysis_done = 0;
>> +  node_enqueued = 0;
>> +  do_clone_for_all_contexts = 0;
>> +  is_all_contexts_clone = 0;
>> +  node_dead = 0;
>>   }
>>
>>   /* Free all ipa_node_params structures.  */
>> @@ -3626,11 +3632,8 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
>>   void
>>   ipa_free_all_node_params (void)
>>   {
>> -  int i;
>> -  struct ipa_node_params *info;
>> -
>> -  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
>> -    ipa_free_node_params_substructures (info);
>> +  delete ipa_node_params_summary;
>> +  ipa_node_params_summary = NULL;
>>
>>     ipa_node_params_vector.release ();
>>   }
>> @@ -3638,8 +3641,8 @@ ipa_free_all_node_params (void)
>>   /* Set the aggregate replacements of NODE to be AGGVALS.  */
>>
>>   void
>> -ipa_set_node_agg_value_chain (struct cgraph_node *node,
>> -                  struct ipa_agg_replacement_value *aggvals)
>> +ipa_set_node_agg_value_chain (const cgraph_node *node,
>> +                  ipa_agg_replacement_value *aggvals)
>>   {
>>     if (vec_safe_length (ipa_node_agg_replacements)
>>         <= (unsigned) symtab->cgraph_max_uid)
>> @@ -3652,9 +3655,9 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
>>   /* Hook that is called by cgraph.c when an edge is removed.  */
>>
>>   static void
>> -ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>> +ipa_edge_removal_hook (cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>   {
>> -  struct ipa_edge_args *args;
>> +  ipa_edge_args *args;
>>
>>     /* During IPA-CP updating we can be called on not-yet analyzed clones.  */
>>     if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
>> @@ -3663,11 +3666,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>     args = IPA_EDGE_REF (cs);
>>     if (args->jump_functions)
>>       {
>> -      struct ipa_jump_func *jf;
>> +      ipa_jump_func *jf;
>>         int i;
>>         FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
>>       {
>> -      struct ipa_cst_ref_desc *rdesc;
>> +      ipa_cst_ref_desc *rdesc;
>>         try_decrement_rdesc_refcount (jf);
>>         if (jf->type == IPA_JF_CONST
>>             && (rdesc = ipa_get_jf_constant_rdesc (jf))
>> @@ -3679,25 +3682,13 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>     ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
>>   }
>>
>> -/* Hook that is called by cgraph.c when a node is removed.  */
>> -
>> -static void
>> -ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>> -{
>> -  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
>> -  if (ipa_node_params_vector.length () > (unsigned)node->uid)
>> -    ipa_free_node_params_substructures (IPA_NODE_REF (node));
>> -  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
>> -    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
>> -}
>> -
>>   /* Hook that is called by cgraph.c when an edge is duplicated.  */
>>
>>   static void
>> -ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>> +ipa_edge_duplication_hook (cgraph_edge *src, cgraph_edge *dst,
>>                  __attribute__((unused)) void *data)
>>   {
>> -  struct ipa_edge_args *old_args, *new_args;
>> +  ipa_edge_args *old_args, *new_args;
>>     unsigned int i;
>>
>>     ipa_check_create_edge_args ();
>> @@ -3712,20 +3703,20 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>
>>     for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
>>       {
>> -      struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
>> -      struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
>> +      ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
>> +      ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
>>
>>         dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
>>
>>         if (src_jf->type == IPA_JF_CONST)
>>       {
>> -      struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
>> +      ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
>>
>>         if (!src_rdesc)
>>           dst_jf->value.constant.rdesc = NULL;
>>         else if (src->caller == dst->caller)
>>           {
>> -          struct ipa_ref *ref;
>> +          ipa_ref *ref;
>>             symtab_node *n = cgraph_node_for_jfunc (src_jf);
>>             gcc_checking_assert (n);
>>             ref = src->caller->find_reference (n, src->call_stmt,
>> @@ -3734,8 +3725,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>             dst->caller->clone_reference (ref, ref->stmt);
>>
>>             gcc_checking_assert (ipa_refdesc_pool);
>> -          struct ipa_cst_ref_desc *dst_rdesc
>> -        = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>> +          ipa_cst_ref_desc *dst_rdesc
>> +        = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>             dst_rdesc->cs = dst;
>>             dst_rdesc->refcount = src_rdesc->refcount;
>>             dst_rdesc->next_duplicate = NULL;
>> @@ -3743,10 +3734,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>           }
>>         else if (src_rdesc->cs == src)
>>           {
>> -          struct ipa_cst_ref_desc *dst_rdesc;
>> +          ipa_cst_ref_desc *dst_rdesc;
>>             gcc_checking_assert (ipa_refdesc_pool);
>>             dst_rdesc
>> -        = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>> +        = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>             dst_rdesc->cs = dst;
>>             dst_rdesc->refcount = src_rdesc->refcount;
>>             dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
>> @@ -3755,7 +3746,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>           }
>>         else
>>           {
>> -          struct ipa_cst_ref_desc *dst_rdesc;
>> +          ipa_cst_ref_desc *dst_rdesc;
>>             /* This can happen during inlining, when a JFUNC can refer to a
>>            reference taken in a function up in the tree of inline clones.
>>            We need to find the duplicate that refers to our tree of
>> @@ -3766,7 +3757,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>              dst_rdesc;
>>              dst_rdesc = dst_rdesc->next_duplicate)
>>           {
>> -          struct cgraph_node *top;
>> +          cgraph_node *top;
>>             top = dst_rdesc->cs->caller->global.inlined_to
>>               ? dst_rdesc->cs->caller->global.inlined_to
>>               : dst_rdesc->cs->caller;
>> @@ -3780,9 +3771,9 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>         else if (dst_jf->type == IPA_JF_PASS_THROUGH
>>              && src->caller == dst->caller)
>>       {
>> -      struct cgraph_node *inline_root = dst->caller->global.inlined_to
>> +      cgraph_node *inline_root = dst->caller->global.inlined_to
>>           ? dst->caller->global.inlined_to : dst->caller;
>> -      struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
>> +      ipa_node_params *root_info = IPA_NODE_REF (inline_root);
>>         int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
>>
>>         int c = ipa_get_controlled_uses (root_info, idx);
>> @@ -3795,18 +3786,24 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>       }
>>   }
>>
>> -/* Hook that is called by cgraph.c when a node is duplicated.  */
>> +/* Analyze newly added function into callgraph.  */
>>
>>   static void
>> -ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>> -               ATTRIBUTE_UNUSED void *data)
>> +ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>>   {
>> -  struct ipa_node_params *old_info, *new_info;
>> -  struct ipa_agg_replacement_value *old_av, *new_av;
>> +  if (node->has_gimple_body_p ())
>> +    ipa_analyze_node (node);
>> +}
>>
>> -  ipa_check_create_node_params ();
>> -  old_info = IPA_NODE_REF (src);
>> -  new_info = IPA_NODE_REF (dst);
>> +/* Hook that is called by summary when a node is duplicated.  */
>> +
>> +void
>> +ipa_node_params_cgraph_summary::duplication_hook(cgraph_node *src,
>> +                            cgraph_node *dst,
>> +                            ipa_node_params *old_info,
>> +                            ipa_node_params *new_info)
>> +{
>> +  ipa_agg_replacement_value *old_av, *new_av;
>>
>>     new_info->descriptors = old_info->descriptors.copy ();
>>     new_info->lattices = NULL;
>> @@ -3822,7 +3819,7 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>>     new_av = NULL;
>>     while (old_av)
>>       {
>> -      struct ipa_agg_replacement_value *v;
>> +      ipa_agg_replacement_value *v;
>>
>>         v = ggc_alloc<ipa_agg_replacement_value> ();
>>         memcpy (v, old_av, sizeof (*v));
>> @@ -3833,33 +3830,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>>     ipa_set_node_agg_value_chain (dst, new_av);
>>   }
>>
>> -
>> -/* Analyze newly added function into callgraph.  */
>> -
>> -static void
>> -ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>> -{
>> -  if (node->has_gimple_body_p ())
>> -    ipa_analyze_node (node);
>> -}
>> -
>>   /* Register our cgraph hooks if they are not already there.  */
>>
>>   void
>>   ipa_register_cgraph_hooks (void)
>>   {
>> +  ipa_check_create_node_params ();
>> +
>>     if (!edge_removal_hook_holder)
>>       edge_removal_hook_holder =
>>         symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
>> -  if (!node_removal_hook_holder)
>> -    node_removal_hook_holder =
>> -      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
>>     if (!edge_duplication_hook_holder)
>>       edge_duplication_hook_holder =
>>         symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
>> -  if (!node_duplication_hook_holder)
>> -    node_duplication_hook_holder =
>> -      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
>>     function_insertion_hook_holder =
>>         symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
>>   }
>> @@ -3871,12 +3854,8 @@ ipa_unregister_cgraph_hooks (void)
>>   {
>>     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
>>     edge_removal_hook_holder = NULL;
>> -  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
>> -  node_removal_hook_holder = NULL;
>>     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
>>     edge_duplication_hook_holder = NULL;
>> -  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
>> -  node_duplication_hook_holder = NULL;
>>     symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
>>     function_insertion_hook_holder = NULL;
>>   }
>> @@ -3923,10 +3902,10 @@ ipa_free_all_structures_after_iinln (void)
>>      callgraph to F.  */
>>
>>   void
>> -ipa_print_node_params (FILE *f, struct cgraph_node *node)
>> +ipa_print_node_params (FILE *f, cgraph_node *node)
>>   {
>>     int i, count;
>> -  struct ipa_node_params *info;
>> +  ipa_node_params *info;
>>
>>     if (!node->definition)
>>       return;
>> @@ -3957,7 +3936,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
>>   void
>>   ipa_print_all_params (FILE * f)
>>   {
>> -  struct cgraph_node *node;
>> +  cgraph_node *node;
>>
>>     fprintf (f, "\nFunction parameters:\n");
>>     FOR_EACH_FUNCTION (node)
>> @@ -4040,7 +4019,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
>>     tree new_arg_types = NULL;
>>     for (int i = 0; i < len; i++)
>>       {
>> -      struct ipa_parm_adjustment *adj;
>> +      ipa_parm_adjustment *adj;
>>         gcc_assert (link);
>>
>>         adj = &adjustments[i];
>> @@ -4158,10 +4137,10 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
>>      contain the corresponding call graph edge.  */
>>
>>   void
>> -ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
>> +ipa_modify_call_arguments (cgraph_edge *cs, gimple stmt,
>>                  ipa_parm_adjustment_vec adjustments)
>>   {
>> -  struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
>> +  cgraph_node *current_node = cgraph_node::get (current_function_decl);
>>     vec<tree> vargs;
>>     vec<tree, va_gc> **debug_args = NULL;
>>     gimple new_stmt;
>> @@ -4179,7 +4158,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
>>     gsi_prev (&prev_gsi);
>>     for (i = 0; i < len; i++)
>>       {
>> -      struct ipa_parm_adjustment *adj;
>> +      ipa_parm_adjustment *adj;
>>
>>         adj = &adjustments[i];
>>
>> @@ -4412,7 +4391,7 @@ bool
>>   ipa_modify_expr (tree *expr, bool convert,
>>            ipa_parm_adjustment_vec adjustments)
>>   {
>> -  struct ipa_parm_adjustment *cand
>> +  ipa_parm_adjustment *cand
>>       = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
>>     if (!cand)
>>       return false;
>> @@ -4500,11 +4479,11 @@ ipa_get_adjustment_candidate (tree **expr, bool *convert,
>>     if (!base || TREE_CODE (base) != PARM_DECL)
>>       return NULL;
>>
>> -  struct ipa_parm_adjustment *cand = NULL;
>> +  ipa_parm_adjustment *cand = NULL;
>>     unsigned int len = adjustments.length ();
>>     for (unsigned i = 0; i < len; i++)
>>       {
>> -      struct ipa_parm_adjustment *adj = &adjustments[i];
>> +      ipa_parm_adjustment *adj = &adjustments[i];
>>
>>         if (adj->base == base
>>         && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
>> @@ -4530,7 +4509,7 @@ index_in_adjustments_multiple_times_p (int base_index,
>>
>>     for (i = 0; i < len; i++)
>>       {
>> -      struct ipa_parm_adjustment *adj;
>> +      ipa_parm_adjustment *adj;
>>         adj = &adjustments[i];
>>
>>         if (adj->base_index == base_index)
>> @@ -4561,7 +4540,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>>     tmp.create (inlen);
>>     for (i = 0; i < inlen; i++)
>>       {
>> -      struct ipa_parm_adjustment *n;
>> +      ipa_parm_adjustment *n;
>>         n = &inner[i];
>>
>>         if (n->op == IPA_PARM_OP_REMOVE)
>> @@ -4577,9 +4556,9 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>>     adjustments.create (outlen + removals);
>>     for (i = 0; i < outlen; i++)
>>       {
>> -      struct ipa_parm_adjustment r;
>> -      struct ipa_parm_adjustment *out = &outer[i];
>> -      struct ipa_parm_adjustment *in = &tmp[out->base_index];
>> +      ipa_parm_adjustment r;
>> +      ipa_parm_adjustment *out = &outer[i];
>> +      ipa_parm_adjustment *in = &tmp[out->base_index];
>>
>>         memset (&r, 0, sizeof (r));
>>         gcc_assert (in->op != IPA_PARM_OP_REMOVE);
>> @@ -4616,7 +4595,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>>
>>     for (i = 0; i < inlen; i++)
>>       {
>> -      struct ipa_parm_adjustment *n = &inner[i];
>> +      ipa_parm_adjustment *n = &inner[i];
>>
>>         if (n->op == IPA_PARM_OP_REMOVE)
>>       adjustments.quick_push (*n);
>> @@ -4640,7 +4619,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
>>     fprintf (file, "IPA param adjustments: ");
>>     for (i = 0; i < len; i++)
>>       {
>> -      struct ipa_parm_adjustment *adj;
>> +      ipa_parm_adjustment *adj;
>>         adj = &adjustments[i];
>>
>>         if (!first)
>> @@ -4683,7 +4662,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
>>   /* Dump the AV linked list.  */
>>
>>   void
>> -ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
>> +ipa_dump_agg_replacement_values (FILE *f, ipa_agg_replacement_value *av)
>>   {
>>     bool comma = false;
>>     fprintf (f, "     Aggregate replacements:");
>> @@ -4700,11 +4679,11 @@ ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
>>   /* Stream out jump function JUMP_FUNC to OB.  */
>>
>>   static void
>> -ipa_write_jump_function (struct output_block *ob,
>> -             struct ipa_jump_func *jump_func)
>> +ipa_write_jump_function (output_block *ob,
>> +             ipa_jump_func *jump_func)
>>   {
>> -  struct ipa_agg_jf_item *item;
>> -  struct bitpack_d bp;
>> +  ipa_agg_jf_item *item;
>> +  bitpack_d bp;
>>     int i, count;
>>
>>     streamer_write_uhwi (ob, jump_func->type);
>> @@ -4768,10 +4747,10 @@ ipa_write_jump_function (struct output_block *ob,
>>   /* Read in jump function JUMP_FUNC from IB.  */
>>
>>   static void
>> -ipa_read_jump_function (struct lto_input_block *ib,
>> -            struct ipa_jump_func *jump_func,
>> -            struct cgraph_edge *cs,
>> -            struct data_in *data_in)
>> +ipa_read_jump_function (lto_input_block *ib,
>> +            ipa_jump_func *jump_func,
>> +            cgraph_edge *cs,
>> +            data_in *data_in)
>>   {
>>     enum jump_func_type jftype;
>>     enum tree_code operation;
>> @@ -4800,7 +4779,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>         if (operation == NOP_EXPR)
>>       {
>>         int formal_id =  streamer_read_uhwi (ib);
>> -      struct bitpack_d bp = streamer_read_bitpack (ib);
>> +      bitpack_d bp = streamer_read_bitpack (ib);
>>         bool agg_preserved = bp_unpack_value (&bp, 1);
>>         bool type_preserved = bp_unpack_value (&bp, 1);
>>         ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
>> @@ -4819,7 +4798,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>       HOST_WIDE_INT offset = streamer_read_uhwi (ib);
>>       tree type = stream_read_tree (ib, data_in);
>>       int formal_id = streamer_read_uhwi (ib);
>> -    struct bitpack_d bp = streamer_read_bitpack (ib);
>> +    bitpack_d bp = streamer_read_bitpack (ib);
>>       bool agg_preserved = bp_unpack_value (&bp, 1);
>>       bool type_preserved = bp_unpack_value (&bp, 1);
>>
>> @@ -4833,12 +4812,12 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>     vec_alloc (jump_func->agg.items, count);
>>     if (count)
>>       {
>> -      struct bitpack_d bp = streamer_read_bitpack (ib);
>> +      bitpack_d bp = streamer_read_bitpack (ib);
>>         jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
>>       }
>>     for (i = 0; i < count; i++)
>>       {
>> -      struct ipa_agg_jf_item item;
>> +      ipa_agg_jf_item item;
>>         item.offset = streamer_read_uhwi (ib);
>>         item.value = stream_read_tree (ib, data_in);
>>         jump_func->agg.items->quick_push (item);
>> @@ -4849,11 +4828,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>      relevant to indirect inlining to OB.  */
>>
>>   static void
>> -ipa_write_indirect_edge_info (struct output_block *ob,
>> -                  struct cgraph_edge *cs)
>> +ipa_write_indirect_edge_info (output_block *ob,
>> +                  cgraph_edge *cs)
>>   {
>> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
>> -  struct bitpack_d bp;
>> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>> +  bitpack_d bp;
>>
>>     streamer_write_hwi (ob, ii->param_index);
>>     bp = bitpack_create (ob->main_stream);
>> @@ -4880,12 +4859,12 @@ ipa_write_indirect_edge_info (struct output_block *ob,
>>      relevant to indirect inlining from IB.  */
>>
>>   static void
>> -ipa_read_indirect_edge_info (struct lto_input_block *ib,
>> -                 struct data_in *data_in,
>> -                 struct cgraph_edge *cs)
>> +ipa_read_indirect_edge_info (lto_input_block *ib,
>> +                 data_in *data_in,
>> +                 cgraph_edge *cs)
>>   {
>> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
>> -  struct bitpack_d bp;
>> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>> +  bitpack_d bp;
>>
>>     ii->param_index = (int) streamer_read_hwi (ib);
>>     bp = streamer_read_bitpack (ib);
>> @@ -4909,14 +4888,14 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
>>   /* Stream out NODE info to OB.  */
>>
>>   static void
>> -ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>> +ipa_write_node_info (output_block *ob, cgraph_node *node)
>>   {
>>     int node_ref;
>>     lto_symtab_encoder_t encoder;
>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>     int j;
>> -  struct cgraph_edge *e;
>> -  struct bitpack_d bp;
>> +  cgraph_edge *e;
>> +  bitpack_d bp;
>>
>>     encoder = ob->decl_state->symtab_node_encoder;
>>     node_ref = lto_symtab_encoder_encode (encoder, node);
>> @@ -4937,7 +4916,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>       streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
>>     for (e = node->callees; e; e = e->next_callee)
>>       {
>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>
>>         streamer_write_uhwi (ob,
>>                  ipa_get_cs_argument_count (args) * 2
>> @@ -4951,7 +4930,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>       }
>>     for (e = node->indirect_calls; e; e = e->next_callee)
>>       {
>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>
>>         streamer_write_uhwi (ob,
>>                  ipa_get_cs_argument_count (args) * 2
>> @@ -4969,13 +4948,13 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>   /* Stream in NODE info from IB.  */
>>
>>   static void
>> -ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>> -            struct data_in *data_in)
>> +ipa_read_node_info (lto_input_block *ib, cgraph_node *node,
>> +            data_in *data_in)
>>   {
>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>     int k;
>> -  struct cgraph_edge *e;
>> -  struct bitpack_d bp;
>> +  cgraph_edge *e;
>> +  bitpack_d bp;
>>
>>     ipa_alloc_node_params (node, streamer_read_uhwi (ib));
>>
>> @@ -4992,7 +4971,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>       ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
>>     for (e = node->callees; e; e = e->next_callee)
>>       {
>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>         int count = streamer_read_uhwi (ib);
>>         bool contexts_computed = count & 1;
>>         count /= 2;
>> @@ -5013,7 +4992,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>       }
>>     for (e = node->indirect_calls; e; e = e->next_callee)
>>       {
>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>         int count = streamer_read_uhwi (ib);
>>         bool contexts_computed = count & 1;
>>         count /= 2;
>> @@ -5040,14 +5019,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>   void
>>   ipa_prop_write_jump_functions (void)
>>   {
>> -  struct cgraph_node *node;
>> -  struct output_block *ob;
>> +  cgraph_node *node;
>> +  output_block *ob;
>>     unsigned int count = 0;
>>     lto_symtab_encoder_iterator lsei;
>>     lto_symtab_encoder_t encoder;
>>
>> -
>> -  if (!ipa_node_params_vector.exists ())
>> +  if (!ipa_node_params_summary)
>>       return;
>>
>>     ob = create_output_block (LTO_section_jump_functions);
>> @@ -5081,15 +5059,15 @@ ipa_prop_write_jump_functions (void)
>>   /* Read section in file FILE_DATA of length LEN with data DATA.  */
>>
>>   static void
>> -ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>> +ipa_prop_read_section (lto_file_decl_data *file_data, const char *data,
>>                  size_t len)
>>   {
>> -  const struct lto_function_header *header =
>> -    (const struct lto_function_header *) data;
>> -  const int cfg_offset = sizeof (struct lto_function_header);
>> +  const lto_function_header *header =
>> +    (const lto_function_header *) data;
>> +  const int cfg_offset = sizeof (lto_function_header);
>>     const int main_offset = cfg_offset + header->cfg_size;
>>     const int string_offset = main_offset + header->main_size;
>> -  struct data_in *data_in;
>> +  data_in *data_in;
>>     unsigned int i;
>>     unsigned int count;
>>
>> @@ -5104,7 +5082,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>>     for (i = 0; i < count; i++)
>>       {
>>         unsigned int index;
>> -      struct cgraph_node *node;
>> +      cgraph_node *node;
>>         lto_symtab_encoder_t encoder;
>>
>>         index = streamer_read_uhwi (&ib_main);
>> @@ -5124,8 +5102,8 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>>   void
>>   ipa_prop_read_jump_functions (void)
>>   {
>> -  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>> -  struct lto_file_decl_data *file_data;
>> +  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>> +  lto_file_decl_data *file_data;
>>     unsigned int j = 0;
>>
>>     ipa_check_create_node_params ();
>> @@ -5154,12 +5132,12 @@ ipa_update_after_lto_read (void)
>>   }
>>
>>   void
>> -write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>> +write_agg_replacement_chain (output_block *ob, cgraph_node *node)
>>   {
>>     int node_ref;
>>     unsigned int count = 0;
>>     lto_symtab_encoder_t encoder;
>> -  struct ipa_agg_replacement_value *aggvals, *av;
>> +  ipa_agg_replacement_value *aggvals, *av;
>>
>>     aggvals = ipa_get_agg_replacements_for_node (node);
>>     encoder = ob->decl_state->symtab_node_encoder;
>> @@ -5172,7 +5150,7 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>>
>>     for (av = aggvals; av; av = av->next)
>>       {
>> -      struct bitpack_d bp;
>> +      bitpack_d bp;
>>
>>         streamer_write_uhwi (ob, av->offset);
>>         streamer_write_uhwi (ob, av->index);
>> @@ -5187,18 +5165,18 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>>   /* Stream in the aggregate value replacement chain for NODE from IB.  */
>>
>>   static void
>> -read_agg_replacement_chain (struct lto_input_block *ib,
>> -                struct cgraph_node *node,
>> -                struct data_in *data_in)
>> +read_agg_replacement_chain (lto_input_block *ib,
>> +                cgraph_node *node,
>> +                data_in *data_in)
>>   {
>> -  struct ipa_agg_replacement_value *aggvals = NULL;
>> +  ipa_agg_replacement_value *aggvals = NULL;
>>     unsigned int count, i;
>>
>>     count = streamer_read_uhwi (ib);
>>     for (i = 0; i <count; i++)
>>       {
>> -      struct ipa_agg_replacement_value *av;
>> -      struct bitpack_d bp;
>> +      ipa_agg_replacement_value *av;
>> +      bitpack_d bp;
>>
>>         av = ggc_alloc<ipa_agg_replacement_value> ();
>>         av->offset = streamer_read_uhwi (ib);
>> @@ -5217,8 +5195,8 @@ read_agg_replacement_chain (struct lto_input_block *ib,
>>   void
>>   ipa_prop_write_all_agg_replacement (void)
>>   {
>> -  struct cgraph_node *node;
>> -  struct output_block *ob;
>> +  cgraph_node *node;
>> +  output_block *ob;
>>     unsigned int count = 0;
>>     lto_symtab_encoder_iterator lsei;
>>     lto_symtab_encoder_t encoder;
>> @@ -5257,16 +5235,16 @@ ipa_prop_write_all_agg_replacement (void)
>>      DATA.  */
>>
>>   static void
>> -read_replacements_section (struct lto_file_decl_data *file_data,
>> +read_replacements_section (lto_file_decl_data *file_data,
>>                  const char *data,
>>                  size_t len)
>>   {
>> -  const struct lto_function_header *header =
>> -    (const struct lto_function_header *) data;
>> -  const int cfg_offset = sizeof (struct lto_function_header);
>> +  const lto_function_header *header =
>> +    (const lto_function_header *) data;
>> +  const int cfg_offset = sizeof (lto_function_header);
>>     const int main_offset = cfg_offset + header->cfg_size;
>>     const int string_offset = main_offset + header->main_size;
>> -  struct data_in *data_in;
>> +  data_in *data_in;
>>     unsigned int i;
>>     unsigned int count;
>>
>> @@ -5280,7 +5258,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
>>     for (i = 0; i < count; i++)
>>       {
>>         unsigned int index;
>> -      struct cgraph_node *node;
>> +      cgraph_node *node;
>>         lto_symtab_encoder_t encoder;
>>
>>         index = streamer_read_uhwi (&ib_main);
>> @@ -5300,8 +5278,8 @@ read_replacements_section (struct lto_file_decl_data *file_data,
>>   void
>>   ipa_prop_read_all_agg_replacement (void)
>>   {
>> -  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>> -  struct lto_file_decl_data *file_data;
>> +  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>> +  lto_file_decl_data *file_data;
>>     unsigned int j = 0;
>>
>>     while ((file_data = file_data_vec[j++]))
>> @@ -5319,10 +5297,10 @@ ipa_prop_read_all_agg_replacement (void)
>>      NODE.  */
>>
>>   static void
>> -adjust_agg_replacement_values (struct cgraph_node *node,
>> -                   struct ipa_agg_replacement_value *aggval)
>> +adjust_agg_replacement_values (cgraph_node *node,
>> +                   ipa_agg_replacement_value *aggval)
>>   {
>> -  struct ipa_agg_replacement_value *v;
>> +  ipa_agg_replacement_value *v;
>>     int i, c = 0, d = 0, *adj;
>>
>>     if (!node->clone.combined_args_to_skip)
>> @@ -5355,9 +5333,9 @@ adjust_agg_replacement_values (struct cgraph_node *node,
>>   class ipcp_modif_dom_walker : public dom_walker
>>   {
>>   public:
>> -  ipcp_modif_dom_walker (struct func_body_info *fbi,
>> +  ipcp_modif_dom_walker (func_body_info *fbi,
>>                vec<ipa_param_descriptor> descs,
>> -             struct ipa_agg_replacement_value *av,
>> +             ipa_agg_replacement_value *av,
>>                bool *sc, bool *cc)
>>       : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
>>         m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
>> @@ -5365,9 +5343,9 @@ public:
>>     virtual void before_dom_children (basic_block);
>>
>>   private:
>> -  struct func_body_info *m_fbi;
>> +  func_body_info *m_fbi;
>>     vec<ipa_param_descriptor> m_descriptors;
>> -  struct ipa_agg_replacement_value *m_aggval;
>> +  ipa_agg_replacement_value *m_aggval;
>>     bool *m_something_changed, *m_cfg_changed;
>>   };
>>
>> @@ -5377,7 +5355,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
>>     gimple_stmt_iterator gsi;
>>     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>>       {
>> -      struct ipa_agg_replacement_value *v;
>> +      ipa_agg_replacement_value *v;
>>         gimple stmt = gsi_stmt (gsi);
>>         tree rhs, val, t;
>>         HOST_WIDE_INT offset, size;
>> @@ -5468,11 +5446,11 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
>>   /* IPCP transformation phase doing propagation of aggregate values.  */
>>
>>   unsigned int
>> -ipcp_transform_function (struct cgraph_node *node)
>> +ipcp_transform_function (cgraph_node *node)
>>   {
>>     vec<ipa_param_descriptor> descriptors = vNULL;
>> -  struct func_body_info fbi;
>> -  struct ipa_agg_replacement_value *aggval;
>> +  func_body_info fbi;
>> +  ipa_agg_replacement_value *aggval;
>>     int param_count;
>>     bool cfg_changed = false, something_changed = false;
>>
>> @@ -5507,7 +5485,7 @@ ipcp_transform_function (struct cgraph_node *node)
>>                &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
>>
>>     int i;
>> -  struct ipa_bb_info *bi;
>> +  ipa_bb_info *bi;
>>     FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
>>       free_ipa_bb_info (bi);
>>     fbi.bb_infos.release ();
>> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
>> index 165fc1a..6c3b31f 100644
>> --- a/gcc/ipa-prop.h
>> +++ b/gcc/ipa-prop.h
>> @@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
>>   #ifndef IPA_PROP_H
>>   #define IPA_PROP_H
>>
>> -
>>   /* The following definitions and interfaces are used by
>>      interprocedural analyses or parameters.  */
>>
>> @@ -356,6 +355,8 @@ struct ipcp_lattice;
>>
>>   struct ipa_node_params
>>   {
>> +  ~ipa_node_params ();
>> +
>>     /* Information about individual formal parameters that are gathered when
>>        summaries are generated. */
>>     vec<ipa_param_descriptor> descriptors;
>> @@ -364,7 +365,7 @@ struct ipa_node_params
>>     struct ipcp_param_lattices *lattices;
>>     /* Only for versioned nodes this field would not be NULL,
>>        it points to the node that IPA cp cloned from.  */
>> -  struct cgraph_node *ipcp_orig_node;
>> +  cgraph_node *ipcp_orig_node;
>>     /* If this node is an ipa-cp clone, these are the known values that describe
>>        what it has been specialized for.  */
>>     vec<tree> known_vals;
>> @@ -470,7 +471,7 @@ struct GTY(()) ipa_agg_replacement_value
>>
>>   typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
>>
>> -void ipa_set_node_agg_value_chain (struct cgraph_node *node,
>> +void ipa_set_node_agg_value_chain (const cgraph_node *node,
>>                      struct ipa_agg_replacement_value *aggvals);
>>
>>   /* ipa_edge_args stores information related to a callsite and particularly its
>> @@ -513,10 +514,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
>>     return &(*args->polymorphic_call_contexts)[i];
>>   }
>>
>> -/* Types of vectors holding the infos.  */
>> +/* Callgraph summary for ipa_node_params.  */
>> +class ipa_node_params_cgraph_summary: public cgraph_summary <ipa_node_params *>
>> +{
>> +public:
>> +  ipa_node_params_cgraph_summary (symbol_table *table):
>> +    cgraph_summary <ipa_node_params *> (table) { }
>> +
>> +  /* Hook that is called by summary when a node is duplicated.  */
>> +  virtual void duplication_hook (cgraph_node *node,
>> +                 cgraph_node *node2,
>> +                 ipa_node_params *data,
>> +                 ipa_node_params *data2);
>> +};
>>
>>   /* Vector where the parameter infos are actually stored. */
>> -extern vec<ipa_node_params> ipa_node_params_vector;
>> +extern ipa_node_params_cgraph_summary *ipa_node_params_summary;
>>   /* Vector of known aggregate values in cloned nodes.  */
>>   extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>>   /* Vector where the parameter infos are actually stored. */
>> @@ -524,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>
>>   /* Return the associated parameter/argument info corresponding to the given
>>      node/edge.  */
>> -#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
>> +#define IPA_NODE_REF(NODE) ((*ipa_node_params_summary)[NODE])
>>   #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
>>   /* This macro checks validity of index returned by
>>      ipa_get_param_decl_index function.  */
>> @@ -534,11 +547,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>   void ipa_create_all_node_params (void);
>>   void ipa_create_all_edge_args (void);
>>   void ipa_free_edge_args_substructures (struct ipa_edge_args *);
>> -void ipa_free_node_params_substructures (struct ipa_node_params *);
>>   void ipa_free_all_node_params (void);
>>   void ipa_free_all_edge_args (void);
>>   void ipa_free_all_structures_after_ipa_cp (void);
>>   void ipa_free_all_structures_after_iinln (void);
>> +
>>   void ipa_register_cgraph_hooks (void);
>>   int count_formal_params (tree fndecl);
>>
>> @@ -548,11 +561,8 @@ int count_formal_params (tree fndecl);
>>   static inline void
>>   ipa_check_create_node_params (void)
>>   {
>> -  if (!ipa_node_params_vector.exists ())
>> -    ipa_node_params_vector.create (symtab->cgraph_max_uid);
>> -
>> -  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
>> -    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
>> +  if (!ipa_node_params_summary)
>> +    ipa_node_params_summary = new ipa_node_params_cgraph_summary (symtab);
>>   }
>>
>>   /* This function ensures the array of edge arguments infos is big enough to
>> @@ -579,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
>>   /* Return the aggregate replacements for NODE, if there are any.  */
>>
>>   static inline struct ipa_agg_replacement_value *
>> -ipa_get_agg_replacements_for_node (struct cgraph_node *node)
>> +ipa_get_agg_replacements_for_node (const cgraph_node *node)
>>   {
>>     if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
>>       return NULL;
>> @@ -587,7 +597,7 @@ ipa_get_agg_replacements_for_node (struct cgraph_node *node)
>>   }
>>
>>   /* Function formal parameters related computations.  */
>> -void ipa_initialize_node_params (struct cgraph_node *node);
>> +void ipa_initialize_node_params (const cgraph_node *node);
>>   bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>>                       vec<cgraph_edge *> *new_edges);
>>
>> @@ -602,7 +612,7 @@ tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
>>   tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
>>
>>   /* Functions related to both.  */
>> -void ipa_analyze_node (struct cgraph_node *);
>> +void ipa_analyze_node (cgraph_node *);
>>
>>   /* Aggregate jump function related functions.  */
>>   tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
>> @@ -611,9 +621,9 @@ bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
>>                    HOST_WIDE_INT *, bool *);
>>
>>   /* Debugging interface.  */
>> -void ipa_print_node_params (FILE *, struct cgraph_node *node);
>> +void ipa_print_node_params (FILE *, cgraph_node *node);
>>   void ipa_print_all_params (FILE *);
>> -void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
>> +void ipa_print_node_jump_functions (FILE *f, cgraph_node *node);
>>   void ipa_print_all_jump_functions (FILE * f);
>>   void ipcp_verify_propagated_values (void);
>>
>> @@ -717,7 +727,7 @@ void ipa_update_after_lto_read (void);
>>   int ipa_get_param_decl_index (struct ipa_node_params *, tree);
>>   tree ipa_value_from_jfunc (struct ipa_node_params *info,
>>                  struct ipa_jump_func *jfunc);
>> -unsigned int ipcp_transform_function (struct cgraph_node *node);
>> +unsigned int ipcp_transform_function (cgraph_node *node);
>>   void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
>>   bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
>>   ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
>> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
>> index 98dbc63..0a7ca53 100644
>> --- a/gcc/ipa-split.c
>> +++ b/gcc/ipa-split.c
>> @@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "gimple-ssa.h"
>>   #include "tree-cfg.h"
>> diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
>> index 22900cc..83111bc 100644
>> --- a/gcc/ipa-utils.c
>> +++ b/gcc/ipa-utils.c
>> @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "langhooks.h"
>>   #include "lto-streamer.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>
>> diff --git a/gcc/ipa.c b/gcc/ipa.c
>> index a6086d8..aded512 100644
>> --- a/gcc/ipa.c
>> +++ b/gcc/ipa.c
>> @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "tree-iterator.h"
>>   #include "ipa-utils.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "tree-inline.h"
>> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
>> index 0e1a95b..37d0f39 100644
>> --- a/gcc/lto/lto-partition.c
>> +++ b/gcc/lto/lto-partition.c
>> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "timevar.h"
>>   #include "params.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "ipa-utils.h"
>> diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
>> index 4c4e48a..ee97d06 100644
>> --- a/gcc/lto/lto-symtab.c
>> +++ b/gcc/lto/lto-symtab.c
>> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "lto-streamer.h"
>>   #include "ipa-utils.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "ipa-inline.h"
>>   #include "builtins.h"
>> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
>> index d8519d9..c99dbdf 100644
>> --- a/gcc/lto/lto.c
>> +++ b/gcc/lto/lto.c
>> @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "bitmap.h"
>>   #include "inchash.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "common.h"
>>   #include "debug.h"
>> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
>> index b59d069..707379a 100644
>> --- a/gcc/omp-low.c
>> +++ b/gcc/omp-low.c
>> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "tree-cfgcleanup.h"
>>   #include "pretty-print.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "tree-nested.h"
>>   #include "tree-eh.h"
>> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
>> index 8cb9510..a8e3561 100644
>> --- a/gcc/tree-inline.c
>> +++ b/gcc/tree-inline.c
>> @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>>   #include "alloc-pool.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "value-prof.h"
>>   #include "tree-pass.h"
>> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
>> index 1e629bc..99b19b8 100644
>> --- a/gcc/tree-sra.c
>> +++ b/gcc/tree-sra.c
>> @@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "plugin-api.h"
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "statistics.h"
>>   #include "params.h"
>> diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
>> index ea99198..b526cc9 100644
>> --- a/gcc/tree-ssa-pre.c
>> +++ b/gcc/tree-ssa-pre.c
>> @@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "plugin-api.h"
>>   #include "ipa-ref.h"
>>   #include "cgraph.h"
>> +#include "cgraph_summary.h"
>>   #include "ipa-prop.h"
>>   #include "tree-ssa-propagate.h"
>>   #include "ipa-utils.h"
>>
>
> Patch v2.
>
> Martin

Patch v3.

Martin

[-- Attachment #2: 0002-First-usage-of-cgraph_summary-in-ipa-prop-pass.patch --]
[-- Type: text/x-patch, Size: 97930 bytes --]

From 7255ffaf7bb416037baa14499b197bac3be8c222 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 14 Nov 2014 16:14:28 +0100
Subject: [PATCH 2/3] First usage of cgraph_summary in ipa-prop pass.

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* auto-profile.c: Include symbol-summary.h.
	* cgraph.c: Likewise.
	* cgraphbuild.c: Likewise.
	* cgraphclones.c: Likewise.
	* cgraphunit.c: Likewise.
	* ipa-cp.c: Likewise.
	* ipa-devirt.c: Likewise.
	* ipa-icf.c: Likewise.
	* ipa-inline-analysis.c (evaluate_properties_for_edge): Usage of
	ipa_node_params_vector is replaced with ipa_node_params_t.
	(inline_node_duplication_hook): Likewise.
	(estimate_function_body_sizes): Likewise.
	(remap_edge_change_prob): Likewise.
	(inline_merge_summary): Likewise.
	* ipa-inline-transform.c: Include of symbol-summary.h.
	* ipa-inline.c (early_inliner): Usage of
	ipa_node_params_vector is replaced with ipa_node_params_t.
	* ipa-polymorphic-call.c: Include of symbol-summary.h.
	* ipa-profile.c: Include of symbol-summary.h.
	* ipa-prop.c (struct func_body_info): Struct keyword is removed.
	(struct ipa_cst_ref_desc): Likewise.
	(ipa_func_spec_opts_forbid_analysis_p): Likewise.
	(ipa_alloc_node_params): Likewise.
	(ipa_initialize_node_params): Likewise.
	(ipa_print_node_jump_functions_for_edge): Likewise.
	(ipa_print_node_jump_functions): Likewise.
	(ipa_print_all_jump_functions): Likewise.
	(ipa_set_jf_constant): Likewise.
	(check_stmt_for_type_change): Likewise.
	(detect_type_change_from_memory_writes): Likewise.
	(find_dominating_aa_status): Likewise.
	(parm_bb_aa_status_for_bb): Likewise.
	(parm_preserved_before_stmt_p): Likewise.
	(parm_ref_data_preserved_p): Likewise.
	(parm_ref_data_pass_through_p): Likewise.
	(struct ipa_known_agg_contents_list): Likewise.
	(get_place_in_agg_contents_list): Likewise.
	(build_agg_jump_func_from_list): Likewise.
	(determine_locally_known_aggregate_parts): Likewise.
	(ipa_compute_jump_functions_for_edge): Likewise.
	(ipa_compute_jump_functions_for_bb): Likewise.
	(ipa_note_param_call): Likewise.
	(ipa_analyze_indirect_call_uses) Likewise.:
	(ipa_analyze_virtual_call_uses): Likewise.
	(ipa_analyze_call_uses): Likewise.
	(visit_ref_for_mod_analysis): Likewise.
	(ipa_analyze_controlled_uses): Likewise.
	(ipa_analyze_node): Likewise.
	(update_jump_functions_after_inlining): Likewise.
	(ipa_make_edge_direct_to_target): Likewise.
	(ipa_find_agg_cst_for_param): Likewise.
	(remove_described_reference): Likewise.
	(jfunc_rdesc_usable): Likewise.
	(try_decrement_rdesc_refcount): Likewise.
	(try_make_edge_direct_simple_call): Likewise.
	(try_make_edge_direct_virtual_call): Likewise.
	(update_indirect_edges_after_inlining): Likewise.
	(propagate_info_to_inlined_callees): Likewise.
	(propagate_controlled_uses): Likewise.
	(ipa_propagate_indirect_call_infos): Likewise.
	(ipa_free_all_edge_args): Likewise.
	(ipa_node_params::~ipa_node_params): Likewise.
	(ipa_free_all_node_params): Likewise.
	(ipa_edge_removal_hook): Likewise.
	(ipa_node_removal_hook): Likewise.
	(ipa_edge_duplication_hook): Likewise.
	(ipa_add_new_function): Removed
	(ipa_node_params_t::duplicate): New function.
	(ipa_node_duplication_hook): Struct keyword removed.
	(ipa_register_cgraph_hooks): Removal of old hooks.
	(ipa_unregister_cgraph_hooks): Likewise.
	(ipa_print_node_params): Struct keyword is removed.
	(ipa_print_all_params): Likewise.
	(ipa_modify_formal_parameters): Likewise.
	(ipa_modify_call_arguments): Likewise.
	(ipa_modify_expr): Likewise.
	(ipa_get_adjustment_candidate): Likewise.
	(index_in_adjustments_multiple_times_p): Likewise.
	(ipa_combine_adjustments): Likewise.
	(ipa_dump_param_adjustments): Likewise.
	(ipa_write_jump_function): Likewise.
	(ipa_read_jump_function): Likewise.
	(ipa_write_indirect_edge_info): Likewise.
	(ipa_read_indirect_edge_info): Likewise.
	(ipa_write_node_info): Likewise.
	(ipa_read_node_info): Likewise.
	(ipa_prop_write_jump_functions): Likewise.
	(ipa_prop_read_section): Likewise.
	(ipa_prop_read_jump_functions): Likewise.
	(write_agg_replacement_chain): Likewise.
	(read_agg_replacement_chain): Likewise.
	(ipa_prop_write_all_agg_replacement): Likewise.
	(read_replacements_section): Likewise.
	(ipa_prop_read_all_agg_replacement): Likewise.
	(adjust_agg_replacement_values): Likewise.
	(ipcp_modif_dom_walker::before_dom_children): Likewise.
	(ipcp_transform_function): Likewise.
	* ipa-prop.h (struct ipa_node_params): Introduction of new class
	ipa_node_params_t.
	* ipa-split.c: Include symbol-summary.h.
	* ipa-utils.c: Likewise.
	* ipa.c: Likewise.
	* omp-low.c: Likewise.
	* tree-inline.c: Likewise.
	* tree-sra.c: Likewise.
	* tree-ssa-pre.c: Likewise.

gcc/lto/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* lto-partition.c: Include symbol-summary.h.
	* lto-symtab.c: Likewise.
	* lto.c: Likewise.

Conflicts:
	gcc/symbol-summary.h
---
 gcc/auto-profile.c         |   1 +
 gcc/cgraph.c               |   1 +
 gcc/cgraphbuild.c          |   1 +
 gcc/cgraphclones.c         |   1 +
 gcc/cgraphunit.c           |   1 +
 gcc/ipa-cp.c               |   1 +
 gcc/ipa-devirt.c           |   1 +
 gcc/ipa-icf.c              |   1 +
 gcc/ipa-inline-analysis.c  |  13 +-
 gcc/ipa-inline-transform.c |   1 +
 gcc/ipa-inline.c           |   3 +-
 gcc/ipa-polymorphic-call.c |   1 +
 gcc/ipa-profile.c          |   1 +
 gcc/ipa-prop.c             | 702 ++++++++++++++++++++++-----------------------
 gcc/ipa-prop.h             |  48 ++--
 gcc/ipa-split.c            |   1 +
 gcc/ipa-utils.c            |   1 +
 gcc/ipa.c                  |   1 +
 gcc/lto/lto-partition.c    |   1 +
 gcc/lto/lto-symtab.c       |   1 +
 gcc/lto/lto.c              |   1 +
 gcc/omp-low.c              |   1 +
 gcc/tree-inline.c          |   1 +
 gcc/tree-sra.c             |   1 +
 gcc/tree-ssa-pre.c         |   1 +
 25 files changed, 397 insertions(+), 390 deletions(-)

diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index 8c7b4ca..3119d04 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coverage.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 7216b89..d60c610 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index c72ceab..007c386 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "except.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index c8892da..5091b3b 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-dump.h"
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 25af234..93f8d91 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -204,6 +204,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 47f9f5c..56d1ae9 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 32c6549..0be721b 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 92ec82d..e8892d4 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index eb1c6ec..84da4dc 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
@@ -910,7 +911,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
   if (known_binfos_ptr)
     known_binfos_ptr->create (0);
 
-  if (ipa_node_params_vector.exists ()
+  if (ipa_node_params_d
       && !e->call_stmt_cannot_inline_p
       && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr))
     {
@@ -1130,7 +1131,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
 
   /* When there are any replacements in the function body, see if we can figure
      out that something was optimized out.  */
-  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
+  if (ipa_node_params_d && dst->clone.tree_map)
     {
       vec<size_time_entry, va_gc> *entry = info->entry;
       /* Use SRC parm info since it may not be copied yet.  */
@@ -2476,7 +2477,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
       calculate_dominance_info (CDI_DOMINATORS);
       loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
 
-      if (ipa_node_params_vector.exists ())
+      if (ipa_node_params_d)
 	{
 	  parms_info = IPA_NODE_REF (node);
 	  nonconstant_names.safe_grow_cleared
@@ -2624,7 +2625,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 		  nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
 		    = false_p;
 		}
-	      if (ipa_node_params_vector.exists ())
+	      if (ipa_node_params_d)
 		{
 		  int count = gimple_call_num_args (stmt);
 		  int i;
@@ -3367,7 +3368,7 @@ static void
 remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 			struct cgraph_edge *edge)
 {
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_d)
     {
       int i;
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
@@ -3523,7 +3524,7 @@ inline_merge_summary (struct cgraph_edge *edge)
   else
     toplev_predicate = true_predicate ();
 
-  if (ipa_node_params_vector.exists () && callee_info->conds)
+  if (ipa_node_params_d && callee_info->conds)
     {
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
       int count = ipa_get_cs_argument_count (args);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index dbc56c5..49c2679 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 5c97815..a8e94e2 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "except.h"
 #include "target.h"
@@ -2400,7 +2401,7 @@ early_inliner (function *fun)
      it.  This may confuse ourself when early inliner decide to inline call to
      function clone, because function clones don't have parameter list in
      ipa-prop matching their signature.  */
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_d)
     return 0;
 
 #ifdef ENABLE_CHECKING
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 33dd1a8..ea7f9a6 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index b83d1cf..ddbc17a 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index db85c7d..c356845 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "gimple-ssa.h"
@@ -119,7 +120,7 @@ struct func_body_info
   cgraph_node *node;
 
   /* Its info.  */
-  struct ipa_node_params *info;
+  ipa_node_params *info;
 
   /* Information about individual BBs. */
   vec<ipa_bb_info> bb_infos;
@@ -131,27 +132,25 @@ struct func_body_info
   unsigned int aa_walked;
 };
 
-/* Vector where the parameter infos are actually stored. */
-vec<ipa_node_params> ipa_node_params_vector;
+/* Function summary where the parameter infos are actually stored. */
+ipa_node_params_t *ipa_node_params_d = NULL;
 /* Vector of known aggregate values in cloned nodes.  */
 vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
 vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
+static cgraph_edge_hook_list *edge_removal_hook_holder;
+static cgraph_2edge_hook_list *edge_duplication_hook_holder;
+static cgraph_node_hook_list *function_insertion_hook_holder;
 
 /* Description of a reference to an IPA constant.  */
 struct ipa_cst_ref_desc
 {
   /* Edge that corresponds to the statement which took the reference.  */
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   /* Linked list of duplicates created when call graph edges are cloned.  */
-  struct ipa_cst_ref_desc *next_duplicate;
+  ipa_cst_ref_desc *next_duplicate;
   /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
      if out of control.  */
   int refcount;
@@ -165,10 +164,10 @@ static alloc_pool ipa_refdesc_pool;
    with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
 
 static bool
-ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
+ipa_func_spec_opts_forbid_analysis_p (cgraph_node *node)
 {
   tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
-  struct cl_optimization *os;
+  cl_optimization *os;
 
   if (!fs_opts)
     return false;
@@ -196,7 +195,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
    to INFO.  */
 
 int
-ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
+ipa_get_param_decl_index (ipa_node_params *info, tree ptree)
 {
   return ipa_get_param_decl_index_1 (info->descriptors, ptree);
 }
@@ -205,7 +204,7 @@ ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
    NODE.  */
 
 static void
-ipa_populate_param_decls (struct cgraph_node *node,
+ipa_populate_param_decls (cgraph_node *node,
 			  vec<ipa_param_descriptor> &descriptors)
 {
   tree fndecl;
@@ -246,7 +245,7 @@ count_formal_params (tree fndecl)
    using ipa_initialize_node_params. */
 
 void
-ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
+ipa_dump_param (FILE *file, ipa_node_params *info, int i)
 {
   fprintf (file, "param #%i", i);
   if (info->descriptors[i].decl)
@@ -260,9 +259,9 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
    to hold PARAM_COUNT parameters.  */
 
 void
-ipa_alloc_node_params (struct cgraph_node *node, int param_count)
+ipa_alloc_node_params (cgraph_node *node, int param_count)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   if (!info->descriptors.exists () && param_count)
     info->descriptors.safe_grow_cleared (param_count);
@@ -273,9 +272,9 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
    param_decls.  */
 
 void
-ipa_initialize_node_params (struct cgraph_node *node)
+ipa_initialize_node_params (cgraph_node *node)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   if (!info->descriptors.exists ())
     {
@@ -287,14 +286,14 @@ ipa_initialize_node_params (struct cgraph_node *node)
 /* Print the jump functions associated with call graph edge CS to file F.  */
 
 static void
-ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
+ipa_print_node_jump_functions_for_edge (FILE *f, cgraph_edge *cs)
 {
   int i, count;
 
   count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *jump_func;
+      ipa_jump_func *jump_func;
       enum jump_func_type type;
 
       jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
@@ -360,7 +359,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 
       if (jump_func->agg.items)
 	{
-	  struct ipa_agg_jf_item *item;
+	  ipa_agg_jf_item *item;
 	  int j;
 
 	  fprintf (f, "         Aggregate passed by %s:\n",
@@ -390,9 +389,9 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
    NODE to file F.  */
 
 void
-ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
+ipa_print_node_jump_functions (FILE *f, cgraph_node *node)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   fprintf (f, "  Jump functions of caller  %s/%i:\n", node->name (),
 	   node->order);
@@ -410,7 +409,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 
   for (cs = node->indirect_calls; cs; cs = cs->next_callee)
     {
-      struct cgraph_indirect_call_info *ii;
+      cgraph_indirect_call_info *ii;
       if (!ipa_edge_args_info_available_for_edge_p (cs))
 	continue;
 
@@ -445,7 +444,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
 void
 ipa_print_all_jump_functions (FILE *f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "\nJump functions:\n");
   FOR_EACH_FUNCTION (node)
@@ -457,7 +456,7 @@ ipa_print_all_jump_functions (FILE *f)
 /* Set JFUNC to be a known type jump function.  */
 
 static void
-ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
+ipa_set_jf_known_type (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
 		       tree base_type, tree component_type)
 {
   /* Recording and propagating main variants increases change that types
@@ -480,8 +479,8 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
    combination code).  The two functions will share their rdesc.  */
 
 static void
-ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
-		     struct ipa_jump_func *src)
+ipa_set_jf_cst_copy (ipa_jump_func *dst,
+		     ipa_jump_func *src)
 
 {
   gcc_checking_assert (src->type == IPA_JF_CONST);
@@ -492,8 +491,8 @@ ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
 /* Set JFUNC to be a constant jmp function.  */
 
 static void
-ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
-		     struct cgraph_edge *cs)
+ipa_set_jf_constant (ipa_jump_func *jfunc, tree constant,
+		     cgraph_edge *cs)
 {
   constant = unshare_expr (constant);
   if (constant && EXPR_P (constant))
@@ -504,12 +503,12 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
   if (TREE_CODE (constant) == ADDR_EXPR
       && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
     {
-      struct ipa_cst_ref_desc *rdesc;
+      ipa_cst_ref_desc *rdesc;
       if (!ipa_refdesc_pool)
 	ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
-					sizeof (struct ipa_cst_ref_desc), 32);
+					sizeof (ipa_cst_ref_desc), 32);
 
-      rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+      rdesc = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
       rdesc->cs = cs;
       rdesc->next_duplicate = NULL;
       rdesc->refcount = 1;
@@ -521,7 +520,7 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
 
 /* Set JFUNC to be a simple pass-through jump function.  */
 static void
-ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+ipa_set_jf_simple_pass_through (ipa_jump_func *jfunc, int formal_id,
 				bool agg_preserved, bool type_preserved)
 {
   jfunc->type = IPA_JF_PASS_THROUGH;
@@ -535,7 +534,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 /* Set JFUNC to be an arithmetic pass through jump function.  */
 
 static void
-ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
+ipa_set_jf_arith_pass_through (ipa_jump_func *jfunc, int formal_id,
 			       tree operand, enum tree_code operation)
 {
   jfunc->type = IPA_JF_PASS_THROUGH;
@@ -549,7 +548,7 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 /* Set JFUNC to be an ancestor jump function.  */
 
 static void
-ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
+ipa_set_ancestor_jf (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
 		     tree type, int formal_id, bool agg_preserved,
 		     bool type_preserved)
 {
@@ -572,7 +571,7 @@ ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
    jump function.  */
 
 tree
-ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
+ipa_binfo_from_known_type_jfunc (ipa_jump_func *jfunc)
 {
   if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
     return NULL_TREE;
@@ -602,8 +601,8 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
 /* Get IPA BB information about the given BB.  FBI is the context of analyzis
    of this function body.  */
 
-static struct ipa_bb_info *
-ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
+static ipa_bb_info *
+ipa_get_bb_info (func_body_info *fbi, basic_block bb)
 {
   gcc_checking_assert (fbi);
   return &fbi->bb_infos[bb->index];
@@ -700,7 +699,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
    identified, return the type.  Otherwise return NULL_TREE.  */
 
 static tree
-extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
+extr_type_from_vtbl_ptr_store (gimple stmt, prop_type_change_info *tci)
 {
   HOST_WIDE_INT offset, size, max_size;
   tree lhs, rhs, base, binfo;
@@ -752,7 +751,7 @@ static bool
 check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
 {
   gimple stmt = SSA_NAME_DEF_STMT (vdef);
-  struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
+  prop_type_change_info *tci = (prop_type_change_info *) data;
 
   if (stmt_may_be_vtbl_ptr_store (stmt))
     {
@@ -847,10 +846,10 @@ param_type_may_change_p (tree function, tree arg, gimple call)
 
 static bool
 detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
-				       gimple call, struct ipa_jump_func *jfunc,
+				       gimple call, ipa_jump_func *jfunc,
 				       HOST_WIDE_INT offset)
 {
-  struct prop_type_change_info tci;
+  prop_type_change_info tci;
   ao_ref ao;
   bool entry_reached = false;
 
@@ -908,7 +907,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
 
 static bool
 detect_type_change (tree arg, tree base, tree comp_type, gimple call,
-		    struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
+		    ipa_jump_func *jfunc, HOST_WIDE_INT offset)
 {
   if (!flag_devirtualize)
     return false;
@@ -928,7 +927,7 @@ detect_type_change (tree arg, tree base, tree comp_type, gimple call,
 
 static bool
 detect_type_change_ssa (tree arg, tree comp_type,
-			gimple call, struct ipa_jump_func *jfunc)
+			gimple call, ipa_jump_func *jfunc)
 {
   gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
   if (!flag_devirtualize
@@ -961,7 +960,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
    should really just start giving up.  */
 
 static bool
-aa_overwalked (struct func_body_info *fbi)
+aa_overwalked (func_body_info *fbi)
 {
   gcc_checking_assert (fbi);
   return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
@@ -970,8 +969,8 @@ aa_overwalked (struct func_body_info *fbi)
 /* Find the nearest valid aa status for parameter specified by INDEX that
    dominates BB.  */
 
-static struct param_aa_status *
-find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
+static param_aa_status *
+find_dominating_aa_status (func_body_info *fbi, basic_block bb,
 			   int index)
 {
   while (true)
@@ -979,7 +978,7 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
       bb = get_immediate_dominator (CDI_DOMINATORS, bb);
       if (!bb)
 	return NULL;
-      struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+      ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
       if (!bi->param_aa_statuses.is_empty ()
 	  && bi->param_aa_statuses[index].valid)
 	return &bi->param_aa_statuses[index];
@@ -990,21 +989,21 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
    structures and/or intialize the result with a dominating description as
    necessary.  */
 
-static struct param_aa_status *
-parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
+static param_aa_status *
+parm_bb_aa_status_for_bb (func_body_info *fbi, basic_block bb,
 			  int index)
 {
   gcc_checking_assert (fbi);
-  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   if (bi->param_aa_statuses.is_empty ())
     bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
-  struct param_aa_status *paa = &bi->param_aa_statuses[index];
+  param_aa_status *paa = &bi->param_aa_statuses[index];
   if (!paa->valid)
     {
       gcc_checking_assert (!paa->parm_modified
 			   && !paa->ref_modified
 			   && !paa->pt_modified);
-      struct param_aa_status *dom_paa;
+      param_aa_status *dom_paa;
       dom_paa = find_dominating_aa_status (fbi, bb, index);
       if (dom_paa)
 	*paa = *dom_paa;
@@ -1021,10 +1020,10 @@ parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
    gathered but do not survive the summary building stage.  */
 
 static bool
-parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
+parm_preserved_before_stmt_p (func_body_info *fbi, int index,
 			      gimple stmt, tree parm_load)
 {
-  struct param_aa_status *paa;
+  param_aa_status *paa;
   bool modified = false;
   ao_ref refd;
 
@@ -1060,7 +1059,7 @@ parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
    modified.  Otherwise return -1.  */
 
 static int
-load_from_unmodified_param (struct func_body_info *fbi,
+load_from_unmodified_param (func_body_info *fbi,
 			    vec<ipa_param_descriptor> descriptors,
 			    gimple stmt)
 {
@@ -1087,10 +1086,10 @@ load_from_unmodified_param (struct func_body_info *fbi,
    before reaching statement STMT.  */
 
 static bool
-parm_ref_data_preserved_p (struct func_body_info *fbi,
+parm_ref_data_preserved_p (func_body_info *fbi,
 			   int index, gimple stmt, tree ref)
 {
-  struct param_aa_status *paa;
+  param_aa_status *paa;
   bool modified = false;
   ao_ref refd;
 
@@ -1126,7 +1125,7 @@ parm_ref_data_preserved_p (struct func_body_info *fbi,
    CALL into which it is passed.  FBI describes the function body.  */
 
 static bool
-parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
+parm_ref_data_pass_through_p (func_body_info *fbi, int index,
 			      gimple call, tree parm)
 {
   bool modified = false;
@@ -1140,7 +1139,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
       || aa_overwalked (fbi))
     return false;
 
-  struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
+  param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
 							  index);
   if (paa->pt_modified)
     return false;
@@ -1165,7 +1164,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
    reference respectively.  */
 
 static bool
-ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
+ipa_load_from_parm_agg_1 (func_body_info *fbi,
 			  vec<ipa_param_descriptor> descriptors,
 			  gimple stmt, tree op, int *index_p,
 			  HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
@@ -1240,7 +1239,7 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
    pointer, for users outside of this file.  */
 
 bool
-ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
+ipa_load_from_parm_agg (ipa_node_params *info, gimple stmt,
 			tree op, int *index_p, HOST_WIDE_INT *offset_p,
 			bool *by_ref_p)
 {
@@ -1302,9 +1301,9 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
    only needed for intraprocedural analysis.  */
 
 static void
-compute_complex_assign_jump_func (struct func_body_info *fbi,
-				  struct ipa_node_params *info,
-				  struct ipa_jump_func *jfunc,
+compute_complex_assign_jump_func (func_body_info *fbi,
+				  ipa_node_params *info,
+				  ipa_jump_func *jfunc,
 				  gimple call, gimple stmt, tree name,
 				  tree param_type)
 {
@@ -1458,9 +1457,9 @@ get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
      return D.1879_6;  */
 
 static void
-compute_complex_ancestor_jump_func (struct func_body_info *fbi,
-				    struct ipa_node_params *info,
-				    struct ipa_jump_func *jfunc,
+compute_complex_ancestor_jump_func (func_body_info *fbi,
+				    ipa_node_params *info,
+				    ipa_jump_func *jfunc,
 				    gimple call, gimple phi, tree param_type)
 {
   HOST_WIDE_INT offset;
@@ -1531,7 +1530,7 @@ compute_complex_ancestor_jump_func (struct func_body_info *fbi,
    EXPECTED_TYPE represents a type the argument should be in  */
 
 static void
-compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
+compute_known_type_jump_func (tree op, ipa_jump_func *jfunc,
 			      gimple call, tree expected_type)
 {
   HOST_WIDE_INT offset, size, max_size;
@@ -1629,7 +1628,7 @@ struct ipa_known_agg_contents_list
   /* Known constant value or NULL if the contents is known to be unknown.  */
   tree constant;
   /* Pointer to the next structure in the list.  */
-  struct ipa_known_agg_contents_list *next;
+  ipa_known_agg_contents_list *next;
 };
 
 /* Find the proper place in linked list of ipa_known_agg_contents_list
@@ -1637,13 +1636,13 @@ struct ipa_known_agg_contents_list
    unless there is a partial overlap, in which case return NULL, or such
    element is already there, in which case set *ALREADY_THERE to true.  */
 
-static struct ipa_known_agg_contents_list **
-get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
+static ipa_known_agg_contents_list **
+get_place_in_agg_contents_list (ipa_known_agg_contents_list **list,
 				HOST_WIDE_INT lhs_offset,
 				HOST_WIDE_INT lhs_size,
 				bool *already_there)
 {
-  struct ipa_known_agg_contents_list **p = list;
+  ipa_known_agg_contents_list **p = list;
   while (*p && (*p)->offset < lhs_offset)
     {
       if ((*p)->offset + (*p)->size > lhs_offset)
@@ -1670,16 +1669,16 @@ get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
    is ARG_OFFSET and store it into JFUNC.  */
 
 static void
-build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
+build_agg_jump_func_from_list (ipa_known_agg_contents_list *list,
 			       int const_count, HOST_WIDE_INT arg_offset,
-			       struct ipa_jump_func *jfunc)
+			       ipa_jump_func *jfunc)
 {
   vec_alloc (jfunc->agg.items, const_count);
   while (list)
     {
       if (list->constant)
 	{
-	  struct ipa_agg_jf_item item;
+	  ipa_agg_jf_item item;
 	  item.offset = list->offset - arg_offset;
 	  gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
 	  item.value = unshare_expr_without_location (list->constant);
@@ -1697,9 +1696,9 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
 
 static void
 determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
-					 struct ipa_jump_func *jfunc)
+					 ipa_jump_func *jfunc)
 {
-  struct ipa_known_agg_contents_list *list = NULL;
+  ipa_known_agg_contents_list *list = NULL;
   int item_count = 0, const_count = 0;
   HOST_WIDE_INT arg_offset, arg_size;
   gimple_stmt_iterator gsi;
@@ -1774,7 +1773,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
   gsi_prev (&gsi);
   for (; !gsi_end_p (gsi); gsi_prev (&gsi))
     {
-      struct ipa_known_agg_contents_list *n, **p;
+      ipa_known_agg_contents_list *n, **p;
       gimple stmt = gsi_stmt (gsi);
       HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
       tree lhs, rhs, lhs_base;
@@ -1821,7 +1820,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
 	continue;
 
       rhs = get_ssa_def_if_simple_copy (rhs);
-      n = XALLOCA (struct ipa_known_agg_contents_list);
+      n = XALLOCA (ipa_known_agg_contents_list);
       n->size = lhs_size;
       n->offset = lhs_offset;
       if (is_gimple_ip_invariant (rhs))
@@ -1852,7 +1851,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
 }
 
 static tree
-ipa_get_callee_param_type (struct cgraph_edge *e, int i)
+ipa_get_callee_param_type (cgraph_edge *e, int i)
 {
   int n;
   tree type = (e->callee
@@ -1887,11 +1886,11 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
    to this callsite.  */
 
 static void
-ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
-				     struct cgraph_edge *cs)
+ipa_compute_jump_functions_for_edge (func_body_info *fbi,
+				     cgraph_edge *cs)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
-  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
+  ipa_node_params *info = IPA_NODE_REF (cs->caller);
+  ipa_edge_args *args = IPA_EDGE_REF (cs);
   gimple call = cs->call_stmt;
   int n, arg_num = gimple_call_num_args (call);
   bool useful_context = false;
@@ -1909,13 +1908,13 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
 
   for (n = 0; n < arg_num; n++)
     {
-      struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
+      ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
       tree arg = gimple_call_arg (call, n);
       tree param_type = ipa_get_callee_param_type (cs, n);
       if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
 	{
 	  tree instance;
-	  struct ipa_polymorphic_call_context context (cs->caller->decl,
+	  ipa_polymorphic_call_context context (cs->caller->decl,
 						       arg, cs->call_stmt,
 						       &instance);
 	  context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
@@ -2003,15 +2002,15 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
    from BB.  */
 
 static void
-ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
+ipa_compute_jump_functions_for_bb (func_body_info *fbi, basic_block bb)
 {
-  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
+  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   int i;
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
     {
-      struct cgraph_node *callee = cs->callee;
+      cgraph_node *callee = cs->callee;
 
       if (callee)
 	{
@@ -2093,10 +2092,10 @@ ipa_is_ssa_with_stmt_def (tree t)
    call to a parameter number PARAM_INDEX.  NODE is the caller.  Return the
    indirect call graph edge.  */
 
-static struct cgraph_edge *
-ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
+static cgraph_edge *
+ipa_note_param_call (cgraph_node *node, int param_index, gimple stmt)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
 
   cs = node->get_edge (stmt);
   cs->indirect_info->param_index = param_index;
@@ -2165,10 +2164,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
    passed by value or reference.  */
 
 static void
-ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
+ipa_analyze_indirect_call_uses (func_body_info *fbi, gimple call,
 				tree target)
 {
-  struct ipa_node_params *info = fbi->info;
+  ipa_node_params *info = fbi->info;
   HOST_WIDE_INT offset;
   bool by_ref;
 
@@ -2188,7 +2187,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
 				   gimple_assign_rhs1 (def), &index, &offset,
 				   NULL, &by_ref))
     {
-      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
       cs->indirect_info->agg_contents = 1;
       cs->indirect_info->by_ref = by_ref;
@@ -2288,7 +2287,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
   if (index >= 0
       && parm_preserved_before_stmt_p (fbi, index, call, rec))
     {
-      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
       cs->indirect_info->agg_contents = 1;
       cs->indirect_info->member_ptr = 1;
@@ -2303,7 +2302,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
    statement.  */
 
 static void
-ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
+ipa_analyze_virtual_call_uses (func_body_info *fbi,
 			       gimple call, tree target)
 {
   tree obj = OBJ_TYPE_REF_OBJECT (target);
@@ -2316,10 +2315,10 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
   if (TREE_CODE (obj) != SSA_NAME)
     return;
 
-  struct ipa_node_params *info = fbi->info;
+  ipa_node_params *info = fbi->info;
   if (SSA_NAME_IS_DEFAULT_DEF (obj))
     {
-      struct ipa_jump_func jfunc;
+      ipa_jump_func jfunc;
       if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
 	return;
 
@@ -2332,7 +2331,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
     }
   else
     {
-      struct ipa_jump_func jfunc;
+      ipa_jump_func jfunc;
       gimple stmt = SSA_NAME_DEF_STMT (obj);
       tree expr;
 
@@ -2347,8 +2346,8 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
 	return;
     }
 
-  struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
+  cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
+  cgraph_indirect_call_info *ii = cs->indirect_info;
   ii->offset = anc_offset;
   ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
   ii->otr_type = obj_type_ref_class (target);
@@ -2360,7 +2359,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
    containing intermediate information about each formal parameter.  */
 
 static void
-ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
+ipa_analyze_call_uses (func_body_info *fbi, gimple call)
 {
   tree target = gimple_call_fn (call);
 
@@ -2369,7 +2368,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
           && !virtual_method_call_p (target)))
     return;
 
-  struct cgraph_edge *cs = fbi->node->get_edge (call);
+  cgraph_edge *cs = fbi->node->get_edge (call);
   /* If we previously turned the call into a direct call, there is
      no need to analyze.  */
   if (cs && !cs->indirect_unknown_callee)
@@ -2406,7 +2405,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
    formal parameters are called.  */
 
 static void
-ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
+ipa_analyze_stmt_uses (func_body_info *fbi, gimple stmt)
 {
   if (is_gimple_call (stmt))
     ipa_analyze_call_uses (fbi, stmt);
@@ -2419,7 +2418,7 @@ ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
 static bool
 visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
 {
-  struct ipa_node_params *info = (struct ipa_node_params *) data;
+  ipa_node_params *info = (ipa_node_params *) data;
 
   op = get_base_address (op);
   if (op
@@ -2439,7 +2438,7 @@ visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
    the function being analyzed.  */
 
 static void
-ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
+ipa_analyze_params_uses_in_bb (func_body_info *fbi, basic_block bb)
 {
   gimple_stmt_iterator gsi;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -2465,9 +2464,9 @@ ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
 /* Calculate controlled uses of parameters of NODE.  */
 
 static void
-ipa_analyze_controlled_uses (struct cgraph_node *node)
+ipa_analyze_controlled_uses (cgraph_node *node)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
 
   for (int i = 0; i < ipa_get_param_count (info); i++)
     {
@@ -2510,7 +2509,7 @@ ipa_analyze_controlled_uses (struct cgraph_node *node)
 /* Free stuff in BI.  */
 
 static void
-free_ipa_bb_info (struct ipa_bb_info *bi)
+free_ipa_bb_info (ipa_bb_info *bi)
 {
   bi->cg_edges.release ();
   bi->param_aa_statuses.release ();
@@ -2521,13 +2520,13 @@ free_ipa_bb_info (struct ipa_bb_info *bi)
 class analysis_dom_walker : public dom_walker
 {
 public:
-  analysis_dom_walker (struct func_body_info *fbi)
+  analysis_dom_walker (func_body_info *fbi)
     : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
 
   virtual void before_dom_children (basic_block);
 
 private:
-  struct func_body_info *m_fbi;
+  func_body_info *m_fbi;
 };
 
 void
@@ -2542,10 +2541,10 @@ analysis_dom_walker::before_dom_children (basic_block bb)
    with actual arguments of calls from within NODE.  */
 
 void
-ipa_analyze_node (struct cgraph_node *node)
+ipa_analyze_node (cgraph_node *node)
 {
-  struct func_body_info fbi;
-  struct ipa_node_params *info;
+  func_body_info fbi;
+  ipa_node_params *info;
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
@@ -2565,7 +2564,7 @@ ipa_analyze_node (struct cgraph_node *node)
       return;
     }
 
-  struct function *func = DECL_STRUCT_FUNCTION (node->decl);
+  function *func = DECL_STRUCT_FUNCTION (node->decl);
   push_cfun (func);
   calculate_dominance_info (CDI_DOMINATORS);
   ipa_initialize_node_params (node);
@@ -2578,13 +2577,13 @@ ipa_analyze_node (struct cgraph_node *node)
   fbi.param_count = ipa_get_param_count (info);
   fbi.aa_walked = 0;
 
-  for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
       bi->cg_edges.safe_push (cs);
     }
 
-  for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
+  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
       bi->cg_edges.safe_push (cs);
@@ -2593,7 +2592,7 @@ ipa_analyze_node (struct cgraph_node *node)
   analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
   int i;
-  struct ipa_bb_info *bi;
+  ipa_bb_info *bi;
   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
     free_ipa_bb_info (bi);
   fbi.bb_infos.release ();
@@ -2606,8 +2605,8 @@ ipa_analyze_node (struct cgraph_node *node)
    type.  */
 
 static void
-combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
-				     struct ipa_jump_func *dst)
+combine_known_type_and_ancestor_jfs (ipa_jump_func *src,
+				     ipa_jump_func *dst)
 {
   HOST_WIDE_INT combined_offset;
   tree combined_type;
@@ -2632,25 +2631,25 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
    indirectly) inlined into CS->callee and that E has not been inlined.  */
 
 static void
-update_jump_functions_after_inlining (struct cgraph_edge *cs,
-				      struct cgraph_edge *e)
+update_jump_functions_after_inlining (cgraph_edge *cs,
+				      cgraph_edge *e)
 {
-  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
-  struct ipa_edge_args *args = IPA_EDGE_REF (e);
+  ipa_edge_args *top = IPA_EDGE_REF (cs);
+  ipa_edge_args *args = IPA_EDGE_REF (e);
   int count = ipa_get_cs_argument_count (args);
   int i;
 
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
-      struct ipa_polymorphic_call_context *dst_ctx
+      ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
+      ipa_polymorphic_call_context *dst_ctx
 	= ipa_get_ith_polymorhic_call_context (args, i);
 
       if (dst->type == IPA_JF_ANCESTOR)
 	{
-	  struct ipa_jump_func *src;
+	  ipa_jump_func *src;
 	  int dst_fid = dst->value.ancestor.formal_id;
-	  struct ipa_polymorphic_call_context *src_ctx
+	  ipa_polymorphic_call_context *src_ctx
 	    = ipa_get_ith_polymorhic_call_context (top, dst_fid);
 
 	  /* Variable number of arguments can cause havoc if we try to access
@@ -2666,7 +2665,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 
 	  if (src_ctx && !src_ctx->useless_p ())
 	    {
-	      struct ipa_polymorphic_call_context ctx = *src_ctx;
+	      ipa_polymorphic_call_context ctx = *src_ctx;
 
 	      /* TODO: Make type preserved safe WRT contexts.  */
 	      if (!dst->value.ancestor.agg_preserved)
@@ -2683,7 +2682,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	  if (src->agg.items
 	      && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
 	    {
-	      struct ipa_agg_jf_item *item;
+	      ipa_agg_jf_item *item;
 	      int j;
 
 	      /* Currently we do not produce clobber aggregate jump functions,
@@ -2721,7 +2720,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	}
       else if (dst->type == IPA_JF_PASS_THROUGH)
 	{
-	  struct ipa_jump_func *src;
+	  ipa_jump_func *src;
 	  /* We must check range due to calls with variable number of arguments
 	     and we cannot combine jump functions with operations.  */
 	  if (dst->value.pass_through.operation == NOP_EXPR
@@ -2731,12 +2730,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 	      int dst_fid = dst->value.pass_through.formal_id;
 	      src = ipa_get_ith_jump_func (top, dst_fid);
 	      bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
-	      struct ipa_polymorphic_call_context *src_ctx
+	      ipa_polymorphic_call_context *src_ctx
 		= ipa_get_ith_polymorhic_call_context (top, dst_fid);
 
 	      if (src_ctx && !src_ctx->useless_p ())
 		{
-		  struct ipa_polymorphic_call_context ctx = *src_ctx;
+		  ipa_polymorphic_call_context ctx = *src_ctx;
 
 		  /* TODO: Make type preserved safe WRT contexts.  */
 		  if (!dst->value.ancestor.agg_preserved)
@@ -2833,11 +2832,11 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
    (SPECULATIVE)destination of an indirect edge IE and return the edge.
    Otherwise, return NULL.  */
 
-struct cgraph_edge *
-ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
+cgraph_edge *
+ipa_make_edge_direct_to_target (cgraph_edge *ie, tree target,
 				bool speculative)
 {
-  struct cgraph_node *callee;
+  cgraph_node *callee;
   struct inline_edge_summary *es = inline_edge_summary (ie);
   bool unreachable = false;
 
@@ -2898,8 +2897,8 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
   /* If the edge is already speculated.  */
   if (speculative && ie->speculative)
     {
-      struct cgraph_edge *e2;
-      struct ipa_ref *ref;
+      cgraph_edge *e2;
+      ipa_ref *ref;
       ie->speculative_call_info (e2, ie, ref);
       if (e2->callee->ultimate_alias_target ()
 	  != callee->ultimate_alias_target ())
@@ -2987,10 +2986,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
    be passed by reference or by value.  */
 
 tree
-ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
+ipa_find_agg_cst_for_param (ipa_agg_jump_function *agg,
 			    HOST_WIDE_INT offset, bool by_ref)
 {
-  struct ipa_agg_jf_item *item;
+  ipa_agg_jf_item *item;
   int i;
 
   if (by_ref != agg->by_ref)
@@ -3012,10 +3011,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
    successfully found and removed.  */
 
 static bool
-remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
+remove_described_reference (symtab_node *symbol, ipa_cst_ref_desc *rdesc)
 {
-  struct ipa_ref *to_del;
-  struct cgraph_edge *origin;
+  ipa_ref *to_del;
+  cgraph_edge *origin;
 
   origin = rdesc->cs;
   if (!origin)
@@ -3037,10 +3036,10 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
    IPA_UNDESCRIBED_USE, return the reference description, otherwise return
    NULL.  JFUNC must be a constant jump function.  */
 
-static struct ipa_cst_ref_desc *
-jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
+static ipa_cst_ref_desc *
+jfunc_rdesc_usable (ipa_jump_func *jfunc)
 {
-  struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
+  ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
   if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
     return rdesc;
   else
@@ -3052,7 +3051,7 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
    NULL.  */
 
 static cgraph_node *
-cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
+cgraph_node_for_jfunc (ipa_jump_func *jfunc)
 {
   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
   tree cst = ipa_get_jf_constant (jfunc);
@@ -3070,9 +3069,9 @@ cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
    reference could not be found, otherwise return true.  */
 
 static bool
-try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
+try_decrement_rdesc_refcount (ipa_jump_func *jfunc)
 {
-  struct ipa_cst_ref_desc *rdesc;
+  ipa_cst_ref_desc *rdesc;
   if (jfunc->type == IPA_JF_CONST
       && (rdesc = jfunc_rdesc_usable (jfunc))
       && --rdesc->refcount == 0)
@@ -3092,12 +3091,12 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
    determined, return the newly direct edge, otherwise return NULL.
    NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
 
-static struct cgraph_edge *
-try_make_edge_direct_simple_call (struct cgraph_edge *ie,
-				  struct ipa_jump_func *jfunc,
-				  struct ipa_node_params *new_root_info)
+static cgraph_edge *
+try_make_edge_direct_simple_call (cgraph_edge *ie,
+				  ipa_jump_func *jfunc,
+				  ipa_node_params *new_root_info)
 {
-  struct cgraph_edge *cs;
+  cgraph_edge *cs;
   tree target;
   bool agg_contents = ie->indirect_info->agg_contents;
 
@@ -3130,7 +3129,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
    and target (the latter can be NULL) are dumped when dumping is enabled.  */
 
 tree
-ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
+ipa_impossible_devirt_target (cgraph_edge *ie, tree target)
 {
   if (dump_file)
     {
@@ -3155,11 +3154,11 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
    Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
    are relative to.  */
 
-static struct cgraph_edge *
-try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
-				   struct ipa_jump_func *jfunc,
-				   struct ipa_node_params *new_root_info,
-				   struct ipa_polymorphic_call_context *ctx_ptr)
+static cgraph_edge *
+try_make_edge_direct_virtual_call (cgraph_edge *ie,
+				   ipa_jump_func *jfunc,
+				   ipa_node_params *new_root_info,
+				   ipa_polymorphic_call_context *ctx_ptr)
 {
   tree binfo, target = NULL;
   bool speculative = false;
@@ -3172,7 +3171,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
      based on knowlede of the context.  */
   if (ctx_ptr && !ie->indirect_info->by_ref)
     {
-      struct ipa_polymorphic_call_context ctx = *ctx_ptr;
+      ipa_polymorphic_call_context ctx = *ctx_ptr;
 
       ctx.offset_by (ie->indirect_info->offset);
 
@@ -3221,7 +3220,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
 
   if (binfo && TREE_CODE (binfo) != TREE_BINFO)
     {
-      struct ipa_polymorphic_call_context ctx (binfo,
+      ipa_polymorphic_call_context ctx (binfo,
 					       ie->indirect_info->otr_type,
 					       ie->indirect_info->offset);
       updated |= ie->indirect_info->context.combine_with
@@ -3296,13 +3295,13 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
    unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
 
 static bool
-update_indirect_edges_after_inlining (struct cgraph_edge *cs,
-				      struct cgraph_node *node,
+update_indirect_edges_after_inlining (cgraph_edge *cs,
+				      cgraph_node *node,
 				      vec<cgraph_edge *> *new_edges)
 {
-  struct ipa_edge_args *top;
-  struct cgraph_edge *ie, *next_ie, *new_direct_edge;
-  struct ipa_node_params *new_root_info;
+  ipa_edge_args *top;
+  cgraph_edge *ie, *next_ie, *new_direct_edge;
+  ipa_node_params *new_root_info;
   bool res = false;
 
   ipa_check_create_edge_args ();
@@ -3313,8 +3312,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
   for (ie = node->indirect_calls; ie; ie = next_ie)
     {
-      struct cgraph_indirect_call_info *ici = ie->indirect_info;
-      struct ipa_jump_func *jfunc;
+      cgraph_indirect_call_info *ici = ie->indirect_info;
+      ipa_jump_func *jfunc;
       int param_index;
 
       next_ie = ie->next_callee;
@@ -3408,11 +3407,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
    created.  */
 
 static bool
-propagate_info_to_inlined_callees (struct cgraph_edge *cs,
-				   struct cgraph_node *node,
+propagate_info_to_inlined_callees (cgraph_edge *cs,
+				   cgraph_node *node,
 				   vec<cgraph_edge *> *new_edges)
 {
-  struct cgraph_edge *e;
+  cgraph_edge *e;
   bool res;
 
   res = update_indirect_edges_after_inlining (cs, node, new_edges);
@@ -3443,21 +3442,21 @@ combine_controlled_uses_counters (int c, int d)
    tree of inlined nodes.  */
 
 static void
-propagate_controlled_uses (struct cgraph_edge *cs)
+propagate_controlled_uses (cgraph_edge *cs)
 {
-  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
-  struct cgraph_node *new_root = cs->caller->global.inlined_to
+  ipa_edge_args *args = IPA_EDGE_REF (cs);
+  cgraph_node *new_root = cs->caller->global.inlined_to
     ? cs->caller->global.inlined_to : cs->caller;
-  struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
-  struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
+  ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
+  ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
   int count, i;
 
   count = MIN (ipa_get_cs_argument_count (args),
 	       ipa_get_param_count (old_root_info));
   for (i = 0; i < count; i++)
     {
-      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
-      struct ipa_cst_ref_desc *rdesc;
+      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
+      ipa_cst_ref_desc *rdesc;
 
       if (jf->type == IPA_JF_PASS_THROUGH)
 	{
@@ -3472,8 +3471,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  ipa_set_controlled_uses (new_root_info, src_idx, c);
 	  if (c == 0 && new_root_info->ipcp_orig_node)
 	    {
-	      struct cgraph_node *n;
-	      struct ipa_ref *ref;
+	      cgraph_node *n;
+	      ipa_ref *ref;
 	      tree t = new_root_info->known_vals[src_idx];
 
 	      if (t && TREE_CODE (t) == ADDR_EXPR
@@ -3500,14 +3499,14 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  if (rdesc->refcount == 0)
 	    {
 	      tree cst = ipa_get_jf_constant (jf);
-	      struct cgraph_node *n;
+	      cgraph_node *n;
 	      gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
 				   && TREE_CODE (TREE_OPERAND (cst, 0))
 				   == FUNCTION_DECL);
 	      n = cgraph_node::get (TREE_OPERAND (cst, 0));
 	      if (n)
 		{
-		  struct cgraph_node *clone;
+		  cgraph_node *clone;
 		  bool ok;
 		  ok = remove_described_reference (n, rdesc);
 		  gcc_checking_assert (ok);
@@ -3517,7 +3516,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 			 && clone != rdesc->cs->caller
 			 && IPA_NODE_REF (clone)->ipcp_orig_node)
 		    {
-		      struct ipa_ref *ref;
+		      ipa_ref *ref;
 		      ref = clone->find_reference (n, NULL, 0);
 		      if (ref)
 			{
@@ -3542,11 +3541,11 @@ propagate_controlled_uses (struct cgraph_edge *cs)
        i < ipa_get_cs_argument_count (args);
        i++)
     {
-      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
+      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
 
       if (jf->type == IPA_JF_CONST)
 	{
-	  struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
+	  ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
 	  if (rdesc)
 	    rdesc->refcount = IPA_UNDESCRIBED_USE;
 	}
@@ -3564,13 +3563,13 @@ propagate_controlled_uses (struct cgraph_edge *cs)
    created.  */
 
 bool
-ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
+ipa_propagate_indirect_call_infos (cgraph_edge *cs,
 				   vec<cgraph_edge *> *new_edges)
 {
   bool changed;
   /* Do nothing if the preparation phase has not been carried out yet
      (i.e. during early inlining).  */
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_d)
     return false;
   gcc_assert (ipa_edge_args_vector);
 
@@ -3584,7 +3583,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
    to.  */
 
 void
-ipa_free_edge_args_substructures (struct ipa_edge_args *args)
+ipa_free_edge_args_substructures (ipa_edge_args *args)
 {
   vec_free (args->jump_functions);
   memset (args, 0, sizeof (*args));
@@ -3596,7 +3595,7 @@ void
 ipa_free_all_edge_args (void)
 {
   int i;
-  struct ipa_edge_args *args;
+  ipa_edge_args *args;
 
   if (!ipa_edge_args_vector)
     return;
@@ -3610,15 +3609,21 @@ ipa_free_all_edge_args (void)
 /* Frees all dynamically allocated structures that the param info points
    to.  */
 
-void
-ipa_free_node_params_substructures (struct ipa_node_params *info)
+ipa_node_params::~ipa_node_params ()
 {
-  info->descriptors.release ();
-  free (info->lattices);
+  descriptors.release ();
+  free (lattices);
   /* Lattice values and their sources are deallocated with their alocation
      pool.  */
-  info->known_vals.release ();
-  memset (info, 0, sizeof (*info));
+  known_vals.release ();
+
+  lattices = NULL;
+  ipcp_orig_node = NULL;
+  analysis_done = 0;
+  node_enqueued = 0;
+  do_clone_for_all_contexts = 0;
+  is_all_contexts_clone = 0;
+  node_dead = 0;
 }
 
 /* Free all ipa_node_params structures.  */
@@ -3626,20 +3631,15 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
 void
 ipa_free_all_node_params (void)
 {
-  int i;
-  struct ipa_node_params *info;
-
-  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
-    ipa_free_node_params_substructures (info);
-
-  ipa_node_params_vector.release ();
+  delete ipa_node_params_d;
+  ipa_node_params_d = NULL;
 }
 
 /* Set the aggregate replacements of NODE to be AGGVALS.  */
 
 void
-ipa_set_node_agg_value_chain (struct cgraph_node *node,
-			      struct ipa_agg_replacement_value *aggvals)
+ipa_set_node_agg_value_chain (const cgraph_node *node,
+			      ipa_agg_replacement_value *aggvals)
 {
   if (vec_safe_length (ipa_node_agg_replacements)
       <= (unsigned) symtab->cgraph_max_uid)
@@ -3652,9 +3652,9 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
 /* Hook that is called by cgraph.c when an edge is removed.  */
 
 static void
-ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
+ipa_edge_removal_hook (cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_edge_args *args;
+  ipa_edge_args *args;
 
   /* During IPA-CP updating we can be called on not-yet analyzed clones.  */
   if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
@@ -3663,11 +3663,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   args = IPA_EDGE_REF (cs);
   if (args->jump_functions)
     {
-      struct ipa_jump_func *jf;
+      ipa_jump_func *jf;
       int i;
       FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
 	{
-	  struct ipa_cst_ref_desc *rdesc;
+	  ipa_cst_ref_desc *rdesc;
 	  try_decrement_rdesc_refcount (jf);
 	  if (jf->type == IPA_JF_CONST
 	      && (rdesc = ipa_get_jf_constant_rdesc (jf))
@@ -3679,25 +3679,13 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
 }
 
-/* Hook that is called by cgraph.c when a node is removed.  */
-
-static void
-ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
-  if (ipa_node_params_vector.length () > (unsigned)node->uid)
-    ipa_free_node_params_substructures (IPA_NODE_REF (node));
-  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
-    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
-}
-
 /* Hook that is called by cgraph.c when an edge is duplicated.  */
 
 static void
-ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
+ipa_edge_duplication_hook (cgraph_edge *src, cgraph_edge *dst,
 			   __attribute__((unused)) void *data)
 {
-  struct ipa_edge_args *old_args, *new_args;
+  ipa_edge_args *old_args, *new_args;
   unsigned int i;
 
   ipa_check_create_edge_args ();
@@ -3712,20 +3700,20 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 
   for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
     {
-      struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
-      struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
+      ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
+      ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
 
       dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
 
       if (src_jf->type == IPA_JF_CONST)
 	{
-	  struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
+	  ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
 
 	  if (!src_rdesc)
 	    dst_jf->value.constant.rdesc = NULL;
 	  else if (src->caller == dst->caller)
 	    {
-	      struct ipa_ref *ref;
+	      ipa_ref *ref;
 	      symtab_node *n = cgraph_node_for_jfunc (src_jf);
 	      gcc_checking_assert (n);
 	      ref = src->caller->find_reference (n, src->call_stmt,
@@ -3734,8 +3722,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	      dst->caller->clone_reference (ref, ref->stmt);
 
 	      gcc_checking_assert (ipa_refdesc_pool);
-	      struct ipa_cst_ref_desc *dst_rdesc
-		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+	      ipa_cst_ref_desc *dst_rdesc
+		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
 	      dst_rdesc->cs = dst;
 	      dst_rdesc->refcount = src_rdesc->refcount;
 	      dst_rdesc->next_duplicate = NULL;
@@ -3743,10 +3731,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	    }
 	  else if (src_rdesc->cs == src)
 	    {
-	      struct ipa_cst_ref_desc *dst_rdesc;
+	      ipa_cst_ref_desc *dst_rdesc;
 	      gcc_checking_assert (ipa_refdesc_pool);
 	      dst_rdesc
-		= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+		= (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
 	      dst_rdesc->cs = dst;
 	      dst_rdesc->refcount = src_rdesc->refcount;
 	      dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
@@ -3755,7 +3743,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 	    }
 	  else
 	    {
-	      struct ipa_cst_ref_desc *dst_rdesc;
+	      ipa_cst_ref_desc *dst_rdesc;
 	      /* This can happen during inlining, when a JFUNC can refer to a
 		 reference taken in a function up in the tree of inline clones.
 		 We need to find the duplicate that refers to our tree of
@@ -3766,7 +3754,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
 		   dst_rdesc;
 		   dst_rdesc = dst_rdesc->next_duplicate)
 		{
-		  struct cgraph_node *top;
+		  cgraph_node *top;
 		  top = dst_rdesc->cs->caller->global.inlined_to
 		    ? dst_rdesc->cs->caller->global.inlined_to
 		    : dst_rdesc->cs->caller;
@@ -3780,9 +3768,9 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
       else if (dst_jf->type == IPA_JF_PASS_THROUGH
 	       && src->caller == dst->caller)
 	{
-	  struct cgraph_node *inline_root = dst->caller->global.inlined_to
+	  cgraph_node *inline_root = dst->caller->global.inlined_to
 	    ? dst->caller->global.inlined_to : dst->caller;
-	  struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
+	  ipa_node_params *root_info = IPA_NODE_REF (inline_root);
 	  int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
 
 	  int c = ipa_get_controlled_uses (root_info, idx);
@@ -3795,18 +3783,23 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
     }
 }
 
-/* Hook that is called by cgraph.c when a node is duplicated.  */
+/* Analyze newly added function into callgraph.  */
 
 static void
-ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
-			   ATTRIBUTE_UNUSED void *data)
+ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_node_params *old_info, *new_info;
-  struct ipa_agg_replacement_value *old_av, *new_av;
+  if (node->has_gimple_body_p ())
+    ipa_analyze_node (node);
+}
 
-  ipa_check_create_node_params ();
-  old_info = IPA_NODE_REF (src);
-  new_info = IPA_NODE_REF (dst);
+/* Hook that is called by summary when a node is duplicated.  */
+
+void
+ipa_node_params_t::duplication_hook(cgraph_node *src, cgraph_node *dst,
+				    ipa_node_params *old_info,
+				    ipa_node_params *new_info)
+{
+  ipa_agg_replacement_value *old_av, *new_av;
 
   new_info->descriptors = old_info->descriptors.copy ();
   new_info->lattices = NULL;
@@ -3822,7 +3815,7 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   new_av = NULL;
   while (old_av)
     {
-      struct ipa_agg_replacement_value *v;
+      ipa_agg_replacement_value *v;
 
       v = ggc_alloc<ipa_agg_replacement_value> ();
       memcpy (v, old_av, sizeof (*v));
@@ -3833,33 +3826,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   ipa_set_node_agg_value_chain (dst, new_av);
 }
 
-
-/* Analyze newly added function into callgraph.  */
-
-static void
-ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  if (node->has_gimple_body_p ())
-    ipa_analyze_node (node);
-}
-
 /* Register our cgraph hooks if they are not already there.  */
 
 void
 ipa_register_cgraph_hooks (void)
 {
+  ipa_check_create_node_params ();
+
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
   function_insertion_hook_holder =
       symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
 }
@@ -3871,12 +3850,8 @@ ipa_unregister_cgraph_hooks (void)
 {
   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
   symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
 }
@@ -3923,10 +3898,10 @@ ipa_free_all_structures_after_iinln (void)
    callgraph to F.  */
 
 void
-ipa_print_node_params (FILE *f, struct cgraph_node *node)
+ipa_print_node_params (FILE *f, cgraph_node *node)
 {
   int i, count;
-  struct ipa_node_params *info;
+  ipa_node_params *info;
 
   if (!node->definition)
     return;
@@ -3957,7 +3932,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
 void
 ipa_print_all_params (FILE * f)
 {
-  struct cgraph_node *node;
+  cgraph_node *node;
 
   fprintf (f, "\nFunction parameters:\n");
   FOR_EACH_FUNCTION (node)
@@ -4040,7 +4015,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
   tree new_arg_types = NULL;
   for (int i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       gcc_assert (link);
 
       adj = &adjustments[i];
@@ -4158,10 +4133,10 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
    contain the corresponding call graph edge.  */
 
 void
-ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
+ipa_modify_call_arguments (cgraph_edge *cs, gimple stmt,
 			   ipa_parm_adjustment_vec adjustments)
 {
-  struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
+  cgraph_node *current_node = cgraph_node::get (current_function_decl);
   vec<tree> vargs;
   vec<tree, va_gc> **debug_args = NULL;
   gimple new_stmt;
@@ -4179,7 +4154,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
   gsi_prev (&prev_gsi);
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
 
       adj = &adjustments[i];
 
@@ -4412,7 +4387,7 @@ bool
 ipa_modify_expr (tree *expr, bool convert,
 		 ipa_parm_adjustment_vec adjustments)
 {
-  struct ipa_parm_adjustment *cand
+  ipa_parm_adjustment *cand
     = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
   if (!cand)
     return false;
@@ -4500,11 +4475,11 @@ ipa_get_adjustment_candidate (tree **expr, bool *convert,
   if (!base || TREE_CODE (base) != PARM_DECL)
     return NULL;
 
-  struct ipa_parm_adjustment *cand = NULL;
+  ipa_parm_adjustment *cand = NULL;
   unsigned int len = adjustments.length ();
   for (unsigned i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj = &adjustments[i];
+      ipa_parm_adjustment *adj = &adjustments[i];
 
       if (adj->base == base
 	  && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
@@ -4530,7 +4505,7 @@ index_in_adjustments_multiple_times_p (int base_index,
 
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       adj = &adjustments[i];
 
       if (adj->base_index == base_index)
@@ -4561,7 +4536,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
   tmp.create (inlen);
   for (i = 0; i < inlen; i++)
     {
-      struct ipa_parm_adjustment *n;
+      ipa_parm_adjustment *n;
       n = &inner[i];
 
       if (n->op == IPA_PARM_OP_REMOVE)
@@ -4577,9 +4552,9 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
   adjustments.create (outlen + removals);
   for (i = 0; i < outlen; i++)
     {
-      struct ipa_parm_adjustment r;
-      struct ipa_parm_adjustment *out = &outer[i];
-      struct ipa_parm_adjustment *in = &tmp[out->base_index];
+      ipa_parm_adjustment r;
+      ipa_parm_adjustment *out = &outer[i];
+      ipa_parm_adjustment *in = &tmp[out->base_index];
 
       memset (&r, 0, sizeof (r));
       gcc_assert (in->op != IPA_PARM_OP_REMOVE);
@@ -4616,7 +4591,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
 
   for (i = 0; i < inlen; i++)
     {
-      struct ipa_parm_adjustment *n = &inner[i];
+      ipa_parm_adjustment *n = &inner[i];
 
       if (n->op == IPA_PARM_OP_REMOVE)
 	adjustments.quick_push (*n);
@@ -4640,7 +4615,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
   fprintf (file, "IPA param adjustments: ");
   for (i = 0; i < len; i++)
     {
-      struct ipa_parm_adjustment *adj;
+      ipa_parm_adjustment *adj;
       adj = &adjustments[i];
 
       if (!first)
@@ -4683,7 +4658,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
 /* Dump the AV linked list.  */
 
 void
-ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
+ipa_dump_agg_replacement_values (FILE *f, ipa_agg_replacement_value *av)
 {
   bool comma = false;
   fprintf (f, "     Aggregate replacements:");
@@ -4700,11 +4675,11 @@ ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
 /* Stream out jump function JUMP_FUNC to OB.  */
 
 static void
-ipa_write_jump_function (struct output_block *ob,
-			 struct ipa_jump_func *jump_func)
+ipa_write_jump_function (output_block *ob,
+			 ipa_jump_func *jump_func)
 {
-  struct ipa_agg_jf_item *item;
-  struct bitpack_d bp;
+  ipa_agg_jf_item *item;
+  bitpack_d bp;
   int i, count;
 
   streamer_write_uhwi (ob, jump_func->type);
@@ -4768,10 +4743,10 @@ ipa_write_jump_function (struct output_block *ob,
 /* Read in jump function JUMP_FUNC from IB.  */
 
 static void
-ipa_read_jump_function (struct lto_input_block *ib,
-			struct ipa_jump_func *jump_func,
-			struct cgraph_edge *cs,
-			struct data_in *data_in)
+ipa_read_jump_function (lto_input_block *ib,
+			ipa_jump_func *jump_func,
+			cgraph_edge *cs,
+			data_in *data_in)
 {
   enum jump_func_type jftype;
   enum tree_code operation;
@@ -4800,7 +4775,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
       if (operation == NOP_EXPR)
 	{
 	  int formal_id =  streamer_read_uhwi (ib);
-	  struct bitpack_d bp = streamer_read_bitpack (ib);
+	  bitpack_d bp = streamer_read_bitpack (ib);
 	  bool agg_preserved = bp_unpack_value (&bp, 1);
 	  bool type_preserved = bp_unpack_value (&bp, 1);
 	  ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
@@ -4819,7 +4794,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
 	HOST_WIDE_INT offset = streamer_read_uhwi (ib);
 	tree type = stream_read_tree (ib, data_in);
 	int formal_id = streamer_read_uhwi (ib);
-	struct bitpack_d bp = streamer_read_bitpack (ib);
+	bitpack_d bp = streamer_read_bitpack (ib);
 	bool agg_preserved = bp_unpack_value (&bp, 1);
 	bool type_preserved = bp_unpack_value (&bp, 1);
 
@@ -4833,12 +4808,12 @@ ipa_read_jump_function (struct lto_input_block *ib,
   vec_alloc (jump_func->agg.items, count);
   if (count)
     {
-      struct bitpack_d bp = streamer_read_bitpack (ib);
+      bitpack_d bp = streamer_read_bitpack (ib);
       jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
     }
   for (i = 0; i < count; i++)
     {
-      struct ipa_agg_jf_item item;
+      ipa_agg_jf_item item;
       item.offset = streamer_read_uhwi (ib);
       item.value = stream_read_tree (ib, data_in);
       jump_func->agg.items->quick_push (item);
@@ -4849,11 +4824,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
    relevant to indirect inlining to OB.  */
 
 static void
-ipa_write_indirect_edge_info (struct output_block *ob,
-			      struct cgraph_edge *cs)
+ipa_write_indirect_edge_info (output_block *ob,
+			      cgraph_edge *cs)
 {
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
-  struct bitpack_d bp;
+  cgraph_indirect_call_info *ii = cs->indirect_info;
+  bitpack_d bp;
 
   streamer_write_hwi (ob, ii->param_index);
   bp = bitpack_create (ob->main_stream);
@@ -4880,12 +4855,12 @@ ipa_write_indirect_edge_info (struct output_block *ob,
    relevant to indirect inlining from IB.  */
 
 static void
-ipa_read_indirect_edge_info (struct lto_input_block *ib,
-			     struct data_in *data_in,
-			     struct cgraph_edge *cs)
+ipa_read_indirect_edge_info (lto_input_block *ib,
+			     data_in *data_in,
+			     cgraph_edge *cs)
 {
-  struct cgraph_indirect_call_info *ii = cs->indirect_info;
-  struct bitpack_d bp;
+  cgraph_indirect_call_info *ii = cs->indirect_info;
+  bitpack_d bp;
 
   ii->param_index = (int) streamer_read_hwi (ib);
   bp = streamer_read_bitpack (ib);
@@ -4909,14 +4884,14 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
 /* Stream out NODE info to OB.  */
 
 static void
-ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
+ipa_write_node_info (output_block *ob, cgraph_node *node)
 {
   int node_ref;
   lto_symtab_encoder_t encoder;
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
   int j;
-  struct cgraph_edge *e;
-  struct bitpack_d bp;
+  cgraph_edge *e;
+  bitpack_d bp;
 
   encoder = ob->decl_state->symtab_node_encoder;
   node_ref = lto_symtab_encoder_encode (encoder, node);
@@ -4937,7 +4912,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
     streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
   for (e = node->callees; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
 
       streamer_write_uhwi (ob,
 			   ipa_get_cs_argument_count (args) * 2
@@ -4951,7 +4926,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
 
       streamer_write_uhwi (ob,
 			   ipa_get_cs_argument_count (args) * 2
@@ -4969,13 +4944,13 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
 /* Stream in NODE info from IB.  */
 
 static void
-ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
-		    struct data_in *data_in)
+ipa_read_node_info (lto_input_block *ib, cgraph_node *node,
+		    data_in *data_in)
 {
-  struct ipa_node_params *info = IPA_NODE_REF (node);
+  ipa_node_params *info = IPA_NODE_REF (node);
   int k;
-  struct cgraph_edge *e;
-  struct bitpack_d bp;
+  cgraph_edge *e;
+  bitpack_d bp;
 
   ipa_alloc_node_params (node, streamer_read_uhwi (ib));
 
@@ -4992,7 +4967,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
     ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
   for (e = node->callees; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
       int count = streamer_read_uhwi (ib);
       bool contexts_computed = count & 1;
       count /= 2;
@@ -5013,7 +4988,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
     {
-      struct ipa_edge_args *args = IPA_EDGE_REF (e);
+      ipa_edge_args *args = IPA_EDGE_REF (e);
       int count = streamer_read_uhwi (ib);
       bool contexts_computed = count & 1;
       count /= 2;
@@ -5040,14 +5015,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
 void
 ipa_prop_write_jump_functions (void)
 {
-  struct cgraph_node *node;
-  struct output_block *ob;
+  cgraph_node *node;
+  output_block *ob;
   unsigned int count = 0;
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
 
-
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_d)
     return;
 
   ob = create_output_block (LTO_section_jump_functions);
@@ -5081,15 +5055,15 @@ ipa_prop_write_jump_functions (void)
 /* Read section in file FILE_DATA of length LEN with data DATA.  */
 
 static void
-ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
+ipa_prop_read_section (lto_file_decl_data *file_data, const char *data,
 		       size_t len)
 {
-  const struct lto_function_header *header =
-    (const struct lto_function_header *) data;
-  const int cfg_offset = sizeof (struct lto_function_header);
+  const lto_function_header *header =
+    (const lto_function_header *) data;
+  const int cfg_offset = sizeof (lto_function_header);
   const int main_offset = cfg_offset + header->cfg_size;
   const int string_offset = main_offset + header->main_size;
-  struct data_in *data_in;
+  data_in *data_in;
   unsigned int i;
   unsigned int count;
 
@@ -5104,7 +5078,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
   for (i = 0; i < count; i++)
     {
       unsigned int index;
-      struct cgraph_node *node;
+      cgraph_node *node;
       lto_symtab_encoder_t encoder;
 
       index = streamer_read_uhwi (&ib_main);
@@ -5124,8 +5098,8 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
 void
 ipa_prop_read_jump_functions (void)
 {
-  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  lto_file_decl_data *file_data;
   unsigned int j = 0;
 
   ipa_check_create_node_params ();
@@ -5154,12 +5128,12 @@ ipa_update_after_lto_read (void)
 }
 
 void
-write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
+write_agg_replacement_chain (output_block *ob, cgraph_node *node)
 {
   int node_ref;
   unsigned int count = 0;
   lto_symtab_encoder_t encoder;
-  struct ipa_agg_replacement_value *aggvals, *av;
+  ipa_agg_replacement_value *aggvals, *av;
 
   aggvals = ipa_get_agg_replacements_for_node (node);
   encoder = ob->decl_state->symtab_node_encoder;
@@ -5172,7 +5146,7 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
 
   for (av = aggvals; av; av = av->next)
     {
-      struct bitpack_d bp;
+      bitpack_d bp;
 
       streamer_write_uhwi (ob, av->offset);
       streamer_write_uhwi (ob, av->index);
@@ -5187,18 +5161,18 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
 /* Stream in the aggregate value replacement chain for NODE from IB.  */
 
 static void
-read_agg_replacement_chain (struct lto_input_block *ib,
-			    struct cgraph_node *node,
-			    struct data_in *data_in)
+read_agg_replacement_chain (lto_input_block *ib,
+			    cgraph_node *node,
+			    data_in *data_in)
 {
-  struct ipa_agg_replacement_value *aggvals = NULL;
+  ipa_agg_replacement_value *aggvals = NULL;
   unsigned int count, i;
 
   count = streamer_read_uhwi (ib);
   for (i = 0; i <count; i++)
     {
-      struct ipa_agg_replacement_value *av;
-      struct bitpack_d bp;
+      ipa_agg_replacement_value *av;
+      bitpack_d bp;
 
       av = ggc_alloc<ipa_agg_replacement_value> ();
       av->offset = streamer_read_uhwi (ib);
@@ -5217,8 +5191,8 @@ read_agg_replacement_chain (struct lto_input_block *ib,
 void
 ipa_prop_write_all_agg_replacement (void)
 {
-  struct cgraph_node *node;
-  struct output_block *ob;
+  cgraph_node *node;
+  output_block *ob;
   unsigned int count = 0;
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
@@ -5257,16 +5231,16 @@ ipa_prop_write_all_agg_replacement (void)
    DATA.  */
 
 static void
-read_replacements_section (struct lto_file_decl_data *file_data,
+read_replacements_section (lto_file_decl_data *file_data,
 			   const char *data,
 			   size_t len)
 {
-  const struct lto_function_header *header =
-    (const struct lto_function_header *) data;
-  const int cfg_offset = sizeof (struct lto_function_header);
+  const lto_function_header *header =
+    (const lto_function_header *) data;
+  const int cfg_offset = sizeof (lto_function_header);
   const int main_offset = cfg_offset + header->cfg_size;
   const int string_offset = main_offset + header->main_size;
-  struct data_in *data_in;
+  data_in *data_in;
   unsigned int i;
   unsigned int count;
 
@@ -5280,7 +5254,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
   for (i = 0; i < count; i++)
     {
       unsigned int index;
-      struct cgraph_node *node;
+      cgraph_node *node;
       lto_symtab_encoder_t encoder;
 
       index = streamer_read_uhwi (&ib_main);
@@ -5300,8 +5274,8 @@ read_replacements_section (struct lto_file_decl_data *file_data,
 void
 ipa_prop_read_all_agg_replacement (void)
 {
-  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
-  struct lto_file_decl_data *file_data;
+  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  lto_file_decl_data *file_data;
   unsigned int j = 0;
 
   while ((file_data = file_data_vec[j++]))
@@ -5319,10 +5293,10 @@ ipa_prop_read_all_agg_replacement (void)
    NODE.  */
 
 static void
-adjust_agg_replacement_values (struct cgraph_node *node,
-			       struct ipa_agg_replacement_value *aggval)
+adjust_agg_replacement_values (cgraph_node *node,
+			       ipa_agg_replacement_value *aggval)
 {
-  struct ipa_agg_replacement_value *v;
+  ipa_agg_replacement_value *v;
   int i, c = 0, d = 0, *adj;
 
   if (!node->clone.combined_args_to_skip)
@@ -5355,9 +5329,9 @@ adjust_agg_replacement_values (struct cgraph_node *node,
 class ipcp_modif_dom_walker : public dom_walker
 {
 public:
-  ipcp_modif_dom_walker (struct func_body_info *fbi,
+  ipcp_modif_dom_walker (func_body_info *fbi,
 			 vec<ipa_param_descriptor> descs,
-			 struct ipa_agg_replacement_value *av,
+			 ipa_agg_replacement_value *av,
 			 bool *sc, bool *cc)
     : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
       m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
@@ -5365,9 +5339,9 @@ public:
   virtual void before_dom_children (basic_block);
 
 private:
-  struct func_body_info *m_fbi;
+  func_body_info *m_fbi;
   vec<ipa_param_descriptor> m_descriptors;
-  struct ipa_agg_replacement_value *m_aggval;
+  ipa_agg_replacement_value *m_aggval;
   bool *m_something_changed, *m_cfg_changed;
 };
 
@@ -5377,7 +5351,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
   gimple_stmt_iterator gsi;
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      struct ipa_agg_replacement_value *v;
+      ipa_agg_replacement_value *v;
       gimple stmt = gsi_stmt (gsi);
       tree rhs, val, t;
       HOST_WIDE_INT offset, size;
@@ -5468,11 +5442,11 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
 /* IPCP transformation phase doing propagation of aggregate values.  */
 
 unsigned int
-ipcp_transform_function (struct cgraph_node *node)
+ipcp_transform_function (cgraph_node *node)
 {
   vec<ipa_param_descriptor> descriptors = vNULL;
-  struct func_body_info fbi;
-  struct ipa_agg_replacement_value *aggval;
+  func_body_info fbi;
+  ipa_agg_replacement_value *aggval;
   int param_count;
   bool cfg_changed = false, something_changed = false;
 
@@ -5507,7 +5481,7 @@ ipcp_transform_function (struct cgraph_node *node)
 			 &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
 
   int i;
-  struct ipa_bb_info *bi;
+  ipa_bb_info *bi;
   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
     free_ipa_bb_info (bi);
   fbi.bb_infos.release ();
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 165fc1a..5e25fd8 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef IPA_PROP_H
 #define IPA_PROP_H
 
-
 /* The following definitions and interfaces are used by
    interprocedural analyses or parameters.  */
 
@@ -356,6 +355,8 @@ struct ipcp_lattice;
 
 struct ipa_node_params
 {
+  ~ipa_node_params ();
+
   /* Information about individual formal parameters that are gathered when
      summaries are generated. */
   vec<ipa_param_descriptor> descriptors;
@@ -364,7 +365,7 @@ struct ipa_node_params
   struct ipcp_param_lattices *lattices;
   /* Only for versioned nodes this field would not be NULL,
      it points to the node that IPA cp cloned from.  */
-  struct cgraph_node *ipcp_orig_node;
+  cgraph_node *ipcp_orig_node;
   /* If this node is an ipa-cp clone, these are the known values that describe
      what it has been specialized for.  */
   vec<tree> known_vals;
@@ -470,7 +471,7 @@ struct GTY(()) ipa_agg_replacement_value
 
 typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
 
-void ipa_set_node_agg_value_chain (struct cgraph_node *node,
+void ipa_set_node_agg_value_chain (const cgraph_node *node,
 				   struct ipa_agg_replacement_value *aggvals);
 
 /* ipa_edge_args stores information related to a callsite and particularly its
@@ -513,10 +514,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Types of vectors holding the infos.  */
+/* Callgraph summary for ipa_node_params.  */
+class ipa_node_params_t: public function_summary <ipa_node_params *>
+{
+public:
+  ipa_node_params_t (symbol_table *table):
+    function_summary<ipa_node_params *> (table) { }
 
-/* Vector where the parameter infos are actually stored. */
-extern vec<ipa_node_params> ipa_node_params_vector;
+  /* Hook that is called by summary when a node is duplicated.  */
+  virtual void duplication_hook (cgraph_node *node,
+				 cgraph_node *node2,
+				 ipa_node_params *data,
+				 ipa_node_params *data2);
+};
+
+/* Function summary where the parameter infos are actually stored. */
+extern ipa_node_params_t *ipa_node_params_d;
 /* Vector of known aggregate values in cloned nodes.  */
 extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
@@ -524,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Return the associated parameter/argument info corresponding to the given
    node/edge.  */
-#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
+#define IPA_NODE_REF(NODE) ((*ipa_node_params_d)[NODE])
 #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
 /* This macro checks validity of index returned by
    ipa_get_param_decl_index function.  */
@@ -534,11 +547,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 void ipa_create_all_node_params (void);
 void ipa_create_all_edge_args (void);
 void ipa_free_edge_args_substructures (struct ipa_edge_args *);
-void ipa_free_node_params_substructures (struct ipa_node_params *);
 void ipa_free_all_node_params (void);
 void ipa_free_all_edge_args (void);
 void ipa_free_all_structures_after_ipa_cp (void);
 void ipa_free_all_structures_after_iinln (void);
+
 void ipa_register_cgraph_hooks (void);
 int count_formal_params (tree fndecl);
 
@@ -548,11 +561,8 @@ int count_formal_params (tree fndecl);
 static inline void
 ipa_check_create_node_params (void)
 {
-  if (!ipa_node_params_vector.exists ())
-    ipa_node_params_vector.create (symtab->cgraph_max_uid);
-
-  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
-    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
+  if (!ipa_node_params_d)
+    ipa_node_params_d = new ipa_node_params_t (symtab);
 }
 
 /* This function ensures the array of edge arguments infos is big enough to
@@ -579,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
 /* Return the aggregate replacements for NODE, if there are any.  */
 
 static inline struct ipa_agg_replacement_value *
-ipa_get_agg_replacements_for_node (struct cgraph_node *node)
+ipa_get_agg_replacements_for_node (const cgraph_node *node)
 {
   if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
     return NULL;
@@ -587,7 +597,7 @@ ipa_get_agg_replacements_for_node (struct cgraph_node *node)
 }
 
 /* Function formal parameters related computations.  */
-void ipa_initialize_node_params (struct cgraph_node *node);
+void ipa_initialize_node_params (const cgraph_node *node);
 bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
 					vec<cgraph_edge *> *new_edges);
 
@@ -602,7 +612,7 @@ tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
 tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
 
 /* Functions related to both.  */
-void ipa_analyze_node (struct cgraph_node *);
+void ipa_analyze_node (cgraph_node *);
 
 /* Aggregate jump function related functions.  */
 tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
@@ -611,9 +621,9 @@ bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
 			     HOST_WIDE_INT *, bool *);
 
 /* Debugging interface.  */
-void ipa_print_node_params (FILE *, struct cgraph_node *node);
+void ipa_print_node_params (FILE *, cgraph_node *node);
 void ipa_print_all_params (FILE *);
-void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
+void ipa_print_node_jump_functions (FILE *f, cgraph_node *node);
 void ipa_print_all_jump_functions (FILE * f);
 void ipcp_verify_propagated_values (void);
 
@@ -717,7 +727,7 @@ void ipa_update_after_lto_read (void);
 int ipa_get_param_decl_index (struct ipa_node_params *, tree);
 tree ipa_value_from_jfunc (struct ipa_node_params *info,
 			   struct ipa_jump_func *jfunc);
-unsigned int ipcp_transform_function (struct cgraph_node *node);
+unsigned int ipcp_transform_function (cgraph_node *node);
 void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
 bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
 ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 98dbc63..16684e2 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "gimple-ssa.h"
 #include "tree-cfg.h"
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 22900cc..e2f8bd2 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa.c b/gcc/ipa.c
index a6086d8..80b8561 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-iterator.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 0e1a95b..3a2f9ed 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "ipa-utils.h"
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 4c4e48a..1afdf73 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "builtins.h"
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index d8519d9..d151522 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "inchash.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "common.h"
 #include "debug.h"
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b59d069..cf51306 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfgcleanup.h"
 #include "pretty-print.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-nested.h"
 #include "tree-eh.h"
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 8cb9510..d49d952 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "value-prof.h"
 #include "tree-pass.h"
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 1e629bc..e0c375d 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "statistics.h"
 #include "params.h"
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ea99198..c2e5907 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-ssa-propagate.h"
 #include "ipa-utils.h"
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 14:13     ` Martin Liška
@ 2014-11-14 15:32       ` Martin Liška
  2014-12-08 17:03         ` Martin Liška
  2014-11-14 16:07       ` Jan Hubicka
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-11-14 15:32 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3673 bytes --]

On 11/14/2014 03:09 PM, Martin Liška wrote:
> On 11/13/2014 05:04 PM, Jan Hubicka wrote:
>>> +  if (!inline_summary_summary)
>>> +    inline_summary_summary = (inline_summary_cgraph_summary *) inline_summary_cgraph_summary::create_ggc (symtab);
>>
>> Hehe, this is funny naming scheme.
>> Peraps inline_summary_d and inline_summary_t for the data and type?
>
> Hello.
>
> I adopted suggested naming scheme.
>
>>> -
>>> -static void
>>> -inline_node_duplication_hook (struct cgraph_node *src,
>>> -                  struct cgraph_node *dst,
>>> -                  ATTRIBUTE_UNUSED void *data)
>>> +void
>>> +inline_summary_cgraph_summary::duplication_hook (cgraph_node *src,
>>> +                  cgraph_node *dst,
>>> +                  inline_summary *,
>>> +                  inline_summary *info)
>>
>> Becuase those are no longer "hooks" but virtual function, I guess we could call them
>> simply duplicate/insert/remove.
>
> Agree with the change.
>
>>
>> In a way I would like to see these to be methods of the underlying type rather than
>> virtual methods of the summary, becuase these are operations on the data themselves.
>> I was thinking to model these by specual constructor and copy constructor
>> (taking the extra node pointer parameters) and standard destructor.  I am not sure this
>> would be more understandable this way?
>
> Motivation for this implementation is:
> a) it's useful to have an access to cgraph_node that is associated with a sumary
> b) with GTY, we cannot call destructors
>
>>> -/* Need a typedef for inline_summary because of inline function
>>> -   'inline_summary' below.  */
>>> -typedef struct inline_summary inline_summary_t;
>>> -extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
>>> +class GTY((user)) inline_summary_cgraph_summary: public cgraph_summary <inline_summary *>
>>> +{
>>> +public:
>>> +  inline_summary_cgraph_summary (symbol_table *symtab, bool ggc):
>>> +    cgraph_summary <inline_summary *> (symtab, ggc) {}
>>> +
>>> +  static inline_summary_cgraph_summary *create_ggc (symbol_table *symtab)
>>> +  {
>>> +    inline_summary_cgraph_summary *summary = new (ggc_cleared_alloc <inline_summary_cgraph_summary> ()) inline_summary_cgraph_summary(symtab, true);
>>> +    summary->disable_insertion_hook ();
>>> +    return summary;
>>> +  }
>>> +
>>> +
>>> +  virtual void insertion_hook (cgraph_node *, inline_summary *);
>>> +  virtual void removal_hook (cgraph_node *node, inline_summary *);
>>> +  virtual void duplication_hook (cgraph_node *src, cgraph_node *dst, inline_summary *src_data, inline_summary *dst_data);
>>> +};
>>> +
>>> +extern GTY(()) cgraph_summary <inline_summary *> *inline_summary_summary;
>>
>> All in all it looks better than original code.  If we moved insert/
>>>
>>>   /* Information kept about parameter of call site.  */
>>>   struct inline_param_summary
>>> @@ -249,10 +265,10 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
>>>   extern int ncalls_inlined;
>>>   extern int nfunctions_inlined;
>>>
>>> -static inline struct inline_summary *
>>> -inline_summary (struct cgraph_node *node)
>>> +static inline inline_summary *
>>> +get_inline_summary (const struct cgraph_node *node)
>>>   {
>>> -  return &(*inline_summary_vec)[node->uid];
>>> +  return (*inline_summary_summary)[node->summary_uid];
>>
>> Hmm, i guess there is no way to avoid the (*...)? Otherwise it would be cleaner
>> to use inline_summary[...] instead of get_inline_summary IMO.
>
> I added function_summary::get method, where the usage looks cleaner:
> inline_summary_d->get (node).
>
> Thanks,
> Martin
>
>> Thanks for working on this!
>> Honza
>>
>

Patch v3.

Martin

[-- Attachment #2: 0003-Data-structure-is-used-for-inline_summary-struct.patch --]
[-- Type: text/x-patch, Size: 46103 bytes --]

From 7f57a3a762fecea9a20e307f06e868a73da98000 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 14 Nov 2014 14:54:12 +0100
Subject: [PATCH 3/3] Data structure is used for inline_summary struct.

gcc/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* cgraphunit.c (symbol_table::process_new_functions):
	inline_summary_vec is replaced with inline_summary_t.
	* ipa-cp.c (ipcp_cloning_candidate_p): Usage of inline_summary_t::get.
	(devirtualization_time_bonus): Likewise.
	(estimate_local_effects): Likewise.
	(ipcp_propagate_stage): Likewise.
	* ipa-inline-analysis.c (evaluate_conditions_for_known_args): Likewise.
	(evaluate_properties_for_edge): Likewise.
	(inline_summary_alloc): Deletion of old hook holders.
	(reset_inline_summary): inline_summary is added as argument.
	(inline_summary_cgraph_summary::removal_hook): New function.
	(inline_summary_cgraph_summary::duplication_hook): Likewise.
	(dump_inline_edge_summary): Struct keyword removed.
	(dump_inline_summary): Likewise.
	(estimate_function_body_sizes): Usage of inline_summary_t::get.
	(compute_inline_parameters): Likewise.
	(estimate_edge_devirt_benefit): Struct keyword removed.
	(estimate_node_size_and_time): Likewise.
	(inline_update_callee_summaries): Likewise.
	(inline_merge_summary): Usage of inline_summary_t::get.
	(inline_update_overall_summary): Likewise.
	(simple_edge_hints): Likewise.
	(do_estimate_edge_time): Likewise.
	(estimate_time_after_inlining): Likewise.
	(estimate_size_after_inlining): Likewise.
	(do_estimate_growth): Likewise.
	(growth_likely_positive): Likewise.
	(inline_generate_summary): inline_summary_t is registered.
	(inline_read_section): Struct keyword removed.
	(inline_read_summary): Likewise.
	(inline_write_summary): Likewise.
	(inline_free_summary): Removal of old hook holders.
	* ipa-inline-transform.c (clone_inlined_nodes): Usage of
	inline_summary_t::get.
	(inline_call): Likewise.
	* ipa-inline.c (caller_growth_limits): Struct keyword is removed.
	(can_inline_edge_p): Usage of inline_summary_t::get.
	(want_early_inline_function_p): Struct keyword removed.
	(compute_uninlined_call_time): Usage of inline_summary_t::get.
	(compute_inlined_call_time): Likewise.
	(big_speedup_p): Likewise.
	(want_inline_small_function_p): Likewise.
	(edge_badness): Likewise.
	(update_caller_keys): Likewise.
	(update_callee_keys): Likewise.
	(recursive_inlining): Likewise.
	(inline_small_functions): Likewise.
	(inline_to_all_callers): Likewise.
	(dump_overall_stats): Likewise.
	(early_inline_small_functions): Likewise.
	* ipa-inline.h (inline_summary_t::get): New function.
	* ipa-split.c (execute_split_functions): Usage of inline_summary_t::get.
	* ipa.c (walk_polymorphic_call_targets): inline_summary_vec is replaced with inline_summary_t.
	* tree-sra.c (ipa_sra_preliminary_function_checks): Usage of inline_summary_t::get.

gcc/lto/ChangeLog:

2014-11-12  Martin Liska  <mliska@suse.cz>

	* lto-partition.c (add_symbol_to_partition_1): Usage of
	inline_summary_t::get.
	(undo_partition): Likewise.
	(lto_balanced_map): Likewise.
---
 gcc/cgraphunit.c           |   2 +-
 gcc/ipa-cp.c               |  10 +--
 gcc/ipa-inline-analysis.c  | 193 ++++++++++++++++++++-------------------------
 gcc/ipa-inline-transform.c |   6 +-
 gcc/ipa-inline.c           |  61 +++++++-------
 gcc/ipa-inline.h           |  32 +++++---
 gcc/ipa-prop.h             |   4 +-
 gcc/ipa-split.c            |   2 +-
 gcc/ipa.c                  |   2 +-
 gcc/lto/lto-partition.c    |  10 +--
 gcc/tree-sra.c             |   2 +-
 11 files changed, 155 insertions(+), 169 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 93f8d91..7486f2a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -338,7 +338,7 @@ symbol_table::process_new_functions (void)
 	  if (state == IPA_SSA
 	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
 	    g->get_passes ()->execute_early_local_passes ();
-	  else if (inline_summary_vec != NULL)
+	  else if (inline_summary_d != NULL)
 	    compute_inline_parameters (node, true);
 	  free_dominance_info (CDI_POST_DOMINATORS);
 	  free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 56d1ae9..14684de 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -552,7 +552,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
   init_caller_stats (&stats);
   node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
 
-  if (inline_summary (node)->self_size < stats.n_calls)
+  if (inline_summary_d->get (node)->self_size < stats.n_calls)
     {
       if (dump_file)
         fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
@@ -1718,7 +1718,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
     {
       struct cgraph_node *callee;
-      struct inline_summary *isummary;
+      inline_summary *isummary;
       enum availability avail;
       tree target;
 
@@ -1735,7 +1735,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
       callee = callee->function_symbol (&avail);
       if (avail < AVAIL_AVAILABLE)
 	continue;
-      isummary = inline_summary (callee);
+      isummary = inline_summary_d->get (callee);
       if (!isummary->inlinable)
 	continue;
 
@@ -1945,7 +1945,7 @@ estimate_local_effects (struct cgraph_node *node)
   vec<ipa_agg_jump_function> known_aggs;
   vec<ipa_agg_jump_function_p> known_aggs_ptrs;
   bool always_const;
-  int base_time = inline_summary (node)->time;
+  int base_time = inline_summary_d->get (node)->time;
   int removable_params_cost;
 
   if (!count || !ipcp_versionable_function_p (node))
@@ -2357,7 +2357,7 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
 	initialize_node_lattices (node);
       }
     if (node->definition && !node->alias)
-      overall_size += inline_summary (node)->self_size;
+      overall_size += inline_summary_d->get (node)->self_size;
     if (node->count > max_count)
       max_count = node->count;
   }
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 84da4dc..b2a91c6 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -148,21 +148,15 @@ enum predicate_conditions
 #define CHANGED IDENTIFIER_NODE
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static void inline_node_removal_hook (struct cgraph_node *, void *);
-static void inline_node_duplication_hook (struct cgraph_node *,
-					  struct cgraph_node *, void *);
 static void inline_edge_removal_hook (struct cgraph_edge *, void *);
 static void inline_edge_duplication_hook (struct cgraph_edge *,
 					  struct cgraph_edge *, void *);
 
 /* VECtor holding inline summaries.  
    In GGC memory because conditions might point to constant trees.  */
-vec<inline_summary_t, va_gc> *inline_summary_vec;
+function_summary <inline_summary *> *inline_summary_d;
 vec<inline_edge_summary_t> inline_edge_summary_vec;
 
 /* Cached node/edge growths.  */
@@ -699,7 +693,7 @@ dump_inline_hints (FILE *f, inline_hints hints)
 /* Record SIZE and TIME under condition PRED into the inline summary.  */
 
 static void
-account_size_time (struct inline_summary *summary, int size, int time,
+account_size_time (inline_summary *summary, int size, int time,
 		   struct predicate *pred)
 {
   size_time_entry *e;
@@ -829,7 +823,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 				    known_aggs)
 {
   clause_t clause = inline_p ? 0 : 1 << predicate_not_inlined_condition;
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   int i;
   struct condition *c;
 
@@ -900,7 +894,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 			      vec<ipa_agg_jump_function_p> *known_aggs_ptr)
 {
   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-  struct inline_summary *info = inline_summary (callee);
+  inline_summary *info = inline_summary_d->get (callee);
   vec<tree> known_vals = vNULL;
   vec<ipa_agg_jump_function_p> known_aggs = vNULL;
 
@@ -974,21 +968,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 static void
 inline_summary_alloc (void)
 {
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&inline_node_removal_hook, NULL);
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&inline_node_duplication_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
 
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) symtab->cgraph_max_uid)
-    vec_safe_grow_cleared (inline_summary_vec, symtab->cgraph_max_uid + 1);
+  if (!inline_summary_d)
+    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
   if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid)
     inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
   if (!edge_predicate_pool)
@@ -1018,9 +1007,9 @@ reset_inline_edge_summary (struct cgraph_edge *e)
    data from previous run so they are not cumulated.  */
 
 static void
-reset_inline_summary (struct cgraph_node *node)
+reset_inline_summary (const struct cgraph_node *node,
+		      inline_summary *info)
 {
-  struct inline_summary *info = inline_summary (node);
   struct cgraph_edge *e;
 
   info->self_size = info->self_time = 0;
@@ -1056,16 +1045,10 @@ reset_inline_summary (struct cgraph_node *node)
 
 /* Hook that is called by cgraph.c when a node is removed.  */
 
-static void
-inline_node_removal_hook (struct cgraph_node *node,
-			  void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::remove (cgraph_node *node, inline_summary *info)
 {
-  struct inline_summary *info;
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) node->uid)
-    return;
-  info = inline_summary (node);
-  reset_inline_summary (node);
-  memset (info, 0, sizeof (inline_summary_t));
+  reset_inline_summary (node, info);
 }
 
 /* Remap predicate P of former function to be predicate of duplicated function.
@@ -1075,7 +1058,7 @@ inline_node_removal_hook (struct cgraph_node *node,
 static struct predicate
 remap_predicate_after_duplication (struct predicate *p,
 				   clause_t possible_truths,
-				   struct inline_summary *info)
+				   inline_summary *info)
 {
   struct predicate new_predicate = true_predicate ();
   int j;
@@ -1099,7 +1082,7 @@ remap_predicate_after_duplication (struct predicate *p,
 static void
 remap_hint_predicate_after_duplication (struct predicate **p,
 					clause_t possible_truths,
-					struct inline_summary *info)
+					inline_summary *info)
 {
   struct predicate new_predicate;
 
@@ -1115,16 +1098,14 @@ remap_hint_predicate_after_duplication (struct predicate **p,
 
 
 /* Hook that is called by cgraph.c when a node is duplicated.  */
-
-static void
-inline_node_duplication_hook (struct cgraph_node *src,
-			      struct cgraph_node *dst,
-			      ATTRIBUTE_UNUSED void *data)
+void
+inline_summary_t::duplicate (cgraph_node *src,
+			     cgraph_node *dst,
+			     inline_summary *,
+			     inline_summary *info)
 {
-  struct inline_summary *info;
   inline_summary_alloc ();
-  info = inline_summary (dst);
-  memcpy (info, inline_summary (src), sizeof (struct inline_summary));
+  memcpy (info, inline_summary_d->get (src), sizeof (inline_summary));
   /* TODO: as an optimization, we may avoid copying conditions
      that are known to be false or true.  */
   info->conds = vec_safe_copy (info->conds);
@@ -1328,7 +1309,7 @@ free_growth_caches (void)
 
 static void
 dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
-			  struct inline_summary *info)
+			  inline_summary *info)
 {
   struct cgraph_edge *edge;
   for (edge = node->callees; edge; edge = edge->next_callee)
@@ -1345,8 +1326,8 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
 	       indent, "", es->loop_depth, edge->frequency,
 	       es->call_stmt_size, es->call_stmt_time,
-	       (int) inline_summary (callee)->size / INLINE_SIZE_SCALE,
-	       (int) inline_summary (callee)->estimated_stack_size);
+	       (int) inline_summary_d->get (callee)->size / INLINE_SIZE_SCALE,
+	       (int) inline_summary_d->get (callee)->estimated_stack_size);
 
       if (es->predicate)
 	{
@@ -1372,9 +1353,9 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
 		   " callee size %i\n",
 		   indent + 2, "",
-		   (int) inline_summary (callee)->stack_frame_offset,
-		   (int) inline_summary (callee)->estimated_self_stack_size,
-		   (int) inline_summary (callee)->estimated_stack_size);
+		   (int) inline_summary_d->get (callee)->stack_frame_offset,
+		   (int) inline_summary_d->get (callee)->estimated_self_stack_size,
+		   (int) inline_summary_d->get (callee)->estimated_stack_size);
 	  dump_inline_edge_summary (f, indent + 2, callee, info);
 	}
     }
@@ -1402,7 +1383,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
 {
   if (node->definition)
     {
-      struct inline_summary *s = inline_summary (node);
+      inline_summary *s = inline_summary_d->get (node);
       size_time_entry *e;
       int i;
       fprintf (f, "Inline summary for %s/%i", node->name (),
@@ -1725,7 +1706,7 @@ eliminated_by_inlining_prob (gimple stmt)
 
 static void
 set_cond_stmt_execution_predicate (struct ipa_node_params *info,
-				   struct inline_summary *summary,
+				   inline_summary *summary,
 				   basic_block bb)
 {
   gimple last;
@@ -1810,7 +1791,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
 
 static void
 set_switch_stmt_execution_predicate (struct ipa_node_params *info,
-				     struct inline_summary *summary,
+				     inline_summary *summary,
 				     basic_block bb)
 {
   gimple last;
@@ -1871,7 +1852,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
 static void
 compute_bb_predicates (struct cgraph_node *node,
 		       struct ipa_node_params *parms_info,
-		       struct inline_summary *summary)
+		       inline_summary *summary)
 {
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   bool done = false;
@@ -1950,7 +1931,7 @@ typedef struct predicate predicate_t;
 
 static struct predicate
 will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
-				    struct inline_summary *summary,
+				    inline_summary *summary,
 				    tree expr,
 				    vec<predicate_t> nonconstant_names)
 {
@@ -2013,7 +1994,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
 
 static struct predicate
 will_be_nonconstant_predicate (struct ipa_node_params *info,
-			       struct inline_summary *summary,
+			       inline_summary *summary,
 			       gimple stmt,
 			       vec<predicate_t> nonconstant_names)
 {
@@ -2215,7 +2196,7 @@ param_change_prob (gimple stmt, int i)
 
 static bool
 phi_result_unknown_predicate (struct ipa_node_params *info,
-			      struct inline_summary *summary, basic_block bb,
+			      inline_summary *summary, basic_block bb,
 			      struct predicate *p,
 			      vec<predicate_t> nonconstant_names)
 {
@@ -2274,7 +2255,7 @@ phi_result_unknown_predicate (struct ipa_node_params *info,
    NONCONSTANT_NAMES, if possible.  */
 
 static void
-predicate_for_phi_result (struct inline_summary *summary, gimple phi,
+predicate_for_phi_result (inline_summary *summary, gimple phi,
 			  struct predicate *p,
 			  vec<predicate_t> nonconstant_names)
 {
@@ -2304,7 +2285,7 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
 /* Return predicate specifying when array index in access OP becomes non-constant.  */
 
 static struct predicate
-array_index_predicate (struct inline_summary *info,
+array_index_predicate (inline_summary *info,
 		       vec< predicate_t> nonconstant_names, tree op)
 {
   struct predicate p = false_predicate ();
@@ -2460,7 +2441,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   gimple_stmt_iterator bsi;
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   int freq;
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   struct predicate bb_predicate;
   struct ipa_node_params *parms_info = NULL;
   vec<predicate_t> nonconstant_names = vNULL;
@@ -2702,7 +2683,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	}
     }
-  set_hint_predicate (&inline_summary (node)->array_index, array_index);
+  set_hint_predicate (&inline_summary_d->get (node)->array_index, array_index);
   time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
   if (time > MAX_TIME)
     time = MAX_TIME;
@@ -2790,9 +2771,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	  free (body);
 	}
-      set_hint_predicate (&inline_summary (node)->loop_iterations,
+      set_hint_predicate (&inline_summary_d->get (node)->loop_iterations,
 			  loop_iterations);
-      set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
+      set_hint_predicate (&inline_summary_d->get (node)->loop_stride, loop_stride);
       scev_finalize ();
     }
   FOR_ALL_BB_FN (bb, my_function)
@@ -2810,8 +2791,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	  e->aux = NULL;
 	}
     }
-  inline_summary (node)->self_time = time;
-  inline_summary (node)->self_size = size;
+  inline_summary_d->get (node)->self_time = time;
+  inline_summary_d->get (node)->self_size = size;
   nonconstant_names.release ();
   if (optimize && !early)
     {
@@ -2834,14 +2815,14 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
 {
   HOST_WIDE_INT self_stack_size;
   struct cgraph_edge *e;
-  struct inline_summary *info;
+  inline_summary *info;
 
   gcc_assert (!node->global.inlined_to);
 
   inline_summary_alloc ();
 
-  info = inline_summary (node);
-  reset_inline_summary (node);
+  info = inline_summary_d->get (node);
+  reset_inline_summary (node, info);
 
   /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
      Once this happen, we will need to more curefully predict call
@@ -2982,7 +2963,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
 {
   tree target;
   struct cgraph_node *callee;
-  struct inline_summary *isummary;
+  inline_summary *isummary;
   enum availability avail;
 
   if (!known_vals.exists () && !known_binfos.exists ())
@@ -3007,7 +2988,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
   callee = callee->function_symbol (&avail);
   if (avail < AVAIL_AVAILABLE)
     return false;
-  isummary = inline_summary (callee);
+  isummary = inline_summary_d->get (callee);
   return isummary->inlinable;
 }
 
@@ -3120,7 +3101,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
 			     vec<inline_param_summary>
 			     inline_param_summary)
 {
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   size_time_entry *e;
   int size = 0;
   int time = 0;
@@ -3246,8 +3227,8 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
    for other purposes).  */
 
 static struct predicate
-remap_predicate (struct inline_summary *info,
-		 struct inline_summary *callee_info,
+remap_predicate (inline_summary *info,
+		 inline_summary *callee_info,
 		 struct predicate *p,
 		 vec<int> operand_map,
 		 vec<int> offset_map,
@@ -3336,8 +3317,8 @@ static void
 inline_update_callee_summaries (struct cgraph_node *node, int depth)
 {
   struct cgraph_edge *e;
-  struct inline_summary *callee_info = inline_summary (node);
-  struct inline_summary *caller_info = inline_summary (node->callers->caller);
+  inline_summary *callee_info = inline_summary_d->get (node);
+  inline_summary *caller_info = inline_summary_d->get (node->callers->caller);
   HOST_WIDE_INT peak;
 
   callee_info->stack_frame_offset
@@ -3345,8 +3326,8 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
     + caller_info->estimated_self_stack_size;
   peak = callee_info->stack_frame_offset
     + callee_info->estimated_self_stack_size;
-  if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
-      inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
+  if (inline_summary_d->get (node->global.inlined_to)->estimated_stack_size < peak)
+      inline_summary_d->get (node->global.inlined_to)->estimated_stack_size = peak;
   ipa_propagate_frequency (node);
   for (e = node->callees; e; e = e->next_callee)
     {
@@ -3407,8 +3388,8 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 static void
 remap_edge_summaries (struct cgraph_edge *inlined_edge,
 		      struct cgraph_node *node,
-		      struct inline_summary *info,
-		      struct inline_summary *callee_info,
+		      inline_summary *info,
+		      inline_summary *callee_info,
 		      vec<int> operand_map,
 		      vec<int> offset_map,
 		      clause_t possible_truths,
@@ -3476,8 +3457,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
 /* Same as remap_predicate, but set result into hint *HINT.  */
 
 static void
-remap_hint_predicate (struct inline_summary *info,
-		      struct inline_summary *callee_info,
+remap_hint_predicate (inline_summary *info,
+		      inline_summary *callee_info,
 		      struct predicate **hint,
 		      vec<int> operand_map,
 		      vec<int> offset_map,
@@ -3506,10 +3487,10 @@ remap_hint_predicate (struct inline_summary *info,
 void
 inline_merge_summary (struct cgraph_edge *edge)
 {
-  struct inline_summary *callee_info = inline_summary (edge->callee);
+  inline_summary *callee_info = inline_summary_d->get (edge->callee);
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  struct inline_summary *info = inline_summary (to);
+  inline_summary *info = inline_summary_d->get (to);
   clause_t clause = 0;		/* not_inline is known to be false.  */
   size_time_entry *e;
   vec<int> operand_map = vNULL;
@@ -3618,7 +3599,7 @@ inline_merge_summary (struct cgraph_edge *edge)
 void
 inline_update_overall_summary (struct cgraph_node *node)
 {
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
   size_time_entry *e;
   int i;
 
@@ -3645,8 +3626,8 @@ simple_edge_hints (struct cgraph_edge *edge)
   int hints = 0;
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  if (inline_summary (to)->scc_no
-      && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
+  if (inline_summary_d->get (to)->scc_no
+      && inline_summary_d->get (to)->scc_no == inline_summary_d->get (edge->callee)->scc_no
       && !edge->recursive_p ())
     hints |= INLINE_HINT_same_scc;
 
@@ -3706,7 +3687,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
   /* When caching, update the cache entry.  */
   if (edge_growth_cache.exists ())
     {
-      inline_summary (edge->callee)->min_size = min_size;
+      inline_summary_d->get (edge->callee)->min_size = min_size;
       if ((int) edge_growth_cache.length () <= edge->uid)
 	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
       edge_growth_cache[edge->uid].time = time + (time >= 0);
@@ -3808,14 +3789,14 @@ estimate_time_after_inlining (struct cgraph_node *node,
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
       gcov_type time =
-	inline_summary (node)->time + estimate_edge_time (edge);
+	inline_summary_d->get (node)->time + estimate_edge_time (edge);
       if (time < 0)
 	time = 0;
       if (time > MAX_TIME)
 	time = MAX_TIME;
       return time;
     }
-  return inline_summary (node)->time;
+  return inline_summary_d->get (node)->time;
 }
 
 
@@ -3829,11 +3810,11 @@ estimate_size_after_inlining (struct cgraph_node *node,
   struct inline_edge_summary *es = inline_edge_summary (edge);
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
-      int size = inline_summary (node)->size + estimate_edge_growth (edge);
+      int size = inline_summary_d->get (node)->size + estimate_edge_growth (edge);
       gcc_assert (size >= 0);
       return size;
     }
-  return inline_summary (node)->size;
+  return inline_summary_d->get (node)->size;
 }
 
 
@@ -3873,7 +3854,7 @@ int
 do_estimate_growth (struct cgraph_node *node)
 {
   struct growth_data d = { node, 0, false };
-  struct inline_summary *info = inline_summary (node);
+  inline_summary *info = inline_summary_d->get (node);
 
   node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
 
@@ -3946,7 +3927,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
       && (!DECL_COMDAT (node->decl)
 	  || !node->can_remove_if_no_direct_calls_p ()))
     return true;
-  max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
+  max_callers = inline_summary_d->get (node)->size * 4 / edge_growth + 2;
 
   for (e = node->callers; e; e = e->next_caller)
     {
@@ -4009,13 +3990,12 @@ inline_analyze_function (struct cgraph_node *node)
 
 /* Called when new function is inserted to callgraph late.  */
 
-static void
-add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::insert (cgraph_node *node, inline_summary *)
 {
   inline_analyze_function (node);
 }
 
-
 /* Note function body size.  */
 
 void
@@ -4028,8 +4008,10 @@ inline_generate_summary (void)
   if (!optimize && !flag_lto && !flag_wpa)
     return;
 
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+  if (!inline_summary_d)
+    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
+  inline_summary_d->enable_insertion_hook ();
 
   ipa_register_cgraph_hooks ();
   inline_free_summary ();
@@ -4113,7 +4095,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
     {
       unsigned int index;
       struct cgraph_node *node;
-      struct inline_summary *info;
+      inline_summary *info;
       lto_symtab_encoder_t encoder;
       struct bitpack_d bp;
       struct cgraph_edge *e;
@@ -4123,7 +4105,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
       encoder = file_data->symtab_node_encoder;
       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
 								index));
-      info = inline_summary (node);
+      info = inline_summary_d->get (node);
 
       info->estimated_stack_size
 	= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
@@ -4212,8 +4194,9 @@ inline_read_summary (void)
       if (!flag_ipa_cp)
 	ipa_prop_read_jump_functions ();
     }
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+
+  gcc_assert (inline_summary_d);
+  inline_summary_d->enable_insertion_hook ();
 }
 
 
@@ -4279,7 +4262,7 @@ inline_write_summary (void)
       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
       if (cnode && (node = cnode)->definition && !node->alias)
 	{
-	  struct inline_summary *info = inline_summary (node);
+	  inline_summary *info = inline_summary_d->get (node);
 	  struct bitpack_d bp;
 	  struct cgraph_edge *edge;
 	  int i;
@@ -4344,23 +4327,15 @@ inline_free_summary (void)
     return;
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->alias)
-      reset_inline_summary (node);
-  if (function_insertion_hook_holder)
-    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
-  function_insertion_hook_holder = NULL;
-  if (node_removal_hook_holder)
-    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
+      reset_inline_summary (node, inline_summary_d->get (node));
   if (edge_removal_hook_holder)
     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  if (node_duplication_hook_holder)
-    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   if (edge_duplication_hook_holder)
     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  vec_free (inline_summary_vec);
+  inline_summary_d->release ();
+  inline_summary_d = NULL;
   inline_edge_summary_vec.release ();
   if (edge_predicate_pool)
     free_alloc_pool (edge_predicate_pool);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 49c2679..841af60 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
 	  if (e->callee->definition && !DECL_EXTERNAL (e->callee->decl))
 	    {
 	      if (overall_size)
-	        *overall_size -= inline_summary (e->callee)->size;
+	        *overall_size -= inline_summary_d->get (e->callee)->size;
 	      nfunctions_inlined++;
 	    }
 	  duplicate = false;
@@ -309,13 +309,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   gcc_assert (curr->callee->global.inlined_to == to);
 
-  old_size = inline_summary (to)->size;
+  old_size = inline_summary_d->get (to)->size;
   inline_merge_summary (e);
   if (optimize)
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   if (update_overall_summary)
    inline_update_overall_summary (to);
-  new_size = inline_summary (to)->size;
+  new_size = inline_summary_d->get (to)->size;
 
   if (callee->calls_comdat_local)
     to->calls_comdat_local = true;
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index a8e94e2..73fb286 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -167,7 +167,7 @@ caller_growth_limits (struct cgraph_edge *e)
   int newsize;
   int limit = 0;
   HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
-  struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
+  inline_summary *info, *what_info, *outer_info = inline_summary_d->get (to);
 
   /* Look for function e->caller is inlined to.  While doing
      so work out the largest function body on the way.  As
@@ -179,7 +179,7 @@ caller_growth_limits (struct cgraph_edge *e)
      too much in order to prevent compiler from exploding".  */
   while (true)
     {
-      info = inline_summary (to);
+      info = inline_summary_d->get (to);
       if (limit < info->self_size)
 	limit = info->self_size;
       if (stack_size_limit < info->estimated_self_stack_size)
@@ -190,7 +190,7 @@ caller_growth_limits (struct cgraph_edge *e)
 	break;
     }
 
-  what_info = inline_summary (what);
+  what_info = inline_summary_d->get (what);
 
   if (limit < what_info->self_size)
     limit = what_info->self_size;
@@ -304,7 +304,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_USES_COMDAT_LOCAL;
       inlinable = false;
     }
-  else if (!inline_summary (callee)->inlinable 
+  else if (!inline_summary_d->get (callee)->inlinable 
 	   || (caller_fun && fn_contains_cilk_spawn_p (caller_fun)))
     {
       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
@@ -458,7 +458,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     ;
-  /* For AutoFDO, we need to make sure that before profile annotation, all
+  /* For AutoFDO, we need to make sure that before profile summary, all
      hot paths' IR look exactly the same as profiled binary. As a result,
      in einliner, we will disregard size limit and inline those callsites
      that are:
@@ -524,13 +524,12 @@ want_early_inline_function_p (struct cgraph_edge *e)
    does not happen.  */
 
 inline gcov_type
-compute_uninlined_call_time (struct inline_summary *callee_info,
-			     struct cgraph_edge *edge)
+compute_uninlined_call_time (inline_summary *callee_info, cgraph_edge *edge)
 {
   gcov_type uninlined_call_time =
     RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
 	  CGRAPH_FREQ_BASE);
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
 				          ? edge->caller->global.inlined_to
 				          : edge->caller)->time;
   return uninlined_call_time + caller_time;
@@ -543,7 +542,7 @@ inline gcov_type
 compute_inlined_call_time (struct cgraph_edge *edge,
 			   int edge_time)
 {
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
 					  ? edge->caller->global.inlined_to
 					  : edge->caller)->time;
   gcov_type time = (caller_time
@@ -563,7 +562,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
 static bool
 big_speedup_p (struct cgraph_edge *e)
 {
-  gcov_type time = compute_uninlined_call_time (inline_summary (e->callee),
+  gcov_type time = compute_uninlined_call_time (inline_summary_d->get (e->callee),
 					  	e);
   gcov_type inlined_time = compute_inlined_call_time (e,
 					              estimate_edge_time (e));
@@ -596,7 +595,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
      MAX_INLINE_INSNS_SINGLE 16-fold for inline functions.  */
   else if ((!DECL_DECLARED_INLINE_P (callee->decl)
 	   && (!e->count || !e->maybe_hot_p ()))
-	   && inline_summary (callee)->min_size
+	   && inline_summary_d->get (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
     {
@@ -604,7 +603,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
       want_inline = false;
     }
   else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
-	   && inline_summary (callee)->min_size
+	   && inline_summary_d->get (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > 16 * MAX_INLINE_INSNS_SINGLE)
     {
@@ -867,8 +866,8 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
    1...RELATIVE_TIME_BENEFIT_RANGE  */
 
 static inline int
-relative_time_benefit (struct inline_summary *callee_info,
-		       struct cgraph_edge *edge,
+relative_time_benefit (inline_summary *callee_info,
+		       cgraph_edge *edge,
 		       int edge_time)
 {
   gcov_type relbenefit;
@@ -913,7 +912,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   gcov_type badness;
   int growth, edge_time;
   struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
-  struct inline_summary *callee_info = inline_summary (callee);
+  inline_summary *callee_info = inline_summary_d->get (callee);
   inline_hints hints;
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
@@ -1188,7 +1187,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
   struct cgraph_edge *edge;
   struct ipa_ref *ref;
 
-  if ((!node->alias && !inline_summary (node)->inlinable)
+  if ((!node->alias && !inline_summary_d->get (node)->inlinable)
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->uid))
@@ -1246,7 +1245,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
            don't need updating.  */
 	if (e->inline_failed
 	    && (callee = e->callee->ultimate_alias_target (&avail))
-	    && inline_summary (callee)->inlinable
+	    && inline_summary_d->get (callee)->inlinable
 	    && avail >= AVAIL_AVAILABLE
 	    && !bitmap_bit_p (updated_nodes, callee->uid))
 	  {
@@ -1424,8 +1423,8 @@ recursive_inlining (struct cgraph_edge *edge,
     fprintf (dump_file,
 	     "\n   Inlined %i times, "
 	     "body grown from size %i to %i, time %i to %i\n", n,
-	     inline_summary (master_clone)->size, inline_summary (node)->size,
-	     inline_summary (master_clone)->time, inline_summary (node)->time);
+	     inline_summary_d->get (master_clone)->size, inline_summary_d->get (node)->size,
+	     inline_summary_d->get (master_clone)->time, inline_summary_d->get (node)->time);
 
   /* Remove master clone we used for inlining.  We rely that clones inlined
      into master clone gets queued just before master clone so we don't
@@ -1599,8 +1598,8 @@ inline_small_functions (void)
 	if (node->has_gimple_body_p ()
 	    || node->thunk.thunk_p)
 	  {
-	    struct inline_summary *info = inline_summary (node);
-	    struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
+	    inline_summary *info = inline_summary_d->get (node);
+	    ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
 
 	    /* Do not account external functions, they will be optimized out
 	       if not inlined.  Also only count the non-cold portion of program.  */
@@ -1610,12 +1609,12 @@ inline_small_functions (void)
 	    info->growth = estimate_growth (node);
 	    if (dfs && dfs->next_cycle)
 	      {
-		struct cgraph_node *n2;
+		cgraph_node *n2;
 		int id = dfs->scc_no + 1;
 		for (n2 = node; n2;
 		     n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
 		  {
-		    struct inline_summary *info2 = inline_summary (n2);
+		    inline_summary *info2 = inline_summary_d->get (n2);
 		    if (info2->scc_no)
 		      break;
 		    info2->scc_no = id;
@@ -1735,7 +1734,7 @@ inline_small_functions (void)
 	  fprintf (dump_file,
 		   "\nConsidering %s/%i with %i size\n",
 		   callee->name (), callee->order,
-		   inline_summary (callee)->size);
+		   inline_summary_d->get (callee)->size);
 	  fprintf (dump_file,
 		   " to be inlined into %s/%i in %s:%i\n"
 		   " Estimated badness is %i, frequency %.2f.\n",
@@ -1853,8 +1852,8 @@ inline_small_functions (void)
 		   " Inlined into %s which now has time %i and size %i,"
 		   "net change of %+i.\n",
 		   edge->caller->name (),
-		   inline_summary (edge->caller)->time,
-		   inline_summary (edge->caller)->size,
+		   inline_summary_d->get (edge->caller)->time,
+		   inline_summary_d->get (edge->caller)->size,
 		   overall_size - old_size);
 	}
       if (min_size > overall_size)
@@ -1992,11 +1991,11 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	  fprintf (dump_file,
 		   "\nInlining %s size %i.\n",
 		   node->name (),
-		   inline_summary (node)->size);
+		   inline_summary_d->get (node)->size);
 	  fprintf (dump_file,
 		   " Called once from %s %i insns.\n",
 		   node->callers->caller->name (),
-		   inline_summary (node->callers->caller)->size);
+		   inline_summary_d->get (node->callers->caller)->size);
 	}
 
       inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
@@ -2004,7 +2003,7 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	fprintf (dump_file,
 		 " Inlined into %s which now has %i size\n",
 		 caller->name (),
-		 inline_summary (caller)->size);
+		 inline_summary_d->get (caller)->size);
       if (!(*num_calls)--)
 	{
 	  if (dump_file)
@@ -2028,7 +2027,7 @@ dump_overall_stats (void)
     if (!node->global.inlined_to
 	&& !node->alias)
       {
-	int time = inline_summary (node)->time;
+	int time = inline_summary_d->get (node)->time;
 	sum += time;
 	sum_weighted += time * node->count;
       }
@@ -2345,7 +2344,7 @@ early_inline_small_functions (struct cgraph_node *node)
   for (e = node->callees; e; e = e->next_callee)
     {
       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-      if (!inline_summary (callee)->inlinable
+      if (!inline_summary_d->get (callee)->inlinable
 	  || !e->inline_failed)
 	continue;
 
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index 2ac6e4e..7a939f4 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -162,10 +162,28 @@ struct GTY(()) inline_summary
   int scc_no;
 };
 
-/* Need a typedef for inline_summary because of inline function
-   'inline_summary' below.  */
-typedef struct inline_summary inline_summary_t;
-extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
+class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
+{
+public:
+  inline_summary_t (symbol_table *symtab, bool ggc):
+    function_summary <inline_summary *> (symtab, ggc) {}
+
+  static inline_summary_t *create_ggc (symbol_table *symtab)
+  {
+    inline_summary_t *summary = new (ggc_cleared_alloc <inline_summary_t> ())
+      inline_summary_t(symtab, true);
+    summary->disable_insertion_hook ();
+    return summary;
+  }
+
+
+  virtual void insert (cgraph_node *, inline_summary *);
+  virtual void remove (cgraph_node *node, inline_summary *);
+  virtual void duplicate (cgraph_node *src, cgraph_node *dst,
+			  inline_summary *src_data, inline_summary *dst_data);
+};
+
+extern GTY(()) function_summary <inline_summary *> *inline_summary_d;
 
 /* Information kept about parameter of call site.  */
 struct inline_param_summary
@@ -249,12 +267,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
 extern int ncalls_inlined;
 extern int nfunctions_inlined;
 
-static inline struct inline_summary *
-inline_summary (struct cgraph_node *node)
-{
-  return &(*inline_summary_vec)[node->uid];
-}
-
 static inline struct inline_edge_summary *
 inline_edge_summary (struct cgraph_edge *edge)
 {
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 5e25fd8..387209b 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -514,7 +514,7 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Callgraph summary for ipa_node_params.  */
+/* Function summary for ipa_node_params.  */
 class ipa_node_params_t: public function_summary <ipa_node_params *>
 {
 public:
@@ -537,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Return the associated parameter/argument info corresponding to the given
    node/edge.  */
-#define IPA_NODE_REF(NODE) ((*ipa_node_params_d)[NODE])
+#define IPA_NODE_REF(NODE) (ipa_node_params_d->get (NODE))
 #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
 /* This macro checks validity of index returned by
    ipa_get_param_decl_index function.  */
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 16684e2..80c3aac 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1669,7 +1669,7 @@ execute_split_functions (void)
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
   if (inline_edge_summary_vec.exists ()
-      && !inline_summary (node)->inlinable)
+      && !inline_summary_d->get (node)->inlinable)
     {
       if (dump_file)
 	fprintf (dump_file, "Not splitting: not inlinable.\n");
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 80b8561..a873635 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -224,7 +224,7 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
                                target->order);
 	    }
 	  edge = edge->make_direct (target);
-	  if (inline_summary_vec)
+	  if (inline_summary_d)
 	    inline_update_overall_summary (node);
 	  else if (edge->call_stmt)
 	    {
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 3a2f9ed..343cd83 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -165,7 +165,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
     {
       struct cgraph_edge *e;
       if (!node->alias)
-        part->insns += inline_summary (cnode)->self_size;
+        part->insns += inline_summary_d->get (cnode)->self_size;
 
       /* Add all inline clones and callees that are duplicated.  */
       for (e = cnode->callees; e; e = e->next_callee)
@@ -274,7 +274,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
       partition->initializers_visited = NULL;
 
       if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
-        partition->insns -= inline_summary (cnode)->self_size;
+        partition->insns -= inline_summary_d->get (cnode)->self_size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->aux = (void *)((size_t)node->aux - 1);
     }
@@ -477,7 +477,7 @@ lto_balanced_map (int n_lto_partitions)
 	else
 	  order[n_nodes++] = node;
 	if (!node->alias)
-	  total_size += inline_summary (node)->size;
+	  total_size += inline_summary_d->get (node)->size;
       }
 
   /* Streaming works best when the source units do not cross partition
@@ -534,14 +534,14 @@ lto_balanced_map (int n_lto_partitions)
 	     && noreorder[noreorder_pos]->order < current_order)
 	{
 	  if (!noreorder[noreorder_pos]->alias)
-	    total_size -= inline_summary (noreorder[noreorder_pos])->size;
+	    total_size -= inline_summary_d->get (noreorder[noreorder_pos])->size;
 	  next_nodes.safe_push (noreorder[noreorder_pos++]);
 	}
       add_sorted_nodes (next_nodes, partition);
 
       add_symbol_to_partition (partition, order[i]);
       if (!order[i]->alias)
-        total_size -= inline_summary (order[i])->size;
+        total_size -= inline_summary_d->get (order[i])->size;
 	  
 
       /* Once we added a new node to the partition, we also want to add
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index e0c375d..980a97b 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -4991,7 +4991,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
     }
 
   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
-      && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
+      && inline_summary_d->get (node)->size >= MAX_INLINE_INSNS_AUTO)
     {
       if (dump_file)
 	fprintf (dump_file, "Function too big to be made truly local.\n");
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 14:13     ` Martin Liška
  2014-11-14 15:32       ` Martin Liška
@ 2014-11-14 16:07       ` Jan Hubicka
  2014-11-14 18:13         ` Martin Jambor
  2014-11-18 10:34         ` Martin Liška
  1 sibling, 2 replies; 40+ messages in thread
From: Jan Hubicka @ 2014-11-14 16:07 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jan Hubicka, gcc-patches

> >
> >In a way I would like to see these to be methods of the underlying type rather than
> >virtual methods of the summary, becuase these are operations on the data themselves.
> >I was thinking to model these by specual constructor and copy constructor
> >(taking the extra node pointer parameters) and standard destructor.  I am not sure this
> >would be more understandable this way?
> 
> Motivation for this implementation is:
> a) it's useful to have an access to cgraph_node that is associated with a sumary

Yep, one would have node addition
 ctor (symtab_node *); (or cgraph/varpool nodes for cgraph/varpool annotations)
that would default to ctor for implementations that do not care about node.
And node duplication ctor
 ctor (summary &, symtab_node *, symtab_node *)
that would default to copy constructor for data that do not need to be copied.

I would say that main advantage (in addition to have a way to provide resonable
defaults) is to make ctors/dtors of the embedded classes working well, so one can
for example embedd pointer_map and not care about its construction/destruction.

> b) with GTY, we cannot call destructor

Everything in symbol table is expecitely memory managed (i.e. enver left
to be freed by garbage collector). It resists in GTY only to allow linking
garbage collected object from them and to get PCH working.

This is however quite cosmetic issue I would preffer our C++ guys to comment on.  We can
tweak this incrementally.
> +void
> +inline_summary_t::duplicate (cgraph_node *src,
> +			     cgraph_node *dst,
> +			     inline_summary *,
> +			     inline_summary *info)

Also we should have a way to say that the annotation do not need to be duplicated (for example
when we do not want to annotate inline clones). Probably by adding duplicate_p predicate that
is called before the actual duplication happens?

The updated patch is OK, I will take a look on the main patch.

Honza
>  {
> -  struct inline_summary *info;
>    inline_summary_alloc ();
> -  info = inline_summary (dst);
> -  memcpy (info, inline_summary (src), sizeof (struct inline_summary));
> +  memcpy (info, inline_summary_d->get (src), sizeof (inline_summary));
>    /* TODO: as an optimization, we may avoid copying conditions
>       that are known to be false or true.  */
>    info->conds = vec_safe_copy (info->conds);
> @@ -1328,7 +1309,7 @@ free_growth_caches (void)
>  
>  static void
>  dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
> -			  struct inline_summary *info)
> +			  inline_summary *info)
>  {
>    struct cgraph_edge *edge;
>    for (edge = node->callees; edge; edge = edge->next_callee)
> @@ -1345,8 +1326,8 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
>  	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
>  	       indent, "", es->loop_depth, edge->frequency,
>  	       es->call_stmt_size, es->call_stmt_time,
> -	       (int) inline_summary (callee)->size / INLINE_SIZE_SCALE,
> -	       (int) inline_summary (callee)->estimated_stack_size);
> +	       (int) inline_summary_d->get (callee)->size / INLINE_SIZE_SCALE,
> +	       (int) inline_summary_d->get (callee)->estimated_stack_size);
>  
>        if (es->predicate)
>  	{
> @@ -1372,9 +1353,9 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
>  	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
>  		   " callee size %i\n",
>  		   indent + 2, "",
> -		   (int) inline_summary (callee)->stack_frame_offset,
> -		   (int) inline_summary (callee)->estimated_self_stack_size,
> -		   (int) inline_summary (callee)->estimated_stack_size);
> +		   (int) inline_summary_d->get (callee)->stack_frame_offset,
> +		   (int) inline_summary_d->get (callee)->estimated_self_stack_size,
> +		   (int) inline_summary_d->get (callee)->estimated_stack_size);
>  	  dump_inline_edge_summary (f, indent + 2, callee, info);
>  	}
>      }
> @@ -1402,7 +1383,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
>  {
>    if (node->definition)
>      {
> -      struct inline_summary *s = inline_summary (node);
> +      inline_summary *s = inline_summary_d->get (node);
>        size_time_entry *e;
>        int i;
>        fprintf (f, "Inline summary for %s/%i", node->name (),
> @@ -1725,7 +1706,7 @@ eliminated_by_inlining_prob (gimple stmt)
>  
>  static void
>  set_cond_stmt_execution_predicate (struct ipa_node_params *info,
> -				   struct inline_summary *summary,
> +				   inline_summary *summary,
>  				   basic_block bb)
>  {
>    gimple last;
> @@ -1810,7 +1791,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
>  
>  static void
>  set_switch_stmt_execution_predicate (struct ipa_node_params *info,
> -				     struct inline_summary *summary,
> +				     inline_summary *summary,
>  				     basic_block bb)
>  {
>    gimple last;
> @@ -1871,7 +1852,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
>  static void
>  compute_bb_predicates (struct cgraph_node *node,
>  		       struct ipa_node_params *parms_info,
> -		       struct inline_summary *summary)
> +		       inline_summary *summary)
>  {
>    struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
>    bool done = false;
> @@ -1950,7 +1931,7 @@ typedef struct predicate predicate_t;
>  
>  static struct predicate
>  will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
> -				    struct inline_summary *summary,
> +				    inline_summary *summary,
>  				    tree expr,
>  				    vec<predicate_t> nonconstant_names)
>  {
> @@ -2013,7 +1994,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
>  
>  static struct predicate
>  will_be_nonconstant_predicate (struct ipa_node_params *info,
> -			       struct inline_summary *summary,
> +			       inline_summary *summary,
>  			       gimple stmt,
>  			       vec<predicate_t> nonconstant_names)
>  {
> @@ -2215,7 +2196,7 @@ param_change_prob (gimple stmt, int i)
>  
>  static bool
>  phi_result_unknown_predicate (struct ipa_node_params *info,
> -			      struct inline_summary *summary, basic_block bb,
> +			      inline_summary *summary, basic_block bb,
>  			      struct predicate *p,
>  			      vec<predicate_t> nonconstant_names)
>  {
> @@ -2274,7 +2255,7 @@ phi_result_unknown_predicate (struct ipa_node_params *info,
>     NONCONSTANT_NAMES, if possible.  */
>  
>  static void
> -predicate_for_phi_result (struct inline_summary *summary, gimple phi,
> +predicate_for_phi_result (inline_summary *summary, gimple phi,
>  			  struct predicate *p,
>  			  vec<predicate_t> nonconstant_names)
>  {
> @@ -2304,7 +2285,7 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
>  /* Return predicate specifying when array index in access OP becomes non-constant.  */
>  
>  static struct predicate
> -array_index_predicate (struct inline_summary *info,
> +array_index_predicate (inline_summary *info,
>  		       vec< predicate_t> nonconstant_names, tree op)
>  {
>    struct predicate p = false_predicate ();
> @@ -2460,7 +2441,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>    gimple_stmt_iterator bsi;
>    struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
>    int freq;
> -  struct inline_summary *info = inline_summary (node);
> +  inline_summary *info = inline_summary_d->get (node);
>    struct predicate bb_predicate;
>    struct ipa_node_params *parms_info = NULL;
>    vec<predicate_t> nonconstant_names = vNULL;
> @@ -2702,7 +2683,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>  	    }
>  	}
>      }
> -  set_hint_predicate (&inline_summary (node)->array_index, array_index);
> +  set_hint_predicate (&inline_summary_d->get (node)->array_index, array_index);
>    time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
>    if (time > MAX_TIME)
>      time = MAX_TIME;
> @@ -2790,9 +2771,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>  	    }
>  	  free (body);
>  	}
> -      set_hint_predicate (&inline_summary (node)->loop_iterations,
> +      set_hint_predicate (&inline_summary_d->get (node)->loop_iterations,
>  			  loop_iterations);
> -      set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
> +      set_hint_predicate (&inline_summary_d->get (node)->loop_stride, loop_stride);
>        scev_finalize ();
>      }
>    FOR_ALL_BB_FN (bb, my_function)
> @@ -2810,8 +2791,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>  	  e->aux = NULL;
>  	}
>      }
> -  inline_summary (node)->self_time = time;
> -  inline_summary (node)->self_size = size;
> +  inline_summary_d->get (node)->self_time = time;
> +  inline_summary_d->get (node)->self_size = size;
>    nonconstant_names.release ();
>    if (optimize && !early)
>      {
> @@ -2834,14 +2815,14 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
>  {
>    HOST_WIDE_INT self_stack_size;
>    struct cgraph_edge *e;
> -  struct inline_summary *info;
> +  inline_summary *info;
>  
>    gcc_assert (!node->global.inlined_to);
>  
>    inline_summary_alloc ();
>  
> -  info = inline_summary (node);
> -  reset_inline_summary (node);
> +  info = inline_summary_d->get (node);
> +  reset_inline_summary (node, info);
>  
>    /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
>       Once this happen, we will need to more curefully predict call
> @@ -2982,7 +2963,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
>  {
>    tree target;
>    struct cgraph_node *callee;
> -  struct inline_summary *isummary;
> +  inline_summary *isummary;
>    enum availability avail;
>  
>    if (!known_vals.exists () && !known_binfos.exists ())
> @@ -3007,7 +2988,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
>    callee = callee->function_symbol (&avail);
>    if (avail < AVAIL_AVAILABLE)
>      return false;
> -  isummary = inline_summary (callee);
> +  isummary = inline_summary_d->get (callee);
>    return isummary->inlinable;
>  }
>  
> @@ -3120,7 +3101,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
>  			     vec<inline_param_summary>
>  			     inline_param_summary)
>  {
> -  struct inline_summary *info = inline_summary (node);
> +  inline_summary *info = inline_summary_d->get (node);
>    size_time_entry *e;
>    int size = 0;
>    int time = 0;
> @@ -3246,8 +3227,8 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
>     for other purposes).  */
>  
>  static struct predicate
> -remap_predicate (struct inline_summary *info,
> -		 struct inline_summary *callee_info,
> +remap_predicate (inline_summary *info,
> +		 inline_summary *callee_info,
>  		 struct predicate *p,
>  		 vec<int> operand_map,
>  		 vec<int> offset_map,
> @@ -3336,8 +3317,8 @@ static void
>  inline_update_callee_summaries (struct cgraph_node *node, int depth)
>  {
>    struct cgraph_edge *e;
> -  struct inline_summary *callee_info = inline_summary (node);
> -  struct inline_summary *caller_info = inline_summary (node->callers->caller);
> +  inline_summary *callee_info = inline_summary_d->get (node);
> +  inline_summary *caller_info = inline_summary_d->get (node->callers->caller);
>    HOST_WIDE_INT peak;
>  
>    callee_info->stack_frame_offset
> @@ -3345,8 +3326,8 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
>      + caller_info->estimated_self_stack_size;
>    peak = callee_info->stack_frame_offset
>      + callee_info->estimated_self_stack_size;
> -  if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
> -      inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
> +  if (inline_summary_d->get (node->global.inlined_to)->estimated_stack_size < peak)
> +      inline_summary_d->get (node->global.inlined_to)->estimated_stack_size = peak;
>    ipa_propagate_frequency (node);
>    for (e = node->callees; e; e = e->next_callee)
>      {
> @@ -3407,8 +3388,8 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
>  static void
>  remap_edge_summaries (struct cgraph_edge *inlined_edge,
>  		      struct cgraph_node *node,
> -		      struct inline_summary *info,
> -		      struct inline_summary *callee_info,
> +		      inline_summary *info,
> +		      inline_summary *callee_info,
>  		      vec<int> operand_map,
>  		      vec<int> offset_map,
>  		      clause_t possible_truths,
> @@ -3476,8 +3457,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
>  /* Same as remap_predicate, but set result into hint *HINT.  */
>  
>  static void
> -remap_hint_predicate (struct inline_summary *info,
> -		      struct inline_summary *callee_info,
> +remap_hint_predicate (inline_summary *info,
> +		      inline_summary *callee_info,
>  		      struct predicate **hint,
>  		      vec<int> operand_map,
>  		      vec<int> offset_map,
> @@ -3506,10 +3487,10 @@ remap_hint_predicate (struct inline_summary *info,
>  void
>  inline_merge_summary (struct cgraph_edge *edge)
>  {
> -  struct inline_summary *callee_info = inline_summary (edge->callee);
> +  inline_summary *callee_info = inline_summary_d->get (edge->callee);
>    struct cgraph_node *to = (edge->caller->global.inlined_to
>  			    ? edge->caller->global.inlined_to : edge->caller);
> -  struct inline_summary *info = inline_summary (to);
> +  inline_summary *info = inline_summary_d->get (to);
>    clause_t clause = 0;		/* not_inline is known to be false.  */
>    size_time_entry *e;
>    vec<int> operand_map = vNULL;
> @@ -3618,7 +3599,7 @@ inline_merge_summary (struct cgraph_edge *edge)
>  void
>  inline_update_overall_summary (struct cgraph_node *node)
>  {
> -  struct inline_summary *info = inline_summary (node);
> +  inline_summary *info = inline_summary_d->get (node);
>    size_time_entry *e;
>    int i;
>  
> @@ -3645,8 +3626,8 @@ simple_edge_hints (struct cgraph_edge *edge)
>    int hints = 0;
>    struct cgraph_node *to = (edge->caller->global.inlined_to
>  			    ? edge->caller->global.inlined_to : edge->caller);
> -  if (inline_summary (to)->scc_no
> -      && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
> +  if (inline_summary_d->get (to)->scc_no
> +      && inline_summary_d->get (to)->scc_no == inline_summary_d->get (edge->callee)->scc_no
>        && !edge->recursive_p ())
>      hints |= INLINE_HINT_same_scc;
>  
> @@ -3706,7 +3687,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
>    /* When caching, update the cache entry.  */
>    if (edge_growth_cache.exists ())
>      {
> -      inline_summary (edge->callee)->min_size = min_size;
> +      inline_summary_d->get (edge->callee)->min_size = min_size;
>        if ((int) edge_growth_cache.length () <= edge->uid)
>  	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
>        edge_growth_cache[edge->uid].time = time + (time >= 0);
> @@ -3808,14 +3789,14 @@ estimate_time_after_inlining (struct cgraph_node *node,
>    if (!es->predicate || !false_predicate_p (es->predicate))
>      {
>        gcov_type time =
> -	inline_summary (node)->time + estimate_edge_time (edge);
> +	inline_summary_d->get (node)->time + estimate_edge_time (edge);
>        if (time < 0)
>  	time = 0;
>        if (time > MAX_TIME)
>  	time = MAX_TIME;
>        return time;
>      }
> -  return inline_summary (node)->time;
> +  return inline_summary_d->get (node)->time;
>  }
>  
>  
> @@ -3829,11 +3810,11 @@ estimate_size_after_inlining (struct cgraph_node *node,
>    struct inline_edge_summary *es = inline_edge_summary (edge);
>    if (!es->predicate || !false_predicate_p (es->predicate))
>      {
> -      int size = inline_summary (node)->size + estimate_edge_growth (edge);
> +      int size = inline_summary_d->get (node)->size + estimate_edge_growth (edge);
>        gcc_assert (size >= 0);
>        return size;
>      }
> -  return inline_summary (node)->size;
> +  return inline_summary_d->get (node)->size;
>  }
>  
>  
> @@ -3873,7 +3854,7 @@ int
>  do_estimate_growth (struct cgraph_node *node)
>  {
>    struct growth_data d = { node, 0, false };
> -  struct inline_summary *info = inline_summary (node);
> +  inline_summary *info = inline_summary_d->get (node);
>  
>    node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
>  
> @@ -3946,7 +3927,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
>        && (!DECL_COMDAT (node->decl)
>  	  || !node->can_remove_if_no_direct_calls_p ()))
>      return true;
> -  max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
> +  max_callers = inline_summary_d->get (node)->size * 4 / edge_growth + 2;
>  
>    for (e = node->callers; e; e = e->next_caller)
>      {
> @@ -4009,13 +3990,12 @@ inline_analyze_function (struct cgraph_node *node)
>  
>  /* Called when new function is inserted to callgraph late.  */
>  
> -static void
> -add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
> +void
> +inline_summary_t::insert (cgraph_node *node, inline_summary *)
>  {
>    inline_analyze_function (node);
>  }
>  
> -
>  /* Note function body size.  */
>  
>  void
> @@ -4028,8 +4008,10 @@ inline_generate_summary (void)
>    if (!optimize && !flag_lto && !flag_wpa)
>      return;
>  
> -  function_insertion_hook_holder =
> -    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
> +  if (!inline_summary_d)
> +    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
> +
> +  inline_summary_d->enable_insertion_hook ();
>  
>    ipa_register_cgraph_hooks ();
>    inline_free_summary ();
> @@ -4113,7 +4095,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
>      {
>        unsigned int index;
>        struct cgraph_node *node;
> -      struct inline_summary *info;
> +      inline_summary *info;
>        lto_symtab_encoder_t encoder;
>        struct bitpack_d bp;
>        struct cgraph_edge *e;
> @@ -4123,7 +4105,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
>        encoder = file_data->symtab_node_encoder;
>        node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
>  								index));
> -      info = inline_summary (node);
> +      info = inline_summary_d->get (node);
>  
>        info->estimated_stack_size
>  	= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
> @@ -4212,8 +4194,9 @@ inline_read_summary (void)
>        if (!flag_ipa_cp)
>  	ipa_prop_read_jump_functions ();
>      }
> -  function_insertion_hook_holder =
> -    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
> +
> +  gcc_assert (inline_summary_d);
> +  inline_summary_d->enable_insertion_hook ();
>  }
>  
>  
> @@ -4279,7 +4262,7 @@ inline_write_summary (void)
>        cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
>        if (cnode && (node = cnode)->definition && !node->alias)
>  	{
> -	  struct inline_summary *info = inline_summary (node);
> +	  inline_summary *info = inline_summary_d->get (node);
>  	  struct bitpack_d bp;
>  	  struct cgraph_edge *edge;
>  	  int i;
> @@ -4344,23 +4327,15 @@ inline_free_summary (void)
>      return;
>    FOR_EACH_DEFINED_FUNCTION (node)
>      if (!node->alias)
> -      reset_inline_summary (node);
> -  if (function_insertion_hook_holder)
> -    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
> -  function_insertion_hook_holder = NULL;
> -  if (node_removal_hook_holder)
> -    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
> -  node_removal_hook_holder = NULL;
> +      reset_inline_summary (node, inline_summary_d->get (node));
>    if (edge_removal_hook_holder)
>      symtab->remove_edge_removal_hook (edge_removal_hook_holder);
>    edge_removal_hook_holder = NULL;
> -  if (node_duplication_hook_holder)
> -    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
> -  node_duplication_hook_holder = NULL;
>    if (edge_duplication_hook_holder)
>      symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
>    edge_duplication_hook_holder = NULL;
> -  vec_free (inline_summary_vec);
> +  inline_summary_d->destroy ();
> +  inline_summary_d = NULL;
>    inline_edge_summary_vec.release ();
>    if (edge_predicate_pool)
>      free_alloc_pool (edge_predicate_pool);
> diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
> index 49c2679..841af60 100644
> --- a/gcc/ipa-inline-transform.c
> +++ b/gcc/ipa-inline-transform.c
> @@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
>  	  if (e->callee->definition && !DECL_EXTERNAL (e->callee->decl))
>  	    {
>  	      if (overall_size)
> -	        *overall_size -= inline_summary (e->callee)->size;
> +	        *overall_size -= inline_summary_d->get (e->callee)->size;
>  	      nfunctions_inlined++;
>  	    }
>  	  duplicate = false;
> @@ -309,13 +309,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
>  
>    gcc_assert (curr->callee->global.inlined_to == to);
>  
> -  old_size = inline_summary (to)->size;
> +  old_size = inline_summary_d->get (to)->size;
>    inline_merge_summary (e);
>    if (optimize)
>      new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
>    if (update_overall_summary)
>     inline_update_overall_summary (to);
> -  new_size = inline_summary (to)->size;
> +  new_size = inline_summary_d->get (to)->size;
>  
>    if (callee->calls_comdat_local)
>      to->calls_comdat_local = true;
> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
> index a8e94e2..73fb286 100644
> --- a/gcc/ipa-inline.c
> +++ b/gcc/ipa-inline.c
> @@ -167,7 +167,7 @@ caller_growth_limits (struct cgraph_edge *e)
>    int newsize;
>    int limit = 0;
>    HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
> -  struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
> +  inline_summary *info, *what_info, *outer_info = inline_summary_d->get (to);
>  
>    /* Look for function e->caller is inlined to.  While doing
>       so work out the largest function body on the way.  As
> @@ -179,7 +179,7 @@ caller_growth_limits (struct cgraph_edge *e)
>       too much in order to prevent compiler from exploding".  */
>    while (true)
>      {
> -      info = inline_summary (to);
> +      info = inline_summary_d->get (to);
>        if (limit < info->self_size)
>  	limit = info->self_size;
>        if (stack_size_limit < info->estimated_self_stack_size)
> @@ -190,7 +190,7 @@ caller_growth_limits (struct cgraph_edge *e)
>  	break;
>      }
>  
> -  what_info = inline_summary (what);
> +  what_info = inline_summary_d->get (what);
>  
>    if (limit < what_info->self_size)
>      limit = what_info->self_size;
> @@ -304,7 +304,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
>        e->inline_failed = CIF_USES_COMDAT_LOCAL;
>        inlinable = false;
>      }
> -  else if (!inline_summary (callee)->inlinable 
> +  else if (!inline_summary_d->get (callee)->inlinable 
>  	   || (caller_fun && fn_contains_cilk_spawn_p (caller_fun)))
>      {
>        e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
> @@ -458,7 +458,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
>  
>    if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
>      ;
> -  /* For AutoFDO, we need to make sure that before profile annotation, all
> +  /* For AutoFDO, we need to make sure that before profile summary, all
>       hot paths' IR look exactly the same as profiled binary. As a result,
>       in einliner, we will disregard size limit and inline those callsites
>       that are:
> @@ -524,13 +524,12 @@ want_early_inline_function_p (struct cgraph_edge *e)
>     does not happen.  */
>  
>  inline gcov_type
> -compute_uninlined_call_time (struct inline_summary *callee_info,
> -			     struct cgraph_edge *edge)
> +compute_uninlined_call_time (inline_summary *callee_info, cgraph_edge *edge)
>  {
>    gcov_type uninlined_call_time =
>      RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
>  	  CGRAPH_FREQ_BASE);
> -  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
> +  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
>  				          ? edge->caller->global.inlined_to
>  				          : edge->caller)->time;
>    return uninlined_call_time + caller_time;
> @@ -543,7 +542,7 @@ inline gcov_type
>  compute_inlined_call_time (struct cgraph_edge *edge,
>  			   int edge_time)
>  {
> -  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
> +  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
>  					  ? edge->caller->global.inlined_to
>  					  : edge->caller)->time;
>    gcov_type time = (caller_time
> @@ -563,7 +562,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
>  static bool
>  big_speedup_p (struct cgraph_edge *e)
>  {
> -  gcov_type time = compute_uninlined_call_time (inline_summary (e->callee),
> +  gcov_type time = compute_uninlined_call_time (inline_summary_d->get (e->callee),
>  					  	e);
>    gcov_type inlined_time = compute_inlined_call_time (e,
>  					              estimate_edge_time (e));
> @@ -596,7 +595,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
>       MAX_INLINE_INSNS_SINGLE 16-fold for inline functions.  */
>    else if ((!DECL_DECLARED_INLINE_P (callee->decl)
>  	   && (!e->count || !e->maybe_hot_p ()))
> -	   && inline_summary (callee)->min_size
> +	   && inline_summary_d->get (callee)->min_size
>  		- inline_edge_summary (e)->call_stmt_size
>  	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
>      {
> @@ -604,7 +603,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
>        want_inline = false;
>      }
>    else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
> -	   && inline_summary (callee)->min_size
> +	   && inline_summary_d->get (callee)->min_size
>  		- inline_edge_summary (e)->call_stmt_size
>  	      > 16 * MAX_INLINE_INSNS_SINGLE)
>      {
> @@ -867,8 +866,8 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
>     1...RELATIVE_TIME_BENEFIT_RANGE  */
>  
>  static inline int
> -relative_time_benefit (struct inline_summary *callee_info,
> -		       struct cgraph_edge *edge,
> +relative_time_benefit (inline_summary *callee_info,
> +		       cgraph_edge *edge,
>  		       int edge_time)
>  {
>    gcov_type relbenefit;
> @@ -913,7 +912,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
>    gcov_type badness;
>    int growth, edge_time;
>    struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
> -  struct inline_summary *callee_info = inline_summary (callee);
> +  inline_summary *callee_info = inline_summary_d->get (callee);
>    inline_hints hints;
>  
>    if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
> @@ -1188,7 +1187,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
>    struct cgraph_edge *edge;
>    struct ipa_ref *ref;
>  
> -  if ((!node->alias && !inline_summary (node)->inlinable)
> +  if ((!node->alias && !inline_summary_d->get (node)->inlinable)
>        || node->global.inlined_to)
>      return;
>    if (!bitmap_set_bit (updated_nodes, node->uid))
> @@ -1246,7 +1245,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
>             don't need updating.  */
>  	if (e->inline_failed
>  	    && (callee = e->callee->ultimate_alias_target (&avail))
> -	    && inline_summary (callee)->inlinable
> +	    && inline_summary_d->get (callee)->inlinable
>  	    && avail >= AVAIL_AVAILABLE
>  	    && !bitmap_bit_p (updated_nodes, callee->uid))
>  	  {
> @@ -1424,8 +1423,8 @@ recursive_inlining (struct cgraph_edge *edge,
>      fprintf (dump_file,
>  	     "\n   Inlined %i times, "
>  	     "body grown from size %i to %i, time %i to %i\n", n,
> -	     inline_summary (master_clone)->size, inline_summary (node)->size,
> -	     inline_summary (master_clone)->time, inline_summary (node)->time);
> +	     inline_summary_d->get (master_clone)->size, inline_summary_d->get (node)->size,
> +	     inline_summary_d->get (master_clone)->time, inline_summary_d->get (node)->time);
>  
>    /* Remove master clone we used for inlining.  We rely that clones inlined
>       into master clone gets queued just before master clone so we don't
> @@ -1599,8 +1598,8 @@ inline_small_functions (void)
>  	if (node->has_gimple_body_p ()
>  	    || node->thunk.thunk_p)
>  	  {
> -	    struct inline_summary *info = inline_summary (node);
> -	    struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
> +	    inline_summary *info = inline_summary_d->get (node);
> +	    ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
>  
>  	    /* Do not account external functions, they will be optimized out
>  	       if not inlined.  Also only count the non-cold portion of program.  */
> @@ -1610,12 +1609,12 @@ inline_small_functions (void)
>  	    info->growth = estimate_growth (node);
>  	    if (dfs && dfs->next_cycle)
>  	      {
> -		struct cgraph_node *n2;
> +		cgraph_node *n2;
>  		int id = dfs->scc_no + 1;
>  		for (n2 = node; n2;
>  		     n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
>  		  {
> -		    struct inline_summary *info2 = inline_summary (n2);
> +		    inline_summary *info2 = inline_summary_d->get (n2);
>  		    if (info2->scc_no)
>  		      break;
>  		    info2->scc_no = id;
> @@ -1735,7 +1734,7 @@ inline_small_functions (void)
>  	  fprintf (dump_file,
>  		   "\nConsidering %s/%i with %i size\n",
>  		   callee->name (), callee->order,
> -		   inline_summary (callee)->size);
> +		   inline_summary_d->get (callee)->size);
>  	  fprintf (dump_file,
>  		   " to be inlined into %s/%i in %s:%i\n"
>  		   " Estimated badness is %i, frequency %.2f.\n",
> @@ -1853,8 +1852,8 @@ inline_small_functions (void)
>  		   " Inlined into %s which now has time %i and size %i,"
>  		   "net change of %+i.\n",
>  		   edge->caller->name (),
> -		   inline_summary (edge->caller)->time,
> -		   inline_summary (edge->caller)->size,
> +		   inline_summary_d->get (edge->caller)->time,
> +		   inline_summary_d->get (edge->caller)->size,
>  		   overall_size - old_size);
>  	}
>        if (min_size > overall_size)
> @@ -1992,11 +1991,11 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
>  	  fprintf (dump_file,
>  		   "\nInlining %s size %i.\n",
>  		   node->name (),
> -		   inline_summary (node)->size);
> +		   inline_summary_d->get (node)->size);
>  	  fprintf (dump_file,
>  		   " Called once from %s %i insns.\n",
>  		   node->callers->caller->name (),
> -		   inline_summary (node->callers->caller)->size);
> +		   inline_summary_d->get (node->callers->caller)->size);
>  	}
>  
>        inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
> @@ -2004,7 +2003,7 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
>  	fprintf (dump_file,
>  		 " Inlined into %s which now has %i size\n",
>  		 caller->name (),
> -		 inline_summary (caller)->size);
> +		 inline_summary_d->get (caller)->size);
>        if (!(*num_calls)--)
>  	{
>  	  if (dump_file)
> @@ -2028,7 +2027,7 @@ dump_overall_stats (void)
>      if (!node->global.inlined_to
>  	&& !node->alias)
>        {
> -	int time = inline_summary (node)->time;
> +	int time = inline_summary_d->get (node)->time;
>  	sum += time;
>  	sum_weighted += time * node->count;
>        }
> @@ -2345,7 +2344,7 @@ early_inline_small_functions (struct cgraph_node *node)
>    for (e = node->callees; e; e = e->next_callee)
>      {
>        struct cgraph_node *callee = e->callee->ultimate_alias_target ();
> -      if (!inline_summary (callee)->inlinable
> +      if (!inline_summary_d->get (callee)->inlinable
>  	  || !e->inline_failed)
>  	continue;
>  
> diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
> index 2ac6e4e..7a939f4 100644
> --- a/gcc/ipa-inline.h
> +++ b/gcc/ipa-inline.h
> @@ -162,10 +162,28 @@ struct GTY(()) inline_summary
>    int scc_no;
>  };
>  
> -/* Need a typedef for inline_summary because of inline function
> -   'inline_summary' below.  */
> -typedef struct inline_summary inline_summary_t;
> -extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
> +class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
> +{
> +public:
> +  inline_summary_t (symbol_table *symtab, bool ggc):
> +    function_summary <inline_summary *> (symtab, ggc) {}
> +
> +  static inline_summary_t *create_ggc (symbol_table *symtab)
> +  {
> +    inline_summary_t *summary = new (ggc_cleared_alloc <inline_summary_t> ())
> +      inline_summary_t(symtab, true);
> +    summary->disable_insertion_hook ();
> +    return summary;
> +  }
> +
> +
> +  virtual void insert (cgraph_node *, inline_summary *);
> +  virtual void remove (cgraph_node *node, inline_summary *);
> +  virtual void duplicate (cgraph_node *src, cgraph_node *dst,
> +			  inline_summary *src_data, inline_summary *dst_data);
> +};
> +
> +extern GTY(()) function_summary <inline_summary *> *inline_summary_d;
>  
>  /* Information kept about parameter of call site.  */
>  struct inline_param_summary
> @@ -249,12 +267,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
>  extern int ncalls_inlined;
>  extern int nfunctions_inlined;
>  
> -static inline struct inline_summary *
> -inline_summary (struct cgraph_node *node)
> -{
> -  return &(*inline_summary_vec)[node->uid];
> -}
> -
>  static inline struct inline_edge_summary *
>  inline_edge_summary (struct cgraph_edge *edge)
>  {
> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
> index 5e25fd8..387209b 100644
> --- a/gcc/ipa-prop.h
> +++ b/gcc/ipa-prop.h
> @@ -514,7 +514,7 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
>    return &(*args->polymorphic_call_contexts)[i];
>  }
>  
> -/* Callgraph summary for ipa_node_params.  */
> +/* Function summary for ipa_node_params.  */
>  class ipa_node_params_t: public function_summary <ipa_node_params *>
>  {
>  public:
> @@ -537,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>  
>  /* Return the associated parameter/argument info corresponding to the given
>     node/edge.  */
> -#define IPA_NODE_REF(NODE) ((*ipa_node_params_d)[NODE])
> +#define IPA_NODE_REF(NODE) (ipa_node_params_d->get (NODE))
>  #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
>  /* This macro checks validity of index returned by
>     ipa_get_param_decl_index function.  */
> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
> index 16684e2..80c3aac 100644
> --- a/gcc/ipa-split.c
> +++ b/gcc/ipa-split.c
> @@ -1669,7 +1669,7 @@ execute_split_functions (void)
>    /* This can be relaxed; function might become inlinable after splitting
>       away the uninlinable part.  */
>    if (inline_edge_summary_vec.exists ()
> -      && !inline_summary (node)->inlinable)
> +      && !inline_summary_d->get (node)->inlinable)
>      {
>        if (dump_file)
>  	fprintf (dump_file, "Not splitting: not inlinable.\n");
> diff --git a/gcc/ipa.c b/gcc/ipa.c
> index 80b8561..a873635 100644
> --- a/gcc/ipa.c
> +++ b/gcc/ipa.c
> @@ -224,7 +224,7 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
>                                 target->order);
>  	    }
>  	  edge = edge->make_direct (target);
> -	  if (inline_summary_vec)
> +	  if (inline_summary_d)
>  	    inline_update_overall_summary (node);
>  	  else if (edge->call_stmt)
>  	    {
> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
> index 3a2f9ed..343cd83 100644
> --- a/gcc/lto/lto-partition.c
> +++ b/gcc/lto/lto-partition.c
> @@ -165,7 +165,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
>      {
>        struct cgraph_edge *e;
>        if (!node->alias)
> -        part->insns += inline_summary (cnode)->self_size;
> +        part->insns += inline_summary_d->get (cnode)->self_size;
>  
>        /* Add all inline clones and callees that are duplicated.  */
>        for (e = cnode->callees; e; e = e->next_callee)
> @@ -274,7 +274,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
>        partition->initializers_visited = NULL;
>  
>        if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
> -        partition->insns -= inline_summary (cnode)->self_size;
> +        partition->insns -= inline_summary_d->get (cnode)->self_size;
>        lto_symtab_encoder_delete_node (partition->encoder, node);
>        node->aux = (void *)((size_t)node->aux - 1);
>      }
> @@ -477,7 +477,7 @@ lto_balanced_map (int n_lto_partitions)
>  	else
>  	  order[n_nodes++] = node;
>  	if (!node->alias)
> -	  total_size += inline_summary (node)->size;
> +	  total_size += inline_summary_d->get (node)->size;
>        }
>  
>    /* Streaming works best when the source units do not cross partition
> @@ -534,14 +534,14 @@ lto_balanced_map (int n_lto_partitions)
>  	     && noreorder[noreorder_pos]->order < current_order)
>  	{
>  	  if (!noreorder[noreorder_pos]->alias)
> -	    total_size -= inline_summary (noreorder[noreorder_pos])->size;
> +	    total_size -= inline_summary_d->get (noreorder[noreorder_pos])->size;
>  	  next_nodes.safe_push (noreorder[noreorder_pos++]);
>  	}
>        add_sorted_nodes (next_nodes, partition);
>  
>        add_symbol_to_partition (partition, order[i]);
>        if (!order[i]->alias)
> -        total_size -= inline_summary (order[i])->size;
> +        total_size -= inline_summary_d->get (order[i])->size;
>  	  
>  
>        /* Once we added a new node to the partition, we also want to add
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index e0c375d..980a97b 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -4991,7 +4991,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
>      }
>  
>    if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
> -      && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
> +      && inline_summary_d->get (node)->size >= MAX_INLINE_INSNS_AUTO)
>      {
>        if (dump_file)
>  	fprintf (dump_file, "Function too big to be made truly local.\n");
> -- 
> 2.1.2
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass.
  2014-11-14 15:31     ` Martin Liška
@ 2014-11-14 17:10       ` Martin Jambor
  2014-12-08 17:02       ` Martin Liška
  1 sibling, 0 replies; 40+ messages in thread
From: Martin Jambor @ 2014-11-14 17:10 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

Hi,

On Fri, Nov 14, 2014 at 04:23:41PM +0100, Martin Liska wrote:
> Patch v3.
> 
> Martin

> From 7255ffaf7bb416037baa14499b197bac3be8c222 Mon Sep 17 00:00:00 2001
> From: mliska <mliska@suse.cz>
> Date: Fri, 14 Nov 2014 16:14:28 +0100
> Subject: [PATCH 2/3] First usage of cgraph_summary in ipa-prop pass.
> 
> gcc/ChangeLog:
> 
> 2014-11-12  Martin Liska  <mliska@suse.cz>
> 
> 	* ipa-prop.c (struct func_body_info): Struct keyword is removed.
> 	(struct ipa_cst_ref_desc): Likewise.
> 	(ipa_func_spec_opts_forbid_analysis_p): Likewise.
> 	(ipa_alloc_node_params): Likewise.
> 	(ipa_initialize_node_params): Likewise.
> 	(ipa_print_node_jump_functions_for_edge): Likewise.
> 	(ipa_print_node_jump_functions): Likewise.
> 	(ipa_print_all_jump_functions): Likewise.
> 	(ipa_set_jf_constant): Likewise.
> 	(check_stmt_for_type_change): Likewise.
> 	(detect_type_change_from_memory_writes): Likewise.
> 	(find_dominating_aa_status): Likewise.
> 	(parm_bb_aa_status_for_bb): Likewise.
> 	(parm_preserved_before_stmt_p): Likewise.
> 	(parm_ref_data_preserved_p): Likewise.
> 	(parm_ref_data_pass_through_p): Likewise.
> 	(struct ipa_known_agg_contents_list): Likewise.
> 	(get_place_in_agg_contents_list): Likewise.
> 	(build_agg_jump_func_from_list): Likewise.
> 	(determine_locally_known_aggregate_parts): Likewise.
> 	(ipa_compute_jump_functions_for_edge): Likewise.
> 	(ipa_compute_jump_functions_for_bb): Likewise.
> 	(ipa_note_param_call): Likewise.
> 	(ipa_analyze_indirect_call_uses) Likewise.:
> 	(ipa_analyze_virtual_call_uses): Likewise.
> 	(ipa_analyze_call_uses): Likewise.
> 	(visit_ref_for_mod_analysis): Likewise.
> 	(ipa_analyze_controlled_uses): Likewise.
> 	(ipa_analyze_node): Likewise.
> 	(update_jump_functions_after_inlining): Likewise.
> 	(ipa_make_edge_direct_to_target): Likewise.
> 	(ipa_find_agg_cst_for_param): Likewise.
> 	(remove_described_reference): Likewise.
> 	(jfunc_rdesc_usable): Likewise.
> 	(try_decrement_rdesc_refcount): Likewise.
> 	(try_make_edge_direct_simple_call): Likewise.
> 	(try_make_edge_direct_virtual_call): Likewise.
> 	(update_indirect_edges_after_inlining): Likewise.
> 	(propagate_info_to_inlined_callees): Likewise.
> 	(propagate_controlled_uses): Likewise.
> 	(ipa_propagate_indirect_call_infos): Likewise.
> 	(ipa_free_all_edge_args): Likewise.
> 	(ipa_node_params::~ipa_node_params): Likewise.
> 	(ipa_free_all_node_params): Likewise.
> 	(ipa_edge_removal_hook): Likewise.
> 	(ipa_node_removal_hook): Likewise.
> 	(ipa_edge_duplication_hook): Likewise.
> 	(ipa_add_new_function): Removed
> 	(ipa_node_params_t::duplicate): New function.
> 	(ipa_node_duplication_hook): Struct keyword removed.
> 	(ipa_register_cgraph_hooks): Removal of old hooks.
> 	(ipa_unregister_cgraph_hooks): Likewise.
> 	(ipa_print_node_params): Struct keyword is removed.
> 	(ipa_print_all_params): Likewise.
> 	(ipa_modify_formal_parameters): Likewise.
> 	(ipa_modify_call_arguments): Likewise.
> 	(ipa_modify_expr): Likewise.
> 	(ipa_get_adjustment_candidate): Likewise.
> 	(index_in_adjustments_multiple_times_p): Likewise.
> 	(ipa_combine_adjustments): Likewise.
> 	(ipa_dump_param_adjustments): Likewise.
> 	(ipa_write_jump_function): Likewise.
> 	(ipa_read_jump_function): Likewise.
> 	(ipa_write_indirect_edge_info): Likewise.
> 	(ipa_read_indirect_edge_info): Likewise.
> 	(ipa_write_node_info): Likewise.
> 	(ipa_read_node_info): Likewise.
> 	(ipa_prop_write_jump_functions): Likewise.
> 	(ipa_prop_read_section): Likewise.
> 	(ipa_prop_read_jump_functions): Likewise.
> 	(write_agg_replacement_chain): Likewise.
> 	(read_agg_replacement_chain): Likewise.
> 	(ipa_prop_write_all_agg_replacement): Likewise.
> 	(read_replacements_section): Likewise.
> 	(ipa_prop_read_all_agg_replacement): Likewise.
> 	(adjust_agg_replacement_values): Likewise.
> 	(ipcp_modif_dom_walker::before_dom_children): Likewise.
> 	(ipcp_transform_function): Likewise.

If you don't have to, please don't.  If you make a change somewhere
for some particular reason, by all means remove all struct keywords on
that line or in its vicinity, that is what I try to do as well.  But
this will just make it much more difficult to revive some older
patches of mine for no good reason. It also makes looking up and
reviewing the functional changes in this patch very slow and
demanding.

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 16:07       ` Jan Hubicka
@ 2014-11-14 18:13         ` Martin Jambor
  2014-11-14 20:12           ` Jan Hubicka
  2014-11-18 10:34         ` Martin Liška
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Jambor @ 2014-11-14 18:13 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Martin Liška, gcc-patches

On Fri, Nov 14, 2014 at 05:06:44PM +0100, Jan Hubicka wrote:
> > >
> > >In a way I would like to see these to be methods of the underlying type rather than
> > >virtual methods of the summary, becuase these are operations on the data themselves.
> > >I was thinking to model these by specual constructor and copy constructor
> > >(taking the extra node pointer parameters) and standard destructor.  I am not sure this
> > >would be more understandable this way?
> > 
> > Motivation for this implementation is:
> > a) it's useful to have an access to cgraph_node that is associated with a sumary
> 
> Yep, one would have node addition
>  ctor (symtab_node *); (or cgraph/varpool nodes for cgraph/varpool annotations)
> that would default to ctor for implementations that do not care about node.
> And node duplication ctor
>  ctor (summary &, symtab_node *, symtab_node *)
> that would default to copy constructor for data that do not need to be copied.
> 
> I would say that main advantage (in addition to have a way to provide resonable
> defaults) is to make ctors/dtors of the embedded classes working well, so one can
> for example embedd pointer_map and not care about its construction/destruction.

It was actually me who suggested virtual methods instead of
constructors.  My idea was to make the summaries very light-weight and
usable even for simple types.  For example, during IPA-CP propagation
phase, I use an (edge) summary that is basically only a pointer to
cgraph_edge.  I'd even prefer that the default duplication hook would
just do an assignment or a memcpy.

> 
> > b) with GTY, we cannot call destructor
> 
> Everything in symbol table is expecitely memory managed (i.e. enver left
> to be freed by garbage collector). It resists in GTY only to allow linking
> garbage collected object from them and to get PCH working.
> 

Well, if I understand the intent correctly, summaries are for stuff
that is not in the symbol table.  For example jump functions are a
vector of structures possibly containing trees, so everything has to
be in garbage collected memory.

When an edge is removed, it is necessary to be notified about it
immediately, for example to decrement rdesc_refcount (you might argue
that that should be done in a separate hook and not from within a
summary class but then you start to rely on hook invocation ordering
so I think it is better to eventually use the summaries for it too).

Thanks,

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 18:13         ` Martin Jambor
@ 2014-11-14 20:12           ` Jan Hubicka
  2014-11-18 12:56             ` Martin Jambor
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2014-11-14 20:12 UTC (permalink / raw)
  To: Jan Hubicka, Martin Liška, gcc-patches

> > I would say that main advantage (in addition to have a way to provide resonable
> > defaults) is to make ctors/dtors of the embedded classes working well, so one can
> > for example embedd pointer_map and not care about its construction/destruction.
> 
> It was actually me who suggested virtual methods instead of
> constructors.  My idea was to make the summaries very light-weight and
> usable even for simple types.  For example, during IPA-CP propagation
> phase, I use an (edge) summary that is basically only a pointer to
> cgraph_edge.  I'd even prefer that the default duplication hook would
> just do an assignment or a memcpy.

Yep, I would hope there is a vairant that makes simple types easy but still
allows to put non-PODs into the summaries (or is that possible with current code?)

Perhaps we can have a base class that provides default implementation of the
insertion/duplication ctor via the default ctor/copy ctor?  That would still
require to wrap your pointer in a trivial class, but you would not need to write
any methods.

The container is template anyway, so one would not need virtual methods for
the maintainance?

> 
> > 
> > > b) with GTY, we cannot call destructor
> > 
> > Everything in symbol table is expecitely memory managed (i.e. enver left
> > to be freed by garbage collector). It resists in GTY only to allow linking
> > garbage collected object from them and to get PCH working.
> > 
> 
> Well, if I understand the intent correctly, summaries are for stuff
> that is not in the symbol table.  For example jump functions are a
Correct.
> vector of structures possibly containing trees, so everything has to
> be in garbage collected memory.
> 
> When an edge is removed, it is necessary to be notified about it
> immediately, for example to decrement rdesc_refcount (you might argue
> that that should be done in a separate hook and not from within a
> summary class but then you start to rely on hook invocation ordering
> so I think it is better to eventually use the summaries for it too).

I do not see why ctors/dtors can not do the reference counting. In fact
this is how refcounting is done usually anyway?

Well, I will read the actual implementation and of our C++ guys are fine
with the current form, I think we can give it a try. Refining the "hooks"
part of the API incrementally should be easy.

Honza
> 
> Thanks,
> 
> Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 16:07       ` Jan Hubicka
  2014-11-14 18:13         ` Martin Jambor
@ 2014-11-18 10:34         ` Martin Liška
  1 sibling, 0 replies; 40+ messages in thread
From: Martin Liška @ 2014-11-18 10:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: hubick >> Jan Hubicka

On 11/14/2014 05:06 PM, Jan Hubicka wrote:
>>>
>>> In a way I would like to see these to be methods of the underlying type rather than
>>> virtual methods of the summary, becuase these are operations on the data themselves.
>>> I was thinking to model these by specual constructor and copy constructor
>>> (taking the extra node pointer parameters) and standard destructor.  I am not sure this
>>> would be more understandable this way?
>>
>> Motivation for this implementation is:
>> a) it's useful to have an access to cgraph_node that is associated with a sumary
>
> Yep, one would have node addition
>   ctor (symtab_node *); (or cgraph/varpool nodes for cgraph/varpool annotations)
> that would default to ctor for implementations that do not care about node.
> And node duplication ctor
>   ctor (summary &, symtab_node *, symtab_node *)
> that would default to copy constructor for data that do not need to be copied.

Hello.

I have no problem with such construction and destruction, we can also provide
base implementation.

> I would say that main advantage (in addition to have a way to provide resonable
> defaults) is to make ctors/dtors of the embedded classes working well, so one can
> for example embedd pointer_map and not care about its construction/destruction.
>
>> b) with GTY, we cannot call destructor
>
> Everything in symbol table is expecitely memory managed (i.e. enver left
> to be freed by garbage collector). It resists in GTY only to allow linking
> garbage collected object from them and to get PCH working.

However GTY types need to be allocated by ggc_alloc and one can't call dtor.
This was main motivation for providing hooks instead of ctor/dtor API.
Maybe I miss something?

Thanks,
Martin

>
> This is however quite cosmetic issue I would preffer our C++ guys to comment on.  We can
> tweak this incrementally.
>> +void
>> +inline_summary_t::duplicate (cgraph_node *src,
>> +			     cgraph_node *dst,
>> +			     inline_summary *,
>> +			     inline_summary *info)
>
> Also we should have a way to say that the annotation do not need to be duplicated (for example
> when we do not want to annotate inline clones). Probably by adding duplicate_p predicate that
> is called before the actual duplication happens?
>
> The updated patch is OK, I will take a look on the main patch.
>
> Honza
>>   {
>> -  struct inline_summary *info;
>>     inline_summary_alloc ();
>> -  info = inline_summary (dst);
>> -  memcpy (info, inline_summary (src), sizeof (struct inline_summary));
>> +  memcpy (info, inline_summary_d->get (src), sizeof (inline_summary));
>>     /* TODO: as an optimization, we may avoid copying conditions
>>        that are known to be false or true.  */
>>     info->conds = vec_safe_copy (info->conds);
>> @@ -1328,7 +1309,7 @@ free_growth_caches (void)
>>
>>   static void
>>   dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
>> -			  struct inline_summary *info)
>> +			  inline_summary *info)
>>   {
>>     struct cgraph_edge *edge;
>>     for (edge = node->callees; edge; edge = edge->next_callee)
>> @@ -1345,8 +1326,8 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
>>   	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
>>   	       indent, "", es->loop_depth, edge->frequency,
>>   	       es->call_stmt_size, es->call_stmt_time,
>> -	       (int) inline_summary (callee)->size / INLINE_SIZE_SCALE,
>> -	       (int) inline_summary (callee)->estimated_stack_size);
>> +	       (int) inline_summary_d->get (callee)->size / INLINE_SIZE_SCALE,
>> +	       (int) inline_summary_d->get (callee)->estimated_stack_size);
>>
>>         if (es->predicate)
>>   	{
>> @@ -1372,9 +1353,9 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
>>   	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
>>   		   " callee size %i\n",
>>   		   indent + 2, "",
>> -		   (int) inline_summary (callee)->stack_frame_offset,
>> -		   (int) inline_summary (callee)->estimated_self_stack_size,
>> -		   (int) inline_summary (callee)->estimated_stack_size);
>> +		   (int) inline_summary_d->get (callee)->stack_frame_offset,
>> +		   (int) inline_summary_d->get (callee)->estimated_self_stack_size,
>> +		   (int) inline_summary_d->get (callee)->estimated_stack_size);
>>   	  dump_inline_edge_summary (f, indent + 2, callee, info);
>>   	}
>>       }
>> @@ -1402,7 +1383,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
>>   {
>>     if (node->definition)
>>       {
>> -      struct inline_summary *s = inline_summary (node);
>> +      inline_summary *s = inline_summary_d->get (node);
>>         size_time_entry *e;
>>         int i;
>>         fprintf (f, "Inline summary for %s/%i", node->name (),
>> @@ -1725,7 +1706,7 @@ eliminated_by_inlining_prob (gimple stmt)
>>
>>   static void
>>   set_cond_stmt_execution_predicate (struct ipa_node_params *info,
>> -				   struct inline_summary *summary,
>> +				   inline_summary *summary,
>>   				   basic_block bb)
>>   {
>>     gimple last;
>> @@ -1810,7 +1791,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
>>
>>   static void
>>   set_switch_stmt_execution_predicate (struct ipa_node_params *info,
>> -				     struct inline_summary *summary,
>> +				     inline_summary *summary,
>>   				     basic_block bb)
>>   {
>>     gimple last;
>> @@ -1871,7 +1852,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
>>   static void
>>   compute_bb_predicates (struct cgraph_node *node,
>>   		       struct ipa_node_params *parms_info,
>> -		       struct inline_summary *summary)
>> +		       inline_summary *summary)
>>   {
>>     struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
>>     bool done = false;
>> @@ -1950,7 +1931,7 @@ typedef struct predicate predicate_t;
>>
>>   static struct predicate
>>   will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
>> -				    struct inline_summary *summary,
>> +				    inline_summary *summary,
>>   				    tree expr,
>>   				    vec<predicate_t> nonconstant_names)
>>   {
>> @@ -2013,7 +1994,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
>>
>>   static struct predicate
>>   will_be_nonconstant_predicate (struct ipa_node_params *info,
>> -			       struct inline_summary *summary,
>> +			       inline_summary *summary,
>>   			       gimple stmt,
>>   			       vec<predicate_t> nonconstant_names)
>>   {
>> @@ -2215,7 +2196,7 @@ param_change_prob (gimple stmt, int i)
>>
>>   static bool
>>   phi_result_unknown_predicate (struct ipa_node_params *info,
>> -			      struct inline_summary *summary, basic_block bb,
>> +			      inline_summary *summary, basic_block bb,
>>   			      struct predicate *p,
>>   			      vec<predicate_t> nonconstant_names)
>>   {
>> @@ -2274,7 +2255,7 @@ phi_result_unknown_predicate (struct ipa_node_params *info,
>>      NONCONSTANT_NAMES, if possible.  */
>>
>>   static void
>> -predicate_for_phi_result (struct inline_summary *summary, gimple phi,
>> +predicate_for_phi_result (inline_summary *summary, gimple phi,
>>   			  struct predicate *p,
>>   			  vec<predicate_t> nonconstant_names)
>>   {
>> @@ -2304,7 +2285,7 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
>>   /* Return predicate specifying when array index in access OP becomes non-constant.  */
>>
>>   static struct predicate
>> -array_index_predicate (struct inline_summary *info,
>> +array_index_predicate (inline_summary *info,
>>   		       vec< predicate_t> nonconstant_names, tree op)
>>   {
>>     struct predicate p = false_predicate ();
>> @@ -2460,7 +2441,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>     gimple_stmt_iterator bsi;
>>     struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
>>     int freq;
>> -  struct inline_summary *info = inline_summary (node);
>> +  inline_summary *info = inline_summary_d->get (node);
>>     struct predicate bb_predicate;
>>     struct ipa_node_params *parms_info = NULL;
>>     vec<predicate_t> nonconstant_names = vNULL;
>> @@ -2702,7 +2683,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>   	    }
>>   	}
>>       }
>> -  set_hint_predicate (&inline_summary (node)->array_index, array_index);
>> +  set_hint_predicate (&inline_summary_d->get (node)->array_index, array_index);
>>     time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
>>     if (time > MAX_TIME)
>>       time = MAX_TIME;
>> @@ -2790,9 +2771,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>   	    }
>>   	  free (body);
>>   	}
>> -      set_hint_predicate (&inline_summary (node)->loop_iterations,
>> +      set_hint_predicate (&inline_summary_d->get (node)->loop_iterations,
>>   			  loop_iterations);
>> -      set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
>> +      set_hint_predicate (&inline_summary_d->get (node)->loop_stride, loop_stride);
>>         scev_finalize ();
>>       }
>>     FOR_ALL_BB_FN (bb, my_function)
>> @@ -2810,8 +2791,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>   	  e->aux = NULL;
>>   	}
>>       }
>> -  inline_summary (node)->self_time = time;
>> -  inline_summary (node)->self_size = size;
>> +  inline_summary_d->get (node)->self_time = time;
>> +  inline_summary_d->get (node)->self_size = size;
>>     nonconstant_names.release ();
>>     if (optimize && !early)
>>       {
>> @@ -2834,14 +2815,14 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
>>   {
>>     HOST_WIDE_INT self_stack_size;
>>     struct cgraph_edge *e;
>> -  struct inline_summary *info;
>> +  inline_summary *info;
>>
>>     gcc_assert (!node->global.inlined_to);
>>
>>     inline_summary_alloc ();
>>
>> -  info = inline_summary (node);
>> -  reset_inline_summary (node);
>> +  info = inline_summary_d->get (node);
>> +  reset_inline_summary (node, info);
>>
>>     /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
>>        Once this happen, we will need to more curefully predict call
>> @@ -2982,7 +2963,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
>>   {
>>     tree target;
>>     struct cgraph_node *callee;
>> -  struct inline_summary *isummary;
>> +  inline_summary *isummary;
>>     enum availability avail;
>>
>>     if (!known_vals.exists () && !known_binfos.exists ())
>> @@ -3007,7 +2988,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
>>     callee = callee->function_symbol (&avail);
>>     if (avail < AVAIL_AVAILABLE)
>>       return false;
>> -  isummary = inline_summary (callee);
>> +  isummary = inline_summary_d->get (callee);
>>     return isummary->inlinable;
>>   }
>>
>> @@ -3120,7 +3101,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
>>   			     vec<inline_param_summary>
>>   			     inline_param_summary)
>>   {
>> -  struct inline_summary *info = inline_summary (node);
>> +  inline_summary *info = inline_summary_d->get (node);
>>     size_time_entry *e;
>>     int size = 0;
>>     int time = 0;
>> @@ -3246,8 +3227,8 @@ estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
>>      for other purposes).  */
>>
>>   static struct predicate
>> -remap_predicate (struct inline_summary *info,
>> -		 struct inline_summary *callee_info,
>> +remap_predicate (inline_summary *info,
>> +		 inline_summary *callee_info,
>>   		 struct predicate *p,
>>   		 vec<int> operand_map,
>>   		 vec<int> offset_map,
>> @@ -3336,8 +3317,8 @@ static void
>>   inline_update_callee_summaries (struct cgraph_node *node, int depth)
>>   {
>>     struct cgraph_edge *e;
>> -  struct inline_summary *callee_info = inline_summary (node);
>> -  struct inline_summary *caller_info = inline_summary (node->callers->caller);
>> +  inline_summary *callee_info = inline_summary_d->get (node);
>> +  inline_summary *caller_info = inline_summary_d->get (node->callers->caller);
>>     HOST_WIDE_INT peak;
>>
>>     callee_info->stack_frame_offset
>> @@ -3345,8 +3326,8 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
>>       + caller_info->estimated_self_stack_size;
>>     peak = callee_info->stack_frame_offset
>>       + callee_info->estimated_self_stack_size;
>> -  if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
>> -      inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
>> +  if (inline_summary_d->get (node->global.inlined_to)->estimated_stack_size < peak)
>> +      inline_summary_d->get (node->global.inlined_to)->estimated_stack_size = peak;
>>     ipa_propagate_frequency (node);
>>     for (e = node->callees; e; e = e->next_callee)
>>       {
>> @@ -3407,8 +3388,8 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
>>   static void
>>   remap_edge_summaries (struct cgraph_edge *inlined_edge,
>>   		      struct cgraph_node *node,
>> -		      struct inline_summary *info,
>> -		      struct inline_summary *callee_info,
>> +		      inline_summary *info,
>> +		      inline_summary *callee_info,
>>   		      vec<int> operand_map,
>>   		      vec<int> offset_map,
>>   		      clause_t possible_truths,
>> @@ -3476,8 +3457,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
>>   /* Same as remap_predicate, but set result into hint *HINT.  */
>>
>>   static void
>> -remap_hint_predicate (struct inline_summary *info,
>> -		      struct inline_summary *callee_info,
>> +remap_hint_predicate (inline_summary *info,
>> +		      inline_summary *callee_info,
>>   		      struct predicate **hint,
>>   		      vec<int> operand_map,
>>   		      vec<int> offset_map,
>> @@ -3506,10 +3487,10 @@ remap_hint_predicate (struct inline_summary *info,
>>   void
>>   inline_merge_summary (struct cgraph_edge *edge)
>>   {
>> -  struct inline_summary *callee_info = inline_summary (edge->callee);
>> +  inline_summary *callee_info = inline_summary_d->get (edge->callee);
>>     struct cgraph_node *to = (edge->caller->global.inlined_to
>>   			    ? edge->caller->global.inlined_to : edge->caller);
>> -  struct inline_summary *info = inline_summary (to);
>> +  inline_summary *info = inline_summary_d->get (to);
>>     clause_t clause = 0;		/* not_inline is known to be false.  */
>>     size_time_entry *e;
>>     vec<int> operand_map = vNULL;
>> @@ -3618,7 +3599,7 @@ inline_merge_summary (struct cgraph_edge *edge)
>>   void
>>   inline_update_overall_summary (struct cgraph_node *node)
>>   {
>> -  struct inline_summary *info = inline_summary (node);
>> +  inline_summary *info = inline_summary_d->get (node);
>>     size_time_entry *e;
>>     int i;
>>
>> @@ -3645,8 +3626,8 @@ simple_edge_hints (struct cgraph_edge *edge)
>>     int hints = 0;
>>     struct cgraph_node *to = (edge->caller->global.inlined_to
>>   			    ? edge->caller->global.inlined_to : edge->caller);
>> -  if (inline_summary (to)->scc_no
>> -      && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
>> +  if (inline_summary_d->get (to)->scc_no
>> +      && inline_summary_d->get (to)->scc_no == inline_summary_d->get (edge->callee)->scc_no
>>         && !edge->recursive_p ())
>>       hints |= INLINE_HINT_same_scc;
>>
>> @@ -3706,7 +3687,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
>>     /* When caching, update the cache entry.  */
>>     if (edge_growth_cache.exists ())
>>       {
>> -      inline_summary (edge->callee)->min_size = min_size;
>> +      inline_summary_d->get (edge->callee)->min_size = min_size;
>>         if ((int) edge_growth_cache.length () <= edge->uid)
>>   	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
>>         edge_growth_cache[edge->uid].time = time + (time >= 0);
>> @@ -3808,14 +3789,14 @@ estimate_time_after_inlining (struct cgraph_node *node,
>>     if (!es->predicate || !false_predicate_p (es->predicate))
>>       {
>>         gcov_type time =
>> -	inline_summary (node)->time + estimate_edge_time (edge);
>> +	inline_summary_d->get (node)->time + estimate_edge_time (edge);
>>         if (time < 0)
>>   	time = 0;
>>         if (time > MAX_TIME)
>>   	time = MAX_TIME;
>>         return time;
>>       }
>> -  return inline_summary (node)->time;
>> +  return inline_summary_d->get (node)->time;
>>   }
>>
>>
>> @@ -3829,11 +3810,11 @@ estimate_size_after_inlining (struct cgraph_node *node,
>>     struct inline_edge_summary *es = inline_edge_summary (edge);
>>     if (!es->predicate || !false_predicate_p (es->predicate))
>>       {
>> -      int size = inline_summary (node)->size + estimate_edge_growth (edge);
>> +      int size = inline_summary_d->get (node)->size + estimate_edge_growth (edge);
>>         gcc_assert (size >= 0);
>>         return size;
>>       }
>> -  return inline_summary (node)->size;
>> +  return inline_summary_d->get (node)->size;
>>   }
>>
>>
>> @@ -3873,7 +3854,7 @@ int
>>   do_estimate_growth (struct cgraph_node *node)
>>   {
>>     struct growth_data d = { node, 0, false };
>> -  struct inline_summary *info = inline_summary (node);
>> +  inline_summary *info = inline_summary_d->get (node);
>>
>>     node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
>>
>> @@ -3946,7 +3927,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
>>         && (!DECL_COMDAT (node->decl)
>>   	  || !node->can_remove_if_no_direct_calls_p ()))
>>       return true;
>> -  max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
>> +  max_callers = inline_summary_d->get (node)->size * 4 / edge_growth + 2;
>>
>>     for (e = node->callers; e; e = e->next_caller)
>>       {
>> @@ -4009,13 +3990,12 @@ inline_analyze_function (struct cgraph_node *node)
>>
>>   /* Called when new function is inserted to callgraph late.  */
>>
>> -static void
>> -add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>> +void
>> +inline_summary_t::insert (cgraph_node *node, inline_summary *)
>>   {
>>     inline_analyze_function (node);
>>   }
>>
>> -
>>   /* Note function body size.  */
>>
>>   void
>> @@ -4028,8 +4008,10 @@ inline_generate_summary (void)
>>     if (!optimize && !flag_lto && !flag_wpa)
>>       return;
>>
>> -  function_insertion_hook_holder =
>> -    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
>> +  if (!inline_summary_d)
>> +    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
>> +
>> +  inline_summary_d->enable_insertion_hook ();
>>
>>     ipa_register_cgraph_hooks ();
>>     inline_free_summary ();
>> @@ -4113,7 +4095,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
>>       {
>>         unsigned int index;
>>         struct cgraph_node *node;
>> -      struct inline_summary *info;
>> +      inline_summary *info;
>>         lto_symtab_encoder_t encoder;
>>         struct bitpack_d bp;
>>         struct cgraph_edge *e;
>> @@ -4123,7 +4105,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
>>         encoder = file_data->symtab_node_encoder;
>>         node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
>>   								index));
>> -      info = inline_summary (node);
>> +      info = inline_summary_d->get (node);
>>
>>         info->estimated_stack_size
>>   	= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
>> @@ -4212,8 +4194,9 @@ inline_read_summary (void)
>>         if (!flag_ipa_cp)
>>   	ipa_prop_read_jump_functions ();
>>       }
>> -  function_insertion_hook_holder =
>> -    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
>> +
>> +  gcc_assert (inline_summary_d);
>> +  inline_summary_d->enable_insertion_hook ();
>>   }
>>
>>
>> @@ -4279,7 +4262,7 @@ inline_write_summary (void)
>>         cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
>>         if (cnode && (node = cnode)->definition && !node->alias)
>>   	{
>> -	  struct inline_summary *info = inline_summary (node);
>> +	  inline_summary *info = inline_summary_d->get (node);
>>   	  struct bitpack_d bp;
>>   	  struct cgraph_edge *edge;
>>   	  int i;
>> @@ -4344,23 +4327,15 @@ inline_free_summary (void)
>>       return;
>>     FOR_EACH_DEFINED_FUNCTION (node)
>>       if (!node->alias)
>> -      reset_inline_summary (node);
>> -  if (function_insertion_hook_holder)
>> -    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
>> -  function_insertion_hook_holder = NULL;
>> -  if (node_removal_hook_holder)
>> -    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
>> -  node_removal_hook_holder = NULL;
>> +      reset_inline_summary (node, inline_summary_d->get (node));
>>     if (edge_removal_hook_holder)
>>       symtab->remove_edge_removal_hook (edge_removal_hook_holder);
>>     edge_removal_hook_holder = NULL;
>> -  if (node_duplication_hook_holder)
>> -    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
>> -  node_duplication_hook_holder = NULL;
>>     if (edge_duplication_hook_holder)
>>       symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
>>     edge_duplication_hook_holder = NULL;
>> -  vec_free (inline_summary_vec);
>> +  inline_summary_d->destroy ();
>> +  inline_summary_d = NULL;
>>     inline_edge_summary_vec.release ();
>>     if (edge_predicate_pool)
>>       free_alloc_pool (edge_predicate_pool);
>> diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
>> index 49c2679..841af60 100644
>> --- a/gcc/ipa-inline-transform.c
>> +++ b/gcc/ipa-inline-transform.c
>> @@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
>>   	  if (e->callee->definition && !DECL_EXTERNAL (e->callee->decl))
>>   	    {
>>   	      if (overall_size)
>> -	        *overall_size -= inline_summary (e->callee)->size;
>> +	        *overall_size -= inline_summary_d->get (e->callee)->size;
>>   	      nfunctions_inlined++;
>>   	    }
>>   	  duplicate = false;
>> @@ -309,13 +309,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
>>
>>     gcc_assert (curr->callee->global.inlined_to == to);
>>
>> -  old_size = inline_summary (to)->size;
>> +  old_size = inline_summary_d->get (to)->size;
>>     inline_merge_summary (e);
>>     if (optimize)
>>       new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
>>     if (update_overall_summary)
>>      inline_update_overall_summary (to);
>> -  new_size = inline_summary (to)->size;
>> +  new_size = inline_summary_d->get (to)->size;
>>
>>     if (callee->calls_comdat_local)
>>       to->calls_comdat_local = true;
>> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
>> index a8e94e2..73fb286 100644
>> --- a/gcc/ipa-inline.c
>> +++ b/gcc/ipa-inline.c
>> @@ -167,7 +167,7 @@ caller_growth_limits (struct cgraph_edge *e)
>>     int newsize;
>>     int limit = 0;
>>     HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
>> -  struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
>> +  inline_summary *info, *what_info, *outer_info = inline_summary_d->get (to);
>>
>>     /* Look for function e->caller is inlined to.  While doing
>>        so work out the largest function body on the way.  As
>> @@ -179,7 +179,7 @@ caller_growth_limits (struct cgraph_edge *e)
>>        too much in order to prevent compiler from exploding".  */
>>     while (true)
>>       {
>> -      info = inline_summary (to);
>> +      info = inline_summary_d->get (to);
>>         if (limit < info->self_size)
>>   	limit = info->self_size;
>>         if (stack_size_limit < info->estimated_self_stack_size)
>> @@ -190,7 +190,7 @@ caller_growth_limits (struct cgraph_edge *e)
>>   	break;
>>       }
>>
>> -  what_info = inline_summary (what);
>> +  what_info = inline_summary_d->get (what);
>>
>>     if (limit < what_info->self_size)
>>       limit = what_info->self_size;
>> @@ -304,7 +304,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
>>         e->inline_failed = CIF_USES_COMDAT_LOCAL;
>>         inlinable = false;
>>       }
>> -  else if (!inline_summary (callee)->inlinable
>> +  else if (!inline_summary_d->get (callee)->inlinable
>>   	   || (caller_fun && fn_contains_cilk_spawn_p (caller_fun)))
>>       {
>>         e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
>> @@ -458,7 +458,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
>>
>>     if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
>>       ;
>> -  /* For AutoFDO, we need to make sure that before profile annotation, all
>> +  /* For AutoFDO, we need to make sure that before profile summary, all
>>        hot paths' IR look exactly the same as profiled binary. As a result,
>>        in einliner, we will disregard size limit and inline those callsites
>>        that are:
>> @@ -524,13 +524,12 @@ want_early_inline_function_p (struct cgraph_edge *e)
>>      does not happen.  */
>>
>>   inline gcov_type
>> -compute_uninlined_call_time (struct inline_summary *callee_info,
>> -			     struct cgraph_edge *edge)
>> +compute_uninlined_call_time (inline_summary *callee_info, cgraph_edge *edge)
>>   {
>>     gcov_type uninlined_call_time =
>>       RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
>>   	  CGRAPH_FREQ_BASE);
>> -  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
>> +  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
>>   				          ? edge->caller->global.inlined_to
>>   				          : edge->caller)->time;
>>     return uninlined_call_time + caller_time;
>> @@ -543,7 +542,7 @@ inline gcov_type
>>   compute_inlined_call_time (struct cgraph_edge *edge,
>>   			   int edge_time)
>>   {
>> -  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
>> +  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
>>   					  ? edge->caller->global.inlined_to
>>   					  : edge->caller)->time;
>>     gcov_type time = (caller_time
>> @@ -563,7 +562,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
>>   static bool
>>   big_speedup_p (struct cgraph_edge *e)
>>   {
>> -  gcov_type time = compute_uninlined_call_time (inline_summary (e->callee),
>> +  gcov_type time = compute_uninlined_call_time (inline_summary_d->get (e->callee),
>>   					  	e);
>>     gcov_type inlined_time = compute_inlined_call_time (e,
>>   					              estimate_edge_time (e));
>> @@ -596,7 +595,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
>>        MAX_INLINE_INSNS_SINGLE 16-fold for inline functions.  */
>>     else if ((!DECL_DECLARED_INLINE_P (callee->decl)
>>   	   && (!e->count || !e->maybe_hot_p ()))
>> -	   && inline_summary (callee)->min_size
>> +	   && inline_summary_d->get (callee)->min_size
>>   		- inline_edge_summary (e)->call_stmt_size
>>   	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
>>       {
>> @@ -604,7 +603,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
>>         want_inline = false;
>>       }
>>     else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
>> -	   && inline_summary (callee)->min_size
>> +	   && inline_summary_d->get (callee)->min_size
>>   		- inline_edge_summary (e)->call_stmt_size
>>   	      > 16 * MAX_INLINE_INSNS_SINGLE)
>>       {
>> @@ -867,8 +866,8 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
>>      1...RELATIVE_TIME_BENEFIT_RANGE  */
>>
>>   static inline int
>> -relative_time_benefit (struct inline_summary *callee_info,
>> -		       struct cgraph_edge *edge,
>> +relative_time_benefit (inline_summary *callee_info,
>> +		       cgraph_edge *edge,
>>   		       int edge_time)
>>   {
>>     gcov_type relbenefit;
>> @@ -913,7 +912,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
>>     gcov_type badness;
>>     int growth, edge_time;
>>     struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
>> -  struct inline_summary *callee_info = inline_summary (callee);
>> +  inline_summary *callee_info = inline_summary_d->get (callee);
>>     inline_hints hints;
>>
>>     if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
>> @@ -1188,7 +1187,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
>>     struct cgraph_edge *edge;
>>     struct ipa_ref *ref;
>>
>> -  if ((!node->alias && !inline_summary (node)->inlinable)
>> +  if ((!node->alias && !inline_summary_d->get (node)->inlinable)
>>         || node->global.inlined_to)
>>       return;
>>     if (!bitmap_set_bit (updated_nodes, node->uid))
>> @@ -1246,7 +1245,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
>>              don't need updating.  */
>>   	if (e->inline_failed
>>   	    && (callee = e->callee->ultimate_alias_target (&avail))
>> -	    && inline_summary (callee)->inlinable
>> +	    && inline_summary_d->get (callee)->inlinable
>>   	    && avail >= AVAIL_AVAILABLE
>>   	    && !bitmap_bit_p (updated_nodes, callee->uid))
>>   	  {
>> @@ -1424,8 +1423,8 @@ recursive_inlining (struct cgraph_edge *edge,
>>       fprintf (dump_file,
>>   	     "\n   Inlined %i times, "
>>   	     "body grown from size %i to %i, time %i to %i\n", n,
>> -	     inline_summary (master_clone)->size, inline_summary (node)->size,
>> -	     inline_summary (master_clone)->time, inline_summary (node)->time);
>> +	     inline_summary_d->get (master_clone)->size, inline_summary_d->get (node)->size,
>> +	     inline_summary_d->get (master_clone)->time, inline_summary_d->get (node)->time);
>>
>>     /* Remove master clone we used for inlining.  We rely that clones inlined
>>        into master clone gets queued just before master clone so we don't
>> @@ -1599,8 +1598,8 @@ inline_small_functions (void)
>>   	if (node->has_gimple_body_p ()
>>   	    || node->thunk.thunk_p)
>>   	  {
>> -	    struct inline_summary *info = inline_summary (node);
>> -	    struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
>> +	    inline_summary *info = inline_summary_d->get (node);
>> +	    ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
>>
>>   	    /* Do not account external functions, they will be optimized out
>>   	       if not inlined.  Also only count the non-cold portion of program.  */
>> @@ -1610,12 +1609,12 @@ inline_small_functions (void)
>>   	    info->growth = estimate_growth (node);
>>   	    if (dfs && dfs->next_cycle)
>>   	      {
>> -		struct cgraph_node *n2;
>> +		cgraph_node *n2;
>>   		int id = dfs->scc_no + 1;
>>   		for (n2 = node; n2;
>>   		     n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
>>   		  {
>> -		    struct inline_summary *info2 = inline_summary (n2);
>> +		    inline_summary *info2 = inline_summary_d->get (n2);
>>   		    if (info2->scc_no)
>>   		      break;
>>   		    info2->scc_no = id;
>> @@ -1735,7 +1734,7 @@ inline_small_functions (void)
>>   	  fprintf (dump_file,
>>   		   "\nConsidering %s/%i with %i size\n",
>>   		   callee->name (), callee->order,
>> -		   inline_summary (callee)->size);
>> +		   inline_summary_d->get (callee)->size);
>>   	  fprintf (dump_file,
>>   		   " to be inlined into %s/%i in %s:%i\n"
>>   		   " Estimated badness is %i, frequency %.2f.\n",
>> @@ -1853,8 +1852,8 @@ inline_small_functions (void)
>>   		   " Inlined into %s which now has time %i and size %i,"
>>   		   "net change of %+i.\n",
>>   		   edge->caller->name (),
>> -		   inline_summary (edge->caller)->time,
>> -		   inline_summary (edge->caller)->size,
>> +		   inline_summary_d->get (edge->caller)->time,
>> +		   inline_summary_d->get (edge->caller)->size,
>>   		   overall_size - old_size);
>>   	}
>>         if (min_size > overall_size)
>> @@ -1992,11 +1991,11 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
>>   	  fprintf (dump_file,
>>   		   "\nInlining %s size %i.\n",
>>   		   node->name (),
>> -		   inline_summary (node)->size);
>> +		   inline_summary_d->get (node)->size);
>>   	  fprintf (dump_file,
>>   		   " Called once from %s %i insns.\n",
>>   		   node->callers->caller->name (),
>> -		   inline_summary (node->callers->caller)->size);
>> +		   inline_summary_d->get (node->callers->caller)->size);
>>   	}
>>
>>         inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
>> @@ -2004,7 +2003,7 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
>>   	fprintf (dump_file,
>>   		 " Inlined into %s which now has %i size\n",
>>   		 caller->name (),
>> -		 inline_summary (caller)->size);
>> +		 inline_summary_d->get (caller)->size);
>>         if (!(*num_calls)--)
>>   	{
>>   	  if (dump_file)
>> @@ -2028,7 +2027,7 @@ dump_overall_stats (void)
>>       if (!node->global.inlined_to
>>   	&& !node->alias)
>>         {
>> -	int time = inline_summary (node)->time;
>> +	int time = inline_summary_d->get (node)->time;
>>   	sum += time;
>>   	sum_weighted += time * node->count;
>>         }
>> @@ -2345,7 +2344,7 @@ early_inline_small_functions (struct cgraph_node *node)
>>     for (e = node->callees; e; e = e->next_callee)
>>       {
>>         struct cgraph_node *callee = e->callee->ultimate_alias_target ();
>> -      if (!inline_summary (callee)->inlinable
>> +      if (!inline_summary_d->get (callee)->inlinable
>>   	  || !e->inline_failed)
>>   	continue;
>>
>> diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
>> index 2ac6e4e..7a939f4 100644
>> --- a/gcc/ipa-inline.h
>> +++ b/gcc/ipa-inline.h
>> @@ -162,10 +162,28 @@ struct GTY(()) inline_summary
>>     int scc_no;
>>   };
>>
>> -/* Need a typedef for inline_summary because of inline function
>> -   'inline_summary' below.  */
>> -typedef struct inline_summary inline_summary_t;
>> -extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
>> +class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
>> +{
>> +public:
>> +  inline_summary_t (symbol_table *symtab, bool ggc):
>> +    function_summary <inline_summary *> (symtab, ggc) {}
>> +
>> +  static inline_summary_t *create_ggc (symbol_table *symtab)
>> +  {
>> +    inline_summary_t *summary = new (ggc_cleared_alloc <inline_summary_t> ())
>> +      inline_summary_t(symtab, true);
>> +    summary->disable_insertion_hook ();
>> +    return summary;
>> +  }
>> +
>> +
>> +  virtual void insert (cgraph_node *, inline_summary *);
>> +  virtual void remove (cgraph_node *node, inline_summary *);
>> +  virtual void duplicate (cgraph_node *src, cgraph_node *dst,
>> +			  inline_summary *src_data, inline_summary *dst_data);
>> +};
>> +
>> +extern GTY(()) function_summary <inline_summary *> *inline_summary_d;
>>
>>   /* Information kept about parameter of call site.  */
>>   struct inline_param_summary
>> @@ -249,12 +267,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
>>   extern int ncalls_inlined;
>>   extern int nfunctions_inlined;
>>
>> -static inline struct inline_summary *
>> -inline_summary (struct cgraph_node *node)
>> -{
>> -  return &(*inline_summary_vec)[node->uid];
>> -}
>> -
>>   static inline struct inline_edge_summary *
>>   inline_edge_summary (struct cgraph_edge *edge)
>>   {
>> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
>> index 5e25fd8..387209b 100644
>> --- a/gcc/ipa-prop.h
>> +++ b/gcc/ipa-prop.h
>> @@ -514,7 +514,7 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
>>     return &(*args->polymorphic_call_contexts)[i];
>>   }
>>
>> -/* Callgraph summary for ipa_node_params.  */
>> +/* Function summary for ipa_node_params.  */
>>   class ipa_node_params_t: public function_summary <ipa_node_params *>
>>   {
>>   public:
>> @@ -537,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>
>>   /* Return the associated parameter/argument info corresponding to the given
>>      node/edge.  */
>> -#define IPA_NODE_REF(NODE) ((*ipa_node_params_d)[NODE])
>> +#define IPA_NODE_REF(NODE) (ipa_node_params_d->get (NODE))
>>   #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
>>   /* This macro checks validity of index returned by
>>      ipa_get_param_decl_index function.  */
>> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
>> index 16684e2..80c3aac 100644
>> --- a/gcc/ipa-split.c
>> +++ b/gcc/ipa-split.c
>> @@ -1669,7 +1669,7 @@ execute_split_functions (void)
>>     /* This can be relaxed; function might become inlinable after splitting
>>        away the uninlinable part.  */
>>     if (inline_edge_summary_vec.exists ()
>> -      && !inline_summary (node)->inlinable)
>> +      && !inline_summary_d->get (node)->inlinable)
>>       {
>>         if (dump_file)
>>   	fprintf (dump_file, "Not splitting: not inlinable.\n");
>> diff --git a/gcc/ipa.c b/gcc/ipa.c
>> index 80b8561..a873635 100644
>> --- a/gcc/ipa.c
>> +++ b/gcc/ipa.c
>> @@ -224,7 +224,7 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
>>                                  target->order);
>>   	    }
>>   	  edge = edge->make_direct (target);
>> -	  if (inline_summary_vec)
>> +	  if (inline_summary_d)
>>   	    inline_update_overall_summary (node);
>>   	  else if (edge->call_stmt)
>>   	    {
>> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
>> index 3a2f9ed..343cd83 100644
>> --- a/gcc/lto/lto-partition.c
>> +++ b/gcc/lto/lto-partition.c
>> @@ -165,7 +165,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
>>       {
>>         struct cgraph_edge *e;
>>         if (!node->alias)
>> -        part->insns += inline_summary (cnode)->self_size;
>> +        part->insns += inline_summary_d->get (cnode)->self_size;
>>
>>         /* Add all inline clones and callees that are duplicated.  */
>>         for (e = cnode->callees; e; e = e->next_callee)
>> @@ -274,7 +274,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
>>         partition->initializers_visited = NULL;
>>
>>         if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
>> -        partition->insns -= inline_summary (cnode)->self_size;
>> +        partition->insns -= inline_summary_d->get (cnode)->self_size;
>>         lto_symtab_encoder_delete_node (partition->encoder, node);
>>         node->aux = (void *)((size_t)node->aux - 1);
>>       }
>> @@ -477,7 +477,7 @@ lto_balanced_map (int n_lto_partitions)
>>   	else
>>   	  order[n_nodes++] = node;
>>   	if (!node->alias)
>> -	  total_size += inline_summary (node)->size;
>> +	  total_size += inline_summary_d->get (node)->size;
>>         }
>>
>>     /* Streaming works best when the source units do not cross partition
>> @@ -534,14 +534,14 @@ lto_balanced_map (int n_lto_partitions)
>>   	     && noreorder[noreorder_pos]->order < current_order)
>>   	{
>>   	  if (!noreorder[noreorder_pos]->alias)
>> -	    total_size -= inline_summary (noreorder[noreorder_pos])->size;
>> +	    total_size -= inline_summary_d->get (noreorder[noreorder_pos])->size;
>>   	  next_nodes.safe_push (noreorder[noreorder_pos++]);
>>   	}
>>         add_sorted_nodes (next_nodes, partition);
>>
>>         add_symbol_to_partition (partition, order[i]);
>>         if (!order[i]->alias)
>> -        total_size -= inline_summary (order[i])->size;
>> +        total_size -= inline_summary_d->get (order[i])->size;
>>   	
>>
>>         /* Once we added a new node to the partition, we also want to add
>> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
>> index e0c375d..980a97b 100644
>> --- a/gcc/tree-sra.c
>> +++ b/gcc/tree-sra.c
>> @@ -4991,7 +4991,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
>>       }
>>
>>     if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
>> -      && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
>> +      && inline_summary_d->get (node)->size >= MAX_INLINE_INSNS_AUTO)
>>       {
>>         if (dump_file)
>>   	fprintf (dump_file, "Function too big to be made truly local.\n");
>> --
>> 2.1.2
>>
>
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 20:12           ` Jan Hubicka
@ 2014-11-18 12:56             ` Martin Jambor
  2014-11-18 15:59               ` Jan Hubicka
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Jambor @ 2014-11-18 12:56 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Martin Liška, gcc-patches

On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
> > > 
> > > > b) with GTY, we cannot call destructor
> > > 
> > > Everything in symbol table is expecitely memory managed (i.e. enver left
> > > to be freed by garbage collector). It resists in GTY only to allow linking
> > > garbage collected object from them and to get PCH working.
> > > 
> > 
> > Well, if I understand the intent correctly, summaries are for stuff
> > that is not in the symbol table.  For example jump functions are a
> Correct.
> > vector of structures possibly containing trees, so everything has to
> > be in garbage collected memory.
> > 
> > When an edge is removed, it is necessary to be notified about it
> > immediately, for example to decrement rdesc_refcount (you might argue
> > that that should be done in a separate hook and not from within a
> > summary class but then you start to rely on hook invocation ordering
> > so I think it is better to eventually use the summaries for it too).
> 
> I do not see why ctors/dtors can not do the reference counting. In fact
> this is how refcounting is done usually anyway?
> 

Well, when there is no garbage collection involved then yes, that is
how you normally do it but in the GC case, there is the question of
what is the appropriate time to call destructor on garbage collected
data (like jump functions)?

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-18 12:56             ` Martin Jambor
@ 2014-11-18 15:59               ` Jan Hubicka
  2014-11-18 18:40                 ` Martin Jambor
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2014-11-18 15:59 UTC (permalink / raw)
  To: Jan Hubicka, Martin Liška, gcc-patches

> On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
> > > > 
> > > > > b) with GTY, we cannot call destructor
> > > > 
> > > > Everything in symbol table is expecitely memory managed (i.e. enver left
> > > > to be freed by garbage collector). It resists in GTY only to allow linking
> > > > garbage collected object from them and to get PCH working.
> > > > 
> > > 
> > > Well, if I understand the intent correctly, summaries are for stuff
> > > that is not in the symbol table.  For example jump functions are a
> > Correct.
> > > vector of structures possibly containing trees, so everything has to
> > > be in garbage collected memory.
> > > 
> > > When an edge is removed, it is necessary to be notified about it
> > > immediately, for example to decrement rdesc_refcount (you might argue
> > > that that should be done in a separate hook and not from within a
> > > summary class but then you start to rely on hook invocation ordering
> > > so I think it is better to eventually use the summaries for it too).
> > 
> > I do not see why ctors/dtors can not do the reference counting. In fact
> > this is how refcounting is done usually anyway?
> > 
> 
> Well, when there is no garbage collection involved then yes, that is
> how you normally do it but in the GC case, there is the question of
> what is the appropriate time to call destructor on garbage collected
> data (like jump functions)?

I still fail to see problem here.  Summaries are explicitly managed- they are
constructed at summary construction time or when new callgarph node is
introduced/duplicated.  They are destroyed when callgarph node is destroyed or
whole summary is ddestroyed.  It is job of the summary datastructure to call
proper ctors/dtors, not job of garbage collector that provides the underlying
memory management.

If you have datastructure that points to something that is not explicitly
managed (i.e. tree expression), you just can not have non-trivial constructor
on that datastructure, because that is freed transparently by gty that don't do
destruction...

Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-18 15:59               ` Jan Hubicka
@ 2014-11-18 18:40                 ` Martin Jambor
  2014-11-18 19:19                   ` Jan Hubicka
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Jambor @ 2014-11-18 18:40 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Martin Liška, gcc-patches

Hi,

On Tue, Nov 18, 2014 at 04:39:00PM +0100, Jan Hubicka wrote:
> > On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
> > > > > 
> > > > > > b) with GTY, we cannot call destructor
> > > > > 
> > > > > Everything in symbol table is expecitely memory managed (i.e. enver left
> > > > > to be freed by garbage collector). It resists in GTY only to allow linking
> > > > > garbage collected object from them and to get PCH working.
> > > > > 
> > > > 
> > > > Well, if I understand the intent correctly, summaries are for stuff
> > > > that is not in the symbol table.  For example jump functions are a
> > > Correct.
> > > > vector of structures possibly containing trees, so everything has to
> > > > be in garbage collected memory.
> > > > 
> > > > When an edge is removed, it is necessary to be notified about it
> > > > immediately, for example to decrement rdesc_refcount (you might argue
> > > > that that should be done in a separate hook and not from within a
> > > > summary class but then you start to rely on hook invocation ordering
> > > > so I think it is better to eventually use the summaries for it too).
> > > 
> > > I do not see why ctors/dtors can not do the reference counting. In fact
> > > this is how refcounting is done usually anyway?
> > > 
> > 
> > Well, when there is no garbage collection involved then yes, that is
> > how you normally do it but in the GC case, there is the question of
> > what is the appropriate time to call destructor on garbage collected
> > data (like jump functions)?
> 
> I still fail to see problem here.  Summaries are explicitly managed- they are
> constructed at summary construction time or when new callgarph node is
> introduced/duplicated.  They are destroyed when callgarph node is destroyed or
> whole summary is ddestroyed.  It is job of the summary datastructure to call
> proper ctors/dtors, not job of garbage collector that provides the underlying
> memory management.

I do not think that all summaries (in the meaning of a description of
one particular symbol table node or call graph edge) are explicitely
managed.  For example ipa_edge_args or ipa_agg_replacement_value
(which my alignment patch changes to ipcp_transformation_summary) are
allocated in GC memory because they contain trees.

> 
> If you have datastructure that points to something that is not
> explicitly managed (i.e. tree expression), you just can not have
> non-trivial constructor on that datastructure, because that is freed
> transparently by gty that don't do destruction...

I admit to not being particularly bright today but that seems to be
exactly my point.

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-18 18:40                 ` Martin Jambor
@ 2014-11-18 19:19                   ` Jan Hubicka
  2014-11-18 22:32                     ` Martin Jambor
  2014-11-19  1:50                     ` Trevor Saunders
  0 siblings, 2 replies; 40+ messages in thread
From: Jan Hubicka @ 2014-11-18 19:19 UTC (permalink / raw)
  To: Jan Hubicka, Martin Liška, gcc-patches

> Hi,
> 
> On Tue, Nov 18, 2014 at 04:39:00PM +0100, Jan Hubicka wrote:
> > > On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
> > > > > > 
> > > > > > > b) with GTY, we cannot call destructor
> > > > > > 
> > > > > > Everything in symbol table is expecitely memory managed (i.e. enver left
> > > > > > to be freed by garbage collector). It resists in GTY only to allow linking
> > > > > > garbage collected object from them and to get PCH working.
> > > > > > 
> > > > > 
> > > > > Well, if I understand the intent correctly, summaries are for stuff
> > > > > that is not in the symbol table.  For example jump functions are a
> > > > Correct.
> > > > > vector of structures possibly containing trees, so everything has to
> > > > > be in garbage collected memory.
> > > > > 
> > > > > When an edge is removed, it is necessary to be notified about it
> > > > > immediately, for example to decrement rdesc_refcount (you might argue
> > > > > that that should be done in a separate hook and not from within a
> > > > > summary class but then you start to rely on hook invocation ordering
> > > > > so I think it is better to eventually use the summaries for it too).
> > > > 
> > > > I do not see why ctors/dtors can not do the reference counting. In fact
> > > > this is how refcounting is done usually anyway?
> > > > 
> > > 
> > > Well, when there is no garbage collection involved then yes, that is
> > > how you normally do it but in the GC case, there is the question of
> > > what is the appropriate time to call destructor on garbage collected
> > > data (like jump functions)?
> > 
> > I still fail to see problem here.  Summaries are explicitly managed- they are
> > constructed at summary construction time or when new callgarph node is
> > introduced/duplicated.  They are destroyed when callgarph node is destroyed or
> > whole summary is ddestroyed.  It is job of the summary datastructure to call
> > proper ctors/dtors, not job of garbage collector that provides the underlying
> > memory management.
> 
> I do not think that all summaries (in the meaning of a description of
> one particular symbol table node or call graph edge) are explicitely
> managed.  For example ipa_edge_args or ipa_agg_replacement_value
> (which my alignment patch changes to ipcp_transformation_summary) are
> allocated in GC memory because they contain trees.
> 
> > 
> > If you have datastructure that points to something that is not
> > explicitly managed (i.e. tree expression), you just can not have
> > non-trivial constructor on that datastructure, because that is freed
> > transparently by gty that don't do destruction...
> 
> I admit to not being particularly bright today but that seems to be
> exactly my point.

Well, in your case you have datastructure jump_function that contain a pointer
to tree (EXPR).  What I am trying to explain is that I see no reson why
jump_function needs to be POD. The tree pointed to by EXPR pointer can not
have a dtor by itself because GGC will not call it upon freeing.

It is true that jump_function lives in GGC memory (to make pointer to expr
work) but it never gets removed by ggc_collect because it is always pointed to
by the summary datastructure.  There are two ways to free the jump_function
datastructure.
  1) removing the symbol node it is attached to.
     Here the symtab code will call removal hook that was registered by container
     template. The container will call destructor of jump_function and the ggc_free
     its memory
  2) removing the summary.  In this case I would again expect the container
     template to walk all summaries and free them.

So even if your structure lives in GGC memory it is not really garbage
collected and thus the lack of machinery to call dtors at a time ggc decides to
free something is not a problem?

In fact looking at struct default_hashmap_traits, I see:

  /* Called to dispose of the key and value before marking the entry as
     deleted.  */

  template<typename T> static void remove (T &v) { v.~T (); }

This trait gets called by the underlying hash table so if you have explicitly
managed hashmap (in GGC memory or not), things just work.  Only catch is that
if you let your hashmap to be garbage collected, then your dtor is not called.

So probably the dtors are working same way with Martin's summaries?
I guess we can follow same scheme here, have summary_traits that default
to calling correspondin ctors/dtors. 

Honza

> 
> Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-18 19:19                   ` Jan Hubicka
@ 2014-11-18 22:32                     ` Martin Jambor
  2014-11-19 13:25                       ` Martin Liška
  2014-11-19  1:50                     ` Trevor Saunders
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Jambor @ 2014-11-18 22:32 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Martin Liška, gcc-patches

On Tue, Nov 18, 2014 at 07:59:26PM +0100, Jan Hubicka wrote:
> > Hi,
> > 
> > On Tue, Nov 18, 2014 at 04:39:00PM +0100, Jan Hubicka wrote:
> > > > On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
> > > > > > > 
> > > > > > > > b) with GTY, we cannot call destructor
> > > > > > > 
> > > > > > > Everything in symbol table is expecitely memory managed (i.e. enver left
> > > > > > > to be freed by garbage collector). It resists in GTY only to allow linking
> > > > > > > garbage collected object from them and to get PCH working.
> > > > > > > 
> > > > > > 
> > > > > > Well, if I understand the intent correctly, summaries are for stuff
> > > > > > that is not in the symbol table.  For example jump functions are a
> > > > > Correct.
> > > > > > vector of structures possibly containing trees, so everything has to
> > > > > > be in garbage collected memory.
> > > > > > 
> > > > > > When an edge is removed, it is necessary to be notified about it
> > > > > > immediately, for example to decrement rdesc_refcount (you might argue
> > > > > > that that should be done in a separate hook and not from within a
> > > > > > summary class but then you start to rely on hook invocation ordering
> > > > > > so I think it is better to eventually use the summaries for it too).
> > > > > 
> > > > > I do not see why ctors/dtors can not do the reference counting. In fact
> > > > > this is how refcounting is done usually anyway?
> > > > > 
> > > > 
> > > > Well, when there is no garbage collection involved then yes, that is
> > > > how you normally do it but in the GC case, there is the question of
> > > > what is the appropriate time to call destructor on garbage collected
> > > > data (like jump functions)?
> > > 
> > > I still fail to see problem here.  Summaries are explicitly managed- they are
> > > constructed at summary construction time or when new callgarph node is
> > > introduced/duplicated.  They are destroyed when callgarph node is destroyed or
> > > whole summary is ddestroyed.  It is job of the summary datastructure to call
> > > proper ctors/dtors, not job of garbage collector that provides the underlying
> > > memory management.
> > 
> > I do not think that all summaries (in the meaning of a description of
> > one particular symbol table node or call graph edge) are explicitely
> > managed.  For example ipa_edge_args or ipa_agg_replacement_value
> > (which my alignment patch changes to ipcp_transformation_summary) are
> > allocated in GC memory because they contain trees.
> > 
> > > 
> > > If you have datastructure that points to something that is not
> > > explicitly managed (i.e. tree expression), you just can not have
> > > non-trivial constructor on that datastructure, because that is freed
> > > transparently by gty that don't do destruction...
> > 
> > I admit to not being particularly bright today but that seems to be
> > exactly my point.
> 
> Well, in your case you have datastructure jump_function that contain a pointer
> to tree (EXPR).  What I am trying to explain is that I see no reson why
> jump_function needs to be POD.

I never said that the summary object needs to be a POD, I only said I
liked the possibility of storing very simple objects (without wrapping
them in classes with constructors and destructors).  That is of course
nothing more than my personal preference.

> The tree pointed to by EXPR pointer can not
> have a dtor by itself because GGC will not call it upon freeing.
> 
> It is true that jump_function lives in GGC memory (to make pointer to expr
> work) but it never gets removed by ggc_collect because it is always pointed to
> by the summary datastructure.  There are two ways to free the jump_function
> datastructure.
>   1) removing the symbol node it is attached to.
>      Here the symtab code will call removal hook that was registered by container
>      template. The container will call destructor of jump_function and the ggc_free
>      its memory
>   2) removing the summary.  In this case I would again expect the container
>      template to walk all summaries and free them.
> 
> So even if your structure lives in GGC memory it is not really garbage
> collected and thus the lack of machinery to call dtors at a time ggc decides to
> free something is not a problem?
> 
> In fact looking at struct default_hashmap_traits, I see:
> 
>   /* Called to dispose of the key and value before marking the entry as
>      deleted.  */
> 
>   template<typename T> static void remove (T &v) { v.~T (); }

Now I see, I should have read your previous email more carefully, by
explicitely managed you mean that destructors will be called
explicitely by the summary infrastructure.  I was wondering how you
wanted to rip the summaries out of GGC memory.

Well, I suppose that would work, and since explicit calls to
destructors are basically the counterpart of placement new that we
already plan to use, it might be actually be the proper C++ thing to
do.

(I am not sure I like it though, for all other purposes the summary
objects will look like managed by the garbage collector and only we
who read this thread will know that the lifetime of the object would
be decoupled from the allocation-span of its memory).

Thanks for the clarification,

Martin

> 
> This trait gets called by the underlying hash table so if you have explicitly
> managed hashmap (in GGC memory or not), things just work.  Only catch is that
> if you let your hashmap to be garbage collected, then your dtor is not called.
> 
> So probably the dtors are working same way with Martin's summaries?
> I guess we can follow same scheme here, have summary_traits that default
> to calling correspondin ctors/dtors. 
> 
> Honza
> 
> > 
> > Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-18 19:19                   ` Jan Hubicka
  2014-11-18 22:32                     ` Martin Jambor
@ 2014-11-19  1:50                     ` Trevor Saunders
  1 sibling, 0 replies; 40+ messages in thread
From: Trevor Saunders @ 2014-11-19  1:50 UTC (permalink / raw)
  To: gcc-patches

On Tue, Nov 18, 2014 at 07:59:26PM +0100, Jan Hubicka wrote:
> > Hi,
> > 
> > On Tue, Nov 18, 2014 at 04:39:00PM +0100, Jan Hubicka wrote:
> > > > On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
> > > > > > > 
> > > > > > > > b) with GTY, we cannot call destructor
> > > > > > > 
> > > > > > > Everything in symbol table is expecitely memory managed (i.e. enver left
> > > > > > > to be freed by garbage collector). It resists in GTY only to allow linking
> > > > > > > garbage collected object from them and to get PCH working.
> > > > > > > 
> > > > > > 
> > > > > > Well, if I understand the intent correctly, summaries are for stuff
> > > > > > that is not in the symbol table.  For example jump functions are a
> > > > > Correct.
> > > > > > vector of structures possibly containing trees, so everything has to
> > > > > > be in garbage collected memory.
> > > > > > 
> > > > > > When an edge is removed, it is necessary to be notified about it
> > > > > > immediately, for example to decrement rdesc_refcount (you might argue
> > > > > > that that should be done in a separate hook and not from within a
> > > > > > summary class but then you start to rely on hook invocation ordering
> > > > > > so I think it is better to eventually use the summaries for it too).
> > > > > 
> > > > > I do not see why ctors/dtors can not do the reference counting. In fact
> > > > > this is how refcounting is done usually anyway?
> > > > > 
> > > > 
> > > > Well, when there is no garbage collection involved then yes, that is
> > > > how you normally do it but in the GC case, there is the question of
> > > > what is the appropriate time to call destructor on garbage collected
> > > > data (like jump functions)?
> > > 
> > > I still fail to see problem here.  Summaries are explicitly managed- they are
> > > constructed at summary construction time or when new callgarph node is
> > > introduced/duplicated.  They are destroyed when callgarph node is destroyed or
> > > whole summary is ddestroyed.  It is job of the summary datastructure to call
> > > proper ctors/dtors, not job of garbage collector that provides the underlying
> > > memory management.
> > 
> > I do not think that all summaries (in the meaning of a description of
> > one particular symbol table node or call graph edge) are explicitely
> > managed.  For example ipa_edge_args or ipa_agg_replacement_value
> > (which my alignment patch changes to ipcp_transformation_summary) are
> > allocated in GC memory because they contain trees.
> > 
> > > 
> > > If you have datastructure that points to something that is not
> > > explicitly managed (i.e. tree expression), you just can not have
> > > non-trivial constructor on that datastructure, because that is freed
> > > transparently by gty that don't do destruction...
> > 
> > I admit to not being particularly bright today but that seems to be
> > exactly my point.
> 
> Well, in your case you have datastructure jump_function that contain a pointer
> to tree (EXPR).  What I am trying to explain is that I see no reson why
> jump_function needs to be POD. The tree pointed to by EXPR pointer can not
> have a dtor by itself because GGC will not call it upon freeing.

ggc does call dtors when it is about to sweep an object.  however if you
explicitly call ggc_free on an object with a dtor you need to call the
dtor manually I believe.

> It is true that jump_function lives in GGC memory (to make pointer to expr
> work) but it never gets removed by ggc_collect because it is always pointed to
> by the summary datastructure.  There are two ways to free the jump_function
> datastructure.

assuming it doesn't need to go into pch, and I would really think it
never does there's no real reason it has to live on the heap, you could
iterate over all the summaries and mark all the trees they point at
"manually".

>   1) removing the symbol node it is attached to.
>      Here the symtab code will call removal hook that was registered by container
>      template. The container will call destructor of jump_function and the ggc_free
>      its memory
>   2) removing the summary.  In this case I would again expect the container
>      template to walk all summaries and free them.
> 
> So even if your structure lives in GGC memory it is not really garbage
> collected and thus the lack of machinery to call dtors at a time ggc decides to
> free something is not a problem?
> 
> In fact looking at struct default_hashmap_traits, I see:
> 
>   /* Called to dispose of the key and value before marking the entry as
>      deleted.  */
> 
>   template<typename T> static void remove (T &v) { v.~T (); }
> 
> This trait gets called by the underlying hash table so if you have explicitly
> managed hashmap (in GGC memory or not), things just work.  Only catch is that
> if you let your hashmap to be garbage collected, then your dtor is not called.

actually I think it should be, ggc tracks when objects with non trivial
dtors are allocated and sets up finalizers for them to run the dtor.

Trev

> So probably the dtors are working same way with Martin's summaries?
> I guess we can follow same scheme here, have summary_traits that default
> to calling correspondin ctors/dtors. 
> 
> Honza
> 
> > 
> > Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-18 22:32                     ` Martin Jambor
@ 2014-11-19 13:25                       ` Martin Liška
  0 siblings, 0 replies; 40+ messages in thread
From: Martin Liška @ 2014-11-19 13:25 UTC (permalink / raw)
  To: gcc-patches

On 11/18/2014 11:25 PM, Martin Jambor wrote:
> On Tue, Nov 18, 2014 at 07:59:26PM +0100, Jan Hubicka wrote:
>>> Hi,
>>>
>>> On Tue, Nov 18, 2014 at 04:39:00PM +0100, Jan Hubicka wrote:
>>>>> On Fri, Nov 14, 2014 at 08:59:10PM +0100, Jan Hubicka wrote:
>>>>>>>>
>>>>>>>>> b) with GTY, we cannot call destructor
>>>>>>>>
>>>>>>>> Everything in symbol table is expecitely memory managed (i.e. enver left
>>>>>>>> to be freed by garbage collector). It resists in GTY only to allow linking
>>>>>>>> garbage collected object from them and to get PCH working.
>>>>>>>>
>>>>>>>
>>>>>>> Well, if I understand the intent correctly, summaries are for stuff
>>>>>>> that is not in the symbol table.  For example jump functions are a
>>>>>> Correct.
>>>>>>> vector of structures possibly containing trees, so everything has to
>>>>>>> be in garbage collected memory.
>>>>>>>
>>>>>>> When an edge is removed, it is necessary to be notified about it
>>>>>>> immediately, for example to decrement rdesc_refcount (you might argue
>>>>>>> that that should be done in a separate hook and not from within a
>>>>>>> summary class but then you start to rely on hook invocation ordering
>>>>>>> so I think it is better to eventually use the summaries for it too).
>>>>>>
>>>>>> I do not see why ctors/dtors can not do the reference counting. In fact
>>>>>> this is how refcounting is done usually anyway?
>>>>>>
>>>>>
>>>>> Well, when there is no garbage collection involved then yes, that is
>>>>> how you normally do it but in the GC case, there is the question of
>>>>> what is the appropriate time to call destructor on garbage collected
>>>>> data (like jump functions)?
>>>>
>>>> I still fail to see problem here.  Summaries are explicitly managed- they are
>>>> constructed at summary construction time or when new callgarph node is
>>>> introduced/duplicated.  They are destroyed when callgarph node is destroyed or
>>>> whole summary is ddestroyed.  It is job of the summary datastructure to call
>>>> proper ctors/dtors, not job of garbage collector that provides the underlying
>>>> memory management.
>>>
>>> I do not think that all summaries (in the meaning of a description of
>>> one particular symbol table node or call graph edge) are explicitely
>>> managed.  For example ipa_edge_args or ipa_agg_replacement_value
>>> (which my alignment patch changes to ipcp_transformation_summary) are
>>> allocated in GC memory because they contain trees.
>>>
>>>>
>>>> If you have datastructure that points to something that is not
>>>> explicitly managed (i.e. tree expression), you just can not have
>>>> non-trivial constructor on that datastructure, because that is freed
>>>> transparently by gty that don't do destruction...
>>>
>>> I admit to not being particularly bright today but that seems to be
>>> exactly my point.
>>
>> Well, in your case you have datastructure jump_function that contain a pointer
>> to tree (EXPR).  What I am trying to explain is that I see no reson why
>> jump_function needs to be POD.
>
> I never said that the summary object needs to be a POD, I only said I
> liked the possibility of storing very simple objects (without wrapping
> them in classes with constructors and destructors).  That is of course
> nothing more than my personal preference.
>
>> The tree pointed to by EXPR pointer can not
>> have a dtor by itself because GGC will not call it upon freeing.
>>
>> It is true that jump_function lives in GGC memory (to make pointer to expr
>> work) but it never gets removed by ggc_collect because it is always pointed to
>> by the summary datastructure.  There are two ways to free the jump_function
>> datastructure.
>>    1) removing the symbol node it is attached to.
>>       Here the symtab code will call removal hook that was registered by container
>>       template. The container will call destructor of jump_function and the ggc_free
>>       its memory
>>    2) removing the summary.  In this case I would again expect the container
>>       template to walk all summaries and free them.
>>
>> So even if your structure lives in GGC memory it is not really garbage
>> collected and thus the lack of machinery to call dtors at a time ggc decides to
>> free something is not a problem?
>>
>> In fact looking at struct default_hashmap_traits, I see:
>>
>>    /* Called to dispose of the key and value before marking the entry as
>>       deleted.  */
>>
>>    template<typename T> static void remove (T &v) { v.~T (); }
>
> Now I see, I should have read your previous email more carefully, by
> explicitely managed you mean that destructors will be called
> explicitely by the summary infrastructure.  I was wondering how you
> wanted to rip the summaries out of GGC memory.
>
> Well, I suppose that would work, and since explicit calls to
> destructors are basically the counterpart of placement new that we
> already plan to use, it might be actually be the proper C++ thing to
> do.
>
> (I am not sure I like it though, for all other purposes the summary
> objects will look like managed by the garbage collector and only we
> who read this thread will know that the lifetime of the object would
> be decoupled from the allocation-span of its memory).
>
> Thanks for the clarification,
>
> Martin

Hello.

I tried to come up with ctor/dtor solution for types passes to symbol_summary
template class.

Example:
struct inline_summary
{
   inline_summary (cgraph_node *node);
   inline_summary (inline_summary &data, cgraph_node *node, cgraph_node *node2);
   ~inline_summary ();
}

There's no technical problem, but two practical I noticed:

1) current implementation of reset_inline_summary calls reset_inline_summary(cgraph_node *).
In inline_summary::~inline_summary we are not given cgraph_node. This implies need of a new
method called 'release' which will be called before summary's dtor.

2) current implementation of add_new_function calls inline_analyze_function which
calls compute_inline_parameters. This function invokes inline_summary (inline_summary_d::get) and
this creates infinite loop because inline_summary ctor hasn't finished and the summary
is not stored within function_summary yet.

I think current implementation can be ported to suggested approach (ctors/dtors API), but
I consider this approach very cumbersome.

Thanks,
Martin

>
>>
>> This trait gets called by the underlying hash table so if you have explicitly
>> managed hashmap (in GGC memory or not), things just work.  Only catch is that
>> if you let your hashmap to be garbage collected, then your dtor is not called.
>>
>> So probably the dtors are working same way with Martin's summaries?
>> I guess we can follow same scheme here, have summary_traits that default
>> to calling correspondin ctors/dtors.
>>
>> Honza
>>
>>>
>>> Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-11-14 15:31       ` Martin Liška
@ 2014-12-08 17:01         ` Martin Liška
  2014-12-18 19:42           ` Jan Hubicka
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-12-08 17:01 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2619 bytes --]

On 11/14/2014 04:23 PM, Martin Liška wrote:
> On 11/14/2014 03:04 PM, Martin Liška wrote:
>> On 11/13/2014 04:50 PM, Jan Hubicka wrote:
>>>> gcc/ChangeLog:
>>>>
>>>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>>>
>>>>     * Makefile.in: New object file is added.
>>>>     * cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
>>>>     is filled up.
>>>>     * cgraph_summary.c: New file.
>>>>     * cgraph_summary.h: New file.
>>>
>>> Since I am trying to get rid of the cgraph prefixes for symbols (keep it for
>>> the graph only) and the summaries can be annotated to variables too. Even if it
>>> not necessarily supported by your current implementation, lets keep API
>>> prepared for it. So I would call it symtab-summary.* for source files and
>>> symtab_summary for base type  (probably function_summary for annotating
>>> functions/cgraph_edge_summary for annotating edges?)
>>
>> Hello.
>>
>> I followed your remarks, new class is called function_summary and is located
>> in symbol-summary.h.
>>>
>>>
>>>> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
>>>> index e2becb9..588b6d5 100644
>>>> --- a/gcc/cgraph.h
>>>> +++ b/gcc/cgraph.h
>>>> @@ -1225,6 +1225,8 @@ public:
>>>>     int count_materialization_scale;
>>>>     /* Unique id of the node.  */
>>>>     int uid;
>>>> +  /* Summary unique id of the node.  */
>>>> +  int summary_uid;
>>>
>>> What makes summary_uid better than uid?
>>
>> Because cgraph_node::uid is not a unique ID, it's recycled. As I can see,
>> there are two remaining usages of the fact that cgraph::uid are quite consecutive:
>>
>> a) node_growth_cache vector is resized according to cgraph_max_uid
>> b) lto-partition.c: lto_balanced_map
>>
>> If we change ipa-related stuff to annotations and lto_balanced_map with be rewritten,
>> we can finally unify uid and summary_uid. As Martin correctly pointed out, we should
>> unify cgraph_node dumps, we combine uid and order.
>>
>>>
>>>> diff --git a/gcc/cgraph_summary.c b/gcc/cgraph_summary.c
>>>> new file mode 100644
>>>> index 0000000..9af1d7e
>>>> --- /dev/null
>>>> +++ b/gcc/cgraph_summary.c
>>>
>>> And why do we need this file?  It will need license header if really needed.
>>
>> Sure, the file can be removed.
>>
>> Martin
>>
>>>
>>> The implementation seems sane - I will check the actual uses :)
>>> Please send the updated patch though.
>>>
>>> Honza
>>>
>>
>
> Hello.
>
> There's v3 of the patch.
>
> Martin

Hello.

Version 4 of the patch. I have a conversation with Trevor and I hope it can be
acceptable to trunk?

Patch set can bootstrap on x86_64-linux-pc and no regression has been seen.

Thanks,
Martin


[-- Attachment #2: 0001-New-symbol_summary-class-introduced.patch --]
[-- Type: text/x-patch, Size: 10826 bytes --]

From df978f4a338869b56dc558c70f6c8f3c884b9fe1 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 5 Dec 2014 15:59:04 +0100
Subject: [PATCH 1/3] New symbol_summary class introduced.

gcc/ChangeLog:

2014-12-08  Martin Liska  <mliska@suse.cz>

	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
	is filled up.
	* symbol-summary.h: New file.
	* gengtype.c (open_base_files): Add symbol-summary.h.
	* toplev.c (general_init): Call constructor of symbol_table.
---
 gcc/cgraph.h         |   8 ++
 gcc/gengtype.c       |   4 +-
 gcc/symbol-summary.h | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/toplev.c         |   3 +-
 4 files changed, 293 insertions(+), 3 deletions(-)
 create mode 100644 gcc/symbol-summary.h

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a5c5f56..1664bd7 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1237,6 +1237,8 @@ public:
   int count_materialization_scale;
   /* Unique id of the node.  */
   int uid;
+  /* Summary unique id of the node.  */
+  int summary_uid;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
   /* Time profiler: first run of function.  */
@@ -1810,6 +1812,10 @@ public:
   friend class cgraph_node;
   friend class cgraph_edge;
 
+  symbol_table (): cgraph_max_summary_uid (1)
+  {
+  }
+
   /* Initialize callgraph dump file.  */
   void initialize (void);
 
@@ -2006,6 +2012,7 @@ public:
 
   int cgraph_count;
   int cgraph_max_uid;
+  int cgraph_max_summary_uid;
 
   int edges_count;
   int edges_max_uid;
@@ -2334,6 +2341,7 @@ symbol_table::allocate_cgraph_symbol (void)
       node->uid = cgraph_max_uid++;
     }
 
+  node->summary_uid = cgraph_max_summary_uid++;
   return node;
 }
 
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 2dc857e..276f543 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1842,8 +1842,8 @@ open_base_files (void)
       "tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h", 
       "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
-      "target-globals.h", "ipa-ref.h", "cgraph.h", "ipa-prop.h", 
-      "ipa-inline.h", "dwarf2out.h", "omp-low.h", NULL
+      "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h",
+      "ipa-prop.h", "ipa-inline.h", "dwarf2out.h", "omp-low.h", NULL
     };
     const char *const *ifp;
     outf_p gtype_desc_c;
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
new file mode 100644
index 0000000..95270e5
--- /dev/null
+++ b/gcc/symbol-summary.h
@@ -0,0 +1,281 @@
+/* Callgraph summary data structure.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Contributed by Martin Liska
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_SYMBOL_SUMMARY_H
+#define GCC_SYMBOL_SUMMARY_H
+
+/* We want to pass just pointer types as argument for function_summary
+   template class.  */
+
+template <class T>
+class function_summary
+{
+private:
+  function_summary();
+};
+
+template <class T>
+class GTY((user)) function_summary <T *>
+{
+public:
+  /* Default construction takes SYMTAB as an argument.  */
+  function_summary (symbol_table *symtab, bool ggc = false): m_ggc (ggc),
+    m_map (13, ggc), m_insertion_enabled (true), m_symtab (symtab)
+  {
+    cgraph_node *node;
+
+#ifdef ENABLE_CHECKING
+    FOR_EACH_FUNCTION (node)
+    {
+      gcc_checking_assert (node->summary_uid > 0);
+    }
+#endif
+
+    m_symtab_insertion_hook =
+      symtab->add_cgraph_insertion_hook
+      (function_summary::symtab_insertion, this);
+
+    m_symtab_removal_hook =
+      symtab->add_cgraph_removal_hook
+      (function_summary::symtab_removal, this);
+    m_symtab_duplication_hook =
+      symtab->add_cgraph_duplication_hook
+      (function_summary::symtab_duplication, this);
+  }
+
+  /* Destructor.  */
+  virtual ~function_summary ()
+  {
+    release ();
+  }
+
+  /* Destruction method that can be called for GGT purpose.  */
+  void release ()
+  {
+    if (m_symtab_insertion_hook)
+      m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook);
+
+    if (m_symtab_removal_hook)
+      m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook);
+
+    if (m_symtab_duplication_hook)
+      m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook);
+
+    m_symtab_insertion_hook = NULL;
+    m_symtab_removal_hook = NULL;
+    m_symtab_duplication_hook = NULL;
+  }
+
+  /* Traverses all summarys with a function F called with
+     ARG as argument.  */
+  template<typename Arg, bool (*f)(const T &, Arg)>
+  void traverse (Arg a) const
+  {
+    m_map.traverse <f> (a);
+  }
+
+  /* Basic implementation of insert operation.  */
+  virtual void insert (cgraph_node *, T *) {}
+
+  /* Basic implementation of removal operation.  */
+  virtual void remove (cgraph_node *, T *) {}
+
+  /* Basic implementation of duplication operation.  */
+  virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) {}
+
+  /* Allocates new data that are stored within map.  */
+  T* allocate_new ()
+  {
+    return m_ggc ? new (ggc_alloc <T> ()) T() : new T () ;
+  }
+
+  /* Getter for summary callgraph node pointer.  */
+  T* get (cgraph_node *node)
+  {
+    return get (node->summary_uid);
+  }
+
+  /* Return number of elements handled by data structure.  */
+  size_t elements ()
+  {
+    return m_map.elements ();
+  }
+
+  /* Enable insertion hook invocation.  */
+  void enable_insertion_hook ()
+  {
+    m_insertion_enabled = true;
+  }
+
+  /* Enable insertion hook invocation.  */
+  void disable_insertion_hook ()
+  {
+    m_insertion_enabled = false;
+  }
+
+  /* Symbol insertion hook that is registered to symbol table.  */
+  static void symtab_insertion (cgraph_node *node, void *data)
+  {
+    function_summary *summary = (function_summary <T *> *) (data);
+
+    if (summary->m_insertion_enabled)
+      summary->insert (node, summary->get (node));
+  }
+
+  /* Symbol removal hook that is registered to symbol table.  */
+  static void symtab_removal (cgraph_node *node, void *data)
+  {
+    gcc_checking_assert (node->summary_uid);
+    function_summary *summary = (function_summary <T *> *) (data);
+
+    int summary_uid = node->summary_uid;
+    T **v = summary->m_map.get (summary_uid);
+
+    if (v)
+      {
+	summary->remove (node, *v);
+
+	if (!summary->m_ggc)
+	  delete (*v);
+
+	summary->m_map.remove (summary_uid);
+      }
+  }
+
+  /* Symbol duplication hook that is registered to symbol table.  */
+  static void symtab_duplication (cgraph_node *node, cgraph_node *node2,
+				  void *data)
+  {
+    function_summary *summary = (function_summary <T *> *) (data);
+    T **v = summary->m_map.get (node->summary_uid);
+
+    gcc_checking_assert (node2->summary_uid > 0);
+
+    if (v)
+      {
+	/* This load is necessary, because we insert a new value!  */
+	T *data = *v;
+	T *duplicate = summary->allocate_new ();
+	summary->m_map.put (node2->summary_uid, duplicate);
+	summary->duplicate (node, node2, data, duplicate);
+      }
+  }
+
+protected:
+  /* Indication if we use ggc summary.  */
+  bool m_ggc;
+
+private:
+  struct summary_hashmap_traits: default_hashmap_traits
+  {
+    static const int deleted_value = -1;
+    static const int empty_value = 0;
+
+    static hashval_t
+    hash (const int v)
+    {
+      return (hashval_t)v;
+    }
+
+    template<typename Type>
+    static bool
+    is_deleted (Type &e)
+    {
+      return e.m_key == deleted_value;
+    }
+
+    template<typename Type>
+    static bool
+    is_empty (Type &e)
+    {
+      return e.m_key == empty_value;
+    }
+
+    template<typename Type>
+    static void
+    mark_deleted (Type &e)
+    {
+      e.m_key = deleted_value;
+    }
+
+    template<typename Type>
+    static void
+    mark_empty (Type &e)
+    {
+      e.m_key = empty_value;
+    }
+  };
+
+  /* Getter for summary callgraph ID.  */
+  T* get (int uid)
+  {
+    bool existed;
+    T **v = &m_map.get_or_insert (uid, &existed);
+    if (!existed)
+      *v = allocate_new ();
+
+    return *v;
+  }
+
+  /* Main summary store, where summary ID is used as key.  */
+  hash_map <int, T *, summary_hashmap_traits> m_map;
+  /* Internal summary insertion hook pointer.  */
+  cgraph_node_hook_list *m_symtab_insertion_hook;
+  /* Internal summary removal hook pointer.  */
+  cgraph_node_hook_list *m_symtab_removal_hook;
+  /* Internal summary duplication hook pointer.  */
+  cgraph_2node_hook_list *m_symtab_duplication_hook;
+  /* Indicates if insertion hook is enabled.  */
+  bool m_insertion_enabled;
+  /* Symbol table the summary is registered to.  */
+  symbol_table *m_symtab;
+
+  template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &);
+  template <typename U> friend void gt_pch_nx (function_summary <U *> * const &,
+      gt_pointer_operator, void *);
+};
+
+template <typename T>
+void
+gt_ggc_mx(function_summary<T *>* const &summary)
+{
+  gcc_checking_assert (summary->m_ggc);
+  gt_ggc_mx (&summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(function_summary<T *>* const &summary)
+{
+  gcc_checking_assert (summary->m_ggc);
+  gt_pch_nx (&summary->m_map);
+}
+
+template <typename T>
+void
+gt_pch_nx(function_summary<T *>* const& summary, gt_pointer_operator op,
+	  void *cookie)
+{
+  gcc_checking_assert (summary->m_ggc);
+  gt_pch_nx (&summary->m_map, op, cookie);
+}
+
+#endif  /* GCC_SYMBOL_SUMMARY_H  */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 6e6adfa..6ce3f7b 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -93,6 +93,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dwarf2out.h"
 #include "bitmap.h"
 #include "ipa-reference.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "gcse.h"
 #include "insn-codes.h"
@@ -1213,7 +1214,7 @@ general_init (const char *argv0)
   /* Create the singleton holder for global state.
      Doing so also creates the pass manager and with it the passes.  */
   g = new gcc::context ();
-  symtab = ggc_cleared_alloc <symbol_table> ();
+  symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table ();
 
   statistics_early_init ();
   finish_params ();
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass.
  2014-11-14 15:31     ` Martin Liška
  2014-11-14 17:10       ` Martin Jambor
@ 2014-12-08 17:02       ` Martin Liška
  2014-12-18 19:44         ` Jan Hubicka
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-12-08 17:02 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 112102 bytes --]

On 11/14/2014 04:23 PM, Martin Liška wrote:
> On 11/14/2014 03:05 PM, Martin Liška wrote:
>> On 11/11/2014 01:26 PM, mliska wrote:
>>> gcc/ChangeLog:
>>>
>>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>>
>>>     * auto-profile.c: Include cgraph_summary.h.
>>>     * cgraph.c: Likewise.
>>>     * cgraphbuild.c: Likewise.
>>>     * cgraphclones.c: Likewise.
>>>     * cgraphunit.c: Likewise.
>>>     * ipa-cp.c: Likewise.
>>>     * ipa-devirt.c: Likewise.
>>>     * ipa-icf.c: Likewise.
>>>     * ipa-inline-analysis.c (evaluate_properties_for_edge): Usage of
>>>     ipa_node_params_vector is replaced with ipa_node_params_summary.
>>>     (inline_node_duplication_hook): Likewise.
>>>     (estimate_function_body_sizes): Likewise.
>>>     (remap_edge_change_prob): Likewise.
>>>     (inline_merge_summary): Likewise.
>>>     * ipa-inline-transform.c: Include of cgraph_summary.h.
>>>     * ipa-inline.c (early_inliner): Usage of
>>>     ipa_node_params_vector is replaced with ipa_node_params_summary.
>>>     * ipa-polymorphic-call.c: Include of cgraph_summary.h.
>>>     * ipa-profile.c: Include of cgraph_summary.h.
>>>     * ipa-prop.c (struct func_body_info): Struct keyword is removed.
>>>     (struct ipa_cst_ref_desc): Likewise.
>>>     (ipa_func_spec_opts_forbid_analysis_p): Likewise.
>>>     (ipa_alloc_node_params): Likewise.
>>>     (ipa_initialize_node_params): Likewise.
>>>     (ipa_print_node_jump_functions_for_edge): Likewise.
>>>     (ipa_print_node_jump_functions): Likewise.
>>>     (ipa_print_all_jump_functions): Likewise.
>>>     (ipa_set_jf_constant): Likewise.
>>>     (check_stmt_for_type_change): Likewise.
>>>     (detect_type_change_from_memory_writes): Likewise.
>>>     (find_dominating_aa_status): Likewise.
>>>     (parm_bb_aa_status_for_bb): Likewise.
>>>     (parm_preserved_before_stmt_p): Likewise.
>>>     (parm_ref_data_preserved_p): Likewise.
>>>     (parm_ref_data_pass_through_p): Likewise.
>>>     (struct ipa_known_agg_contents_list): Likewise.
>>>     (get_place_in_agg_contents_list): Likewise.
>>>     (build_agg_jump_func_from_list): Likewise.
>>>     (determine_locally_known_aggregate_parts): Likewise.
>>>     (ipa_compute_jump_functions_for_edge): Likewise.
>>>     (ipa_compute_jump_functions_for_bb): Likewise.
>>>     (ipa_note_param_call): Likewise.
>>>     (ipa_analyze_indirect_call_uses) Likewise.:
>>>     (ipa_analyze_virtual_call_uses): Likewise.
>>>     (ipa_analyze_call_uses): Likewise.
>>>     (visit_ref_for_mod_analysis): Likewise.
>>>     (ipa_analyze_controlled_uses): Likewise.
>>>     (ipa_analyze_node): Likewise.
>>>     (update_jump_functions_after_inlining): Likewise.
>>>     (ipa_make_edge_direct_to_target): Likewise.
>>>     (ipa_find_agg_cst_for_param): Likewise.
>>>     (remove_described_reference): Likewise.
>>>     (jfunc_rdesc_usable): Likewise.
>>>     (try_decrement_rdesc_refcount): Likewise.
>>>     (try_make_edge_direct_simple_call): Likewise.
>>>     (try_make_edge_direct_virtual_call): Likewise.
>>>     (update_indirect_edges_after_inlining): Likewise.
>>>     (propagate_info_to_inlined_callees): Likewise.
>>>     (propagate_controlled_uses): Likewise.
>>>     (ipa_propagate_indirect_call_infos): Likewise.
>>>     (ipa_free_all_edge_args): Likewise.
>>>     (ipa_node_params::~ipa_node_params): Likewise.
>>>     (ipa_free_all_node_params): Likewise.
>>>     (ipa_edge_removal_hook): Likewise.
>>>     (ipa_node_removal_hook): Likewise.
>>>     (ipa_edge_duplication_hook): Likewise.
>>>     (ipa_add_new_function): Removed
>>>     (ipa_node_params_cgraph_summary::duplication_hook): New function.
>>>     (ipa_node_duplication_hook): Struct keyword removed.
>>>     (ipa_register_cgraph_hooks): Removal of old hooks.
>>>     (ipa_unregister_cgraph_hooks): Likewise.
>>>     (ipa_print_node_params): Struct keyword is removed.
>>>     (ipa_print_all_params): Likewise.
>>>     (ipa_modify_formal_parameters): Likewise.
>>>     (ipa_modify_call_arguments): Likewise.
>>>     (ipa_modify_expr): Likewise.
>>>     (ipa_get_adjustment_candidate): Likewise.
>>>     (index_in_adjustments_multiple_times_p): Likewise.
>>>     (ipa_combine_adjustments): Likewise.
>>>     (ipa_dump_param_adjustments): Likewise.
>>>     (ipa_write_jump_function): Likewise.
>>>     (ipa_read_jump_function): Likewise.
>>>     (ipa_write_indirect_edge_info): Likewise.
>>>     (ipa_read_indirect_edge_info): Likewise.
>>>     (ipa_write_node_info): Likewise.
>>>     (ipa_read_node_info): Likewise.
>>>     (ipa_prop_write_jump_functions): Likewise.
>>>     (ipa_prop_read_section): Likewise.
>>>     (ipa_prop_read_jump_functions): Likewise.
>>>     (write_agg_replacement_chain): Likewise.
>>>     (read_agg_replacement_chain): Likewise.
>>>     (ipa_prop_write_all_agg_replacement): Likewise.
>>>     (read_replacements_section): Likewise.
>>>     (ipa_prop_read_all_agg_replacement): Likewise.
>>>     (adjust_agg_replacement_values): Likewise.
>>>     (ipcp_modif_dom_walker::before_dom_children): Likewise.
>>>     (ipcp_transform_function): Likewise.
>>>     * ipa-prop.h (struct ipa_node_params): Introduction of new class
>>>     ipa_node_params_cgraph_summary.
>>>     * ipa-split.c: Include cgraph_summary.h.
>>>     * ipa-utils.c: Likewise.
>>>     * ipa.c: Likewise.
>>>     * omp-low.c: Likewise.
>>>     * tree-inline.c: Likewise.
>>>     * tree-sra.c: Likewise.
>>>     * tree-ssa-pre.c: Likewise.
>>>
>>> gcc/lto/ChangeLog:
>>>
>>> 2014-11-12  Martin Liska  <mliska@suse.cz>
>>>
>>>     * lto-partition.c: Include cgraph_summary.h.
>>>     * lto-symtab.c: Likewise.
>>>     * lto.c: Likewise.
>>> ---
>>>   gcc/auto-profile.c         |   1 +
>>>   gcc/cgraph.c               |   1 +
>>>   gcc/cgraphbuild.c          |   1 +
>>>   gcc/cgraphclones.c         |   1 +
>>>   gcc/cgraphunit.c           |   1 +
>>>   gcc/ipa-cp.c               |   1 +
>>>   gcc/ipa-devirt.c           |   1 +
>>>   gcc/ipa-icf.c              |   1 +
>>>   gcc/ipa-inline-analysis.c  |  13 +-
>>>   gcc/ipa-inline-transform.c |   1 +
>>>   gcc/ipa-inline.c           |   3 +-
>>>   gcc/ipa-polymorphic-call.c |   1 +
>>>   gcc/ipa-profile.c          |   1 +
>>>   gcc/ipa-prop.c             | 700 ++++++++++++++++++++++-----------------------
>>>   gcc/ipa-prop.h             |  46 +--
>>>   gcc/ipa-split.c            |   1 +
>>>   gcc/ipa-utils.c            |   1 +
>>>   gcc/ipa.c                  |   1 +
>>>   gcc/lto/lto-partition.c    |   1 +
>>>   gcc/lto/lto-symtab.c       |   1 +
>>>   gcc/lto/lto.c              |   1 +
>>>   gcc/omp-low.c              |   1 +
>>>   gcc/tree-inline.c          |   1 +
>>>   gcc/tree-sra.c             |   1 +
>>>   gcc/tree-ssa-pre.c         |   1 +
>>>   25 files changed, 397 insertions(+), 386 deletions(-)
>>>
>>> diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
>>> index 8c7b4ca..49f9b8c 100644
>>> --- a/gcc/auto-profile.c
>>> +++ b/gcc/auto-profile.c
>>> @@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "coverage.h"
>>>   #include "params.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "tree-inline.h"
>>> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
>>> index 7216b89..af1835a 100644
>>> --- a/gcc/cgraph.c
>>> +++ b/gcc/cgraph.c
>>> @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-utils.h"
>>>   #include "lto-streamer.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "cfgloop.h"
>>> diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
>>> index c72ceab..a93b0aa 100644
>>> --- a/gcc/cgraphbuild.c
>>> +++ b/gcc/cgraphbuild.c
>>> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-utils.h"
>>>   #include "except.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>
>>> diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
>>> index c8892da..79f95ef 100644
>>> --- a/gcc/cgraphclones.c
>>> +++ b/gcc/cgraphclones.c
>>> @@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "tree-iterator.h"
>>>   #include "tree-dump.h"
>>> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
>>> index 25af234..dbbdc44 100644
>>> --- a/gcc/cgraphunit.c
>>> +++ b/gcc/cgraphunit.c
>>> @@ -204,6 +204,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "tree-iterator.h"
>>>   #include "tree-pass.h"
>>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>>> index 47f9f5c..da589af 100644
>>> --- a/gcc/ipa-cp.c
>>> +++ b/gcc/ipa-cp.c
>>> @@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "bitmap.h"
>>>   #include "tree-pass.h"
>>> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
>>> index 32c6549..8e1f9ce 100644
>>> --- a/gcc/ipa-devirt.c
>>> +++ b/gcc/ipa-devirt.c
>>> @@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "gimple-expr.h"
>>>   #include "gimple.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "diagnostic.h"
>>> diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
>>> index 92ec82d..9778323 100644
>>> --- a/gcc/ipa-icf.c
>>> +++ b/gcc/ipa-icf.c
>>> @@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "cfgloop.h"
>>> diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
>>> index eb1c6ec..c7a52d2 100644
>>> --- a/gcc/ipa-inline-analysis.c
>>> +++ b/gcc/ipa-inline-analysis.c
>>> @@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "lto-streamer.h"
>>>   #include "data-streamer.h"
>>> @@ -910,7 +911,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
>>>     if (known_binfos_ptr)
>>>       known_binfos_ptr->create (0);
>>>
>>> -  if (ipa_node_params_vector.exists ()
>>> +  if (ipa_node_params_summary
>>>         && !e->call_stmt_cannot_inline_p
>>>         && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr))
>>>       {
>>> @@ -1130,7 +1131,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
>>>
>>>     /* When there are any replacements in the function body, see if we can figure
>>>        out that something was optimized out.  */
>>> -  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
>>> +  if (ipa_node_params_summary && dst->clone.tree_map)
>>>       {
>>>         vec<size_time_entry, va_gc> *entry = info->entry;
>>>         /* Use SRC parm info since it may not be copied yet.  */
>>> @@ -2476,7 +2477,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>>         calculate_dominance_info (CDI_DOMINATORS);
>>>         loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
>>>
>>> -      if (ipa_node_params_vector.exists ())
>>> +      if (ipa_node_params_summary)
>>>       {
>>>         parms_info = IPA_NODE_REF (node);
>>>         nonconstant_names.safe_grow_cleared
>>> @@ -2624,7 +2625,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
>>>             nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
>>>               = false_p;
>>>           }
>>> -          if (ipa_node_params_vector.exists ())
>>> +          if (ipa_node_params_summary)
>>>           {
>>>             int count = gimple_call_num_args (stmt);
>>>             int i;
>>> @@ -3367,7 +3368,7 @@ static void
>>>   remap_edge_change_prob (struct cgraph_edge *inlined_edge,
>>>               struct cgraph_edge *edge)
>>>   {
>>> -  if (ipa_node_params_vector.exists ())
>>> +  if (ipa_node_params_summary)
>>>       {
>>>         int i;
>>>         struct ipa_edge_args *args = IPA_EDGE_REF (edge);
>>> @@ -3523,7 +3524,7 @@ inline_merge_summary (struct cgraph_edge *edge)
>>>     else
>>>       toplev_predicate = true_predicate ();
>>>
>>> -  if (ipa_node_params_vector.exists () && callee_info->conds)
>>> +  if (ipa_node_params_summary && callee_info->conds)
>>>       {
>>>         struct ipa_edge_args *args = IPA_EDGE_REF (edge);
>>>         int count = ipa_get_cs_argument_count (args);
>>> diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
>>> index dbc56c5..fd700ff 100644
>>> --- a/gcc/ipa-inline-transform.c
>>> +++ b/gcc/ipa-inline-transform.c
>>> @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "tree-inline.h"
>>> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
>>> index 5c97815..8a08cd4 100644
>>> --- a/gcc/ipa-inline.c
>>> +++ b/gcc/ipa-inline.c
>>> @@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "except.h"
>>>   #include "target.h"
>>> @@ -2400,7 +2401,7 @@ early_inliner (function *fun)
>>>        it.  This may confuse ourself when early inliner decide to inline call to
>>>        function clone, because function clones don't have parameter list in
>>>        ipa-prop matching their signature.  */
>>> -  if (ipa_node_params_vector.exists ())
>>> +  if (ipa_node_params_summary)
>>>       return 0;
>>>
>>>   #ifdef ENABLE_CHECKING
>>> diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
>>> index 33dd1a8..e0555f2 100644
>>> --- a/gcc/ipa-polymorphic-call.c
>>> +++ b/gcc/ipa-polymorphic-call.c
>>> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "gimple-expr.h"
>>>   #include "gimple.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "diagnostic.h"
>>> diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
>>> index b83d1cf..4fdee09 100644
>>> --- a/gcc/ipa-profile.c
>>> +++ b/gcc/ipa-profile.c
>>> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "tree-inline.h"
>>>   #include "lto-streamer.h"
>>>   #include "data-streamer.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>
>>> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
>>> index db85c7d..ce9745e 100644
>>> --- a/gcc/ipa-prop.c
>>> +++ b/gcc/ipa-prop.c
>>> @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "bitmap.h"
>>>   #include "gimple-ssa.h"
>>> @@ -119,7 +120,7 @@ struct func_body_info
>>>     cgraph_node *node;
>>>
>>>     /* Its info.  */
>>> -  struct ipa_node_params *info;
>>> +  ipa_node_params *info;
>>>
>>>     /* Information about individual BBs. */
>>>     vec<ipa_bb_info> bb_infos;
>>> @@ -131,7 +132,8 @@ struct func_body_info
>>>     unsigned int aa_walked;
>>>   };
>>>
>>> -/* Vector where the parameter infos are actually stored. */
>>> +/* Callgraph summary where the parameter infos are actually stored. */
>>> +ipa_node_params_cgraph_summary *ipa_node_params_summary = NULL;
>>>   vec<ipa_node_params> ipa_node_params_vector;
>>>   /* Vector of known aggregate values in cloned nodes.  */
>>>   vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>>> @@ -139,19 +141,17 @@ vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>>>   vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>>
>>>   /* Holders of ipa cgraph hooks: */
>>> -static struct cgraph_edge_hook_list *edge_removal_hook_holder;
>>> -static struct cgraph_node_hook_list *node_removal_hook_holder;
>>> -static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
>>> -static struct cgraph_2node_hook_list *node_duplication_hook_holder;
>>> -static struct cgraph_node_hook_list *function_insertion_hook_holder;
>>> +static cgraph_edge_hook_list *edge_removal_hook_holder;
>>> +static cgraph_2edge_hook_list *edge_duplication_hook_holder;
>>> +static cgraph_node_hook_list *function_insertion_hook_holder;
>>>
>>>   /* Description of a reference to an IPA constant.  */
>>>   struct ipa_cst_ref_desc
>>>   {
>>>     /* Edge that corresponds to the statement which took the reference.  */
>>> -  struct cgraph_edge *cs;
>>> +  cgraph_edge *cs;
>>>     /* Linked list of duplicates created when call graph edges are cloned.  */
>>> -  struct ipa_cst_ref_desc *next_duplicate;
>>> +  ipa_cst_ref_desc *next_duplicate;
>>>     /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
>>>        if out of control.  */
>>>     int refcount;
>>> @@ -165,10 +165,10 @@ static alloc_pool ipa_refdesc_pool;
>>>      with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
>>>
>>>   static bool
>>> -ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
>>> +ipa_func_spec_opts_forbid_analysis_p (cgraph_node *node)
>>>   {
>>>     tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
>>> -  struct cl_optimization *os;
>>> +  cl_optimization *os;
>>>
>>>     if (!fs_opts)
>>>       return false;
>>> @@ -196,7 +196,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor> descriptors, tree ptree)
>>>      to INFO.  */
>>>
>>>   int
>>> -ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
>>> +ipa_get_param_decl_index (ipa_node_params *info, tree ptree)
>>>   {
>>>     return ipa_get_param_decl_index_1 (info->descriptors, ptree);
>>>   }
>>> @@ -205,7 +205,7 @@ ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
>>>      NODE.  */
>>>
>>>   static void
>>> -ipa_populate_param_decls (struct cgraph_node *node,
>>> +ipa_populate_param_decls (cgraph_node *node,
>>>                 vec<ipa_param_descriptor> &descriptors)
>>>   {
>>>     tree fndecl;
>>> @@ -246,7 +246,7 @@ count_formal_params (tree fndecl)
>>>      using ipa_initialize_node_params. */
>>>
>>>   void
>>> -ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
>>> +ipa_dump_param (FILE *file, ipa_node_params *info, int i)
>>>   {
>>>     fprintf (file, "param #%i", i);
>>>     if (info->descriptors[i].decl)
>>> @@ -260,9 +260,9 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
>>>      to hold PARAM_COUNT parameters.  */
>>>
>>>   void
>>> -ipa_alloc_node_params (struct cgraph_node *node, int param_count)
>>> +ipa_alloc_node_params (cgraph_node *node, int param_count)
>>>   {
>>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>>
>>>     if (!info->descriptors.exists () && param_count)
>>>       info->descriptors.safe_grow_cleared (param_count);
>>> @@ -273,9 +273,9 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
>>>      param_decls.  */
>>>
>>>   void
>>> -ipa_initialize_node_params (struct cgraph_node *node)
>>> +ipa_initialize_node_params (cgraph_node *node)
>>>   {
>>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>>
>>>     if (!info->descriptors.exists ())
>>>       {
>>> @@ -287,14 +287,14 @@ ipa_initialize_node_params (struct cgraph_node *node)
>>>   /* Print the jump functions associated with call graph edge CS to file F.  */
>>>
>>>   static void
>>> -ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>>> +ipa_print_node_jump_functions_for_edge (FILE *f, cgraph_edge *cs)
>>>   {
>>>     int i, count;
>>>
>>>     count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
>>>     for (i = 0; i < count; i++)
>>>       {
>>> -      struct ipa_jump_func *jump_func;
>>> +      ipa_jump_func *jump_func;
>>>         enum jump_func_type type;
>>>
>>>         jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
>>> @@ -360,7 +360,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>>>
>>>         if (jump_func->agg.items)
>>>       {
>>> -      struct ipa_agg_jf_item *item;
>>> +      ipa_agg_jf_item *item;
>>>         int j;
>>>
>>>         fprintf (f, "         Aggregate passed by %s:\n",
>>> @@ -390,9 +390,9 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
>>>      NODE to file F.  */
>>>
>>>   void
>>> -ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>>> +ipa_print_node_jump_functions (FILE *f, cgraph_node *node)
>>>   {
>>> -  struct cgraph_edge *cs;
>>> +  cgraph_edge *cs;
>>>
>>>     fprintf (f, "  Jump functions of caller  %s/%i:\n", node->name (),
>>>          node->order);
>>> @@ -410,7 +410,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>>>
>>>     for (cs = node->indirect_calls; cs; cs = cs->next_callee)
>>>       {
>>> -      struct cgraph_indirect_call_info *ii;
>>> +      cgraph_indirect_call_info *ii;
>>>         if (!ipa_edge_args_info_available_for_edge_p (cs))
>>>       continue;
>>>
>>> @@ -445,7 +445,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
>>>   void
>>>   ipa_print_all_jump_functions (FILE *f)
>>>   {
>>> -  struct cgraph_node *node;
>>> +  cgraph_node *node;
>>>
>>>     fprintf (f, "\nJump functions:\n");
>>>     FOR_EACH_FUNCTION (node)
>>> @@ -457,7 +457,7 @@ ipa_print_all_jump_functions (FILE *f)
>>>   /* Set JFUNC to be a known type jump function.  */
>>>
>>>   static void
>>> -ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>> +ipa_set_jf_known_type (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>>                  tree base_type, tree component_type)
>>>   {
>>>     /* Recording and propagating main variants increases change that types
>>> @@ -480,8 +480,8 @@ ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>>      combination code).  The two functions will share their rdesc.  */
>>>
>>>   static void
>>> -ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
>>> -             struct ipa_jump_func *src)
>>> +ipa_set_jf_cst_copy (ipa_jump_func *dst,
>>> +             ipa_jump_func *src)
>>>
>>>   {
>>>     gcc_checking_assert (src->type == IPA_JF_CONST);
>>> @@ -492,8 +492,8 @@ ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
>>>   /* Set JFUNC to be a constant jmp function.  */
>>>
>>>   static void
>>> -ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>>> -             struct cgraph_edge *cs)
>>> +ipa_set_jf_constant (ipa_jump_func *jfunc, tree constant,
>>> +             cgraph_edge *cs)
>>>   {
>>>     constant = unshare_expr (constant);
>>>     if (constant && EXPR_P (constant))
>>> @@ -504,12 +504,12 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>>>     if (TREE_CODE (constant) == ADDR_EXPR
>>>         && TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL)
>>>       {
>>> -      struct ipa_cst_ref_desc *rdesc;
>>> +      ipa_cst_ref_desc *rdesc;
>>>         if (!ipa_refdesc_pool)
>>>       ipa_refdesc_pool = create_alloc_pool ("IPA-PROP ref descriptions",
>>> -                    sizeof (struct ipa_cst_ref_desc), 32);
>>> +                    sizeof (ipa_cst_ref_desc), 32);
>>>
>>> -      rdesc = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>> +      rdesc = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>>         rdesc->cs = cs;
>>>         rdesc->next_duplicate = NULL;
>>>         rdesc->refcount = 1;
>>> @@ -521,7 +521,7 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
>>>
>>>   /* Set JFUNC to be a simple pass-through jump function.  */
>>>   static void
>>> -ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>>> +ipa_set_jf_simple_pass_through (ipa_jump_func *jfunc, int formal_id,
>>>                   bool agg_preserved, bool type_preserved)
>>>   {
>>>     jfunc->type = IPA_JF_PASS_THROUGH;
>>> @@ -535,7 +535,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>>>   /* Set JFUNC to be an arithmetic pass through jump function.  */
>>>
>>>   static void
>>> -ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>>> +ipa_set_jf_arith_pass_through (ipa_jump_func *jfunc, int formal_id,
>>>                      tree operand, enum tree_code operation)
>>>   {
>>>     jfunc->type = IPA_JF_PASS_THROUGH;
>>> @@ -549,7 +549,7 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
>>>   /* Set JFUNC to be an ancestor jump function.  */
>>>
>>>   static void
>>> -ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>> +ipa_set_ancestor_jf (ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>>                tree type, int formal_id, bool agg_preserved,
>>>                bool type_preserved)
>>>   {
>>> @@ -572,7 +572,7 @@ ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
>>>      jump function.  */
>>>
>>>   tree
>>> -ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
>>> +ipa_binfo_from_known_type_jfunc (ipa_jump_func *jfunc)
>>>   {
>>>     if (!RECORD_OR_UNION_TYPE_P (jfunc->value.known_type.base_type))
>>>       return NULL_TREE;
>>> @@ -602,8 +602,8 @@ ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *jfunc)
>>>   /* Get IPA BB information about the given BB.  FBI is the context of analyzis
>>>      of this function body.  */
>>>
>>> -static struct ipa_bb_info *
>>> -ipa_get_bb_info (struct func_body_info *fbi, basic_block bb)
>>> +static ipa_bb_info *
>>> +ipa_get_bb_info (func_body_info *fbi, basic_block bb)
>>>   {
>>>     gcc_checking_assert (fbi);
>>>     return &fbi->bb_infos[bb->index];
>>> @@ -700,7 +700,7 @@ stmt_may_be_vtbl_ptr_store (gimple stmt)
>>>      identified, return the type.  Otherwise return NULL_TREE.  */
>>>
>>>   static tree
>>> -extr_type_from_vtbl_ptr_store (gimple stmt, struct prop_type_change_info *tci)
>>> +extr_type_from_vtbl_ptr_store (gimple stmt, prop_type_change_info *tci)
>>>   {
>>>     HOST_WIDE_INT offset, size, max_size;
>>>     tree lhs, rhs, base, binfo;
>>> @@ -752,7 +752,7 @@ static bool
>>>   check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
>>>   {
>>>     gimple stmt = SSA_NAME_DEF_STMT (vdef);
>>> -  struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
>>> +  prop_type_change_info *tci = (prop_type_change_info *) data;
>>>
>>>     if (stmt_may_be_vtbl_ptr_store (stmt))
>>>       {
>>> @@ -847,10 +847,10 @@ param_type_may_change_p (tree function, tree arg, gimple call)
>>>
>>>   static bool
>>>   detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
>>> -                       gimple call, struct ipa_jump_func *jfunc,
>>> +                       gimple call, ipa_jump_func *jfunc,
>>>                          HOST_WIDE_INT offset)
>>>   {
>>> -  struct prop_type_change_info tci;
>>> +  prop_type_change_info tci;
>>>     ao_ref ao;
>>>     bool entry_reached = false;
>>>
>>> @@ -908,7 +908,7 @@ detect_type_change_from_memory_writes (tree arg, tree base, tree comp_type,
>>>
>>>   static bool
>>>   detect_type_change (tree arg, tree base, tree comp_type, gimple call,
>>> -            struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
>>> +            ipa_jump_func *jfunc, HOST_WIDE_INT offset)
>>>   {
>>>     if (!flag_devirtualize)
>>>       return false;
>>> @@ -928,7 +928,7 @@ detect_type_change (tree arg, tree base, tree comp_type, gimple call,
>>>
>>>   static bool
>>>   detect_type_change_ssa (tree arg, tree comp_type,
>>> -            gimple call, struct ipa_jump_func *jfunc)
>>> +            gimple call, ipa_jump_func *jfunc)
>>>   {
>>>     gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
>>>     if (!flag_devirtualize
>>> @@ -961,7 +961,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
>>>      should really just start giving up.  */
>>>
>>>   static bool
>>> -aa_overwalked (struct func_body_info *fbi)
>>> +aa_overwalked (func_body_info *fbi)
>>>   {
>>>     gcc_checking_assert (fbi);
>>>     return fbi->aa_walked > (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
>>> @@ -970,8 +970,8 @@ aa_overwalked (struct func_body_info *fbi)
>>>   /* Find the nearest valid aa status for parameter specified by INDEX that
>>>      dominates BB.  */
>>>
>>> -static struct param_aa_status *
>>> -find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>>> +static param_aa_status *
>>> +find_dominating_aa_status (func_body_info *fbi, basic_block bb,
>>>                  int index)
>>>   {
>>>     while (true)
>>> @@ -979,7 +979,7 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>>>         bb = get_immediate_dominator (CDI_DOMINATORS, bb);
>>>         if (!bb)
>>>       return NULL;
>>> -      struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>> +      ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>>         if (!bi->param_aa_statuses.is_empty ()
>>>         && bi->param_aa_statuses[index].valid)
>>>       return &bi->param_aa_statuses[index];
>>> @@ -990,21 +990,21 @@ find_dominating_aa_status (struct func_body_info *fbi, basic_block bb,
>>>      structures and/or intialize the result with a dominating description as
>>>      necessary.  */
>>>
>>> -static struct param_aa_status *
>>> -parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
>>> +static param_aa_status *
>>> +parm_bb_aa_status_for_bb (func_body_info *fbi, basic_block bb,
>>>                 int index)
>>>   {
>>>     gcc_checking_assert (fbi);
>>> -  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>> +  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>>     if (bi->param_aa_statuses.is_empty ())
>>>       bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
>>> -  struct param_aa_status *paa = &bi->param_aa_statuses[index];
>>> +  param_aa_status *paa = &bi->param_aa_statuses[index];
>>>     if (!paa->valid)
>>>       {
>>>         gcc_checking_assert (!paa->parm_modified
>>>                  && !paa->ref_modified
>>>                  && !paa->pt_modified);
>>> -      struct param_aa_status *dom_paa;
>>> +      param_aa_status *dom_paa;
>>>         dom_paa = find_dominating_aa_status (fbi, bb, index);
>>>         if (dom_paa)
>>>       *paa = *dom_paa;
>>> @@ -1021,10 +1021,10 @@ parm_bb_aa_status_for_bb (struct func_body_info *fbi, basic_block bb,
>>>      gathered but do not survive the summary building stage.  */
>>>
>>>   static bool
>>> -parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
>>> +parm_preserved_before_stmt_p (func_body_info *fbi, int index,
>>>                     gimple stmt, tree parm_load)
>>>   {
>>> -  struct param_aa_status *paa;
>>> +  param_aa_status *paa;
>>>     bool modified = false;
>>>     ao_ref refd;
>>>
>>> @@ -1060,7 +1060,7 @@ parm_preserved_before_stmt_p (struct func_body_info *fbi, int index,
>>>      modified.  Otherwise return -1.  */
>>>
>>>   static int
>>> -load_from_unmodified_param (struct func_body_info *fbi,
>>> +load_from_unmodified_param (func_body_info *fbi,
>>>                   vec<ipa_param_descriptor> descriptors,
>>>                   gimple stmt)
>>>   {
>>> @@ -1087,10 +1087,10 @@ load_from_unmodified_param (struct func_body_info *fbi,
>>>      before reaching statement STMT.  */
>>>
>>>   static bool
>>> -parm_ref_data_preserved_p (struct func_body_info *fbi,
>>> +parm_ref_data_preserved_p (func_body_info *fbi,
>>>                  int index, gimple stmt, tree ref)
>>>   {
>>> -  struct param_aa_status *paa;
>>> +  param_aa_status *paa;
>>>     bool modified = false;
>>>     ao_ref refd;
>>>
>>> @@ -1126,7 +1126,7 @@ parm_ref_data_preserved_p (struct func_body_info *fbi,
>>>      CALL into which it is passed.  FBI describes the function body.  */
>>>
>>>   static bool
>>> -parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>>> +parm_ref_data_pass_through_p (func_body_info *fbi, int index,
>>>                     gimple call, tree parm)
>>>   {
>>>     bool modified = false;
>>> @@ -1140,7 +1140,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>>>         || aa_overwalked (fbi))
>>>       return false;
>>>
>>> -  struct param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
>>> +  param_aa_status *paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (call),
>>>                                 index);
>>>     if (paa->pt_modified)
>>>       return false;
>>> @@ -1165,7 +1165,7 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
>>>      reference respectively.  */
>>>
>>>   static bool
>>> -ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
>>> +ipa_load_from_parm_agg_1 (func_body_info *fbi,
>>>                 vec<ipa_param_descriptor> descriptors,
>>>                 gimple stmt, tree op, int *index_p,
>>>                 HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
>>> @@ -1240,7 +1240,7 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
>>>      pointer, for users outside of this file.  */
>>>
>>>   bool
>>> -ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
>>> +ipa_load_from_parm_agg (ipa_node_params *info, gimple stmt,
>>>               tree op, int *index_p, HOST_WIDE_INT *offset_p,
>>>               bool *by_ref_p)
>>>   {
>>> @@ -1302,9 +1302,9 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
>>>      only needed for intraprocedural analysis.  */
>>>
>>>   static void
>>> -compute_complex_assign_jump_func (struct func_body_info *fbi,
>>> -                  struct ipa_node_params *info,
>>> -                  struct ipa_jump_func *jfunc,
>>> +compute_complex_assign_jump_func (func_body_info *fbi,
>>> +                  ipa_node_params *info,
>>> +                  ipa_jump_func *jfunc,
>>>                     gimple call, gimple stmt, tree name,
>>>                     tree param_type)
>>>   {
>>> @@ -1458,9 +1458,9 @@ get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
>>>        return D.1879_6;  */
>>>
>>>   static void
>>> -compute_complex_ancestor_jump_func (struct func_body_info *fbi,
>>> -                    struct ipa_node_params *info,
>>> -                    struct ipa_jump_func *jfunc,
>>> +compute_complex_ancestor_jump_func (func_body_info *fbi,
>>> +                    ipa_node_params *info,
>>> +                    ipa_jump_func *jfunc,
>>>                       gimple call, gimple phi, tree param_type)
>>>   {
>>>     HOST_WIDE_INT offset;
>>> @@ -1531,7 +1531,7 @@ compute_complex_ancestor_jump_func (struct func_body_info *fbi,
>>>      EXPECTED_TYPE represents a type the argument should be in  */
>>>
>>>   static void
>>> -compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
>>> +compute_known_type_jump_func (tree op, ipa_jump_func *jfunc,
>>>                     gimple call, tree expected_type)
>>>   {
>>>     HOST_WIDE_INT offset, size, max_size;
>>> @@ -1629,7 +1629,7 @@ struct ipa_known_agg_contents_list
>>>     /* Known constant value or NULL if the contents is known to be unknown.  */
>>>     tree constant;
>>>     /* Pointer to the next structure in the list.  */
>>> -  struct ipa_known_agg_contents_list *next;
>>> +  ipa_known_agg_contents_list *next;
>>>   };
>>>
>>>   /* Find the proper place in linked list of ipa_known_agg_contents_list
>>> @@ -1637,13 +1637,13 @@ struct ipa_known_agg_contents_list
>>>      unless there is a partial overlap, in which case return NULL, or such
>>>      element is already there, in which case set *ALREADY_THERE to true.  */
>>>
>>> -static struct ipa_known_agg_contents_list **
>>> -get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
>>> +static ipa_known_agg_contents_list **
>>> +get_place_in_agg_contents_list (ipa_known_agg_contents_list **list,
>>>                   HOST_WIDE_INT lhs_offset,
>>>                   HOST_WIDE_INT lhs_size,
>>>                   bool *already_there)
>>>   {
>>> -  struct ipa_known_agg_contents_list **p = list;
>>> +  ipa_known_agg_contents_list **p = list;
>>>     while (*p && (*p)->offset < lhs_offset)
>>>       {
>>>         if ((*p)->offset + (*p)->size > lhs_offset)
>>> @@ -1670,16 +1670,16 @@ get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
>>>      is ARG_OFFSET and store it into JFUNC.  */
>>>
>>>   static void
>>> -build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
>>> +build_agg_jump_func_from_list (ipa_known_agg_contents_list *list,
>>>                      int const_count, HOST_WIDE_INT arg_offset,
>>> -                   struct ipa_jump_func *jfunc)
>>> +                   ipa_jump_func *jfunc)
>>>   {
>>>     vec_alloc (jfunc->agg.items, const_count);
>>>     while (list)
>>>       {
>>>         if (list->constant)
>>>       {
>>> -      struct ipa_agg_jf_item item;
>>> +      ipa_agg_jf_item item;
>>>         item.offset = list->offset - arg_offset;
>>>         gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
>>>         item.value = unshare_expr_without_location (list->constant);
>>> @@ -1697,9 +1697,9 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
>>>
>>>   static void
>>>   determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>> -                     struct ipa_jump_func *jfunc)
>>> +                     ipa_jump_func *jfunc)
>>>   {
>>> -  struct ipa_known_agg_contents_list *list = NULL;
>>> +  ipa_known_agg_contents_list *list = NULL;
>>>     int item_count = 0, const_count = 0;
>>>     HOST_WIDE_INT arg_offset, arg_size;
>>>     gimple_stmt_iterator gsi;
>>> @@ -1774,7 +1774,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>>     gsi_prev (&gsi);
>>>     for (; !gsi_end_p (gsi); gsi_prev (&gsi))
>>>       {
>>> -      struct ipa_known_agg_contents_list *n, **p;
>>> +      ipa_known_agg_contents_list *n, **p;
>>>         gimple stmt = gsi_stmt (gsi);
>>>         HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
>>>         tree lhs, rhs, lhs_base;
>>> @@ -1821,7 +1821,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>>       continue;
>>>
>>>         rhs = get_ssa_def_if_simple_copy (rhs);
>>> -      n = XALLOCA (struct ipa_known_agg_contents_list);
>>> +      n = XALLOCA (ipa_known_agg_contents_list);
>>>         n->size = lhs_size;
>>>         n->offset = lhs_offset;
>>>         if (is_gimple_ip_invariant (rhs))
>>> @@ -1852,7 +1852,7 @@ determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
>>>   }
>>>
>>>   static tree
>>> -ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>>> +ipa_get_callee_param_type (cgraph_edge *e, int i)
>>>   {
>>>     int n;
>>>     tree type = (e->callee
>>> @@ -1887,11 +1887,11 @@ ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>>>      to this callsite.  */
>>>
>>>   static void
>>> -ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>>> -                     struct cgraph_edge *cs)
>>> +ipa_compute_jump_functions_for_edge (func_body_info *fbi,
>>> +                     cgraph_edge *cs)
>>>   {
>>> -  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
>>> -  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
>>> +  ipa_node_params *info = IPA_NODE_REF (cs->caller);
>>> +  ipa_edge_args *args = IPA_EDGE_REF (cs);
>>>     gimple call = cs->call_stmt;
>>>     int n, arg_num = gimple_call_num_args (call);
>>>     bool useful_context = false;
>>> @@ -1909,13 +1909,13 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>>>
>>>     for (n = 0; n < arg_num; n++)
>>>       {
>>> -      struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
>>> +      ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
>>>         tree arg = gimple_call_arg (call, n);
>>>         tree param_type = ipa_get_callee_param_type (cs, n);
>>>         if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
>>>       {
>>>         tree instance;
>>> -      struct ipa_polymorphic_call_context context (cs->caller->decl,
>>> +      ipa_polymorphic_call_context context (cs->caller->decl,
>>>                                  arg, cs->call_stmt,
>>>                                  &instance);
>>>         context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
>>> @@ -2003,15 +2003,15 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
>>>      from BB.  */
>>>
>>>   static void
>>> -ipa_compute_jump_functions_for_bb (struct func_body_info *fbi, basic_block bb)
>>> +ipa_compute_jump_functions_for_bb (func_body_info *fbi, basic_block bb)
>>>   {
>>> -  struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>> +  ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
>>>     int i;
>>> -  struct cgraph_edge *cs;
>>> +  cgraph_edge *cs;
>>>
>>>     FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
>>>       {
>>> -      struct cgraph_node *callee = cs->callee;
>>> +      cgraph_node *callee = cs->callee;
>>>
>>>         if (callee)
>>>       {
>>> @@ -2093,10 +2093,10 @@ ipa_is_ssa_with_stmt_def (tree t)
>>>      call to a parameter number PARAM_INDEX.  NODE is the caller.  Return the
>>>      indirect call graph edge.  */
>>>
>>> -static struct cgraph_edge *
>>> -ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
>>> +static cgraph_edge *
>>> +ipa_note_param_call (cgraph_node *node, int param_index, gimple stmt)
>>>   {
>>> -  struct cgraph_edge *cs;
>>> +  cgraph_edge *cs;
>>>
>>>     cs = node->get_edge (stmt);
>>>     cs->indirect_info->param_index = param_index;
>>> @@ -2165,10 +2165,10 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt)
>>>      passed by value or reference.  */
>>>
>>>   static void
>>> -ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>> +ipa_analyze_indirect_call_uses (func_body_info *fbi, gimple call,
>>>                   tree target)
>>>   {
>>> -  struct ipa_node_params *info = fbi->info;
>>> +  ipa_node_params *info = fbi->info;
>>>     HOST_WIDE_INT offset;
>>>     bool by_ref;
>>>
>>> @@ -2188,7 +2188,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>>                      gimple_assign_rhs1 (def), &index, &offset,
>>>                      NULL, &by_ref))
>>>       {
>>> -      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>> +      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>>         cs->indirect_info->offset = offset;
>>>         cs->indirect_info->agg_contents = 1;
>>>         cs->indirect_info->by_ref = by_ref;
>>> @@ -2288,7 +2288,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>>     if (index >= 0
>>>         && parm_preserved_before_stmt_p (fbi, index, call, rec))
>>>       {
>>> -      struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>> +      cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>>         cs->indirect_info->offset = offset;
>>>         cs->indirect_info->agg_contents = 1;
>>>         cs->indirect_info->member_ptr = 1;
>>> @@ -2303,7 +2303,7 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gimple call,
>>>      statement.  */
>>>
>>>   static void
>>> -ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>> +ipa_analyze_virtual_call_uses (func_body_info *fbi,
>>>                      gimple call, tree target)
>>>   {
>>>     tree obj = OBJ_TYPE_REF_OBJECT (target);
>>> @@ -2316,10 +2316,10 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>>     if (TREE_CODE (obj) != SSA_NAME)
>>>       return;
>>>
>>> -  struct ipa_node_params *info = fbi->info;
>>> +  ipa_node_params *info = fbi->info;
>>>     if (SSA_NAME_IS_DEFAULT_DEF (obj))
>>>       {
>>> -      struct ipa_jump_func jfunc;
>>> +      ipa_jump_func jfunc;
>>>         if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
>>>       return;
>>>
>>> @@ -2332,7 +2332,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>>       }
>>>     else
>>>       {
>>> -      struct ipa_jump_func jfunc;
>>> +      ipa_jump_func jfunc;
>>>         gimple stmt = SSA_NAME_DEF_STMT (obj);
>>>         tree expr;
>>>
>>> @@ -2347,8 +2347,8 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>>       return;
>>>       }
>>>
>>> -  struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
>>> +  cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
>>> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>>>     ii->offset = anc_offset;
>>>     ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
>>>     ii->otr_type = obj_type_ref_class (target);
>>> @@ -2360,7 +2360,7 @@ ipa_analyze_virtual_call_uses (struct func_body_info *fbi,
>>>      containing intermediate information about each formal parameter.  */
>>>
>>>   static void
>>> -ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>>> +ipa_analyze_call_uses (func_body_info *fbi, gimple call)
>>>   {
>>>     tree target = gimple_call_fn (call);
>>>
>>> @@ -2369,7 +2369,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>>>             && !virtual_method_call_p (target)))
>>>       return;
>>>
>>> -  struct cgraph_edge *cs = fbi->node->get_edge (call);
>>> +  cgraph_edge *cs = fbi->node->get_edge (call);
>>>     /* If we previously turned the call into a direct call, there is
>>>        no need to analyze.  */
>>>     if (cs && !cs->indirect_unknown_callee)
>>> @@ -2406,7 +2406,7 @@ ipa_analyze_call_uses (struct func_body_info *fbi, gimple call)
>>>      formal parameters are called.  */
>>>
>>>   static void
>>> -ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
>>> +ipa_analyze_stmt_uses (func_body_info *fbi, gimple stmt)
>>>   {
>>>     if (is_gimple_call (stmt))
>>>       ipa_analyze_call_uses (fbi, stmt);
>>> @@ -2419,7 +2419,7 @@ ipa_analyze_stmt_uses (struct func_body_info *fbi, gimple stmt)
>>>   static bool
>>>   visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
>>>   {
>>> -  struct ipa_node_params *info = (struct ipa_node_params *) data;
>>> +  ipa_node_params *info = (ipa_node_params *) data;
>>>
>>>     op = get_base_address (op);
>>>     if (op
>>> @@ -2439,7 +2439,7 @@ visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
>>>      the function being analyzed.  */
>>>
>>>   static void
>>> -ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
>>> +ipa_analyze_params_uses_in_bb (func_body_info *fbi, basic_block bb)
>>>   {
>>>     gimple_stmt_iterator gsi;
>>>     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>>> @@ -2465,9 +2465,9 @@ ipa_analyze_params_uses_in_bb (struct func_body_info *fbi, basic_block bb)
>>>   /* Calculate controlled uses of parameters of NODE.  */
>>>
>>>   static void
>>> -ipa_analyze_controlled_uses (struct cgraph_node *node)
>>> +ipa_analyze_controlled_uses (cgraph_node *node)
>>>   {
>>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>>
>>>     for (int i = 0; i < ipa_get_param_count (info); i++)
>>>       {
>>> @@ -2510,7 +2510,7 @@ ipa_analyze_controlled_uses (struct cgraph_node *node)
>>>   /* Free stuff in BI.  */
>>>
>>>   static void
>>> -free_ipa_bb_info (struct ipa_bb_info *bi)
>>> +free_ipa_bb_info (ipa_bb_info *bi)
>>>   {
>>>     bi->cg_edges.release ();
>>>     bi->param_aa_statuses.release ();
>>> @@ -2521,13 +2521,13 @@ free_ipa_bb_info (struct ipa_bb_info *bi)
>>>   class analysis_dom_walker : public dom_walker
>>>   {
>>>   public:
>>> -  analysis_dom_walker (struct func_body_info *fbi)
>>> +  analysis_dom_walker (func_body_info *fbi)
>>>       : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
>>>
>>>     virtual void before_dom_children (basic_block);
>>>
>>>   private:
>>> -  struct func_body_info *m_fbi;
>>> +  func_body_info *m_fbi;
>>>   };
>>>
>>>   void
>>> @@ -2542,10 +2542,10 @@ analysis_dom_walker::before_dom_children (basic_block bb)
>>>      with actual arguments of calls from within NODE.  */
>>>
>>>   void
>>> -ipa_analyze_node (struct cgraph_node *node)
>>> +ipa_analyze_node (cgraph_node *node)
>>>   {
>>> -  struct func_body_info fbi;
>>> -  struct ipa_node_params *info;
>>> +  func_body_info fbi;
>>> +  ipa_node_params *info;
>>>
>>>     ipa_check_create_node_params ();
>>>     ipa_check_create_edge_args ();
>>> @@ -2565,7 +2565,7 @@ ipa_analyze_node (struct cgraph_node *node)
>>>         return;
>>>       }
>>>
>>> -  struct function *func = DECL_STRUCT_FUNCTION (node->decl);
>>> +  function *func = DECL_STRUCT_FUNCTION (node->decl);
>>>     push_cfun (func);
>>>     calculate_dominance_info (CDI_DOMINATORS);
>>>     ipa_initialize_node_params (node);
>>> @@ -2578,13 +2578,13 @@ ipa_analyze_node (struct cgraph_node *node)
>>>     fbi.param_count = ipa_get_param_count (info);
>>>     fbi.aa_walked = 0;
>>>
>>> -  for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
>>> +  for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
>>>       {
>>>         ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
>>>         bi->cg_edges.safe_push (cs);
>>>       }
>>>
>>> -  for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
>>> +  for (cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
>>>       {
>>>         ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
>>>         bi->cg_edges.safe_push (cs);
>>> @@ -2593,7 +2593,7 @@ ipa_analyze_node (struct cgraph_node *node)
>>>     analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
>>>
>>>     int i;
>>> -  struct ipa_bb_info *bi;
>>> +  ipa_bb_info *bi;
>>>     FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
>>>       free_ipa_bb_info (bi);
>>>     fbi.bb_infos.release ();
>>> @@ -2606,8 +2606,8 @@ ipa_analyze_node (struct cgraph_node *node)
>>>      type.  */
>>>
>>>   static void
>>> -combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
>>> -                     struct ipa_jump_func *dst)
>>> +combine_known_type_and_ancestor_jfs (ipa_jump_func *src,
>>> +                     ipa_jump_func *dst)
>>>   {
>>>     HOST_WIDE_INT combined_offset;
>>>     tree combined_type;
>>> @@ -2632,25 +2632,25 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
>>>      indirectly) inlined into CS->callee and that E has not been inlined.  */
>>>
>>>   static void
>>> -update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>> -                      struct cgraph_edge *e)
>>> +update_jump_functions_after_inlining (cgraph_edge *cs,
>>> +                      cgraph_edge *e)
>>>   {
>>> -  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
>>> -  struct ipa_edge_args *args = IPA_EDGE_REF (e);
>>> +  ipa_edge_args *top = IPA_EDGE_REF (cs);
>>> +  ipa_edge_args *args = IPA_EDGE_REF (e);
>>>     int count = ipa_get_cs_argument_count (args);
>>>     int i;
>>>
>>>     for (i = 0; i < count; i++)
>>>       {
>>> -      struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
>>> -      struct ipa_polymorphic_call_context *dst_ctx
>>> +      ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
>>> +      ipa_polymorphic_call_context *dst_ctx
>>>       = ipa_get_ith_polymorhic_call_context (args, i);
>>>
>>>         if (dst->type == IPA_JF_ANCESTOR)
>>>       {
>>> -      struct ipa_jump_func *src;
>>> +      ipa_jump_func *src;
>>>         int dst_fid = dst->value.ancestor.formal_id;
>>> -      struct ipa_polymorphic_call_context *src_ctx
>>> +      ipa_polymorphic_call_context *src_ctx
>>>           = ipa_get_ith_polymorhic_call_context (top, dst_fid);
>>>
>>>         /* Variable number of arguments can cause havoc if we try to access
>>> @@ -2666,7 +2666,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>>
>>>         if (src_ctx && !src_ctx->useless_p ())
>>>           {
>>> -          struct ipa_polymorphic_call_context ctx = *src_ctx;
>>> +          ipa_polymorphic_call_context ctx = *src_ctx;
>>>
>>>             /* TODO: Make type preserved safe WRT contexts.  */
>>>             if (!dst->value.ancestor.agg_preserved)
>>> @@ -2683,7 +2683,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>>         if (src->agg.items
>>>             && (dst->value.ancestor.agg_preserved || !src->agg.by_ref))
>>>           {
>>> -          struct ipa_agg_jf_item *item;
>>> +          ipa_agg_jf_item *item;
>>>             int j;
>>>
>>>             /* Currently we do not produce clobber aggregate jump functions,
>>> @@ -2721,7 +2721,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>>       }
>>>         else if (dst->type == IPA_JF_PASS_THROUGH)
>>>       {
>>> -      struct ipa_jump_func *src;
>>> +      ipa_jump_func *src;
>>>         /* We must check range due to calls with variable number of arguments
>>>            and we cannot combine jump functions with operations.  */
>>>         if (dst->value.pass_through.operation == NOP_EXPR
>>> @@ -2731,12 +2731,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>>             int dst_fid = dst->value.pass_through.formal_id;
>>>             src = ipa_get_ith_jump_func (top, dst_fid);
>>>             bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
>>> -          struct ipa_polymorphic_call_context *src_ctx
>>> +          ipa_polymorphic_call_context *src_ctx
>>>           = ipa_get_ith_polymorhic_call_context (top, dst_fid);
>>>
>>>             if (src_ctx && !src_ctx->useless_p ())
>>>           {
>>> -          struct ipa_polymorphic_call_context ctx = *src_ctx;
>>> +          ipa_polymorphic_call_context ctx = *src_ctx;
>>>
>>>             /* TODO: Make type preserved safe WRT contexts.  */
>>>             if (!dst->value.ancestor.agg_preserved)
>>> @@ -2833,11 +2833,11 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
>>>      (SPECULATIVE)destination of an indirect edge IE and return the edge.
>>>      Otherwise, return NULL.  */
>>>
>>> -struct cgraph_edge *
>>> -ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>>> +cgraph_edge *
>>> +ipa_make_edge_direct_to_target (cgraph_edge *ie, tree target,
>>>                   bool speculative)
>>>   {
>>> -  struct cgraph_node *callee;
>>> +  cgraph_node *callee;
>>>     struct inline_edge_summary *es = inline_edge_summary (ie);
>>>     bool unreachable = false;
>>>
>>> @@ -2898,8 +2898,8 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>>>     /* If the edge is already speculated.  */
>>>     if (speculative && ie->speculative)
>>>       {
>>> -      struct cgraph_edge *e2;
>>> -      struct ipa_ref *ref;
>>> +      cgraph_edge *e2;
>>> +      ipa_ref *ref;
>>>         ie->speculative_call_info (e2, ie, ref);
>>>         if (e2->callee->ultimate_alias_target ()
>>>         != callee->ultimate_alias_target ())
>>> @@ -2987,10 +2987,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
>>>      be passed by reference or by value.  */
>>>
>>>   tree
>>> -ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
>>> +ipa_find_agg_cst_for_param (ipa_agg_jump_function *agg,
>>>                   HOST_WIDE_INT offset, bool by_ref)
>>>   {
>>> -  struct ipa_agg_jf_item *item;
>>> +  ipa_agg_jf_item *item;
>>>     int i;
>>>
>>>     if (by_ref != agg->by_ref)
>>> @@ -3012,10 +3012,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
>>>      successfully found and removed.  */
>>>
>>>   static bool
>>> -remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
>>> +remove_described_reference (symtab_node *symbol, ipa_cst_ref_desc *rdesc)
>>>   {
>>> -  struct ipa_ref *to_del;
>>> -  struct cgraph_edge *origin;
>>> +  ipa_ref *to_del;
>>> +  cgraph_edge *origin;
>>>
>>>     origin = rdesc->cs;
>>>     if (!origin)
>>> @@ -3037,10 +3037,10 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
>>>      IPA_UNDESCRIBED_USE, return the reference description, otherwise return
>>>      NULL.  JFUNC must be a constant jump function.  */
>>>
>>> -static struct ipa_cst_ref_desc *
>>> -jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
>>> +static ipa_cst_ref_desc *
>>> +jfunc_rdesc_usable (ipa_jump_func *jfunc)
>>>   {
>>> -  struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
>>> +  ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
>>>     if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
>>>       return rdesc;
>>>     else
>>> @@ -3052,7 +3052,7 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
>>>      NULL.  */
>>>
>>>   static cgraph_node *
>>> -cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
>>> +cgraph_node_for_jfunc (ipa_jump_func *jfunc)
>>>   {
>>>     gcc_checking_assert (jfunc->type == IPA_JF_CONST);
>>>     tree cst = ipa_get_jf_constant (jfunc);
>>> @@ -3070,9 +3070,9 @@ cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
>>>      reference could not be found, otherwise return true.  */
>>>
>>>   static bool
>>> -try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
>>> +try_decrement_rdesc_refcount (ipa_jump_func *jfunc)
>>>   {
>>> -  struct ipa_cst_ref_desc *rdesc;
>>> +  ipa_cst_ref_desc *rdesc;
>>>     if (jfunc->type == IPA_JF_CONST
>>>         && (rdesc = jfunc_rdesc_usable (jfunc))
>>>         && --rdesc->refcount == 0)
>>> @@ -3092,12 +3092,12 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
>>>      determined, return the newly direct edge, otherwise return NULL.
>>>      NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
>>>
>>> -static struct cgraph_edge *
>>> -try_make_edge_direct_simple_call (struct cgraph_edge *ie,
>>> -                  struct ipa_jump_func *jfunc,
>>> -                  struct ipa_node_params *new_root_info)
>>> +static cgraph_edge *
>>> +try_make_edge_direct_simple_call (cgraph_edge *ie,
>>> +                  ipa_jump_func *jfunc,
>>> +                  ipa_node_params *new_root_info)
>>>   {
>>> -  struct cgraph_edge *cs;
>>> +  cgraph_edge *cs;
>>>     tree target;
>>>     bool agg_contents = ie->indirect_info->agg_contents;
>>>
>>> @@ -3130,7 +3130,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
>>>      and target (the latter can be NULL) are dumped when dumping is enabled.  */
>>>
>>>   tree
>>> -ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
>>> +ipa_impossible_devirt_target (cgraph_edge *ie, tree target)
>>>   {
>>>     if (dump_file)
>>>       {
>>> @@ -3155,11 +3155,11 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
>>>      Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
>>>      are relative to.  */
>>>
>>> -static struct cgraph_edge *
>>> -try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>> -                   struct ipa_jump_func *jfunc,
>>> -                   struct ipa_node_params *new_root_info,
>>> -                   struct ipa_polymorphic_call_context *ctx_ptr)
>>> +static cgraph_edge *
>>> +try_make_edge_direct_virtual_call (cgraph_edge *ie,
>>> +                   ipa_jump_func *jfunc,
>>> +                   ipa_node_params *new_root_info,
>>> +                   ipa_polymorphic_call_context *ctx_ptr)
>>>   {
>>>     tree binfo, target = NULL;
>>>     bool speculative = false;
>>> @@ -3172,7 +3172,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>>        based on knowlede of the context.  */
>>>     if (ctx_ptr && !ie->indirect_info->by_ref)
>>>       {
>>> -      struct ipa_polymorphic_call_context ctx = *ctx_ptr;
>>> +      ipa_polymorphic_call_context ctx = *ctx_ptr;
>>>
>>>         ctx.offset_by (ie->indirect_info->offset);
>>>
>>> @@ -3221,7 +3221,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>>
>>>     if (binfo && TREE_CODE (binfo) != TREE_BINFO)
>>>       {
>>> -      struct ipa_polymorphic_call_context ctx (binfo,
>>> +      ipa_polymorphic_call_context ctx (binfo,
>>>                              ie->indirect_info->otr_type,
>>>                              ie->indirect_info->offset);
>>>         updated |= ie->indirect_info->context.combine_with
>>> @@ -3296,13 +3296,13 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
>>>      unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
>>>
>>>   static bool
>>> -update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>>> -                      struct cgraph_node *node,
>>> +update_indirect_edges_after_inlining (cgraph_edge *cs,
>>> +                      cgraph_node *node,
>>>                         vec<cgraph_edge *> *new_edges)
>>>   {
>>> -  struct ipa_edge_args *top;
>>> -  struct cgraph_edge *ie, *next_ie, *new_direct_edge;
>>> -  struct ipa_node_params *new_root_info;
>>> +  ipa_edge_args *top;
>>> +  cgraph_edge *ie, *next_ie, *new_direct_edge;
>>> +  ipa_node_params *new_root_info;
>>>     bool res = false;
>>>
>>>     ipa_check_create_edge_args ();
>>> @@ -3313,8 +3313,8 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>>>
>>>     for (ie = node->indirect_calls; ie; ie = next_ie)
>>>       {
>>> -      struct cgraph_indirect_call_info *ici = ie->indirect_info;
>>> -      struct ipa_jump_func *jfunc;
>>> +      cgraph_indirect_call_info *ici = ie->indirect_info;
>>> +      ipa_jump_func *jfunc;
>>>         int param_index;
>>>
>>>         next_ie = ie->next_callee;
>>> @@ -3408,11 +3408,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
>>>      created.  */
>>>
>>>   static bool
>>> -propagate_info_to_inlined_callees (struct cgraph_edge *cs,
>>> -                   struct cgraph_node *node,
>>> +propagate_info_to_inlined_callees (cgraph_edge *cs,
>>> +                   cgraph_node *node,
>>>                      vec<cgraph_edge *> *new_edges)
>>>   {
>>> -  struct cgraph_edge *e;
>>> +  cgraph_edge *e;
>>>     bool res;
>>>
>>>     res = update_indirect_edges_after_inlining (cs, node, new_edges);
>>> @@ -3443,21 +3443,21 @@ combine_controlled_uses_counters (int c, int d)
>>>      tree of inlined nodes.  */
>>>
>>>   static void
>>> -propagate_controlled_uses (struct cgraph_edge *cs)
>>> +propagate_controlled_uses (cgraph_edge *cs)
>>>   {
>>> -  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
>>> -  struct cgraph_node *new_root = cs->caller->global.inlined_to
>>> +  ipa_edge_args *args = IPA_EDGE_REF (cs);
>>> +  cgraph_node *new_root = cs->caller->global.inlined_to
>>>       ? cs->caller->global.inlined_to : cs->caller;
>>> -  struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
>>> -  struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
>>> +  ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
>>> +  ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
>>>     int count, i;
>>>
>>>     count = MIN (ipa_get_cs_argument_count (args),
>>>              ipa_get_param_count (old_root_info));
>>>     for (i = 0; i < count; i++)
>>>       {
>>> -      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>>> -      struct ipa_cst_ref_desc *rdesc;
>>> +      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>>> +      ipa_cst_ref_desc *rdesc;
>>>
>>>         if (jf->type == IPA_JF_PASS_THROUGH)
>>>       {
>>> @@ -3472,8 +3472,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>>         ipa_set_controlled_uses (new_root_info, src_idx, c);
>>>         if (c == 0 && new_root_info->ipcp_orig_node)
>>>           {
>>> -          struct cgraph_node *n;
>>> -          struct ipa_ref *ref;
>>> +          cgraph_node *n;
>>> +          ipa_ref *ref;
>>>             tree t = new_root_info->known_vals[src_idx];
>>>
>>>             if (t && TREE_CODE (t) == ADDR_EXPR
>>> @@ -3500,14 +3500,14 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>>         if (rdesc->refcount == 0)
>>>           {
>>>             tree cst = ipa_get_jf_constant (jf);
>>> -          struct cgraph_node *n;
>>> +          cgraph_node *n;
>>>             gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
>>>                      && TREE_CODE (TREE_OPERAND (cst, 0))
>>>                      == FUNCTION_DECL);
>>>             n = cgraph_node::get (TREE_OPERAND (cst, 0));
>>>             if (n)
>>>           {
>>> -          struct cgraph_node *clone;
>>> +          cgraph_node *clone;
>>>             bool ok;
>>>             ok = remove_described_reference (n, rdesc);
>>>             gcc_checking_assert (ok);
>>> @@ -3517,7 +3517,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>>                && clone != rdesc->cs->caller
>>>                && IPA_NODE_REF (clone)->ipcp_orig_node)
>>>               {
>>> -              struct ipa_ref *ref;
>>> +              ipa_ref *ref;
>>>                 ref = clone->find_reference (n, NULL, 0);
>>>                 if (ref)
>>>               {
>>> @@ -3542,11 +3542,11 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>>          i < ipa_get_cs_argument_count (args);
>>>          i++)
>>>       {
>>> -      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>>> +      ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
>>>
>>>         if (jf->type == IPA_JF_CONST)
>>>       {
>>> -      struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
>>> +      ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
>>>         if (rdesc)
>>>           rdesc->refcount = IPA_UNDESCRIBED_USE;
>>>       }
>>> @@ -3564,13 +3564,13 @@ propagate_controlled_uses (struct cgraph_edge *cs)
>>>      created.  */
>>>
>>>   bool
>>> -ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>>> +ipa_propagate_indirect_call_infos (cgraph_edge *cs,
>>>                      vec<cgraph_edge *> *new_edges)
>>>   {
>>>     bool changed;
>>>     /* Do nothing if the preparation phase has not been carried out yet
>>>        (i.e. during early inlining).  */
>>> -  if (!ipa_node_params_vector.exists ())
>>> +  if (!ipa_node_params_summary)
>>>       return false;
>>>     gcc_assert (ipa_edge_args_vector);
>>>
>>> @@ -3584,7 +3584,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>>>      to.  */
>>>
>>>   void
>>> -ipa_free_edge_args_substructures (struct ipa_edge_args *args)
>>> +ipa_free_edge_args_substructures (ipa_edge_args *args)
>>>   {
>>>     vec_free (args->jump_functions);
>>>     memset (args, 0, sizeof (*args));
>>> @@ -3596,7 +3596,7 @@ void
>>>   ipa_free_all_edge_args (void)
>>>   {
>>>     int i;
>>> -  struct ipa_edge_args *args;
>>> +  ipa_edge_args *args;
>>>
>>>     if (!ipa_edge_args_vector)
>>>       return;
>>> @@ -3610,15 +3610,21 @@ ipa_free_all_edge_args (void)
>>>   /* Frees all dynamically allocated structures that the param info points
>>>      to.  */
>>>
>>> -void
>>> -ipa_free_node_params_substructures (struct ipa_node_params *info)
>>> +ipa_node_params::~ipa_node_params ()
>>>   {
>>> -  info->descriptors.release ();
>>> -  free (info->lattices);
>>> +  descriptors.release ();
>>> +  free (lattices);
>>>     /* Lattice values and their sources are deallocated with their alocation
>>>        pool.  */
>>> -  info->known_vals.release ();
>>> -  memset (info, 0, sizeof (*info));
>>> +  known_vals.release ();
>>> +
>>> +  lattices = NULL;
>>> +  ipcp_orig_node = NULL;
>>> +  analysis_done = 0;
>>> +  node_enqueued = 0;
>>> +  do_clone_for_all_contexts = 0;
>>> +  is_all_contexts_clone = 0;
>>> +  node_dead = 0;
>>>   }
>>>
>>>   /* Free all ipa_node_params structures.  */
>>> @@ -3626,11 +3632,8 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
>>>   void
>>>   ipa_free_all_node_params (void)
>>>   {
>>> -  int i;
>>> -  struct ipa_node_params *info;
>>> -
>>> -  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
>>> -    ipa_free_node_params_substructures (info);
>>> +  delete ipa_node_params_summary;
>>> +  ipa_node_params_summary = NULL;
>>>
>>>     ipa_node_params_vector.release ();
>>>   }
>>> @@ -3638,8 +3641,8 @@ ipa_free_all_node_params (void)
>>>   /* Set the aggregate replacements of NODE to be AGGVALS.  */
>>>
>>>   void
>>> -ipa_set_node_agg_value_chain (struct cgraph_node *node,
>>> -                  struct ipa_agg_replacement_value *aggvals)
>>> +ipa_set_node_agg_value_chain (const cgraph_node *node,
>>> +                  ipa_agg_replacement_value *aggvals)
>>>   {
>>>     if (vec_safe_length (ipa_node_agg_replacements)
>>>         <= (unsigned) symtab->cgraph_max_uid)
>>> @@ -3652,9 +3655,9 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
>>>   /* Hook that is called by cgraph.c when an edge is removed.  */
>>>
>>>   static void
>>> -ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>> +ipa_edge_removal_hook (cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>>   {
>>> -  struct ipa_edge_args *args;
>>> +  ipa_edge_args *args;
>>>
>>>     /* During IPA-CP updating we can be called on not-yet analyzed clones.  */
>>>     if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
>>> @@ -3663,11 +3666,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>>     args = IPA_EDGE_REF (cs);
>>>     if (args->jump_functions)
>>>       {
>>> -      struct ipa_jump_func *jf;
>>> +      ipa_jump_func *jf;
>>>         int i;
>>>         FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
>>>       {
>>> -      struct ipa_cst_ref_desc *rdesc;
>>> +      ipa_cst_ref_desc *rdesc;
>>>         try_decrement_rdesc_refcount (jf);
>>>         if (jf->type == IPA_JF_CONST
>>>             && (rdesc = ipa_get_jf_constant_rdesc (jf))
>>> @@ -3679,25 +3682,13 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
>>>     ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
>>>   }
>>>
>>> -/* Hook that is called by cgraph.c when a node is removed.  */
>>> -
>>> -static void
>>> -ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>>> -{
>>> -  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
>>> -  if (ipa_node_params_vector.length () > (unsigned)node->uid)
>>> -    ipa_free_node_params_substructures (IPA_NODE_REF (node));
>>> -  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
>>> -    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
>>> -}
>>> -
>>>   /* Hook that is called by cgraph.c when an edge is duplicated.  */
>>>
>>>   static void
>>> -ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>> +ipa_edge_duplication_hook (cgraph_edge *src, cgraph_edge *dst,
>>>                  __attribute__((unused)) void *data)
>>>   {
>>> -  struct ipa_edge_args *old_args, *new_args;
>>> +  ipa_edge_args *old_args, *new_args;
>>>     unsigned int i;
>>>
>>>     ipa_check_create_edge_args ();
>>> @@ -3712,20 +3703,20 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>
>>>     for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
>>>       {
>>> -      struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
>>> -      struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
>>> +      ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
>>> +      ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
>>>
>>>         dst_jf->agg.items = vec_safe_copy (dst_jf->agg.items);
>>>
>>>         if (src_jf->type == IPA_JF_CONST)
>>>       {
>>> -      struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
>>> +      ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
>>>
>>>         if (!src_rdesc)
>>>           dst_jf->value.constant.rdesc = NULL;
>>>         else if (src->caller == dst->caller)
>>>           {
>>> -          struct ipa_ref *ref;
>>> +          ipa_ref *ref;
>>>             symtab_node *n = cgraph_node_for_jfunc (src_jf);
>>>             gcc_checking_assert (n);
>>>             ref = src->caller->find_reference (n, src->call_stmt,
>>> @@ -3734,8 +3725,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>             dst->caller->clone_reference (ref, ref->stmt);
>>>
>>>             gcc_checking_assert (ipa_refdesc_pool);
>>> -          struct ipa_cst_ref_desc *dst_rdesc
>>> -        = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>> +          ipa_cst_ref_desc *dst_rdesc
>>> +        = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>>             dst_rdesc->cs = dst;
>>>             dst_rdesc->refcount = src_rdesc->refcount;
>>>             dst_rdesc->next_duplicate = NULL;
>>> @@ -3743,10 +3734,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>           }
>>>         else if (src_rdesc->cs == src)
>>>           {
>>> -          struct ipa_cst_ref_desc *dst_rdesc;
>>> +          ipa_cst_ref_desc *dst_rdesc;
>>>             gcc_checking_assert (ipa_refdesc_pool);
>>>             dst_rdesc
>>> -        = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>> +        = (ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
>>>             dst_rdesc->cs = dst;
>>>             dst_rdesc->refcount = src_rdesc->refcount;
>>>             dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
>>> @@ -3755,7 +3746,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>           }
>>>         else
>>>           {
>>> -          struct ipa_cst_ref_desc *dst_rdesc;
>>> +          ipa_cst_ref_desc *dst_rdesc;
>>>             /* This can happen during inlining, when a JFUNC can refer to a
>>>            reference taken in a function up in the tree of inline clones.
>>>            We need to find the duplicate that refers to our tree of
>>> @@ -3766,7 +3757,7 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>              dst_rdesc;
>>>              dst_rdesc = dst_rdesc->next_duplicate)
>>>           {
>>> -          struct cgraph_node *top;
>>> +          cgraph_node *top;
>>>             top = dst_rdesc->cs->caller->global.inlined_to
>>>               ? dst_rdesc->cs->caller->global.inlined_to
>>>               : dst_rdesc->cs->caller;
>>> @@ -3780,9 +3771,9 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>         else if (dst_jf->type == IPA_JF_PASS_THROUGH
>>>              && src->caller == dst->caller)
>>>       {
>>> -      struct cgraph_node *inline_root = dst->caller->global.inlined_to
>>> +      cgraph_node *inline_root = dst->caller->global.inlined_to
>>>           ? dst->caller->global.inlined_to : dst->caller;
>>> -      struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
>>> +      ipa_node_params *root_info = IPA_NODE_REF (inline_root);
>>>         int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
>>>
>>>         int c = ipa_get_controlled_uses (root_info, idx);
>>> @@ -3795,18 +3786,24 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
>>>       }
>>>   }
>>>
>>> -/* Hook that is called by cgraph.c when a node is duplicated.  */
>>> +/* Analyze newly added function into callgraph.  */
>>>
>>>   static void
>>> -ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>>> -               ATTRIBUTE_UNUSED void *data)
>>> +ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>>>   {
>>> -  struct ipa_node_params *old_info, *new_info;
>>> -  struct ipa_agg_replacement_value *old_av, *new_av;
>>> +  if (node->has_gimple_body_p ())
>>> +    ipa_analyze_node (node);
>>> +}
>>>
>>> -  ipa_check_create_node_params ();
>>> -  old_info = IPA_NODE_REF (src);
>>> -  new_info = IPA_NODE_REF (dst);
>>> +/* Hook that is called by summary when a node is duplicated.  */
>>> +
>>> +void
>>> +ipa_node_params_cgraph_summary::duplication_hook(cgraph_node *src,
>>> +                            cgraph_node *dst,
>>> +                            ipa_node_params *old_info,
>>> +                            ipa_node_params *new_info)
>>> +{
>>> +  ipa_agg_replacement_value *old_av, *new_av;
>>>
>>>     new_info->descriptors = old_info->descriptors.copy ();
>>>     new_info->lattices = NULL;
>>> @@ -3822,7 +3819,7 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>>>     new_av = NULL;
>>>     while (old_av)
>>>       {
>>> -      struct ipa_agg_replacement_value *v;
>>> +      ipa_agg_replacement_value *v;
>>>
>>>         v = ggc_alloc<ipa_agg_replacement_value> ();
>>>         memcpy (v, old_av, sizeof (*v));
>>> @@ -3833,33 +3830,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
>>>     ipa_set_node_agg_value_chain (dst, new_av);
>>>   }
>>>
>>> -
>>> -/* Analyze newly added function into callgraph.  */
>>> -
>>> -static void
>>> -ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>>> -{
>>> -  if (node->has_gimple_body_p ())
>>> -    ipa_analyze_node (node);
>>> -}
>>> -
>>>   /* Register our cgraph hooks if they are not already there.  */
>>>
>>>   void
>>>   ipa_register_cgraph_hooks (void)
>>>   {
>>> +  ipa_check_create_node_params ();
>>> +
>>>     if (!edge_removal_hook_holder)
>>>       edge_removal_hook_holder =
>>>         symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
>>> -  if (!node_removal_hook_holder)
>>> -    node_removal_hook_holder =
>>> -      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
>>>     if (!edge_duplication_hook_holder)
>>>       edge_duplication_hook_holder =
>>>         symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
>>> -  if (!node_duplication_hook_holder)
>>> -    node_duplication_hook_holder =
>>> -      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
>>>     function_insertion_hook_holder =
>>>         symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
>>>   }
>>> @@ -3871,12 +3854,8 @@ ipa_unregister_cgraph_hooks (void)
>>>   {
>>>     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
>>>     edge_removal_hook_holder = NULL;
>>> -  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
>>> -  node_removal_hook_holder = NULL;
>>>     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
>>>     edge_duplication_hook_holder = NULL;
>>> -  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
>>> -  node_duplication_hook_holder = NULL;
>>>     symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
>>>     function_insertion_hook_holder = NULL;
>>>   }
>>> @@ -3923,10 +3902,10 @@ ipa_free_all_structures_after_iinln (void)
>>>      callgraph to F.  */
>>>
>>>   void
>>> -ipa_print_node_params (FILE *f, struct cgraph_node *node)
>>> +ipa_print_node_params (FILE *f, cgraph_node *node)
>>>   {
>>>     int i, count;
>>> -  struct ipa_node_params *info;
>>> +  ipa_node_params *info;
>>>
>>>     if (!node->definition)
>>>       return;
>>> @@ -3957,7 +3936,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
>>>   void
>>>   ipa_print_all_params (FILE * f)
>>>   {
>>> -  struct cgraph_node *node;
>>> +  cgraph_node *node;
>>>
>>>     fprintf (f, "\nFunction parameters:\n");
>>>     FOR_EACH_FUNCTION (node)
>>> @@ -4040,7 +4019,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
>>>     tree new_arg_types = NULL;
>>>     for (int i = 0; i < len; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *adj;
>>> +      ipa_parm_adjustment *adj;
>>>         gcc_assert (link);
>>>
>>>         adj = &adjustments[i];
>>> @@ -4158,10 +4137,10 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
>>>      contain the corresponding call graph edge.  */
>>>
>>>   void
>>> -ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
>>> +ipa_modify_call_arguments (cgraph_edge *cs, gimple stmt,
>>>                  ipa_parm_adjustment_vec adjustments)
>>>   {
>>> -  struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
>>> +  cgraph_node *current_node = cgraph_node::get (current_function_decl);
>>>     vec<tree> vargs;
>>>     vec<tree, va_gc> **debug_args = NULL;
>>>     gimple new_stmt;
>>> @@ -4179,7 +4158,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
>>>     gsi_prev (&prev_gsi);
>>>     for (i = 0; i < len; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *adj;
>>> +      ipa_parm_adjustment *adj;
>>>
>>>         adj = &adjustments[i];
>>>
>>> @@ -4412,7 +4391,7 @@ bool
>>>   ipa_modify_expr (tree *expr, bool convert,
>>>            ipa_parm_adjustment_vec adjustments)
>>>   {
>>> -  struct ipa_parm_adjustment *cand
>>> +  ipa_parm_adjustment *cand
>>>       = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
>>>     if (!cand)
>>>       return false;
>>> @@ -4500,11 +4479,11 @@ ipa_get_adjustment_candidate (tree **expr, bool *convert,
>>>     if (!base || TREE_CODE (base) != PARM_DECL)
>>>       return NULL;
>>>
>>> -  struct ipa_parm_adjustment *cand = NULL;
>>> +  ipa_parm_adjustment *cand = NULL;
>>>     unsigned int len = adjustments.length ();
>>>     for (unsigned i = 0; i < len; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *adj = &adjustments[i];
>>> +      ipa_parm_adjustment *adj = &adjustments[i];
>>>
>>>         if (adj->base == base
>>>         && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
>>> @@ -4530,7 +4509,7 @@ index_in_adjustments_multiple_times_p (int base_index,
>>>
>>>     for (i = 0; i < len; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *adj;
>>> +      ipa_parm_adjustment *adj;
>>>         adj = &adjustments[i];
>>>
>>>         if (adj->base_index == base_index)
>>> @@ -4561,7 +4540,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>>>     tmp.create (inlen);
>>>     for (i = 0; i < inlen; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *n;
>>> +      ipa_parm_adjustment *n;
>>>         n = &inner[i];
>>>
>>>         if (n->op == IPA_PARM_OP_REMOVE)
>>> @@ -4577,9 +4556,9 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>>>     adjustments.create (outlen + removals);
>>>     for (i = 0; i < outlen; i++)
>>>       {
>>> -      struct ipa_parm_adjustment r;
>>> -      struct ipa_parm_adjustment *out = &outer[i];
>>> -      struct ipa_parm_adjustment *in = &tmp[out->base_index];
>>> +      ipa_parm_adjustment r;
>>> +      ipa_parm_adjustment *out = &outer[i];
>>> +      ipa_parm_adjustment *in = &tmp[out->base_index];
>>>
>>>         memset (&r, 0, sizeof (r));
>>>         gcc_assert (in->op != IPA_PARM_OP_REMOVE);
>>> @@ -4616,7 +4595,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
>>>
>>>     for (i = 0; i < inlen; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *n = &inner[i];
>>> +      ipa_parm_adjustment *n = &inner[i];
>>>
>>>         if (n->op == IPA_PARM_OP_REMOVE)
>>>       adjustments.quick_push (*n);
>>> @@ -4640,7 +4619,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
>>>     fprintf (file, "IPA param adjustments: ");
>>>     for (i = 0; i < len; i++)
>>>       {
>>> -      struct ipa_parm_adjustment *adj;
>>> +      ipa_parm_adjustment *adj;
>>>         adj = &adjustments[i];
>>>
>>>         if (!first)
>>> @@ -4683,7 +4662,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
>>>   /* Dump the AV linked list.  */
>>>
>>>   void
>>> -ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
>>> +ipa_dump_agg_replacement_values (FILE *f, ipa_agg_replacement_value *av)
>>>   {
>>>     bool comma = false;
>>>     fprintf (f, "     Aggregate replacements:");
>>> @@ -4700,11 +4679,11 @@ ipa_dump_agg_replacement_values (FILE *f, struct ipa_agg_replacement_value *av)
>>>   /* Stream out jump function JUMP_FUNC to OB.  */
>>>
>>>   static void
>>> -ipa_write_jump_function (struct output_block *ob,
>>> -             struct ipa_jump_func *jump_func)
>>> +ipa_write_jump_function (output_block *ob,
>>> +             ipa_jump_func *jump_func)
>>>   {
>>> -  struct ipa_agg_jf_item *item;
>>> -  struct bitpack_d bp;
>>> +  ipa_agg_jf_item *item;
>>> +  bitpack_d bp;
>>>     int i, count;
>>>
>>>     streamer_write_uhwi (ob, jump_func->type);
>>> @@ -4768,10 +4747,10 @@ ipa_write_jump_function (struct output_block *ob,
>>>   /* Read in jump function JUMP_FUNC from IB.  */
>>>
>>>   static void
>>> -ipa_read_jump_function (struct lto_input_block *ib,
>>> -            struct ipa_jump_func *jump_func,
>>> -            struct cgraph_edge *cs,
>>> -            struct data_in *data_in)
>>> +ipa_read_jump_function (lto_input_block *ib,
>>> +            ipa_jump_func *jump_func,
>>> +            cgraph_edge *cs,
>>> +            data_in *data_in)
>>>   {
>>>     enum jump_func_type jftype;
>>>     enum tree_code operation;
>>> @@ -4800,7 +4779,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>>         if (operation == NOP_EXPR)
>>>       {
>>>         int formal_id =  streamer_read_uhwi (ib);
>>> -      struct bitpack_d bp = streamer_read_bitpack (ib);
>>> +      bitpack_d bp = streamer_read_bitpack (ib);
>>>         bool agg_preserved = bp_unpack_value (&bp, 1);
>>>         bool type_preserved = bp_unpack_value (&bp, 1);
>>>         ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
>>> @@ -4819,7 +4798,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>>       HOST_WIDE_INT offset = streamer_read_uhwi (ib);
>>>       tree type = stream_read_tree (ib, data_in);
>>>       int formal_id = streamer_read_uhwi (ib);
>>> -    struct bitpack_d bp = streamer_read_bitpack (ib);
>>> +    bitpack_d bp = streamer_read_bitpack (ib);
>>>       bool agg_preserved = bp_unpack_value (&bp, 1);
>>>       bool type_preserved = bp_unpack_value (&bp, 1);
>>>
>>> @@ -4833,12 +4812,12 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>>     vec_alloc (jump_func->agg.items, count);
>>>     if (count)
>>>       {
>>> -      struct bitpack_d bp = streamer_read_bitpack (ib);
>>> +      bitpack_d bp = streamer_read_bitpack (ib);
>>>         jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
>>>       }
>>>     for (i = 0; i < count; i++)
>>>       {
>>> -      struct ipa_agg_jf_item item;
>>> +      ipa_agg_jf_item item;
>>>         item.offset = streamer_read_uhwi (ib);
>>>         item.value = stream_read_tree (ib, data_in);
>>>         jump_func->agg.items->quick_push (item);
>>> @@ -4849,11 +4828,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
>>>      relevant to indirect inlining to OB.  */
>>>
>>>   static void
>>> -ipa_write_indirect_edge_info (struct output_block *ob,
>>> -                  struct cgraph_edge *cs)
>>> +ipa_write_indirect_edge_info (output_block *ob,
>>> +                  cgraph_edge *cs)
>>>   {
>>> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
>>> -  struct bitpack_d bp;
>>> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>>> +  bitpack_d bp;
>>>
>>>     streamer_write_hwi (ob, ii->param_index);
>>>     bp = bitpack_create (ob->main_stream);
>>> @@ -4880,12 +4859,12 @@ ipa_write_indirect_edge_info (struct output_block *ob,
>>>      relevant to indirect inlining from IB.  */
>>>
>>>   static void
>>> -ipa_read_indirect_edge_info (struct lto_input_block *ib,
>>> -                 struct data_in *data_in,
>>> -                 struct cgraph_edge *cs)
>>> +ipa_read_indirect_edge_info (lto_input_block *ib,
>>> +                 data_in *data_in,
>>> +                 cgraph_edge *cs)
>>>   {
>>> -  struct cgraph_indirect_call_info *ii = cs->indirect_info;
>>> -  struct bitpack_d bp;
>>> +  cgraph_indirect_call_info *ii = cs->indirect_info;
>>> +  bitpack_d bp;
>>>
>>>     ii->param_index = (int) streamer_read_hwi (ib);
>>>     bp = streamer_read_bitpack (ib);
>>> @@ -4909,14 +4888,14 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
>>>   /* Stream out NODE info to OB.  */
>>>
>>>   static void
>>> -ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>> +ipa_write_node_info (output_block *ob, cgraph_node *node)
>>>   {
>>>     int node_ref;
>>>     lto_symtab_encoder_t encoder;
>>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>>     int j;
>>> -  struct cgraph_edge *e;
>>> -  struct bitpack_d bp;
>>> +  cgraph_edge *e;
>>> +  bitpack_d bp;
>>>
>>>     encoder = ob->decl_state->symtab_node_encoder;
>>>     node_ref = lto_symtab_encoder_encode (encoder, node);
>>> @@ -4937,7 +4916,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>>       streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
>>>     for (e = node->callees; e; e = e->next_callee)
>>>       {
>>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>>
>>>         streamer_write_uhwi (ob,
>>>                  ipa_get_cs_argument_count (args) * 2
>>> @@ -4951,7 +4930,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>>       }
>>>     for (e = node->indirect_calls; e; e = e->next_callee)
>>>       {
>>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>>
>>>         streamer_write_uhwi (ob,
>>>                  ipa_get_cs_argument_count (args) * 2
>>> @@ -4969,13 +4948,13 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
>>>   /* Stream in NODE info from IB.  */
>>>
>>>   static void
>>> -ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>> -            struct data_in *data_in)
>>> +ipa_read_node_info (lto_input_block *ib, cgraph_node *node,
>>> +            data_in *data_in)
>>>   {
>>> -  struct ipa_node_params *info = IPA_NODE_REF (node);
>>> +  ipa_node_params *info = IPA_NODE_REF (node);
>>>     int k;
>>> -  struct cgraph_edge *e;
>>> -  struct bitpack_d bp;
>>> +  cgraph_edge *e;
>>> +  bitpack_d bp;
>>>
>>>     ipa_alloc_node_params (node, streamer_read_uhwi (ib));
>>>
>>> @@ -4992,7 +4971,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>>       ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
>>>     for (e = node->callees; e; e = e->next_callee)
>>>       {
>>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>>         int count = streamer_read_uhwi (ib);
>>>         bool contexts_computed = count & 1;
>>>         count /= 2;
>>> @@ -5013,7 +4992,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>>       }
>>>     for (e = node->indirect_calls; e; e = e->next_callee)
>>>       {
>>> -      struct ipa_edge_args *args = IPA_EDGE_REF (e);
>>> +      ipa_edge_args *args = IPA_EDGE_REF (e);
>>>         int count = streamer_read_uhwi (ib);
>>>         bool contexts_computed = count & 1;
>>>         count /= 2;
>>> @@ -5040,14 +5019,13 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
>>>   void
>>>   ipa_prop_write_jump_functions (void)
>>>   {
>>> -  struct cgraph_node *node;
>>> -  struct output_block *ob;
>>> +  cgraph_node *node;
>>> +  output_block *ob;
>>>     unsigned int count = 0;
>>>     lto_symtab_encoder_iterator lsei;
>>>     lto_symtab_encoder_t encoder;
>>>
>>> -
>>> -  if (!ipa_node_params_vector.exists ())
>>> +  if (!ipa_node_params_summary)
>>>       return;
>>>
>>>     ob = create_output_block (LTO_section_jump_functions);
>>> @@ -5081,15 +5059,15 @@ ipa_prop_write_jump_functions (void)
>>>   /* Read section in file FILE_DATA of length LEN with data DATA.  */
>>>
>>>   static void
>>> -ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>>> +ipa_prop_read_section (lto_file_decl_data *file_data, const char *data,
>>>                  size_t len)
>>>   {
>>> -  const struct lto_function_header *header =
>>> -    (const struct lto_function_header *) data;
>>> -  const int cfg_offset = sizeof (struct lto_function_header);
>>> +  const lto_function_header *header =
>>> +    (const lto_function_header *) data;
>>> +  const int cfg_offset = sizeof (lto_function_header);
>>>     const int main_offset = cfg_offset + header->cfg_size;
>>>     const int string_offset = main_offset + header->main_size;
>>> -  struct data_in *data_in;
>>> +  data_in *data_in;
>>>     unsigned int i;
>>>     unsigned int count;
>>>
>>> @@ -5104,7 +5082,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>>>     for (i = 0; i < count; i++)
>>>       {
>>>         unsigned int index;
>>> -      struct cgraph_node *node;
>>> +      cgraph_node *node;
>>>         lto_symtab_encoder_t encoder;
>>>
>>>         index = streamer_read_uhwi (&ib_main);
>>> @@ -5124,8 +5102,8 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
>>>   void
>>>   ipa_prop_read_jump_functions (void)
>>>   {
>>> -  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>>> -  struct lto_file_decl_data *file_data;
>>> +  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>>> +  lto_file_decl_data *file_data;
>>>     unsigned int j = 0;
>>>
>>>     ipa_check_create_node_params ();
>>> @@ -5154,12 +5132,12 @@ ipa_update_after_lto_read (void)
>>>   }
>>>
>>>   void
>>> -write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>>> +write_agg_replacement_chain (output_block *ob, cgraph_node *node)
>>>   {
>>>     int node_ref;
>>>     unsigned int count = 0;
>>>     lto_symtab_encoder_t encoder;
>>> -  struct ipa_agg_replacement_value *aggvals, *av;
>>> +  ipa_agg_replacement_value *aggvals, *av;
>>>
>>>     aggvals = ipa_get_agg_replacements_for_node (node);
>>>     encoder = ob->decl_state->symtab_node_encoder;
>>> @@ -5172,7 +5150,7 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>>>
>>>     for (av = aggvals; av; av = av->next)
>>>       {
>>> -      struct bitpack_d bp;
>>> +      bitpack_d bp;
>>>
>>>         streamer_write_uhwi (ob, av->offset);
>>>         streamer_write_uhwi (ob, av->index);
>>> @@ -5187,18 +5165,18 @@ write_agg_replacement_chain (struct output_block *ob, struct cgraph_node *node)
>>>   /* Stream in the aggregate value replacement chain for NODE from IB.  */
>>>
>>>   static void
>>> -read_agg_replacement_chain (struct lto_input_block *ib,
>>> -                struct cgraph_node *node,
>>> -                struct data_in *data_in)
>>> +read_agg_replacement_chain (lto_input_block *ib,
>>> +                cgraph_node *node,
>>> +                data_in *data_in)
>>>   {
>>> -  struct ipa_agg_replacement_value *aggvals = NULL;
>>> +  ipa_agg_replacement_value *aggvals = NULL;
>>>     unsigned int count, i;
>>>
>>>     count = streamer_read_uhwi (ib);
>>>     for (i = 0; i <count; i++)
>>>       {
>>> -      struct ipa_agg_replacement_value *av;
>>> -      struct bitpack_d bp;
>>> +      ipa_agg_replacement_value *av;
>>> +      bitpack_d bp;
>>>
>>>         av = ggc_alloc<ipa_agg_replacement_value> ();
>>>         av->offset = streamer_read_uhwi (ib);
>>> @@ -5217,8 +5195,8 @@ read_agg_replacement_chain (struct lto_input_block *ib,
>>>   void
>>>   ipa_prop_write_all_agg_replacement (void)
>>>   {
>>> -  struct cgraph_node *node;
>>> -  struct output_block *ob;
>>> +  cgraph_node *node;
>>> +  output_block *ob;
>>>     unsigned int count = 0;
>>>     lto_symtab_encoder_iterator lsei;
>>>     lto_symtab_encoder_t encoder;
>>> @@ -5257,16 +5235,16 @@ ipa_prop_write_all_agg_replacement (void)
>>>      DATA.  */
>>>
>>>   static void
>>> -read_replacements_section (struct lto_file_decl_data *file_data,
>>> +read_replacements_section (lto_file_decl_data *file_data,
>>>                  const char *data,
>>>                  size_t len)
>>>   {
>>> -  const struct lto_function_header *header =
>>> -    (const struct lto_function_header *) data;
>>> -  const int cfg_offset = sizeof (struct lto_function_header);
>>> +  const lto_function_header *header =
>>> +    (const lto_function_header *) data;
>>> +  const int cfg_offset = sizeof (lto_function_header);
>>>     const int main_offset = cfg_offset + header->cfg_size;
>>>     const int string_offset = main_offset + header->main_size;
>>> -  struct data_in *data_in;
>>> +  data_in *data_in;
>>>     unsigned int i;
>>>     unsigned int count;
>>>
>>> @@ -5280,7 +5258,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
>>>     for (i = 0; i < count; i++)
>>>       {
>>>         unsigned int index;
>>> -      struct cgraph_node *node;
>>> +      cgraph_node *node;
>>>         lto_symtab_encoder_t encoder;
>>>
>>>         index = streamer_read_uhwi (&ib_main);
>>> @@ -5300,8 +5278,8 @@ read_replacements_section (struct lto_file_decl_data *file_data,
>>>   void
>>>   ipa_prop_read_all_agg_replacement (void)
>>>   {
>>> -  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>>> -  struct lto_file_decl_data *file_data;
>>> +  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>>> +  lto_file_decl_data *file_data;
>>>     unsigned int j = 0;
>>>
>>>     while ((file_data = file_data_vec[j++]))
>>> @@ -5319,10 +5297,10 @@ ipa_prop_read_all_agg_replacement (void)
>>>      NODE.  */
>>>
>>>   static void
>>> -adjust_agg_replacement_values (struct cgraph_node *node,
>>> -                   struct ipa_agg_replacement_value *aggval)
>>> +adjust_agg_replacement_values (cgraph_node *node,
>>> +                   ipa_agg_replacement_value *aggval)
>>>   {
>>> -  struct ipa_agg_replacement_value *v;
>>> +  ipa_agg_replacement_value *v;
>>>     int i, c = 0, d = 0, *adj;
>>>
>>>     if (!node->clone.combined_args_to_skip)
>>> @@ -5355,9 +5333,9 @@ adjust_agg_replacement_values (struct cgraph_node *node,
>>>   class ipcp_modif_dom_walker : public dom_walker
>>>   {
>>>   public:
>>> -  ipcp_modif_dom_walker (struct func_body_info *fbi,
>>> +  ipcp_modif_dom_walker (func_body_info *fbi,
>>>                vec<ipa_param_descriptor> descs,
>>> -             struct ipa_agg_replacement_value *av,
>>> +             ipa_agg_replacement_value *av,
>>>                bool *sc, bool *cc)
>>>       : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
>>>         m_aggval (av), m_something_changed (sc), m_cfg_changed (cc) {}
>>> @@ -5365,9 +5343,9 @@ public:
>>>     virtual void before_dom_children (basic_block);
>>>
>>>   private:
>>> -  struct func_body_info *m_fbi;
>>> +  func_body_info *m_fbi;
>>>     vec<ipa_param_descriptor> m_descriptors;
>>> -  struct ipa_agg_replacement_value *m_aggval;
>>> +  ipa_agg_replacement_value *m_aggval;
>>>     bool *m_something_changed, *m_cfg_changed;
>>>   };
>>>
>>> @@ -5377,7 +5355,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
>>>     gimple_stmt_iterator gsi;
>>>     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>>>       {
>>> -      struct ipa_agg_replacement_value *v;
>>> +      ipa_agg_replacement_value *v;
>>>         gimple stmt = gsi_stmt (gsi);
>>>         tree rhs, val, t;
>>>         HOST_WIDE_INT offset, size;
>>> @@ -5468,11 +5446,11 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
>>>   /* IPCP transformation phase doing propagation of aggregate values.  */
>>>
>>>   unsigned int
>>> -ipcp_transform_function (struct cgraph_node *node)
>>> +ipcp_transform_function (cgraph_node *node)
>>>   {
>>>     vec<ipa_param_descriptor> descriptors = vNULL;
>>> -  struct func_body_info fbi;
>>> -  struct ipa_agg_replacement_value *aggval;
>>> +  func_body_info fbi;
>>> +  ipa_agg_replacement_value *aggval;
>>>     int param_count;
>>>     bool cfg_changed = false, something_changed = false;
>>>
>>> @@ -5507,7 +5485,7 @@ ipcp_transform_function (struct cgraph_node *node)
>>>                &cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
>>>
>>>     int i;
>>> -  struct ipa_bb_info *bi;
>>> +  ipa_bb_info *bi;
>>>     FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
>>>       free_ipa_bb_info (bi);
>>>     fbi.bb_infos.release ();
>>> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
>>> index 165fc1a..6c3b31f 100644
>>> --- a/gcc/ipa-prop.h
>>> +++ b/gcc/ipa-prop.h
>>> @@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
>>>   #ifndef IPA_PROP_H
>>>   #define IPA_PROP_H
>>>
>>> -
>>>   /* The following definitions and interfaces are used by
>>>      interprocedural analyses or parameters.  */
>>>
>>> @@ -356,6 +355,8 @@ struct ipcp_lattice;
>>>
>>>   struct ipa_node_params
>>>   {
>>> +  ~ipa_node_params ();
>>> +
>>>     /* Information about individual formal parameters that are gathered when
>>>        summaries are generated. */
>>>     vec<ipa_param_descriptor> descriptors;
>>> @@ -364,7 +365,7 @@ struct ipa_node_params
>>>     struct ipcp_param_lattices *lattices;
>>>     /* Only for versioned nodes this field would not be NULL,
>>>        it points to the node that IPA cp cloned from.  */
>>> -  struct cgraph_node *ipcp_orig_node;
>>> +  cgraph_node *ipcp_orig_node;
>>>     /* If this node is an ipa-cp clone, these are the known values that describe
>>>        what it has been specialized for.  */
>>>     vec<tree> known_vals;
>>> @@ -470,7 +471,7 @@ struct GTY(()) ipa_agg_replacement_value
>>>
>>>   typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
>>>
>>> -void ipa_set_node_agg_value_chain (struct cgraph_node *node,
>>> +void ipa_set_node_agg_value_chain (const cgraph_node *node,
>>>                      struct ipa_agg_replacement_value *aggvals);
>>>
>>>   /* ipa_edge_args stores information related to a callsite and particularly its
>>> @@ -513,10 +514,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
>>>     return &(*args->polymorphic_call_contexts)[i];
>>>   }
>>>
>>> -/* Types of vectors holding the infos.  */
>>> +/* Callgraph summary for ipa_node_params.  */
>>> +class ipa_node_params_cgraph_summary: public cgraph_summary <ipa_node_params *>
>>> +{
>>> +public:
>>> +  ipa_node_params_cgraph_summary (symbol_table *table):
>>> +    cgraph_summary <ipa_node_params *> (table) { }
>>> +
>>> +  /* Hook that is called by summary when a node is duplicated.  */
>>> +  virtual void duplication_hook (cgraph_node *node,
>>> +                 cgraph_node *node2,
>>> +                 ipa_node_params *data,
>>> +                 ipa_node_params *data2);
>>> +};
>>>
>>>   /* Vector where the parameter infos are actually stored. */
>>> -extern vec<ipa_node_params> ipa_node_params_vector;
>>> +extern ipa_node_params_cgraph_summary *ipa_node_params_summary;
>>>   /* Vector of known aggregate values in cloned nodes.  */
>>>   extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
>>>   /* Vector where the parameter infos are actually stored. */
>>> @@ -524,7 +537,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>>
>>>   /* Return the associated parameter/argument info corresponding to the given
>>>      node/edge.  */
>>> -#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
>>> +#define IPA_NODE_REF(NODE) ((*ipa_node_params_summary)[NODE])
>>>   #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
>>>   /* This macro checks validity of index returned by
>>>      ipa_get_param_decl_index function.  */
>>> @@ -534,11 +547,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
>>>   void ipa_create_all_node_params (void);
>>>   void ipa_create_all_edge_args (void);
>>>   void ipa_free_edge_args_substructures (struct ipa_edge_args *);
>>> -void ipa_free_node_params_substructures (struct ipa_node_params *);
>>>   void ipa_free_all_node_params (void);
>>>   void ipa_free_all_edge_args (void);
>>>   void ipa_free_all_structures_after_ipa_cp (void);
>>>   void ipa_free_all_structures_after_iinln (void);
>>> +
>>>   void ipa_register_cgraph_hooks (void);
>>>   int count_formal_params (tree fndecl);
>>>
>>> @@ -548,11 +561,8 @@ int count_formal_params (tree fndecl);
>>>   static inline void
>>>   ipa_check_create_node_params (void)
>>>   {
>>> -  if (!ipa_node_params_vector.exists ())
>>> -    ipa_node_params_vector.create (symtab->cgraph_max_uid);
>>> -
>>> -  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
>>> -    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
>>> +  if (!ipa_node_params_summary)
>>> +    ipa_node_params_summary = new ipa_node_params_cgraph_summary (symtab);
>>>   }
>>>
>>>   /* This function ensures the array of edge arguments infos is big enough to
>>> @@ -579,7 +589,7 @@ ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
>>>   /* Return the aggregate replacements for NODE, if there are any.  */
>>>
>>>   static inline struct ipa_agg_replacement_value *
>>> -ipa_get_agg_replacements_for_node (struct cgraph_node *node)
>>> +ipa_get_agg_replacements_for_node (const cgraph_node *node)
>>>   {
>>>     if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
>>>       return NULL;
>>> @@ -587,7 +597,7 @@ ipa_get_agg_replacements_for_node (struct cgraph_node *node)
>>>   }
>>>
>>>   /* Function formal parameters related computations.  */
>>> -void ipa_initialize_node_params (struct cgraph_node *node);
>>> +void ipa_initialize_node_params (const cgraph_node *node);
>>>   bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
>>>                       vec<cgraph_edge *> *new_edges);
>>>
>>> @@ -602,7 +612,7 @@ tree ipa_binfo_from_known_type_jfunc (struct ipa_jump_func *);
>>>   tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
>>>
>>>   /* Functions related to both.  */
>>> -void ipa_analyze_node (struct cgraph_node *);
>>> +void ipa_analyze_node (cgraph_node *);
>>>
>>>   /* Aggregate jump function related functions.  */
>>>   tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
>>> @@ -611,9 +621,9 @@ bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
>>>                    HOST_WIDE_INT *, bool *);
>>>
>>>   /* Debugging interface.  */
>>> -void ipa_print_node_params (FILE *, struct cgraph_node *node);
>>> +void ipa_print_node_params (FILE *, cgraph_node *node);
>>>   void ipa_print_all_params (FILE *);
>>> -void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
>>> +void ipa_print_node_jump_functions (FILE *f, cgraph_node *node);
>>>   void ipa_print_all_jump_functions (FILE * f);
>>>   void ipcp_verify_propagated_values (void);
>>>
>>> @@ -717,7 +727,7 @@ void ipa_update_after_lto_read (void);
>>>   int ipa_get_param_decl_index (struct ipa_node_params *, tree);
>>>   tree ipa_value_from_jfunc (struct ipa_node_params *info,
>>>                  struct ipa_jump_func *jfunc);
>>> -unsigned int ipcp_transform_function (struct cgraph_node *node);
>>> +unsigned int ipcp_transform_function (cgraph_node *node);
>>>   void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
>>>   bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
>>>   ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
>>> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
>>> index 98dbc63..0a7ca53 100644
>>> --- a/gcc/ipa-split.c
>>> +++ b/gcc/ipa-split.c
>>> @@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "gimple-ssa.h"
>>>   #include "tree-cfg.h"
>>> diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
>>> index 22900cc..83111bc 100644
>>> --- a/gcc/ipa-utils.c
>>> +++ b/gcc/ipa-utils.c
>>> @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "langhooks.h"
>>>   #include "lto-streamer.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>
>>> diff --git a/gcc/ipa.c b/gcc/ipa.c
>>> index a6086d8..aded512 100644
>>> --- a/gcc/ipa.c
>>> +++ b/gcc/ipa.c
>>> @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "tree-iterator.h"
>>>   #include "ipa-utils.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "tree-inline.h"
>>> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
>>> index 0e1a95b..37d0f39 100644
>>> --- a/gcc/lto/lto-partition.c
>>> +++ b/gcc/lto/lto-partition.c
>>> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "timevar.h"
>>>   #include "params.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "ipa-utils.h"
>>> diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
>>> index 4c4e48a..ee97d06 100644
>>> --- a/gcc/lto/lto-symtab.c
>>> +++ b/gcc/lto/lto-symtab.c
>>> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "lto-streamer.h"
>>>   #include "ipa-utils.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "ipa-inline.h"
>>>   #include "builtins.h"
>>> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
>>> index d8519d9..c99dbdf 100644
>>> --- a/gcc/lto/lto.c
>>> +++ b/gcc/lto/lto.c
>>> @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "bitmap.h"
>>>   #include "inchash.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "common.h"
>>>   #include "debug.h"
>>> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
>>> index b59d069..707379a 100644
>>> --- a/gcc/omp-low.c
>>> +++ b/gcc/omp-low.c
>>> @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "tree-cfgcleanup.h"
>>>   #include "pretty-print.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "tree-nested.h"
>>>   #include "tree-eh.h"
>>> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
>>> index 8cb9510..a8e3561 100644
>>> --- a/gcc/tree-inline.c
>>> +++ b/gcc/tree-inline.c
>>> @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>>   #include "alloc-pool.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "value-prof.h"
>>>   #include "tree-pass.h"
>>> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
>>> index 1e629bc..99b19b8 100644
>>> --- a/gcc/tree-sra.c
>>> +++ b/gcc/tree-sra.c
>>> @@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "plugin-api.h"
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "statistics.h"
>>>   #include "params.h"
>>> diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
>>> index ea99198..b526cc9 100644
>>> --- a/gcc/tree-ssa-pre.c
>>> +++ b/gcc/tree-ssa-pre.c
>>> @@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   #include "plugin-api.h"
>>>   #include "ipa-ref.h"
>>>   #include "cgraph.h"
>>> +#include "cgraph_summary.h"
>>>   #include "ipa-prop.h"
>>>   #include "tree-ssa-propagate.h"
>>>   #include "ipa-utils.h"
>>>
>>
>> Patch v2.
>>
>> Martin
>
> Patch v3.
>
> Martin

Version v4.

Martin

[-- Attachment #2: 0002-ipa-prop-uses-symbol_summary-class.patch --]
[-- Type: text/x-patch, Size: 24463 bytes --]

From 28747d788fc962dc554e2e06f053536a76d2cf48 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 5 Dec 2014 15:59:18 +0100
Subject: [PATCH 2/3] ipa-prop uses symbol_summary class.

gcc/lto/ChangeLog:

2014-12-08  Martin Liska  <mliska@suse.cz>

	* lto-partition.c: Include of symbol-summary.h is added.
	* lto-symtab.c: Likewise.
	* lto.c: Likewise.

gcc/ChangeLog:

2014-12-08  Martin Liska  <mliska@suse.cz>

	* auto-profile.c: Include of symtab-summary.h is added.
	* cgraph.c: Likewise.
	* cgraphbuild.c: Likewise.
	* cgraphclones.c: Likewise.
	* cgraphunit.c: Likewise.
	* ipa-cp.c: Likewise.
	* ipa-devirt.c: Likewise.
	* ipa-icf.c: Likewise.
	* ipa-inline-analysis.c (evaluate_properties_for_edge): New
	ipa_node_params_d data structure is used.
	(inline_node_duplication_hook): Likewise.
	(estimate_function_body_sizes): Likewise.
	(remap_edge_change_prob): Likewise.
	(inline_merge_summary): Likewise.
	* ipa-inline-transform.c: Include of symtab-summary.h is added.
	* ipa-inline.c (early_inliner): New ipa_node_params_d data structure
	is used.
	* ipa-polymorphic-call.c: Include of symtab-summary.h is added.
	* ipa-profile.c: Include of symtab-summary.h is added.
	* ipa-prop.c (ipa_propagate_indirect_call_infos): New ipa_node_params_d
	data structure is used.
	(ipa_node_params::~ipa_node_params): New function.
	(ipa_free_all_node_params): Destruction is simplified.
	(ipa_node_removal_hook): Removed.
	(ipa_add_new_function): Renamed from ipa_node_duplication_hook.
	(ipa_node_params_t::duplicate): New function.
	(ipa_register_cgraph_hooks): Few hooks are removed.
	(ipa_unregister_cgraph_hooks): Likewise.
	(ipa_prop_write_jump_functions): New ipa_node_params_d is used.
	* ipa-prop.h (struct ipa_node_params): Destructor instroduced for
	the structure.
	(ipa_check_create_node_params): Vector for ipa_node_params is replaced
	with function_summary.
	* ipa-split.c: Include of symtab-summary.h is added.
	* ipa-utils.c: Include of symtab-summary.h is added.
	* ipa.c: Include of symtab-summary.h is added.
	* omp-low.c: Include of symtab-summary.h is added.
	* tree-inline.c: Include of symtab-summary.h is added.
	* tree-sra.c: Include of symtab-summary.h is added.
	* tree-ssa-pre.c: Include of symtab-summary.h is added.
---
 gcc/auto-profile.c         |  1 +
 gcc/cgraph.c               |  1 +
 gcc/cgraphbuild.c          |  1 +
 gcc/cgraphclones.c         |  1 +
 gcc/cgraphunit.c           |  1 +
 gcc/ipa-cp.c               |  1 +
 gcc/ipa-devirt.c           |  1 +
 gcc/ipa-icf.c              |  1 +
 gcc/ipa-inline-analysis.c  | 13 ++++---
 gcc/ipa-inline-transform.c |  1 +
 gcc/ipa-inline.c           |  3 +-
 gcc/ipa-polymorphic-call.c |  1 +
 gcc/ipa-profile.c          |  1 +
 gcc/ipa-prop.c             | 97 +++++++++++++++++-----------------------------
 gcc/ipa-prop.h             | 32 +++++++++------
 gcc/ipa-split.c            |  1 +
 gcc/ipa-utils.c            |  1 +
 gcc/ipa.c                  |  1 +
 gcc/lto/lto-partition.c    |  1 +
 gcc/lto/lto-symtab.c       |  1 +
 gcc/lto/lto.c              |  1 +
 gcc/omp-low.c              |  1 +
 gcc/tree-inline.c          |  1 +
 gcc/tree-sra.c             |  1 +
 gcc/tree-ssa-pre.c         |  1 +
 25 files changed, 86 insertions(+), 80 deletions(-)

diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index 7055c4a..614b776 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coverage.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 5323468..196dad8 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 53acb43..2a5bc9b 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "except.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 086dd92..96d1e2c 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -103,6 +103,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-dump.h"
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 2fd99a7..664e67c 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -203,6 +203,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-iterator.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index f97912b..a60100c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -123,6 +123,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "tree-pass.h"
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 41d4554..dce8ba5 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index e0633e7..e3b9a82 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -87,6 +87,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "cfgloop.h"
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 2f2993c..be80a0a 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
@@ -911,7 +912,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
   if (known_contexts_ptr)
     known_contexts_ptr->create (0);
 
-  if (ipa_node_params_vector.exists ()
+  if (ipa_node_params_d
       && !e->call_stmt_cannot_inline_p
       && ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
     {
@@ -1133,7 +1134,7 @@ inline_node_duplication_hook (struct cgraph_node *src,
 
   /* When there are any replacements in the function body, see if we can figure
      out that something was optimized out.  */
-  if (ipa_node_params_vector.exists () && dst->clone.tree_map)
+  if (ipa_node_params_d && dst->clone.tree_map)
     {
       vec<size_time_entry, va_gc> *entry = info->entry;
       /* Use SRC parm info since it may not be copied yet.  */
@@ -2479,7 +2480,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
       calculate_dominance_info (CDI_DOMINATORS);
       loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
 
-      if (ipa_node_params_vector.exists ())
+      if (ipa_node_params_d)
 	{
 	  parms_info = IPA_NODE_REF (node);
 	  nonconstant_names.safe_grow_cleared
@@ -2629,7 +2630,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 		  nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
 		    = false_p;
 		}
-	      if (ipa_node_params_vector.exists ())
+	      if (ipa_node_params_d)
 		{
 		  int count = gimple_call_num_args (stmt);
 		  int i;
@@ -3374,7 +3375,7 @@ static void
 remap_edge_change_prob (struct cgraph_edge *inlined_edge,
 			struct cgraph_edge *edge)
 {
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_d)
     {
       int i;
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
@@ -3530,7 +3531,7 @@ inline_merge_summary (struct cgraph_edge *edge)
   else
     toplev_predicate = true_predicate ();
 
-  if (ipa_node_params_vector.exists () && callee_info->conds)
+  if (ipa_node_params_d && callee_info->conds)
     {
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
       int count = ipa_get_cs_argument_count (args);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 063cd94..62f68f0 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 26335ec..aebfaba 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -128,6 +128,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "except.h"
 #include "target.h"
@@ -2390,7 +2391,7 @@ early_inliner (function *fun)
      it.  This may confuse ourself when early inliner decide to inline call to
      function clone, because function clones don't have parameter list in
      ipa-prop matching their signature.  */
-  if (ipa_node_params_vector.exists ())
+  if (ipa_node_params_d)
     return 0;
 
 #ifdef ENABLE_CHECKING
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 6fed594..1b04dbb 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "diagnostic.h"
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index 340d033..73ab944 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "lto-streamer.h"
 #include "data-streamer.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 2e0016b..9416b6d 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "bitmap.h"
 #include "gimple-ssa.h"
@@ -131,8 +132,8 @@ struct func_body_info
   unsigned int aa_walked;
 };
 
-/* Vector where the parameter infos are actually stored. */
-vec<ipa_node_params> ipa_node_params_vector;
+/* Function summary where the parameter infos are actually stored. */
+ipa_node_params_t *ipa_node_params_d = NULL;
 /* Vector of known aggregate values in cloned nodes.  */
 vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
@@ -140,9 +141,7 @@ vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Holders of ipa cgraph hooks: */
 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
 static struct cgraph_node_hook_list *function_insertion_hook_holder;
 
 /* Description of a reference to an IPA constant.  */
@@ -3263,7 +3262,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
   bool changed;
   /* Do nothing if the preparation phase has not been carried out yet
      (i.e. during early inlining).  */
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_d)
     return false;
   gcc_assert (ipa_edge_args_vector);
 
@@ -3303,16 +3302,21 @@ ipa_free_all_edge_args (void)
 /* Frees all dynamically allocated structures that the param info points
    to.  */
 
-void
-ipa_free_node_params_substructures (struct ipa_node_params *info)
+ipa_node_params::~ipa_node_params ()
 {
-  info->descriptors.release ();
-  free (info->lattices);
+  descriptors.release ();
+  free (lattices);
   /* Lattice values and their sources are deallocated with their alocation
      pool.  */
-  info->known_csts.release ();
-  info->known_contexts.release ();
-  memset (info, 0, sizeof (*info));
+  known_contexts.release ();
+
+  lattices = NULL;
+  ipcp_orig_node = NULL;
+  analysis_done = 0;
+  node_enqueued = 0;
+  do_clone_for_all_contexts = 0;
+  is_all_contexts_clone = 0;
+  node_dead = 0;
 }
 
 /* Free all ipa_node_params structures.  */
@@ -3320,13 +3324,8 @@ ipa_free_node_params_substructures (struct ipa_node_params *info)
 void
 ipa_free_all_node_params (void)
 {
-  int i;
-  struct ipa_node_params *info;
-
-  FOR_EACH_VEC_ELT (ipa_node_params_vector, i, info)
-    ipa_free_node_params_substructures (info);
-
-  ipa_node_params_vector.release ();
+  delete ipa_node_params_d;
+  ipa_node_params_d = NULL;
 }
 
 /* Set the aggregate replacements of NODE to be AGGVALS.  */
@@ -3373,23 +3372,11 @@ ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
   ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
 }
 
-/* Hook that is called by cgraph.c when a node is removed.  */
-
-static void
-ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
-  if (ipa_node_params_vector.length () > (unsigned)node->uid)
-    ipa_free_node_params_substructures (IPA_NODE_REF (node));
-  if (vec_safe_length (ipa_node_agg_replacements) > (unsigned)node->uid)
-    (*ipa_node_agg_replacements)[(unsigned)node->uid] = NULL;
-}
-
 /* Hook that is called by cgraph.c when an edge is duplicated.  */
 
 static void
 ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
-			   __attribute__((unused)) void *data)
+			   void *)
 {
   struct ipa_edge_args *old_args, *new_args;
   unsigned int i;
@@ -3489,18 +3476,23 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
     }
 }
 
-/* Hook that is called by cgraph.c when a node is duplicated.  */
+/* Analyze newly added function into callgraph.  */
 
 static void
-ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
-			   ATTRIBUTE_UNUSED void *data)
+ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 {
-  struct ipa_node_params *old_info, *new_info;
-  struct ipa_agg_replacement_value *old_av, *new_av;
+  if (node->has_gimple_body_p ())
+    ipa_analyze_node (node);
+}
 
-  ipa_check_create_node_params ();
-  old_info = IPA_NODE_REF (src);
-  new_info = IPA_NODE_REF (dst);
+/* Hook that is called by summary when a node is duplicated.  */
+
+void
+ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst,
+			     ipa_node_params *old_info,
+			     ipa_node_params *new_info)
+{
+  ipa_agg_replacement_value *old_av, *new_av;
 
   new_info->descriptors = old_info->descriptors.copy ();
   new_info->lattices = NULL;
@@ -3527,33 +3519,19 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
   ipa_set_node_agg_value_chain (dst, new_av);
 }
 
-
-/* Analyze newly added function into callgraph.  */
-
-static void
-ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
-  if (node->has_gimple_body_p ())
-    ipa_analyze_node (node);
-}
-
 /* Register our cgraph hooks if they are not already there.  */
 
 void
 ipa_register_cgraph_hooks (void)
 {
+  ipa_check_create_node_params ();
+
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&ipa_node_removal_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&ipa_node_duplication_hook, NULL);
   function_insertion_hook_holder =
       symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
 }
@@ -3565,12 +3543,8 @@ ipa_unregister_cgraph_hooks (void)
 {
   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
   symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
-  symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
   function_insertion_hook_holder = NULL;
 }
@@ -4720,8 +4694,7 @@ ipa_prop_write_jump_functions (void)
   lto_symtab_encoder_iterator lsei;
   lto_symtab_encoder_t encoder;
 
-
-  if (!ipa_node_params_vector.exists ())
+  if (!ipa_node_params_d)
     return;
 
   ob = create_output_block (LTO_section_jump_functions);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 9190aad..d02353e 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef IPA_PROP_H
 #define IPA_PROP_H
 
-
 /* The following definitions and interfaces are used by
    interprocedural analyses or parameters.  */
 
@@ -287,6 +286,8 @@ struct ipa_param_descriptor
 
 struct ipa_node_params
 {
+  ~ipa_node_params ();
+
   /* Information about individual formal parameters that are gathered when
      summaries are generated. */
   vec<ipa_param_descriptor> descriptors;
@@ -447,10 +448,22 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Types of vectors holding the infos.  */
+/* Callgraph summary for ipa_node_params.  */
+class ipa_node_params_t: public function_summary <ipa_node_params *>
+{
+public:
+  ipa_node_params_t (symbol_table *table):
+    function_summary<ipa_node_params *> (table) { }
 
-/* Vector where the parameter infos are actually stored. */
-extern vec<ipa_node_params> ipa_node_params_vector;
+  /* Hook that is called by summary when a node is duplicated.  */
+  virtual void duplicate (cgraph_node *node,
+			  cgraph_node *node2,
+			  ipa_node_params *data,
+			  ipa_node_params *data2);
+};
+
+/* Function summary where the parameter infos are actually stored. */
+extern ipa_node_params_t *ipa_node_params_d;
 /* Vector of known aggregate values in cloned nodes.  */
 extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
 /* Vector where the parameter infos are actually stored. */
@@ -458,7 +471,7 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 
 /* Return the associated parameter/argument info corresponding to the given
    node/edge.  */
-#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
+#define IPA_NODE_REF(NODE) (ipa_node_params_d->get (NODE))
 #define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
 /* This macro checks validity of index returned by
    ipa_get_param_decl_index function.  */
@@ -468,11 +481,11 @@ extern GTY(()) vec<ipa_edge_args, va_gc> *ipa_edge_args_vector;
 void ipa_create_all_node_params (void);
 void ipa_create_all_edge_args (void);
 void ipa_free_edge_args_substructures (struct ipa_edge_args *);
-void ipa_free_node_params_substructures (struct ipa_node_params *);
 void ipa_free_all_node_params (void);
 void ipa_free_all_edge_args (void);
 void ipa_free_all_structures_after_ipa_cp (void);
 void ipa_free_all_structures_after_iinln (void);
+
 void ipa_register_cgraph_hooks (void);
 int count_formal_params (tree fndecl);
 
@@ -482,11 +495,8 @@ int count_formal_params (tree fndecl);
 static inline void
 ipa_check_create_node_params (void)
 {
-  if (!ipa_node_params_vector.exists ())
-    ipa_node_params_vector.create (symtab->cgraph_max_uid);
-
-  if (ipa_node_params_vector.length () <= (unsigned) symtab->cgraph_max_uid)
-    ipa_node_params_vector.safe_grow_cleared (symtab->cgraph_max_uid + 1);
+  if (!ipa_node_params_d)
+    ipa_node_params_d = new ipa_node_params_t (symtab);
 }
 
 /* This function ensures the array of edge arguments infos is big enough to
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 134b33f..1123d070 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -109,6 +109,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "gimple-ssa.h"
 #include "tree-cfg.h"
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 7613205..a0d699b 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "lto-streamer.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 4f87b75..16e264d 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-iterator.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "tree-inline.h"
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 65f0582..2bbb91c 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "params.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "ipa-utils.h"
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 4c4e48a..1afdf73 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-streamer.h"
 #include "ipa-utils.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "builtins.h"
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index a1cd958..af5fc6c 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "inchash.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "common.h"
 #include "debug.h"
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 3924282..43a8181 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfgcleanup.h"
 #include "pretty-print.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-nested.h"
 #include "tree-eh.h"
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index d4864ae..279474d 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "alloc-pool.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "value-prof.h"
 #include "tree-pass.h"
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 0d5bcef..26c9226 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "statistics.h"
 #include "params.h"
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 933cf36..062dc68 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin-api.h"
 #include "ipa-ref.h"
 #include "cgraph.h"
+#include "symbol-summary.h"
 #include "ipa-prop.h"
 #include "tree-ssa-propagate.h"
 #include "ipa-utils.h"
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-11-14 15:32       ` Martin Liška
@ 2014-12-08 17:03         ` Martin Liška
  2014-12-18 19:56           ` Jan Hubicka
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-12-08 17:03 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3839 bytes --]

On 11/14/2014 04:24 PM, Martin Liška wrote:
> On 11/14/2014 03:09 PM, Martin Liška wrote:
>> On 11/13/2014 05:04 PM, Jan Hubicka wrote:
>>>> +  if (!inline_summary_summary)
>>>> +    inline_summary_summary = (inline_summary_cgraph_summary *) inline_summary_cgraph_summary::create_ggc (symtab);
>>>
>>> Hehe, this is funny naming scheme.
>>> Peraps inline_summary_d and inline_summary_t for the data and type?
>>
>> Hello.
>>
>> I adopted suggested naming scheme.
>>
>>>> -
>>>> -static void
>>>> -inline_node_duplication_hook (struct cgraph_node *src,
>>>> -                  struct cgraph_node *dst,
>>>> -                  ATTRIBUTE_UNUSED void *data)
>>>> +void
>>>> +inline_summary_cgraph_summary::duplication_hook (cgraph_node *src,
>>>> +                  cgraph_node *dst,
>>>> +                  inline_summary *,
>>>> +                  inline_summary *info)
>>>
>>> Becuase those are no longer "hooks" but virtual function, I guess we could call them
>>> simply duplicate/insert/remove.
>>
>> Agree with the change.
>>
>>>
>>> In a way I would like to see these to be methods of the underlying type rather than
>>> virtual methods of the summary, becuase these are operations on the data themselves.
>>> I was thinking to model these by specual constructor and copy constructor
>>> (taking the extra node pointer parameters) and standard destructor.  I am not sure this
>>> would be more understandable this way?
>>
>> Motivation for this implementation is:
>> a) it's useful to have an access to cgraph_node that is associated with a sumary
>> b) with GTY, we cannot call destructors
>>
>>>> -/* Need a typedef for inline_summary because of inline function
>>>> -   'inline_summary' below.  */
>>>> -typedef struct inline_summary inline_summary_t;
>>>> -extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
>>>> +class GTY((user)) inline_summary_cgraph_summary: public cgraph_summary <inline_summary *>
>>>> +{
>>>> +public:
>>>> +  inline_summary_cgraph_summary (symbol_table *symtab, bool ggc):
>>>> +    cgraph_summary <inline_summary *> (symtab, ggc) {}
>>>> +
>>>> +  static inline_summary_cgraph_summary *create_ggc (symbol_table *symtab)
>>>> +  {
>>>> +    inline_summary_cgraph_summary *summary = new (ggc_cleared_alloc <inline_summary_cgraph_summary> ()) inline_summary_cgraph_summary(symtab, true);
>>>> +    summary->disable_insertion_hook ();
>>>> +    return summary;
>>>> +  }
>>>> +
>>>> +
>>>> +  virtual void insertion_hook (cgraph_node *, inline_summary *);
>>>> +  virtual void removal_hook (cgraph_node *node, inline_summary *);
>>>> +  virtual void duplication_hook (cgraph_node *src, cgraph_node *dst, inline_summary *src_data, inline_summary *dst_data);
>>>> +};
>>>> +
>>>> +extern GTY(()) cgraph_summary <inline_summary *> *inline_summary_summary;
>>>
>>> All in all it looks better than original code.  If we moved insert/
>>>>
>>>>   /* Information kept about parameter of call site.  */
>>>>   struct inline_param_summary
>>>> @@ -249,10 +265,10 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
>>>>   extern int ncalls_inlined;
>>>>   extern int nfunctions_inlined;
>>>>
>>>> -static inline struct inline_summary *
>>>> -inline_summary (struct cgraph_node *node)
>>>> +static inline inline_summary *
>>>> +get_inline_summary (const struct cgraph_node *node)
>>>>   {
>>>> -  return &(*inline_summary_vec)[node->uid];
>>>> +  return (*inline_summary_summary)[node->summary_uid];
>>>
>>> Hmm, i guess there is no way to avoid the (*...)? Otherwise it would be cleaner
>>> to use inline_summary[...] instead of get_inline_summary IMO.
>>
>> I added function_summary::get method, where the usage looks cleaner:
>> inline_summary_d->get (node).
>>
>> Thanks,
>> Martin
>>
>>> Thanks for working on this!
>>> Honza
>>>
>>
>
> Patch v3.
>
> Martin

Version v4.

Martin

[-- Attachment #2: 0003-symbol_summary-is-used-for-inline_summary.patch --]
[-- Type: text/x-patch, Size: 39135 bytes --]

From 4f87fdf746532a9ad89fcf85246cc449a49ba09d Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Mon, 8 Dec 2014 11:33:08 +0100
Subject: [PATCH 3/3] symbol_summary is used for inline_summary.

gcc/lto/ChangeLog:

2014-12-08  Martin Liska  <mliska@suse.cz>

	* lto-partition.c (add_symbol_to_partition_1): New inline_summary_d
	is used.
	(undo_partition): Likewise.
	(lto_balanced_map): Likewise.

gcc/ChangeLog:

2014-12-08  Martin Liska  <mliska@suse.cz>

	* cgraphunit.c (symbol_table::process_new_functions): New inline_summary_d
	is used.
	* ipa-cp.c (ipcp_cloning_candidate_p): Likewise.
	(devirtualization_time_bonus): Likewise.
	(estimate_local_effects): Likewise.
	(ipcp_propagate_stage): Likewise.
	* ipa-inline-analysis.c (evaluate_conditions_for_known_args): Likewise.
	(evaluate_properties_for_edge): Likewise.
	(inline_summary_alloc): Likewise.
	(reset_inline_summary): New inline_summary argument is introduced.
	(inline_summary_t::remove): New function.
	(inline_summary_t::duplicate): Likewise.
	(dump_inline_edge_summary): New inline_summary_d is used.
	(dump_inline_summary): Likewise.
	(estimate_function_body_sizes): Likewise.
	(compute_inline_parameters): Likewise.
	(estimate_edge_devirt_benefit): Likewise.
	(estimate_node_size_and_time): Likewise.
	(inline_update_callee_summaries): Likewise.
	(inline_merge_summary): Likewise.
	(inline_update_overall_summary): Likewise.
	(simple_edge_hints): Likewise.
	(do_estimate_edge_time): Likewise.
	(estimate_time_after_inlining): Likewise.
	(estimate_size_after_inlining): Likewise.
	(do_estimate_growth): Likewise.
	(growth_likely_positive): Likewise.
	(inline_generate_summary): Likewise.
	(inline_read_section): Likewise.
	(inline_read_summary): Likewise.
	(inline_write_summary): Likewise.
	(inline_free_summary): Likewise.
	* ipa-inline-transform.c (clone_inlined_nodes): Likewise.
	(inline_call): Likewise.
	* ipa-inline.c (caller_growth_limits): Likewise.
	(can_inline_edge_p): Likewise.
	(want_early_inline_function_p): Likewise.
	(compute_uninlined_call_time): Likewise.
	(compute_inlined_call_time): Likewise.
	(big_speedup_p): Likewise.
	(want_inline_small_function_p): Likewise.
	(edge_badness): Likewise.
	(update_caller_keys): Likewise.
	(update_callee_keys): Likewise.
	(recursive_inlining): Likewise.
	(inline_small_functions): Likewise.
	(inline_to_all_callers): Likewise.
	(dump_overall_stats): Likewise.
	(early_inline_small_functions): Likewise.
	* ipa-inline.h: New class inline_summary_t replaces
	vec<inline_summary_t>.
	* ipa-split.c (execute_split_functions): New inline_summary_d is used.
	* ipa.c (walk_polymorphic_call_targets): Likewise.
	* tree-sra.c (ipa_sra_preliminary_function_checks): Likewise.
---
 gcc/cgraphunit.c           |   2 +-
 gcc/ipa-cp.c               |   8 +--
 gcc/ipa-inline-analysis.c  | 155 +++++++++++++++++++--------------------------
 gcc/ipa-inline-transform.c |   6 +-
 gcc/ipa-inline.c           |  50 +++++++--------
 gcc/ipa-inline.h           |  32 +++++++---
 gcc/ipa-prop.h             |   2 +-
 gcc/ipa-split.c            |   2 +-
 gcc/ipa.c                  |   2 +-
 gcc/lto/lto-partition.c    |  10 +--
 gcc/tree-sra.c             |   2 +-
 11 files changed, 129 insertions(+), 142 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 664e67c..ca74778 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -339,7 +339,7 @@ symbol_table::process_new_functions (void)
 	  if (state == IPA_SSA
 	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
 	    g->get_passes ()->execute_early_local_passes ();
-	  else if (inline_summary_vec != NULL)
+	  else if (inline_summary_d != NULL)
 	    compute_inline_parameters (node, true);
 	  free_dominance_info (CDI_POST_DOMINATORS);
 	  free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index a60100c..7ca224a 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -588,7 +588,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
   init_caller_stats (&stats);
   node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
 
-  if (inline_summary (node)->self_size < stats.n_calls)
+  if (inline_summary_d->get (node)->self_size < stats.n_calls)
     {
       if (dump_file)
         fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
@@ -1958,7 +1958,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
       callee = callee->function_symbol (&avail);
       if (avail < AVAIL_AVAILABLE)
 	continue;
-      isummary = inline_summary (callee);
+      isummary = inline_summary_d->get (callee);
       if (!isummary->inlinable)
 	continue;
 
@@ -2205,7 +2205,7 @@ estimate_local_effects (struct cgraph_node *node)
   vec<ipa_agg_jump_function> known_aggs;
   vec<ipa_agg_jump_function_p> known_aggs_ptrs;
   bool always_const;
-  int base_time = inline_summary (node)->time;
+  int base_time = inline_summary_d->get (node)->time;
   int removable_params_cost;
 
   if (!count || !ipcp_versionable_function_p (node))
@@ -2622,7 +2622,7 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
 	initialize_node_lattices (node);
       }
     if (node->definition && !node->alias)
-      overall_size += inline_summary (node)->self_size;
+      overall_size += inline_summary_d->get (node)->self_size;
     if (node->count > max_count)
       max_count = node->count;
   }
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index be80a0a..78e803c 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -148,21 +148,15 @@ enum predicate_conditions
 #define CHANGED IDENTIFIER_NODE
 
 /* Holders of ipa cgraph hooks: */
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
 static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
 static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static void inline_node_removal_hook (struct cgraph_node *, void *);
-static void inline_node_duplication_hook (struct cgraph_node *,
-					  struct cgraph_node *, void *);
 static void inline_edge_removal_hook (struct cgraph_edge *, void *);
 static void inline_edge_duplication_hook (struct cgraph_edge *,
 					  struct cgraph_edge *, void *);
 
 /* VECtor holding inline summaries.  
    In GGC memory because conditions might point to constant trees.  */
-vec<inline_summary_t, va_gc> *inline_summary_vec;
+function_summary <inline_summary *> *inline_summary_d;
 vec<inline_edge_summary_t> inline_edge_summary_vec;
 
 /* Cached node/edge growths.  */
@@ -829,7 +823,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 				    known_aggs)
 {
   clause_t clause = inline_p ? 0 : 1 << predicate_not_inlined_condition;
-  struct inline_summary *info = inline_summary (node);
+  struct inline_summary *info = inline_summary_d->get (node);
   int i;
   struct condition *c;
 
@@ -901,7 +895,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 			      vec<ipa_agg_jump_function_p> *known_aggs_ptr)
 {
   struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-  struct inline_summary *info = inline_summary (callee);
+  struct inline_summary *info = inline_summary_d->get (callee);
   vec<tree> known_vals = vNULL;
   vec<ipa_agg_jump_function_p> known_aggs = vNULL;
 
@@ -977,21 +971,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 static void
 inline_summary_alloc (void)
 {
-  if (!node_removal_hook_holder)
-    node_removal_hook_holder =
-      symtab->add_cgraph_removal_hook (&inline_node_removal_hook, NULL);
   if (!edge_removal_hook_holder)
     edge_removal_hook_holder =
       symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
-  if (!node_duplication_hook_holder)
-    node_duplication_hook_holder =
-      symtab->add_cgraph_duplication_hook (&inline_node_duplication_hook, NULL);
   if (!edge_duplication_hook_holder)
     edge_duplication_hook_holder =
       symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
 
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) symtab->cgraph_max_uid)
-    vec_safe_grow_cleared (inline_summary_vec, symtab->cgraph_max_uid + 1);
+  if (!inline_summary_d)
+    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
   if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid)
     inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
   if (!edge_predicate_pool)
@@ -1021,9 +1010,9 @@ reset_inline_edge_summary (struct cgraph_edge *e)
    data from previous run so they are not cumulated.  */
 
 static void
-reset_inline_summary (struct cgraph_node *node)
+reset_inline_summary (struct cgraph_node *node,
+		      inline_summary *info)
 {
-  struct inline_summary *info = inline_summary (node);
   struct cgraph_edge *e;
 
   info->self_size = info->self_time = 0;
@@ -1059,16 +1048,10 @@ reset_inline_summary (struct cgraph_node *node)
 
 /* Hook that is called by cgraph.c when a node is removed.  */
 
-static void
-inline_node_removal_hook (struct cgraph_node *node,
-			  void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::remove (cgraph_node *node, inline_summary *info)
 {
-  struct inline_summary *info;
-  if (vec_safe_length (inline_summary_vec) <= (unsigned) node->uid)
-    return;
-  info = inline_summary (node);
-  reset_inline_summary (node);
-  memset (info, 0, sizeof (inline_summary_t));
+  reset_inline_summary (node, info);
 }
 
 /* Remap predicate P of former function to be predicate of duplicated function.
@@ -1118,16 +1101,14 @@ remap_hint_predicate_after_duplication (struct predicate **p,
 
 
 /* Hook that is called by cgraph.c when a node is duplicated.  */
-
-static void
-inline_node_duplication_hook (struct cgraph_node *src,
-			      struct cgraph_node *dst,
-			      ATTRIBUTE_UNUSED void *data)
+void
+inline_summary_t::duplicate (cgraph_node *src,
+			     cgraph_node *dst,
+			     inline_summary *,
+			     inline_summary *info)
 {
-  struct inline_summary *info;
   inline_summary_alloc ();
-  info = inline_summary (dst);
-  memcpy (info, inline_summary (src), sizeof (struct inline_summary));
+  memcpy (info, inline_summary_d->get (src), sizeof (inline_summary));
   /* TODO: as an optimization, we may avoid copying conditions
      that are known to be false or true.  */
   info->conds = vec_safe_copy (info->conds);
@@ -1348,8 +1329,8 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	       ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
 	       indent, "", es->loop_depth, edge->frequency,
 	       es->call_stmt_size, es->call_stmt_time,
-	       (int) inline_summary (callee)->size / INLINE_SIZE_SCALE,
-	       (int) inline_summary (callee)->estimated_stack_size);
+	       (int) inline_summary_d->get (callee)->size / INLINE_SIZE_SCALE,
+	       (int) inline_summary_d->get (callee)->estimated_stack_size);
 
       if (es->predicate)
 	{
@@ -1375,9 +1356,9 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
 	  fprintf (f, "%*sStack frame offset %i, callee self size %i,"
 		   " callee size %i\n",
 		   indent + 2, "",
-		   (int) inline_summary (callee)->stack_frame_offset,
-		   (int) inline_summary (callee)->estimated_self_stack_size,
-		   (int) inline_summary (callee)->estimated_stack_size);
+		   (int) inline_summary_d->get (callee)->stack_frame_offset,
+		   (int) inline_summary_d->get (callee)->estimated_self_stack_size,
+		   (int) inline_summary_d->get (callee)->estimated_stack_size);
 	  dump_inline_edge_summary (f, indent + 2, callee, info);
 	}
     }
@@ -1405,7 +1386,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
 {
   if (node->definition)
     {
-      struct inline_summary *s = inline_summary (node);
+      struct inline_summary *s = inline_summary_d->get (node);
       size_time_entry *e;
       int i;
       fprintf (f, "Inline summary for %s/%i", node->name (),
@@ -2219,7 +2200,7 @@ param_change_prob (gimple stmt, int i)
 
 static bool
 phi_result_unknown_predicate (struct ipa_node_params *info,
-			      struct inline_summary *summary, basic_block bb,
+			      inline_summary *summary, basic_block bb,
 			      struct predicate *p,
 			      vec<predicate_t> nonconstant_names)
 {
@@ -2308,7 +2289,7 @@ predicate_for_phi_result (struct inline_summary *summary, gphi *phi,
 /* Return predicate specifying when array index in access OP becomes non-constant.  */
 
 static struct predicate
-array_index_predicate (struct inline_summary *info,
+array_index_predicate (inline_summary *info,
 		       vec< predicate_t> nonconstant_names, tree op)
 {
   struct predicate p = false_predicate ();
@@ -2463,7 +2444,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   basic_block bb;
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
   int freq;
-  struct inline_summary *info = inline_summary (node);
+  struct inline_summary *info = inline_summary_d->get (node);
   struct predicate bb_predicate;
   struct ipa_node_params *parms_info = NULL;
   vec<predicate_t> nonconstant_names = vNULL;
@@ -2707,7 +2688,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	}
     }
-  set_hint_predicate (&inline_summary (node)->array_index, array_index);
+  set_hint_predicate (&inline_summary_d->get (node)->array_index, array_index);
   time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
   if (time > MAX_TIME)
     time = MAX_TIME;
@@ -2795,9 +2776,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	    }
 	  free (body);
 	}
-      set_hint_predicate (&inline_summary (node)->loop_iterations,
+      set_hint_predicate (&inline_summary_d->get (node)->loop_iterations,
 			  loop_iterations);
-      set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
+      set_hint_predicate (&inline_summary_d->get (node)->loop_stride, loop_stride);
       scev_finalize ();
     }
   FOR_ALL_BB_FN (bb, my_function)
@@ -2815,8 +2796,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	  e->aux = NULL;
 	}
     }
-  inline_summary (node)->self_time = time;
-  inline_summary (node)->self_size = size;
+  inline_summary_d->get (node)->self_time = time;
+  inline_summary_d->get (node)->self_size = size;
   nonconstant_names.release ();
   if (opt_for_fn (node->decl, optimize) && !early)
     {
@@ -2845,8 +2826,8 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
 
   inline_summary_alloc ();
 
-  info = inline_summary (node);
-  reset_inline_summary (node);
+  info = inline_summary_d->get (node);
+  reset_inline_summary (node, info);
 
   /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
      Once this happen, we will need to more curefully predict call
@@ -3014,7 +2995,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
   callee = callee->function_symbol (&avail);
   if (avail < AVAIL_AVAILABLE)
     return false;
-  isummary = inline_summary (callee);
+  isummary = inline_summary_d->get (callee);
   return isummary->inlinable;
 }
 
@@ -3126,7 +3107,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
 			     vec<inline_param_summary>
 			     inline_param_summary)
 {
-  struct inline_summary *info = inline_summary (node);
+  struct inline_summary *info = inline_summary_d->get (node);
   size_time_entry *e;
   int size = 0;
   int time = 0;
@@ -3343,8 +3324,8 @@ static void
 inline_update_callee_summaries (struct cgraph_node *node, int depth)
 {
   struct cgraph_edge *e;
-  struct inline_summary *callee_info = inline_summary (node);
-  struct inline_summary *caller_info = inline_summary (node->callers->caller);
+  struct inline_summary *callee_info = inline_summary_d->get (node);
+  struct inline_summary *caller_info = inline_summary_d->get (node->callers->caller);
   HOST_WIDE_INT peak;
 
   callee_info->stack_frame_offset
@@ -3352,8 +3333,8 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
     + caller_info->estimated_self_stack_size;
   peak = callee_info->stack_frame_offset
     + callee_info->estimated_self_stack_size;
-  if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
-      inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
+  if (inline_summary_d->get (node->global.inlined_to)->estimated_stack_size < peak)
+      inline_summary_d->get (node->global.inlined_to)->estimated_stack_size = peak;
   ipa_propagate_frequency (node);
   for (e = node->callees; e; e = e->next_callee)
     {
@@ -3513,10 +3494,10 @@ remap_hint_predicate (struct inline_summary *info,
 void
 inline_merge_summary (struct cgraph_edge *edge)
 {
-  struct inline_summary *callee_info = inline_summary (edge->callee);
+  struct inline_summary *callee_info = inline_summary_d->get (edge->callee);
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  struct inline_summary *info = inline_summary (to);
+  struct inline_summary *info = inline_summary_d->get (to);
   clause_t clause = 0;		/* not_inline is known to be false.  */
   size_time_entry *e;
   vec<int> operand_map = vNULL;
@@ -3625,7 +3606,7 @@ inline_merge_summary (struct cgraph_edge *edge)
 void
 inline_update_overall_summary (struct cgraph_node *node)
 {
-  struct inline_summary *info = inline_summary (node);
+  struct inline_summary *info = inline_summary_d->get (node);
   size_time_entry *e;
   int i;
 
@@ -3652,8 +3633,8 @@ simple_edge_hints (struct cgraph_edge *edge)
   int hints = 0;
   struct cgraph_node *to = (edge->caller->global.inlined_to
 			    ? edge->caller->global.inlined_to : edge->caller);
-  if (inline_summary (to)->scc_no
-      && inline_summary (to)->scc_no == inline_summary (edge->callee)->scc_no
+  if (inline_summary_d->get (to)->scc_no
+      && inline_summary_d->get (to)->scc_no == inline_summary_d->get (edge->callee)->scc_no
       && !edge->recursive_p ())
     hints |= INLINE_HINT_same_scc;
 
@@ -3713,7 +3694,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
   /* When caching, update the cache entry.  */
   if (edge_growth_cache.exists ())
     {
-      inline_summary (edge->callee)->min_size = min_size;
+      inline_summary_d->get (edge->callee)->min_size = min_size;
       if ((int) edge_growth_cache.length () <= edge->uid)
 	edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
       edge_growth_cache[edge->uid].time = time + (time >= 0);
@@ -3815,14 +3796,14 @@ estimate_time_after_inlining (struct cgraph_node *node,
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
       gcov_type time =
-	inline_summary (node)->time + estimate_edge_time (edge);
+	inline_summary_d->get (node)->time + estimate_edge_time (edge);
       if (time < 0)
 	time = 0;
       if (time > MAX_TIME)
 	time = MAX_TIME;
       return time;
     }
-  return inline_summary (node)->time;
+  return inline_summary_d->get (node)->time;
 }
 
 
@@ -3836,11 +3817,11 @@ estimate_size_after_inlining (struct cgraph_node *node,
   struct inline_edge_summary *es = inline_edge_summary (edge);
   if (!es->predicate || !false_predicate_p (es->predicate))
     {
-      int size = inline_summary (node)->size + estimate_edge_growth (edge);
+      int size = inline_summary_d->get (node)->size + estimate_edge_growth (edge);
       gcc_assert (size >= 0);
       return size;
     }
-  return inline_summary (node)->size;
+  return inline_summary_d->get (node)->size;
 }
 
 
@@ -3880,7 +3861,7 @@ int
 do_estimate_growth (struct cgraph_node *node)
 {
   struct growth_data d = { node, 0, false };
-  struct inline_summary *info = inline_summary (node);
+  struct inline_summary *info = inline_summary_d->get (node);
 
   node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
 
@@ -3953,7 +3934,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
       && (!DECL_COMDAT (node->decl)
 	  || !node->can_remove_if_no_direct_calls_p ()))
     return true;
-  max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
+  max_callers = inline_summary_d->get (node)->size * 4 / edge_growth + 2;
 
   for (e = node->callers; e; e = e->next_caller)
     {
@@ -4016,13 +3997,12 @@ inline_analyze_function (struct cgraph_node *node)
 
 /* Called when new function is inserted to callgraph late.  */
 
-static void
-add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::insert (struct cgraph_node *node, inline_summary *)
 {
   inline_analyze_function (node);
 }
 
-
 /* Note function body size.  */
 
 void
@@ -4035,8 +4015,10 @@ inline_generate_summary (void)
   if (!optimize && !flag_generate_lto && !flag_wpa)
     return;
 
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+  if (!inline_summary_d)
+    inline_summary_d = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
+  inline_summary_d->enable_insertion_hook ();
 
   ipa_register_cgraph_hooks ();
   inline_free_summary ();
@@ -4130,7 +4112,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
       encoder = file_data->symtab_node_encoder;
       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
 								index));
-      info = inline_summary (node);
+      info = inline_summary_d->get (node);
 
       info->estimated_stack_size
 	= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
@@ -4219,8 +4201,9 @@ inline_read_summary (void)
       if (!flag_ipa_cp)
 	ipa_prop_read_jump_functions ();
     }
-  function_insertion_hook_holder =
-    symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+
+  gcc_assert (inline_summary_d);
+  inline_summary_d->enable_insertion_hook ();
 }
 
 
@@ -4286,7 +4269,7 @@ inline_write_summary (void)
       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
       if (cnode && (node = cnode)->definition && !node->alias)
 	{
-	  struct inline_summary *info = inline_summary (node);
+	  struct inline_summary *info = inline_summary_d->get (node);
 	  struct bitpack_d bp;
 	  struct cgraph_edge *edge;
 	  int i;
@@ -4347,18 +4330,9 @@ void
 inline_free_summary (void)
 {
   struct cgraph_node *node;
-  if (function_insertion_hook_holder)
-    symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
-  function_insertion_hook_holder = NULL;
-  if (node_removal_hook_holder)
-    symtab->remove_cgraph_removal_hook (node_removal_hook_holder);
-  node_removal_hook_holder = NULL;
   if (edge_removal_hook_holder)
     symtab->remove_edge_removal_hook (edge_removal_hook_holder);
   edge_removal_hook_holder = NULL;
-  if (node_duplication_hook_holder)
-    symtab->remove_cgraph_duplication_hook (node_duplication_hook_holder);
-  node_duplication_hook_holder = NULL;
   if (edge_duplication_hook_holder)
     symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
   edge_duplication_hook_holder = NULL;
@@ -4366,8 +4340,9 @@ inline_free_summary (void)
     return;
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->alias)
-      reset_inline_summary (node);
-  vec_free (inline_summary_vec);
+      reset_inline_summary (node, inline_summary_d->get (node));
+  inline_summary_d->release ();
+  inline_summary_d = NULL;
   inline_edge_summary_vec.release ();
   if (edge_predicate_pool)
     free_alloc_pool (edge_predicate_pool);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 62f68f0..d0337c2 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -212,7 +212,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
 	  if (e->callee->definition && !DECL_EXTERNAL (e->callee->decl))
 	    {
 	      if (overall_size)
-	        *overall_size -= inline_summary (e->callee)->size;
+	        *overall_size -= inline_summary_d->get (e->callee)->size;
 	      nfunctions_inlined++;
 	    }
 	  duplicate = false;
@@ -322,13 +322,13 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   gcc_assert (curr->callee->global.inlined_to == to);
 
-  old_size = inline_summary (to)->size;
+  old_size = inline_summary_d->get (to)->size;
   inline_merge_summary (e);
   if (optimize)
     new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
   if (update_overall_summary)
    inline_update_overall_summary (to);
-  new_size = inline_summary (to)->size;
+  new_size = inline_summary_d->get (to)->size;
 
   if (callee->calls_comdat_local)
     to->calls_comdat_local = true;
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index aebfaba..bd8003de 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -170,7 +170,7 @@ caller_growth_limits (struct cgraph_edge *e)
   int newsize;
   int limit = 0;
   HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
-  struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
+  inline_summary *info, *what_info, *outer_info = inline_summary_d->get (to);
 
   /* Look for function e->caller is inlined to.  While doing
      so work out the largest function body on the way.  As
@@ -182,7 +182,7 @@ caller_growth_limits (struct cgraph_edge *e)
      too much in order to prevent compiler from exploding".  */
   while (true)
     {
-      info = inline_summary (to);
+      info = inline_summary_d->get (to);
       if (limit < info->self_size)
 	limit = info->self_size;
       if (stack_size_limit < info->estimated_self_stack_size)
@@ -193,7 +193,7 @@ caller_growth_limits (struct cgraph_edge *e)
 	break;
     }
 
-  what_info = inline_summary (what);
+  what_info = inline_summary_d->get (what);
 
   if (limit < what_info->self_size)
     limit = what_info->self_size;
@@ -307,7 +307,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_USES_COMDAT_LOCAL;
       inlinable = false;
     }
-  else if (!inline_summary (callee)->inlinable 
+  else if (!inline_summary_d->get (callee)->inlinable
 	   || (caller_fun && fn_contains_cilk_spawn_p (caller_fun)))
     {
       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
@@ -453,7 +453,7 @@ want_early_inline_function_p (struct cgraph_edge *e)
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
     ;
-  /* For AutoFDO, we need to make sure that before profile annotation, all
+  /* For AutoFDO, we need to make sure that before profile summary, all
      hot paths' IR look exactly the same as profiled binary. As a result,
      in einliner, we will disregard size limit and inline those callsites
      that are:
@@ -525,7 +525,7 @@ compute_uninlined_call_time (struct inline_summary *callee_info,
   gcov_type uninlined_call_time =
     RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
 	  CGRAPH_FREQ_BASE);
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
 				          ? edge->caller->global.inlined_to
 				          : edge->caller)->time;
   return uninlined_call_time + caller_time;
@@ -538,7 +538,7 @@ inline gcov_type
 compute_inlined_call_time (struct cgraph_edge *edge,
 			   int edge_time)
 {
-  gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+  gcov_type caller_time = inline_summary_d->get (edge->caller->global.inlined_to
 					  ? edge->caller->global.inlined_to
 					  : edge->caller)->time;
   gcov_type time = (caller_time
@@ -558,7 +558,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
 static bool
 big_speedup_p (struct cgraph_edge *e)
 {
-  gcov_type time = compute_uninlined_call_time (inline_summary (e->callee),
+  gcov_type time = compute_uninlined_call_time (inline_summary_d->get (e->callee),
 					  	e);
   gcov_type inlined_time = compute_inlined_call_time (e,
 					              estimate_edge_time (e));
@@ -591,7 +591,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
      MAX_INLINE_INSNS_SINGLE 16-fold for inline functions.  */
   else if ((!DECL_DECLARED_INLINE_P (callee->decl)
 	   && (!e->count || !e->maybe_hot_p ()))
-	   && inline_summary (callee)->min_size
+	   && inline_summary_d->get (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
     {
@@ -599,7 +599,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
       want_inline = false;
     }
   else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
-	   && inline_summary (callee)->min_size
+	   && inline_summary_d->get (callee)->min_size
 		- inline_edge_summary (e)->call_stmt_size
 	      > 16 * MAX_INLINE_INSNS_SINGLE)
     {
@@ -910,7 +910,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   sreal badness;
   int growth, edge_time;
   struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
-  struct inline_summary *callee_info = inline_summary (callee);
+  struct inline_summary *callee_info = inline_summary_d->get (callee);
   inline_hints hints;
 
   if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
@@ -1188,7 +1188,7 @@ update_caller_keys (edge_heap_t *heap, struct cgraph_node *node,
   struct cgraph_edge *edge;
   struct ipa_ref *ref;
 
-  if ((!node->alias && !inline_summary (node)->inlinable)
+  if ((!node->alias && !inline_summary_d->get (node)->inlinable)
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->uid))
@@ -1246,7 +1246,7 @@ update_callee_keys (edge_heap_t *heap, struct cgraph_node *node,
            don't need updating.  */
 	if (e->inline_failed
 	    && (callee = e->callee->ultimate_alias_target (&avail))
-	    && inline_summary (callee)->inlinable
+	    && inline_summary_d->get (callee)->inlinable
 	    && avail >= AVAIL_AVAILABLE
 	    && !bitmap_bit_p (updated_nodes, callee->uid))
 	  {
@@ -1417,8 +1417,8 @@ recursive_inlining (struct cgraph_edge *edge,
     fprintf (dump_file,
 	     "\n   Inlined %i times, "
 	     "body grown from size %i to %i, time %i to %i\n", n,
-	     inline_summary (master_clone)->size, inline_summary (node)->size,
-	     inline_summary (master_clone)->time, inline_summary (node)->time);
+	     inline_summary_d->get (master_clone)->size, inline_summary_d->get (node)->size,
+	     inline_summary_d->get (master_clone)->time, inline_summary_d->get (node)->time);
 
   /* Remove master clone we used for inlining.  We rely that clones inlined
      into master clone gets queued just before master clone so we don't
@@ -1591,7 +1591,7 @@ inline_small_functions (void)
 	if (node->has_gimple_body_p ()
 	    || node->thunk.thunk_p)
 	  {
-	    struct inline_summary *info = inline_summary (node);
+	    struct inline_summary *info = inline_summary_d->get (node);
 	    struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
 
 	    /* Do not account external functions, they will be optimized out
@@ -1607,7 +1607,7 @@ inline_small_functions (void)
 		for (n2 = node; n2;
 		     n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
 		  {
-		    struct inline_summary *info2 = inline_summary (n2);
+		    struct inline_summary *info2 = inline_summary_d->get (n2);
 		    if (info2->scc_no)
 		      break;
 		    info2->scc_no = id;
@@ -1727,7 +1727,7 @@ inline_small_functions (void)
 	  fprintf (dump_file,
 		   "\nConsidering %s/%i with %i size\n",
 		   callee->name (), callee->order,
-		   inline_summary (callee)->size);
+		   inline_summary_d->get (callee)->size);
 	  fprintf (dump_file,
 		   " to be inlined into %s/%i in %s:%i\n"
 		   " Estimated badness is %"PRId64", frequency %.2f.\n",
@@ -1845,8 +1845,8 @@ inline_small_functions (void)
 		   " Inlined into %s which now has time %i and size %i,"
 		   "net change of %+i.\n",
 		   edge->caller->name (),
-		   inline_summary (edge->caller)->time,
-		   inline_summary (edge->caller)->size,
+		   inline_summary_d->get (edge->caller)->time,
+		   inline_summary_d->get (edge->caller)->size,
 		   overall_size - old_size);
 	}
       if (min_size > overall_size)
@@ -1983,11 +1983,11 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	  fprintf (dump_file,
 		   "\nInlining %s size %i.\n",
 		   node->name (),
-		   inline_summary (node)->size);
+		   inline_summary_d->get (node)->size);
 	  fprintf (dump_file,
 		   " Called once from %s %i insns.\n",
 		   node->callers->caller->name (),
-		   inline_summary (node->callers->caller)->size);
+		   inline_summary_d->get (node->callers->caller)->size);
 	}
 
       inline_call (node->callers, true, NULL, NULL, true, &callee_removed);
@@ -1995,7 +1995,7 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
 	fprintf (dump_file,
 		 " Inlined into %s which now has %i size\n",
 		 caller->name (),
-		 inline_summary (caller)->size);
+		 inline_summary_d->get (caller)->size);
       if (!(*num_calls)--)
 	{
 	  if (dump_file)
@@ -2019,7 +2019,7 @@ dump_overall_stats (void)
     if (!node->global.inlined_to
 	&& !node->alias)
       {
-	int time = inline_summary (node)->time;
+	int time = inline_summary_d->get (node)->time;
 	sum += time;
 	sum_weighted += time * node->count;
       }
@@ -2335,7 +2335,7 @@ early_inline_small_functions (struct cgraph_node *node)
   for (e = node->callees; e; e = e->next_callee)
     {
       struct cgraph_node *callee = e->callee->ultimate_alias_target ();
-      if (!inline_summary (callee)->inlinable
+      if (!inline_summary_d->get (callee)->inlinable
 	  || !e->inline_failed)
 	continue;
 
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index 4ba6264..5d3b7c6e 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -162,10 +162,28 @@ struct GTY(()) inline_summary
   int scc_no;
 };
 
-/* Need a typedef for inline_summary because of inline function
-   'inline_summary' below.  */
-typedef struct inline_summary inline_summary_t;
-extern GTY(()) vec<inline_summary_t, va_gc> *inline_summary_vec;
+class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
+{
+public:
+  inline_summary_t (symbol_table *symtab, bool ggc):
+    function_summary <inline_summary *> (symtab, ggc) {}
+
+  static inline_summary_t *create_ggc (symbol_table *symtab)
+  {
+    struct inline_summary_t *summary = new (ggc_cleared_alloc <inline_summary_t> ())
+      inline_summary_t(symtab, true);
+    summary->disable_insertion_hook ();
+    return summary;
+  }
+
+
+  virtual void insert (cgraph_node *, inline_summary *);
+  virtual void remove (cgraph_node *node, inline_summary *);
+  virtual void duplicate (cgraph_node *src, cgraph_node *dst,
+			  inline_summary *src_data, inline_summary *dst_data);
+};
+
+extern GTY(()) function_summary <inline_summary *> *inline_summary_d;
 
 /* Information kept about parameter of call site.  */
 struct inline_param_summary
@@ -250,12 +268,6 @@ void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
 extern int ncalls_inlined;
 extern int nfunctions_inlined;
 
-static inline struct inline_summary *
-inline_summary (struct cgraph_node *node)
-{
-  return &(*inline_summary_vec)[node->uid];
-}
-
 static inline struct inline_edge_summary *
 inline_edge_summary (struct cgraph_edge *edge)
 {
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index d02353e..247b64e 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -448,7 +448,7 @@ ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
   return &(*args->polymorphic_call_contexts)[i];
 }
 
-/* Callgraph summary for ipa_node_params.  */
+/* Function summary for ipa_node_params.  */
 class ipa_node_params_t: public function_summary <ipa_node_params *>
 {
 public:
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 1123d070..d073286 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1679,7 +1679,7 @@ execute_split_functions (void)
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
   if (inline_edge_summary_vec.exists ()
-      && !inline_summary (node)->inlinable)
+      && !inline_summary_d->get (node)->inlinable)
     {
       if (dump_file)
 	fprintf (dump_file, "Not splitting: not inlinable.\n");
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 16e264d..589f984 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -224,7 +224,7 @@ walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
                                target->order);
 	    }
 	  edge = edge->make_direct (target);
-	  if (inline_summary_vec)
+	  if (inline_summary_d)
 	    inline_update_overall_summary (node);
 	  else if (edge->call_stmt)
 	    {
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 2bbb91c..d210cb5 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -165,7 +165,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
     {
       struct cgraph_edge *e;
       if (!node->alias)
-        part->insns += inline_summary (cnode)->self_size;
+        part->insns += inline_summary_d->get (cnode)->self_size;
 
       /* Add all inline clones and callees that are duplicated.  */
       for (e = cnode->callees; e; e = e->next_callee)
@@ -274,7 +274,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
       partition->initializers_visited = NULL;
 
       if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
-        partition->insns -= inline_summary (cnode)->self_size;
+        partition->insns -= inline_summary_d->get (cnode)->self_size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->aux = (void *)((size_t)node->aux - 1);
     }
@@ -477,7 +477,7 @@ lto_balanced_map (int n_lto_partitions)
 	else
 	  order[n_nodes++] = node;
 	if (!node->alias)
-	  total_size += inline_summary (node)->size;
+	  total_size += inline_summary_d->get (node)->size;
       }
 
   /* Streaming works best when the source units do not cross partition
@@ -534,14 +534,14 @@ lto_balanced_map (int n_lto_partitions)
 	     && noreorder[noreorder_pos]->order < current_order)
 	{
 	  if (!noreorder[noreorder_pos]->alias)
-	    total_size -= inline_summary (noreorder[noreorder_pos])->size;
+	    total_size -= inline_summary_d->get (noreorder[noreorder_pos])->size;
 	  next_nodes.safe_push (noreorder[noreorder_pos++]);
 	}
       add_sorted_nodes (next_nodes, partition);
 
       add_symbol_to_partition (partition, order[i]);
       if (!order[i]->alias)
-        total_size -= inline_summary (order[i])->size;
+        total_size -= inline_summary_d->get (order[i])->size;
 	  
 
       /* Once we added a new node to the partition, we also want to add
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 26c9226..69af554 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -5032,7 +5032,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
     }
 
   if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
-      && inline_summary (node)->size >= MAX_INLINE_INSNS_AUTO)
+      && inline_summary_d->get (node)->size >= MAX_INLINE_INSNS_AUTO)
     {
       if (dump_file)
 	fprintf (dump_file, "Function too big to be made truly local.\n");
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-12-08 17:01         ` Martin Liška
@ 2014-12-18 19:42           ` Jan Hubicka
  2014-12-22 14:52             ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2014-12-18 19:42 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

> 2014-12-08  Martin Liska  <mliska@suse.cz>
> 
> 	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
> 	is filled up.
> 	* symbol-summary.h: New file.
> 	* gengtype.c (open_base_files): Add symbol-summary.h.
> 	* toplev.c (general_init): Call constructor of symbol_table.
> ---
>  gcc/cgraph.h         |   8 ++
>  gcc/gengtype.c       |   4 +-
>  gcc/symbol-summary.h | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  gcc/toplev.c         |   3 +-
>  4 files changed, 293 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/symbol-summary.h
> 
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index a5c5f56..1664bd7 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -1237,6 +1237,8 @@ public:
>    int count_materialization_scale;
>    /* Unique id of the node.  */
>    int uid;
> +  /* Summary unique id of the node.  */
> +  int summary_uid;

Hmm, can't we just use uid here?  I guess the only difference is that summary
uid is not kept dense, unlike the uid.
This should not propagate into much of trouble simply because the summary datastructure
should safely remove the summaires via removal hook.
> +
> +/* We want to pass just pointer types as argument for function_summary
> +   template class.  */
> +
> +template <class T>
> +class function_summary
> +{
> +private:
> +  function_summary();
> +};
> +
> +template <class T>
> +class GTY((user)) function_summary <T *>

Eventually I would like this to allow attaching summaries to variables (and symbols in general),
too. But currently we do not have use for it, so we can care about this later.

The patch is OK.  Preferrably with summary_uid replaced by uid if it is easily doable.

Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass.
  2014-12-08 17:02       ` Martin Liška
@ 2014-12-18 19:44         ` Jan Hubicka
  0 siblings, 0 replies; 40+ messages in thread
From: Jan Hubicka @ 2014-12-18 19:44 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

> 
> gcc/lto/ChangeLog:
> 
> 2014-12-08  Martin Liska  <mliska@suse.cz>
> 
> 	* lto-partition.c: Include of symbol-summary.h is added.
> 	* lto-symtab.c: Likewise.
> 	* lto.c: Likewise.

I must say I am not friend of flattening. Hope this will be resolved for 5.1
> 
> gcc/ChangeLog:
> 
> 2014-12-08  Martin Liska  <mliska@suse.cz>
> 
> 	* auto-profile.c: Include of symtab-summary.h is added.
> 	* cgraph.c: Likewise.
> 	* cgraphbuild.c: Likewise.
> 	* cgraphclones.c: Likewise.
> 	* cgraphunit.c: Likewise.
> 	* ipa-cp.c: Likewise.
> 	* ipa-devirt.c: Likewise.
> 	* ipa-icf.c: Likewise.
> 	* ipa-inline-analysis.c (evaluate_properties_for_edge): New
> 	ipa_node_params_d data structure is used.
> 	(inline_node_duplication_hook): Likewise.
> 	(estimate_function_body_sizes): Likewise.
> 	(remap_edge_change_prob): Likewise.
> 	(inline_merge_summary): Likewise.
> 	* ipa-inline-transform.c: Include of symtab-summary.h is added.
> 	* ipa-inline.c (early_inliner): New ipa_node_params_d data structure
> 	is used.
> 	* ipa-polymorphic-call.c: Include of symtab-summary.h is added.
> 	* ipa-profile.c: Include of symtab-summary.h is added.
> 	* ipa-prop.c (ipa_propagate_indirect_call_infos): New ipa_node_params_d
> 	data structure is used.
> 	(ipa_node_params::~ipa_node_params): New function.
> 	(ipa_free_all_node_params): Destruction is simplified.
> 	(ipa_node_removal_hook): Removed.
> 	(ipa_add_new_function): Renamed from ipa_node_duplication_hook.
> 	(ipa_node_params_t::duplicate): New function.
> 	(ipa_register_cgraph_hooks): Few hooks are removed.
> 	(ipa_unregister_cgraph_hooks): Likewise.
> 	(ipa_prop_write_jump_functions): New ipa_node_params_d is used.
> 	* ipa-prop.h (struct ipa_node_params): Destructor instroduced for
> 	the structure.
> 	(ipa_check_create_node_params): Vector for ipa_node_params is replaced
> 	with function_summary.
> 	* ipa-split.c: Include of symtab-summary.h is added.
> 	* ipa-utils.c: Include of symtab-summary.h is added.
> 	* ipa.c: Include of symtab-summary.h is added.
> 	* omp-low.c: Include of symtab-summary.h is added.
> 	* tree-inline.c: Include of symtab-summary.h is added.
> 	* tree-sra.c: Include of symtab-summary.h is added.
> 	* tree-ssa-pre.c: Include of symtab-summary.h is added.

OK.
Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] Data structure is used for inline_summary struct.
  2014-12-08 17:03         ` Martin Liška
@ 2014-12-18 19:56           ` Jan Hubicka
  0 siblings, 0 replies; 40+ messages in thread
From: Jan Hubicka @ 2014-12-18 19:56 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

> 
> 2014-12-08  Martin Liska  <mliska@suse.cz>
> 
> 	* lto-partition.c (add_symbol_to_partition_1): New inline_summary_d
> 	is used.
> 	(undo_partition): Likewise.
> 	(lto_balanced_map): Likewise.
> 
> gcc/ChangeLog:
> 
> 2014-12-08  Martin Liska  <mliska@suse.cz>
> 
> 	* cgraphunit.c (symbol_table::process_new_functions): New inline_summary_d
> 	is used.
> 	* ipa-cp.c (ipcp_cloning_candidate_p): Likewise.
> 	(devirtualization_time_bonus): Likewise.
> 	(estimate_local_effects): Likewise.
> 	(ipcp_propagate_stage): Likewise.
> 	* ipa-inline-analysis.c (evaluate_conditions_for_known_args): Likewise.
> 	(evaluate_properties_for_edge): Likewise.
> 	(inline_summary_alloc): Likewise.
> 	(reset_inline_summary): New inline_summary argument is introduced.
> 	(inline_summary_t::remove): New function.
> 	(inline_summary_t::duplicate): Likewise.
> 	(dump_inline_edge_summary): New inline_summary_d is used.
> 	(dump_inline_summary): Likewise.
> 	(estimate_function_body_sizes): Likewise.
> 	(compute_inline_parameters): Likewise.
> 	(estimate_edge_devirt_benefit): Likewise.
> 	(estimate_node_size_and_time): Likewise.
> 	(inline_update_callee_summaries): Likewise.
> 	(inline_merge_summary): Likewise.
> 	(inline_update_overall_summary): Likewise.
> 	(simple_edge_hints): Likewise.
> 	(do_estimate_edge_time): Likewise.
> 	(estimate_time_after_inlining): Likewise.
> 	(estimate_size_after_inlining): Likewise.
> 	(do_estimate_growth): Likewise.
> 	(growth_likely_positive): Likewise.
> 	(inline_generate_summary): Likewise.
> 	(inline_read_section): Likewise.
> 	(inline_read_summary): Likewise.
> 	(inline_write_summary): Likewise.
> 	(inline_free_summary): Likewise.
> 	* ipa-inline-transform.c (clone_inlined_nodes): Likewise.
> 	(inline_call): Likewise.
> 	* ipa-inline.c (caller_growth_limits): Likewise.
> 	(can_inline_edge_p): Likewise.
> 	(want_early_inline_function_p): Likewise.
> 	(compute_uninlined_call_time): Likewise.
> 	(compute_inlined_call_time): Likewise.
> 	(big_speedup_p): Likewise.
> 	(want_inline_small_function_p): Likewise.
> 	(edge_badness): Likewise.
> 	(update_caller_keys): Likewise.
> 	(update_callee_keys): Likewise.
> 	(recursive_inlining): Likewise.
> 	(inline_small_functions): Likewise.
> 	(inline_to_all_callers): Likewise.
> 	(dump_overall_stats): Likewise.
> 	(early_inline_small_functions): Likewise.
> 	* ipa-inline.h: New class inline_summary_t replaces
> 	vec<inline_summary_t>.
> 	* ipa-split.c (execute_split_functions): New inline_summary_d is used.
> 	* ipa.c (walk_polymorphic_call_targets): Likewise.
> 	* tree-sra.c (ipa_sra_preliminary_function_checks): Likewise.

Patch is OK. I only changed mind about inline_summary_d.  It does not look good used
with inline_summary_d->get() especially because _d prefix was used in C++ication days
for type names only.
Probably inline_summaries->get() is better.

OK with this change.

Thanks,
Honza

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-12-18 19:42           ` Jan Hubicka
@ 2014-12-22 14:52             ` Martin Liška
  2015-01-14 15:31               ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2014-12-22 14:52 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]

On 12/18/2014 08:40 PM, Jan Hubicka wrote:
>> 2014-12-08  Martin Liska  <mliska@suse.cz>
>>
>> 	* cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
>> 	is filled up.
>> 	* symbol-summary.h: New file.
>> 	* gengtype.c (open_base_files): Add symbol-summary.h.
>> 	* toplev.c (general_init): Call constructor of symbol_table.
>> ---
>>   gcc/cgraph.h         |   8 ++
>>   gcc/gengtype.c       |   4 +-
>>   gcc/symbol-summary.h | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>   gcc/toplev.c         |   3 +-
>>   4 files changed, 293 insertions(+), 3 deletions(-)
>>   create mode 100644 gcc/symbol-summary.h
>>
>> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
>> index a5c5f56..1664bd7 100644
>> --- a/gcc/cgraph.h
>> +++ b/gcc/cgraph.h
>> @@ -1237,6 +1237,8 @@ public:
>>     int count_materialization_scale;
>>     /* Unique id of the node.  */
>>     int uid;
>> +  /* Summary unique id of the node.  */
>> +  int summary_uid;
>
> Hmm, can't we just use uid here?  I guess the only difference is that summary
> uid is not kept dense, unlike the uid.
> This should not propagate into much of trouble simply because the summary datastructure
> should safely remove the summaires via removal hook.

Hello.

There's patch I've been just testing. It removes summary_uid and uid is going to be
really unique. I tested the change on Inkscape WPA, and there's time difference in level
of < 1%.

Ready for trunk after proper testing?
Thanks,
Martin

>> +
>> +/* We want to pass just pointer types as argument for function_summary
>> +   template class.  */
>> +
>> +template <class T>
>> +class function_summary
>> +{
>> +private:
>> +  function_summary();
>> +};
>> +
>> +template <class T>
>> +class GTY((user)) function_summary <T *>
>
> Eventually I would like this to allow attaching summaries to variables (and symbols in general),
> too. But currently we do not have use for it, so we can care about this later.
>
> The patch is OK.  Preferrably with summary_uid replaced by uid if it is easily doable.
>
> Honza
>


[-- Attachment #2: 0001-Call-graph-summary_uid-is-removed.patch --]
[-- Type: text/x-patch, Size: 8100 bytes --]

From 852166518eedaa75562ad8e8324a8dfd25e2b7ff Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 19 Dec 2014 15:10:27 +0100
Subject: [PATCH] Call graph: summary_uid is removed.

gcc/ChangeLog:

2014-12-22  Martin Liska  <mliska@suse.cz>

	* cgraph.h (symbol_table::allocate_cgraph_symbol):
	Replace cgraph_max_summary_uid with cgraph_max_uid.
	* passes.c (struct cgraph_order_traits): New structure.
	(remove_cgraph_node_from_order): Replace int* with hash_map<int, int>.
	(do_per_function_toporder): Likewise.
	* symbol-summary.h: Change cgraph_node::symbol_uid with uid that
	is going to be really unique and not recycled.

gcc/lto/ChangeLog:

2014-12-22  Martin Liska  <mliska@suse.cz>

	* lto-partition.c (lto_balanced_map): Replace array with
	vec data structure.
---
 gcc/cgraph.h            | 10 ++--------
 gcc/lto/lto-partition.c | 11 ++++++-----
 gcc/passes.c            | 44 +++++++++++++++++++++++++++++++++++---------
 gcc/symbol-summary.h    | 18 +++++++++---------
 4 files changed, 52 insertions(+), 31 deletions(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 0cff779..10f60ad 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1255,8 +1255,6 @@ public:
   int count_materialization_scale;
   /* Unique id of the node.  */
   int uid;
-  /* Summary unique id of the node.  */
-  int summary_uid;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
   /* Time profiler: first run of function.  */
@@ -1839,7 +1837,7 @@ public:
   friend class cgraph_node;
   friend class cgraph_edge;
 
-  symbol_table (): cgraph_max_summary_uid (1)
+  symbol_table (): cgraph_max_uid (1)
   {
   }
 
@@ -2039,7 +2037,6 @@ public:
 
   int cgraph_count;
   int cgraph_max_uid;
-  int cgraph_max_summary_uid;
 
   int edges_count;
   int edges_max_uid;
@@ -2363,12 +2360,9 @@ symbol_table::allocate_cgraph_symbol (void)
       free_nodes = NEXT_FREE_NODE (node);
     }
   else
-    {
       node = ggc_cleared_alloc<cgraph_node> ();
-      node->uid = cgraph_max_uid++;
-    }
 
-  node->summary_uid = cgraph_max_summary_uid++;
+  node->uid = cgraph_max_uid++;
   return node;
 }
 
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 160b910..6c61102 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -449,7 +449,8 @@ lto_balanced_map (int n_lto_partitions)
 {
   int n_nodes = 0;
   int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0;
-  struct cgraph_node **order = XNEWVEC (cgraph_node *, symtab->cgraph_max_uid);
+
+  auto_vec<cgraph_node *> order;
   auto_vec<cgraph_node *> noreorder;
   auto_vec<varpool_node *> varpool_order;
   int i;
@@ -475,17 +476,19 @@ lto_balanced_map (int n_lto_partitions)
 	if (node->no_reorder)
 	  noreorder.safe_push (node);
 	else
-	  order[n_nodes++] = node;
+	  order.safe_push (node);
 	if (!node->alias)
 	  total_size += inline_summaries->get (node)->size;
       }
 
+  n_nodes = order.length ();
+
   /* Streaming works best when the source units do not cross partition
      boundaries much.  This is because importing function from a source
      unit tends to import a lot of global trees defined there.  We should
      get better about minimizing the function bounday, but until that
      things works smoother if we order in source order.  */
-  qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
+  order.qsort(node_cmp);
   noreorder.qsort (node_cmp);
 
   if (symtab->dump_file)
@@ -772,8 +775,6 @@ lto_balanced_map (int n_lto_partitions)
   while (noreorder_pos < (int)noreorder.length ())
     next_nodes.safe_push (noreorder[noreorder_pos++]);
   add_sorted_nodes (next_nodes, partition);
-
-  free (order);
 }
 
 /* Mangle NODE symbol name into a local name.  
diff --git a/gcc/passes.c b/gcc/passes.c
index 3f9f7df..436b4cb 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1646,6 +1646,33 @@ do_per_function (void (*callback) (function *, void *data), void *data)
 static int nnodes;
 static GTY ((length ("nnodes"))) cgraph_node **order;
 
+struct cgraph_order_traits : default_hashmap_traits
+{
+  template<typename T>
+  static bool
+  is_empty (T &e)
+  {
+    return e.m_key == INT_MIN;
+  }
+
+  template<typename  T>
+  static bool
+  is_deleted (T &e)
+  {
+    return e.m_key == (INT_MIN + 1);
+  }
+
+  template<typename T> static void mark_empty (T &e) { e.m_key = INT_MIN; }
+
+  template<typename T>
+  static void
+  mark_deleted (T &e)
+  {
+    e.m_key = INT_MIN + 1;
+  }
+};
+
+
 /* Hook called when NODE is removed and therefore should be
    excluded from order vector.  DATA is an array of integers.
    DATA[0] holds max index it may be accessed by.  For cgraph
@@ -1654,12 +1681,13 @@ static GTY ((length ("nnodes"))) cgraph_node **order;
 static void
 remove_cgraph_node_from_order (cgraph_node *node, void *data)
 {
-  int *order_idx = (int *)data;
+  hash_map<int, int, cgraph_order_traits> *order_idx_map =
+    (hash_map <int, int, cgraph_order_traits> *)data;
 
-  if (node->uid >= order_idx[0])
+  if (node->uid >= *order_idx_map->get (0))
     return;
 
-  int idx = order_idx[node->uid + 1];
+  int idx = *order_idx_map->get (node->uid + 1);
   if (idx >= 0 && idx < nnodes && order[idx] == node)
     order[idx] = NULL;
 }
@@ -1678,22 +1706,20 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
   else
     {
       cgraph_node_hook_list *hook;
-      int *order_idx;
       gcc_assert (!order);
       order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
 
-      order_idx = XALLOCAVEC (int, symtab->cgraph_max_uid + 1);
-      memset (order_idx + 1, -1, sizeof (int) * symtab->cgraph_max_uid);
-      order_idx[0] = symtab->cgraph_max_uid;
+      hash_map<int, int, cgraph_order_traits> order_idx_map;
+      order_idx_map.put (0, symtab->cgraph_max_uid);
 
       nnodes = ipa_reverse_postorder (order);
       for (i = nnodes - 1; i >= 0; i--)
 	{
 	  order[i]->process = 1;
-	  order_idx[order[i]->uid + 1] = i;
+	  order_idx_map.put (order[i]->uid + 1, i);
 	}
       hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
-					      order_idx);
+					      &order_idx_map);
       for (i = nnodes - 1; i >= 0; i--)
 	{
 	  /* Function could be inlined and removed as unreachable.  */
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index d001f64..ec1dc9c 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -44,7 +44,7 @@ public:
 
     FOR_EACH_FUNCTION (node)
     {
-      gcc_checking_assert (node->summary_uid > 0);
+      gcc_checking_assert (node->uid > 0);
     }
 #endif
 
@@ -109,7 +109,7 @@ public:
   /* Getter for summary callgraph node pointer.  */
   T* get (cgraph_node *node)
   {
-    return get (node->summary_uid);
+    return get (node->uid);
   }
 
   /* Return number of elements handled by data structure.  */
@@ -142,11 +142,11 @@ public:
   /* Symbol removal hook that is registered to symbol table.  */
   static void symtab_removal (cgraph_node *node, void *data)
   {
-    gcc_checking_assert (node->summary_uid);
+    gcc_checking_assert (node->uid);
     function_summary *summary = (function_summary <T *> *) (data);
 
-    int summary_uid = node->summary_uid;
-    T **v = summary->m_map.get (summary_uid);
+    int uid = node->uid;
+    T **v = summary->m_map.get (uid);
 
     if (v)
       {
@@ -155,7 +155,7 @@ public:
 	if (!summary->m_ggc)
 	  delete (*v);
 
-	summary->m_map.remove (summary_uid);
+	summary->m_map.remove (uid);
       }
   }
 
@@ -164,16 +164,16 @@ public:
 				  void *data)
   {
     function_summary *summary = (function_summary <T *> *) (data);
-    T **v = summary->m_map.get (node->summary_uid);
+    T **v = summary->m_map.get (node->uid);
 
-    gcc_checking_assert (node2->summary_uid > 0);
+    gcc_checking_assert (node2->uid > 0);
 
     if (v)
       {
 	/* This load is necessary, because we insert a new value!  */
 	T *data = *v;
 	T *duplicate = summary->allocate_new ();
-	summary->m_map.put (node2->summary_uid, duplicate);
+	summary->m_map.put (node2->uid, duplicate);
 	summary->duplicate (node, node2, data, duplicate);
       }
   }
-- 
2.1.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/4] New data structure for cgraph_summary introduced.
  2014-12-22 14:52             ` Martin Liška
@ 2015-01-14 15:31               ` Martin Liška
  0 siblings, 0 replies; 40+ messages in thread
From: Martin Liška @ 2015-01-14 15:31 UTC (permalink / raw)
  To: gcc-patches

On 12/22/2014 03:50 PM, Martin Liška wrote:
> On 12/18/2014 08:40 PM, Jan Hubicka wrote:
>>> 2014-12-08  Martin Liska  <mliska@suse.cz>
>>>
>>>     * cgraph.h (symbol_table::allocate_cgraph_symbol): Summary UID
>>>     is filled up.
>>>     * symbol-summary.h: New file.
>>>     * gengtype.c (open_base_files): Add symbol-summary.h.
>>>     * toplev.c (general_init): Call constructor of symbol_table.
>>> ---
>>>   gcc/cgraph.h         |   8 ++
>>>   gcc/gengtype.c       |   4 +-
>>>   gcc/symbol-summary.h | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>>   gcc/toplev.c         |   3 +-
>>>   4 files changed, 293 insertions(+), 3 deletions(-)
>>>   create mode 100644 gcc/symbol-summary.h
>>>
>>> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
>>> index a5c5f56..1664bd7 100644
>>> --- a/gcc/cgraph.h
>>> +++ b/gcc/cgraph.h
>>> @@ -1237,6 +1237,8 @@ public:
>>>     int count_materialization_scale;
>>>     /* Unique id of the node.  */
>>>     int uid;
>>> +  /* Summary unique id of the node.  */
>>> +  int summary_uid;
>>
>> Hmm, can't we just use uid here?  I guess the only difference is that summary
>> uid is not kept dense, unlike the uid.
>> This should not propagate into much of trouble simply because the summary datastructure
>> should safely remove the summaires via removal hook.
>
> Hello.
>
> There's patch I've been just testing. It removes summary_uid and uid is going to be
> really unique. I tested the change on Inkscape WPA, and there's time difference in level
> of < 1%.
>
> Ready for trunk after proper testing?
> Thanks,
> Martin
>
>>> +
>>> +/* We want to pass just pointer types as argument for function_summary
>>> +   template class.  */
>>> +
>>> +template <class T>
>>> +class function_summary
>>> +{
>>> +private:
>>> +  function_summary();
>>> +};
>>> +
>>> +template <class T>
>>> +class GTY((user)) function_summary <T *>
>>
>> Eventually I would like this to allow attaching summaries to variables (and symbols in general),
>> too. But currently we do not have use for it, so we can care about this later.
>>
>> The patch is OK.  Preferrably with summary_uid replaced by uid if it is easily doable.
>>
>> Honza
>>
>

PING.

Thanks,
Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2015-01-14 15:09 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-13 14:23 [PATCH 1/4] cgraph_summary data structure introduction mliska
2014-11-13 14:23 ` [PATCH 4/4] Data structure is used for inline_summary struct mliska
2014-11-13 16:04   ` Jan Hubicka
2014-11-14 14:13     ` Martin Liška
2014-11-14 15:32       ` Martin Liška
2014-12-08 17:03         ` Martin Liška
2014-12-18 19:56           ` Jan Hubicka
2014-11-14 16:07       ` Jan Hubicka
2014-11-14 18:13         ` Martin Jambor
2014-11-14 20:12           ` Jan Hubicka
2014-11-18 12:56             ` Martin Jambor
2014-11-18 15:59               ` Jan Hubicka
2014-11-18 18:40                 ` Martin Jambor
2014-11-18 19:19                   ` Jan Hubicka
2014-11-18 22:32                     ` Martin Jambor
2014-11-19 13:25                       ` Martin Liška
2014-11-19  1:50                     ` Trevor Saunders
2014-11-18 10:34         ` Martin Liška
2014-11-13 14:23 ` [PATCH 3/4] First usage of cgraph_summary in ipa-prop pass mliska
2014-11-14 14:12   ` Martin Liška
2014-11-14 15:31     ` Martin Liška
2014-11-14 17:10       ` Martin Jambor
2014-12-08 17:02       ` Martin Liška
2014-12-18 19:44         ` Jan Hubicka
2014-11-13 14:24 ` [PATCH 2/4] New data structure for cgraph_summary introduced mliska
2014-11-13 14:52   ` Markus Trippelsdorf
2014-11-13 15:04     ` Martin Liška
2014-11-13 21:35     ` Trevor Saunders
2014-11-13 22:30       ` Markus Trippelsdorf
2014-11-13 23:15         ` Trevor Saunders
2014-11-13 15:57   ` Jan Hubicka
2014-11-14 10:22     ` Richard Biener
2014-11-14 14:11     ` Martin Liška
2014-11-14 15:31       ` Martin Liška
2014-12-08 17:01         ` Martin Liška
2014-12-18 19:42           ` Jan Hubicka
2014-12-22 14:52             ` Martin Liška
2015-01-14 15:31               ` Martin Liška
2014-11-13 14:34 ` [PATCH 1/4] cgraph_summary data structure introduction Richard Biener
2014-11-13 14:45   ` Martin Liška

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).