diff mbox

[4/4] Data structure is used for inline_summary struct.

Message ID 0747c9874be8f00250182794f2eb38d021464046.1415888515.git.mliska@suse.cz
State New
Headers show

Commit Message

Martin Liška Nov. 11, 2014, 12:41 p.m. UTC
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(-)

Comments

Jan Hubicka Nov. 13, 2014, 4:04 p.m. UTC | #1
> +  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
diff mbox

Patch

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");