Clean-up usage of ipa_fn_summary and ipa_call_summary summaries.
authorMartin Liska <mliska@suse.cz>
Tue, 19 Jun 2018 14:31:20 +0000 (16:31 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 19 Jun 2018 14:31:20 +0000 (14:31 +0000)
2018-06-19  Martin Liska  <mliska@suse.cz>

* config/i386/i386.c (ix86_can_inline_p): Do not use
        ipa_fn_summaries::get_create.
* ipa-cp.c (ipcp_cloning_candidate_p): Replace get_create with
        get.
(devirtualization_time_bonus): Likewise.
(ipcp_propagate_stage): Likewise.
* ipa-fnsummary.c (redirect_to_unreachable): Likewise.
(edge_set_predicate): Likewise.
(evaluate_conditions_for_known_args): Likewise.
(evaluate_properties_for_edge): Likewise.
(ipa_call_summary::reset): Tranform to ...
(ipa_call_summary::~ipa_call_summary): ... this.
(ipa_fn_summary::reset): Transform to ...
(ipa_fn_summary::~ipa_fn_summary): ... this.
(ipa_fn_summary_t::remove): Rename to ...
(ipa_fn_summary_t::remove_callees): ... this.
(ipa_fn_summary_t::duplicate): Use placement new
        instead of memory copy.
(ipa_call_summary_t::duplicate): Likewise.
(ipa_call_summary_t::remove): Remove.
(dump_ipa_call_summary): Change get_create to get.
(ipa_dump_fn_summary): Dump only when summary exists.
(analyze_function_body): Use symbol_summary::get instead
        of get_create.
(compute_fn_summary): Likewise.
(estimate_edge_devirt_benefit): Likewise.
(estimate_edge_size_and_time): Likewise.
(inline_update_callee_summaries): Likewise.
(remap_edge_change_prob): Likewise.
(remap_edge_summaries): Likewise.
(ipa_merge_fn_summary_after_inlining): Likewise.
(write_ipa_call_summary): Likewise.
(ipa_fn_summary_write): Likewise.
(ipa_free_fn_summary): Likewise.
* ipa-fnsummary.h (struct GTY): Add new ctor and copy ctor.
(struct ipa_call_summary): Likewise.
* ipa-icf.c (sem_function::merge): Use symbol_summary::get instead
        of get_create.
* ipa-inline-analysis.c (do_estimate_edge_time): Likewise.
(estimate_size_after_inlining): Likewise.
(estimate_growth): Likewise.
(growth_likely_positive): Likewise.
* ipa-inline-transform.c (clone_inlined_nodes): Likewise.
(inline_call): Likewise.
* ipa-inline.c (caller_growth_limits): Likewise.
(can_inline_edge_p): Likewise.
(can_inline_edge_by_limits_p): Likewise.
(compute_uninlined_call_time): Likewise.
(compute_inlined_call_time): Likewise.
(want_inline_small_function_p): Likewise.
(edge_badness): Likewise.
(update_caller_keys): Likewise.
(update_callee_keys): Likewise.
(inline_small_functions): Likewise.
(inline_to_all_callers_1): Likewise.
(dump_overall_stats): Likewise.
(early_inline_small_functions): Likewise.
(early_inliner): Likewise.
* ipa-profile.c (ipa_propagate_frequency_1): Likewise.
* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
* ipa-pure-const.c (malloc_candidate_p): Likewise.
* ipa-split.c (execute_split_functions): Likewise.
* symbol-summary.h: Likewise.
* tree-sra.c (ipa_sra_preliminary_function_checks): Likewise.
2018-06-19  Martin Liska  <mliska@suse.cz>

* lto-partition.c (add_symbol_to_partition_1): Use symbol_summary::get instead
        of get_create.
(undo_partition): Likewise.
(lto_balanced_map): Likewise.

From-SVN: r261744

17 files changed:
gcc/ChangeLog
gcc/config/i386/i386.c
gcc/ipa-cp.c
gcc/ipa-fnsummary.c
gcc/ipa-fnsummary.h
gcc/ipa-icf.c
gcc/ipa-inline-analysis.c
gcc/ipa-inline-transform.c
gcc/ipa-inline.c
gcc/ipa-profile.c
gcc/ipa-prop.c
gcc/ipa-pure-const.c
gcc/ipa-split.c
gcc/lto/ChangeLog
gcc/lto/lto-partition.c
gcc/symbol-summary.h
gcc/tree-sra.c

index 7c4b9e6ae965e8a45c5ced07040c4975b9b3ce5a..c4a48f068c74ed295c29936c7ca0336f05b0accd 100644 (file)
@@ -1,3 +1,70 @@
+2018-06-19  Martin Liska  <mliska@suse.cz>
+
+       * config/i386/i386.c (ix86_can_inline_p): Do not use
+        ipa_fn_summaries::get_create.
+       * ipa-cp.c (ipcp_cloning_candidate_p): Replace get_create with
+        get.
+       (devirtualization_time_bonus): Likewise.
+       (ipcp_propagate_stage): Likewise.
+       * ipa-fnsummary.c (redirect_to_unreachable): Likewise.
+       (edge_set_predicate): Likewise.
+       (evaluate_conditions_for_known_args): Likewise.
+       (evaluate_properties_for_edge): Likewise.
+       (ipa_call_summary::reset): Tranform to ...
+       (ipa_call_summary::~ipa_call_summary): ... this.
+       (ipa_fn_summary::reset): Transform to ...
+       (ipa_fn_summary::~ipa_fn_summary): ... this.
+       (ipa_fn_summary_t::remove): Rename to ...
+       (ipa_fn_summary_t::remove_callees): ... this.
+       (ipa_fn_summary_t::duplicate): Use placement new
+        instead of memory copy.
+       (ipa_call_summary_t::duplicate): Likewise.
+       (ipa_call_summary_t::remove): Remove.
+       (dump_ipa_call_summary): Change get_create to get.
+       (ipa_dump_fn_summary): Dump only when summary exists.
+       (analyze_function_body): Use symbol_summary::get instead
+        of get_create.
+       (compute_fn_summary): Likewise.
+       (estimate_edge_devirt_benefit): Likewise.
+       (estimate_edge_size_and_time): Likewise.
+       (inline_update_callee_summaries): Likewise.
+       (remap_edge_change_prob): Likewise.
+       (remap_edge_summaries): Likewise.
+       (ipa_merge_fn_summary_after_inlining): Likewise.
+       (write_ipa_call_summary): Likewise.
+       (ipa_fn_summary_write): Likewise.
+       (ipa_free_fn_summary): Likewise.
+       * ipa-fnsummary.h (struct GTY): Add new ctor and copy ctor.
+       (struct ipa_call_summary): Likewise.
+       * ipa-icf.c (sem_function::merge): Use symbol_summary::get instead
+        of get_create.
+       * ipa-inline-analysis.c (do_estimate_edge_time): Likewise.
+       (estimate_size_after_inlining): Likewise.
+       (estimate_growth): Likewise.
+       (growth_likely_positive): Likewise.
+       * ipa-inline-transform.c (clone_inlined_nodes): Likewise.
+       (inline_call): Likewise.
+       * ipa-inline.c (caller_growth_limits): Likewise.
+       (can_inline_edge_p): Likewise.
+       (can_inline_edge_by_limits_p): Likewise.
+       (compute_uninlined_call_time): Likewise.
+       (compute_inlined_call_time): Likewise.
+       (want_inline_small_function_p): Likewise.
+       (edge_badness): Likewise.
+       (update_caller_keys): Likewise.
+       (update_callee_keys): Likewise.
+       (inline_small_functions): Likewise.
+       (inline_to_all_callers_1): Likewise.
+       (dump_overall_stats): Likewise.
+       (early_inline_small_functions): Likewise.
+       (early_inliner): Likewise.
+       * ipa-profile.c (ipa_propagate_frequency_1): Likewise.
+       * ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
+       * ipa-pure-const.c (malloc_candidate_p): Likewise.
+       * ipa-split.c (execute_split_functions): Likewise.
+       * symbol-summary.h: Likewise.
+       * tree-sra.c (ipa_sra_preliminary_function_checks): Likewise.
+
 2018-06-19  Richard Biener  <rguenther@suse.de>
 
        * tree-vectorizer.c (try_vectorize_loop_1): Split out of ...
index f88680703ed33e4bc0a4de1ebd4195bfce3ffecb..ba23cd0a1abc47cd7396003ecda11dd1783df233 100644 (file)
@@ -5760,6 +5760,7 @@ ix86_can_inline_p (tree caller, tree callee)
       && lookup_attribute ("always_inline",
                           DECL_ATTRIBUTES (callee)));
 
+  cgraph_node *callee_node = cgraph_node::get (callee);
   /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
      function can inline a SSE2 function but a SSE2 function can't inline
      a SSE4 function.  */
@@ -5789,8 +5790,8 @@ ix86_can_inline_p (tree caller, tree callee)
              for multi-versioning call optimization, so beware of
              ipa_fn_summaries not available.  */
           && (! ipa_fn_summaries
-              || ipa_fn_summaries->get_create
-              (cgraph_node::get (callee))->fp_expressions))
+              || ipa_fn_summaries->get (callee_node) == NULL
+              || ipa_fn_summaries->get (callee_node)->fp_expressions))
     ret = false;
 
   else if (!always_inline
index 435c9ee1638799dbe414da108391d76917447c3c..c192e84f452ce3fb940bc75d44b0fd4eed9c6589 100644 (file)
@@ -736,7 +736,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 (ipa_fn_summaries->get_create (node)->self_size < stats.n_calls)
+  if (ipa_fn_summaries->get (node)->self_size < stats.n_calls)
     {
       if (dump_file)
        fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
@@ -2583,7 +2583,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
       callee = callee->function_symbol (&avail);
       if (avail < AVAIL_AVAILABLE)
        continue;
-      isummary = ipa_fn_summaries->get_create (callee);
+      isummary = ipa_fn_summaries->get (callee);
       if (!isummary->inlinable)
        continue;
 
@@ -3287,8 +3287,9 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
                                   ipa_get_param_count (info));
        initialize_node_lattices (node);
       }
-    if (node->definition && !node->alias)
-      overall_size += ipa_fn_summaries->get_create (node)->self_size;
+    ipa_fn_summary *s = ipa_fn_summaries->get (node);
+    if (node->definition && !node->alias && s != NULL)
+      overall_size += s->self_size;
     max_count = max_count.max (node->count.ipa ());
   }
 
index 504a2d1ce55a32c254cf96ebabe5266e6ce59a44..c99718a265f3ca034f1b13bb855cd24cd7841925 100644 (file)
@@ -241,7 +241,7 @@ redirect_to_unreachable (struct cgraph_edge *e)
     e->make_direct (target);
   else
     e->redirect_callee (target);
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+  struct ipa_call_summary *es = ipa_call_summaries->get (e);
   e->inline_failed = CIF_UNREACHABLE;
   e->count = profile_count::zero ();
   es->call_stmt_size = 0;
@@ -266,7 +266,7 @@ edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
       && (!e->speculative || e->callee))
     e = redirect_to_unreachable (e);
 
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+  struct ipa_call_summary *es = ipa_call_summaries->get (e);
   if (predicate && *predicate != true)
     {
       if (!es->predicate)
@@ -328,7 +328,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 {
   clause_t clause = inline_p ? 0 : 1 << predicate::not_inlined_condition;
   clause_t nonspec_clause = 1 << predicate::not_inlined_condition;
-  struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+  struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
   int i;
   struct condition *c;
 
@@ -428,7 +428,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 ipa_fn_summary *info = ipa_fn_summaries->get_create (callee);
+  struct ipa_fn_summary *info = ipa_fn_summaries->get (callee);
   vec<tree> known_vals = vNULL;
   vec<ipa_agg_jump_function_p> known_aggs = vNULL;
 
@@ -445,7 +445,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
     {
       struct ipa_node_params *caller_parms_info, *callee_pi;
       struct ipa_edge_args *args = IPA_EDGE_REF (e);
-      struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+      struct ipa_call_summary *es = ipa_call_summaries->get (e);
       int i, count = ipa_get_cs_argument_count (args);
 
       if (e->caller->global.inlined_to)
@@ -535,66 +535,34 @@ ipa_fn_summary_alloc (void)
   ipa_call_summaries = new ipa_call_summary_t (symtab, false);
 }
 
-/* We are called multiple time for given function; clear
-   data from previous run so they are not cumulated.  */
-
-void
-ipa_call_summary::reset ()
+ipa_call_summary::~ipa_call_summary ()
 {
-  call_stmt_size = call_stmt_time = 0;
-  is_return_callee_uncaptured = false;
   if (predicate)
     edge_predicate_pool.remove (predicate);
-  predicate = NULL;
+
   param.release ();
 }
 
-/* We are called multiple time for given function; clear
-   data from previous run so they are not cumulated.  */
-
-void
-ipa_fn_summary::reset (struct cgraph_node *node)
+ipa_fn_summary::~ipa_fn_summary ()
 {
-  struct cgraph_edge *e;
-
-  self_size = 0;
-  estimated_stack_size = 0;
-  estimated_self_stack_size = 0;
-  stack_frame_offset = 0;
-  size = 0;
-  time = 0;
-  growth = 0;
-  scc_no = 0;
   if (loop_iterations)
-    {
-      edge_predicate_pool.remove (loop_iterations);
-      loop_iterations = NULL;
-    }
+    edge_predicate_pool.remove (loop_iterations);
   if (loop_stride)
-    {
-      edge_predicate_pool.remove (loop_stride);
-      loop_stride = NULL;
-    }
+    edge_predicate_pool.remove (loop_stride);
   if (array_index)
-    {
-      edge_predicate_pool.remove (array_index);
-      array_index = NULL;
-    }
+    edge_predicate_pool.remove (array_index);
   vec_free (conds);
   vec_free (size_time_table);
-  for (e = node->callees; e; e = e->next_callee)
-    ipa_call_summaries->get_create (e)->reset ();
-  for (e = node->indirect_calls; e; e = e->next_callee)
-    ipa_call_summaries->get_create (e)->reset ();
-  fp_expressions = false;
 }
 
-/* Hook that is called by cgraph.c when a node is removed.  */
-
 void
-ipa_fn_summary_t::remove (cgraph_node *node, ipa_fn_summary *info)
+ipa_fn_summary_t::remove_callees (cgraph_node *node)
 {
-  info->reset (node);
+  cgraph_edge *e;
+  for (e = node->callees; e; e = e->next_callee)
+    ipa_call_summaries->remove (e);
+  for (e = node->indirect_calls; e; e = e->next_callee)
+    ipa_call_summaries->remove (e);
 }
 
 /* Same as remap_predicate_after_duplication but handle hint predicate *P.
@@ -625,7 +593,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
                             ipa_fn_summary *,
                             ipa_fn_summary *info)
 {
-  memcpy (info, ipa_fn_summaries->get_create (src), sizeof (ipa_fn_summary));
+  new (info) ipa_fn_summary (*ipa_fn_summaries->get (src));
   /* TODO: as an optimization, we may avoid copying conditions
      that are known to be false or true.  */
   info->conds = vec_safe_copy (info->conds);
@@ -779,7 +747,7 @@ ipa_call_summary_t::duplicate (struct cgraph_edge *src,
                               struct ipa_call_summary *srcinfo,
                               struct ipa_call_summary *info)
 {
-  *info = *srcinfo;
+  new (info) ipa_call_summary (*srcinfo);
   info->predicate = NULL;
   edge_set_predicate (dst, srcinfo->predicate);
   info->param = srcinfo->param.copy ();
@@ -792,17 +760,6 @@ ipa_call_summary_t::duplicate (struct cgraph_edge *src,
     }
 }
 
-
-/* Keep edge cache consistent across edge removal.  */
-
-void
-ipa_call_summary_t::remove (struct cgraph_edge *,
-                           struct ipa_call_summary *sum)
-{
-  sum->reset ();
-}
-
-
 /* Dump edge summaries associated to NODE and recursively to all clones.
    Indent by INDENT.  */
 
@@ -813,21 +770,23 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
   struct cgraph_edge *edge;
   for (edge = node->callees; edge; edge = edge->next_callee)
     {
-      struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+      struct ipa_call_summary *es = ipa_call_summaries->get (edge);
       struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
       int i;
 
       fprintf (f,
-              "%*s%s/%i %s\n%*s  loop depth:%2i freq:%4.2f size:%2i"
-              " time: %2i callee size:%2i stack:%2i",
+              "%*s%s/%i %s\n%*s  loop depth:%2i freq:%4.2f size:%2i time: %2i",
               indent, "", callee->name (), callee->order,
               !edge->inline_failed
               ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
               indent, "", es->loop_depth, edge->sreal_frequency ().to_double (),
-              es->call_stmt_size, es->call_stmt_time,
-              (int) (ipa_fn_summaries->get_create (callee)->size
-                     / ipa_fn_summary::size_scale),
-              (int) ipa_fn_summaries->get_create (callee)->estimated_stack_size);
+              es->call_stmt_size, es->call_stmt_time);
+
+      ipa_fn_summary *s = ipa_fn_summaries->get (callee);
+      if (s != NULL)
+       fprintf (f, "callee size:%2i stack:%2i",
+                (int) (s->size / ipa_fn_summary::size_scale),
+                (int) s->estimated_stack_size);
 
       if (es->predicate)
        {
@@ -862,7 +821,7 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
     }
   for (edge = node->indirect_calls; edge; edge = edge->next_callee)
     {
-      struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+      struct ipa_call_summary *es = ipa_call_summaries->get (edge);
       fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
               " time: %2i",
               indent, "",
@@ -885,63 +844,67 @@ ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
 {
   if (node->definition)
     {
-      struct ipa_fn_summary *s = ipa_fn_summaries->get_create (node);
-      size_time_entry *e;
-      int i;
-      fprintf (f, "IPA function summary for %s/%i", node->name (),
-              node->order);
-      if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
-       fprintf (f, " always_inline");
-      if (s->inlinable)
-       fprintf (f, " inlinable");
-      if (s->fp_expressions)
-       fprintf (f, " fp_expression");
-      fprintf (f, "\n  global time:     %f\n", s->time.to_double ());
-      fprintf (f, "  self size:       %i\n", s->self_size);
-      fprintf (f, "  global size:     %i\n", s->size);
-      fprintf (f, "  min size:       %i\n", s->min_size);
-      fprintf (f, "  self stack:      %i\n",
-              (int) s->estimated_self_stack_size);
-      fprintf (f, "  global stack:    %i\n", (int) s->estimated_stack_size);
-      if (s->growth)
-       fprintf (f, "  estimated growth:%i\n", (int) s->growth);
-      if (s->scc_no)
-       fprintf (f, "  In SCC:          %i\n", (int) s->scc_no);
-      for (i = 0; vec_safe_iterate (s->size_time_table, i, &e); i++)
+      struct ipa_fn_summary *s = ipa_fn_summaries->get (node);
+      if (s != NULL)
        {
-         fprintf (f, "    size:%f, time:%f",
-                  (double) e->size / ipa_fn_summary::size_scale,
-                  e->time.to_double ());
-         if (e->exec_predicate != true)
+         size_time_entry *e;
+         int i;
+         fprintf (f, "IPA function summary for %s", node->dump_name ());
+         if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
+           fprintf (f, " always_inline");
+         if (s->inlinable)
+           fprintf (f, " inlinable");
+         if (s->fp_expressions)
+           fprintf (f, " fp_expression");
+         fprintf (f, "\n  global time:     %f\n", s->time.to_double ());
+         fprintf (f, "  self size:       %i\n", s->self_size);
+         fprintf (f, "  global size:     %i\n", s->size);
+         fprintf (f, "  min size:       %i\n", s->min_size);
+         fprintf (f, "  self stack:      %i\n",
+                  (int) s->estimated_self_stack_size);
+         fprintf (f, "  global stack:    %i\n", (int) s->estimated_stack_size);
+         if (s->growth)
+           fprintf (f, "  estimated growth:%i\n", (int) s->growth);
+         if (s->scc_no)
+           fprintf (f, "  In SCC:          %i\n", (int) s->scc_no);
+         for (i = 0; vec_safe_iterate (s->size_time_table, i, &e); i++)
+           {
+             fprintf (f, "    size:%f, time:%f",
+                      (double) e->size / ipa_fn_summary::size_scale,
+                      e->time.to_double ());
+             if (e->exec_predicate != true)
+               {
+                 fprintf (f, ",  executed if:");
+                 e->exec_predicate.dump (f, s->conds, 0);
+               }
+             if (e->exec_predicate != e->nonconst_predicate)
+               {
+                 fprintf (f, ",  nonconst if:");
+                 e->nonconst_predicate.dump (f, s->conds, 0);
+               }
+             fprintf (f, "\n");
+           }
+         if (s->loop_iterations)
            {
-             fprintf (f, ",  executed if:");
-             e->exec_predicate.dump (f, s->conds, 0);
+             fprintf (f, "  loop iterations:");
+             s->loop_iterations->dump (f, s->conds);
            }
-         if (e->exec_predicate != e->nonconst_predicate)
+         if (s->loop_stride)
            {
-             fprintf (f, ",  nonconst if:");
-             e->nonconst_predicate.dump (f, s->conds, 0);
+             fprintf (f, "  loop stride:");
+             s->loop_stride->dump (f, s->conds);
            }
+         if (s->array_index)
+           {
+             fprintf (f, "  array index:");
+             s->array_index->dump (f, s->conds);
+           }
+         fprintf (f, "  calls:\n");
+         dump_ipa_call_summary (f, 4, node, s);
          fprintf (f, "\n");
        }
-      if (s->loop_iterations)
-       {
-         fprintf (f, "  loop iterations:");
-         s->loop_iterations->dump (f, s->conds);
-       }
-      if (s->loop_stride)
-       {
-         fprintf (f, "  loop stride:");
-         s->loop_stride->dump (f, s->conds);
-       }
-      if (s->array_index)
-       {
-         fprintf (f, "  array index:");
-         s->array_index->dump (f, s->conds);
-       }
-      fprintf (f, "  calls:\n");
-      dump_ipa_call_summary (f, 4, node, s);
-      fprintf (f, "\n");
+      else
+       fprintf (f, "IPA summary for %s is missing.\n", node->dump_name ());
     }
 }
 
@@ -2365,7 +2328,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
            }
          free (body);
        }
-      ipa_fn_summary *s = ipa_fn_summaries->get_create (node);
+      ipa_fn_summary *s = ipa_fn_summaries->get (node);
       set_hint_predicate (&s->loop_iterations, loop_iterations);
       set_hint_predicate (&s->loop_stride, loop_stride);
       scev_finalize ();
@@ -2385,7 +2348,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
          e->aux = NULL;
        }
     }
-  ipa_fn_summary *s = ipa_fn_summaries->get_create (node);
+  ipa_fn_summary *s = ipa_fn_summaries->get (node);
   s->time = time;
   s->self_size = size;
   nonconstant_names.release ();
@@ -2421,8 +2384,10 @@ compute_fn_summary (struct cgraph_node *node, bool early)
   if (!ipa_fn_summaries)
     ipa_fn_summary_alloc ();
 
+  /* Create a new ipa_fn_summary.  */
+  ((ipa_fn_summary_t *)ipa_fn_summaries)->remove_callees (node);
+  ipa_fn_summaries->remove (node);
   info = ipa_fn_summaries->get_create (node);
-  info->reset (node);
 
   /* Estimate the stack size for the function if we're optimizing.  */
   self_stack_size = optimize && !node->thunk.thunk_p
@@ -2577,7 +2542,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
   callee = callee->function_symbol (&avail);
   if (avail < AVAIL_AVAILABLE)
     return false;
-  isummary = ipa_fn_summaries->get_create (callee);
+  isummary = ipa_fn_summaries->get (callee);
   return isummary->inlinable;
 }
 
@@ -2596,7 +2561,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
                             vec<ipa_agg_jump_function_p> known_aggs,
                             ipa_hints *hints)
 {
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+  struct ipa_call_summary *es = ipa_call_summaries->get (e);
   int call_size = es->call_stmt_size;
   int call_time = es->call_stmt_time;
   int cur_size;
@@ -2853,9 +2818,8 @@ static void
 inline_update_callee_summaries (struct cgraph_node *node, int depth)
 {
   struct cgraph_edge *e;
-  ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (node);
-  ipa_fn_summary *caller_info
-    = ipa_fn_summaries->get_create (node->callers->caller);
+  ipa_fn_summary *callee_info = ipa_fn_summaries->get (node);
+  ipa_fn_summary *caller_info = ipa_fn_summaries->get (node->callers->caller);
   HOST_WIDE_INT peak;
 
   callee_info->stack_frame_offset
@@ -2864,7 +2828,7 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
   peak = callee_info->stack_frame_offset
     + callee_info->estimated_self_stack_size;
 
-  ipa_fn_summary *s = ipa_fn_summaries->get_create (node->global.inlined_to);
+  ipa_fn_summary *s = ipa_fn_summaries->get (node->global.inlined_to);
   if (s->estimated_stack_size < peak)
     s->estimated_stack_size = peak;
   ipa_propagate_frequency (node);
@@ -2872,10 +2836,10 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
     {
       if (!e->inline_failed)
        inline_update_callee_summaries (e->callee, depth);
-      ipa_call_summaries->get_create (e)->loop_depth += depth;
+      ipa_call_summaries->get (e)->loop_depth += depth;
     }
   for (e = node->indirect_calls; e; e = e->next_callee)
-    ipa_call_summaries->get_create (e)->loop_depth += depth;
+    ipa_call_summaries->get (e)->loop_depth += depth;
 }
 
 /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
@@ -2892,9 +2856,9 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
     {
       int i;
       struct ipa_edge_args *args = IPA_EDGE_REF (edge);
-      struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+      struct ipa_call_summary *es = ipa_call_summaries->get (edge);
       struct ipa_call_summary *inlined_es
-       = ipa_call_summaries->get_create (inlined_edge);
+       = ipa_call_summaries->get (inlined_edge);
 
       for (i = 0; i < ipa_get_cs_argument_count (args); i++)
        {
@@ -2941,7 +2905,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
   struct cgraph_edge *e, *next;
   for (e = node->callees; e; e = next)
     {
-      struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+      struct ipa_call_summary *es = ipa_call_summaries->get (e);
       predicate p;
       next = e->next_callee;
 
@@ -2967,7 +2931,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
     }
   for (e = node->indirect_calls; e; e = next)
     {
-      struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+      struct ipa_call_summary *es = ipa_call_summaries->get (e);
       predicate p;
       next = e->next_callee;
 
@@ -3017,10 +2981,10 @@ remap_hint_predicate (struct ipa_fn_summary *info,
 void
 ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
 {
-  ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (edge->callee);
+  ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
   struct cgraph_node *to = (edge->caller->global.inlined_to
                            ? edge->caller->global.inlined_to : edge->caller);
-  struct ipa_fn_summary *info = ipa_fn_summaries->get_create (to);
+  struct ipa_fn_summary *info = ipa_fn_summaries->get (to);
   clause_t clause = 0; /* not_inline is known to be false.  */
   size_time_entry *e;
   vec<int> operand_map = vNULL;
@@ -3028,7 +2992,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
   int i;
   predicate toplev_predicate;
   predicate true_p = true;
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+  struct ipa_call_summary *es = ipa_call_summaries->get (edge);
 
   if (es->predicate)
     toplev_predicate = *es->predicate;
@@ -3117,7 +3081,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
                        &callee_info->array_index,
                        operand_map, offset_map, clause, &toplev_predicate);
 
-  ipa_call_summary *s = ipa_call_summaries->get_create (edge);
+  ipa_call_summary *s = ipa_call_summaries->get (edge);
   inline_update_callee_summaries (edge->callee, s->loop_depth);
 
   /* We do not maintain predicates of inlined edges, free it.  */
@@ -3392,7 +3356,7 @@ ipa_fn_summary_read (void)
 static void
 write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
 {
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+  struct ipa_call_summary *es = ipa_call_summaries->get (e);
   int i;
 
   streamer_write_uhwi (ob, es->call_stmt_size);
@@ -3440,7 +3404,7 @@ ipa_fn_summary_write (void)
       cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
       if (cnode && cnode->definition && !cnode->alias)
        {
-         struct ipa_fn_summary *info = ipa_fn_summaries->get_create (cnode);
+         struct ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
          struct bitpack_d bp;
          struct cgraph_edge *edge;
          int i;
@@ -3515,7 +3479,7 @@ ipa_free_fn_summary (void)
     return;
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->alias)
-      ipa_fn_summaries->get_create (node)->reset (node);
+      ipa_fn_summaries->remove (node);
   ipa_fn_summaries->release ();
   ipa_fn_summaries = NULL;
   ipa_call_summaries->release ();
index c2187510cb625d3f81cafacdf2bb0c472eeeb839..9e79594423635e68ba6c947176ba10b67451f13d 100644 (file)
@@ -87,6 +87,34 @@ struct GTY(()) size_time_entry
 /* Function inlining information.  */
 struct GTY(()) ipa_fn_summary
 {
+  /* Keep all field empty so summary dumping works during its computation.
+     This is useful for debugging.  */
+  ipa_fn_summary ()
+    : estimated_self_stack_size (0), self_size (0), min_size (0),
+      inlinable (false), single_caller (false),
+      fp_expressions (false), estimated_stack_size (false),
+      stack_frame_offset (false), time (0), size (0), conds (NULL),
+      size_time_table (NULL), loop_iterations (NULL), loop_stride (NULL),
+      array_index (NULL), growth (0), scc_no (0)
+  {
+  }
+
+  /* Copy constructor.  */
+  ipa_fn_summary (const ipa_fn_summary &s)
+    : estimated_self_stack_size (s.estimated_self_stack_size),
+    self_size (s.self_size), min_size (s.min_size),
+    inlinable (s.inlinable), single_caller (s.single_caller),
+    fp_expressions (s.fp_expressions),
+    estimated_stack_size (s.estimated_stack_size),
+    stack_frame_offset (s.stack_frame_offset), time (s.time), size (s.size),
+    conds (s.conds), size_time_table (s.size_time_table),
+    loop_iterations (s.loop_iterations), loop_stride (s.loop_stride),
+    array_index (s.array_index), growth (s.growth), scc_no (s.scc_no)
+  {}
+
+  /* Default constructor.  */
+  ~ipa_fn_summary ();
+
   /* Information about the function body itself.  */
 
   /* Estimated stack frame consumption by the function.  */
@@ -138,24 +166,9 @@ struct GTY(()) ipa_fn_summary
   /* Number of SCC on the beginning of inlining process.  */
   int scc_no;
 
-  /* Keep all field empty so summary dumping works during its computation.
-     This is useful for debugging.  */
-  ipa_fn_summary ()
-    : estimated_self_stack_size (0), self_size (0), min_size (0),
-      inlinable (false), single_caller (false),
-      fp_expressions (false), estimated_stack_size (false),
-      stack_frame_offset (false), time (0), size (0), conds (NULL),
-      size_time_table (NULL), loop_iterations (NULL), loop_stride (NULL),
-      array_index (NULL), growth (0), scc_no (0)
-    {
-    }
-
   /* Record time and size under given predicates.  */
   void account_size_time (int, sreal, const predicate &, const predicate &);
 
-  /* Reset summary to empty state.  */
-  void reset (struct cgraph_node *node);
-
   /* We keep values scaled up, so fractional sizes can be accounted.  */
   static const int size_scale = 2;
 };
@@ -174,9 +187,15 @@ public:
     return summary;
   }
 
+  /* Remove ipa_fn_summary for all callees of NODE.  */
+  void remove_callees (cgraph_node *node);
 
   virtual void insert (cgraph_node *, ipa_fn_summary *);
-  virtual void remove (cgraph_node *node, ipa_fn_summary *);
+  virtual void remove (cgraph_node *node, ipa_fn_summary *)
+  {
+    remove_callees (node);
+  }
+
   virtual void duplicate (cgraph_node *src, cgraph_node *dst,
                          ipa_fn_summary *src_data, ipa_fn_summary *dst_data);
 };
@@ -186,6 +205,25 @@ extern GTY(()) function_summary <ipa_fn_summary *> *ipa_fn_summaries;
 /* Information kept about callgraph edges.  */
 struct ipa_call_summary
 {
+  /* Keep all field empty so summary dumping works during its computation.
+     This is useful for debugging.  */
+  ipa_call_summary ()
+    : predicate (NULL), param (vNULL), call_stmt_size (0), call_stmt_time (0),
+      loop_depth (0), is_return_callee_uncaptured (false)
+    {
+    }
+
+  /* Copy constructor.  */
+  ipa_call_summary (const ipa_call_summary &s):
+    predicate (s.predicate), param (s.param), call_stmt_size (s.call_stmt_size),
+    call_stmt_time (s.call_stmt_time), loop_depth (s.loop_depth),
+    is_return_callee_uncaptured (s.is_return_callee_uncaptured)
+  {
+  }
+
+  /* Default destructor.  */
+  ~ipa_call_summary ();
+
   class predicate *predicate;
   /* Vector indexed by parameters.  */
   vec<inline_param_summary> param;
@@ -196,17 +234,6 @@ struct ipa_call_summary
   unsigned int loop_depth;
   /* Indicates whether the caller returns the value of it's callee.  */
   bool is_return_callee_uncaptured;
-
-  /* Keep all field empty so summary dumping works during its computation.
-     This is useful for debugging.  */
-  ipa_call_summary ()
-    : predicate (NULL), param (vNULL), call_stmt_size (0), call_stmt_time (0),
-      loop_depth (0)
-    {
-    }
-
-  /* Reset inline summary to empty state.  */
-  void reset ();
 };
 
 class ipa_call_summary_t: public call_summary <ipa_call_summary *>
@@ -215,8 +242,6 @@ public:
   ipa_call_summary_t (symbol_table *symtab, bool ggc):
     call_summary <ipa_call_summary *> (symtab, ggc) {}
 
-  /* Hook that is called by summary when an edge is duplicated.  */
-  virtual void remove (cgraph_edge *cs, ipa_call_summary *);
   /* Hook that is called by summary when an edge is duplicated.  */
   virtual void duplicate (cgraph_edge *src, cgraph_edge *dst,
                          ipa_call_summary *src_data,
index bededc3bbd5cd9b8956911cd4c3a3e6104ca0d27..90d1e17e5cd4d9b6824f0f671a3d9c6e2e77969b 100644 (file)
@@ -1199,7 +1199,8 @@ sem_function::merge (sem_item *alias_item)
                     "can not create wrapper of stdarg function.\n");
        }
       else if (ipa_fn_summaries
-              && ipa_fn_summaries->get_create (alias)->self_size <= 2)
+              && ipa_fn_summaries->get (alias) != NULL
+              && ipa_fn_summaries->get (alias)->self_size <= 2)
        {
          if (dump_file)
            fprintf (dump_file, "Wrapper creation is not "
index c781d368a8a5d57950e71d4374d677c50af17244..c967eaa91b58431d8526a0a4bcfabac85dacbeb1 100644 (file)
@@ -128,7 +128,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
   vec<tree> known_vals;
   vec<ipa_polymorphic_call_context> known_contexts;
   vec<ipa_agg_jump_function_p> known_aggs;
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+  struct ipa_call_summary *es = ipa_call_summaries->get (edge);
   int min_size;
 
   callee = edge->callee->ultimate_alias_target ();
@@ -264,8 +264,8 @@ int
 estimate_size_after_inlining (struct cgraph_node *node,
                              struct cgraph_edge *edge)
 {
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
-  ipa_fn_summary *s = ipa_fn_summaries->get_create (node);
+  struct ipa_call_summary *es = ipa_call_summaries->get (edge);
+  ipa_fn_summary *s = ipa_fn_summaries->get (node);
   if (!es->predicate || *es->predicate != false)
     {
       int size = s->size + estimate_edge_growth (edge);
@@ -321,7 +321,7 @@ int
 estimate_growth (struct cgraph_node *node)
 {
   struct growth_data d = { node, false, false, 0 };
-  struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+  struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
 
   node->call_for_symbol_and_aliases (do_estimate_growth_1, &d, true);
 
@@ -396,7 +396,7 @@ growth_likely_positive (struct cgraph_node *node,
       || node->address_taken)
     return true;
 
-  max_callers = ipa_fn_summaries->get_create (node)->size * 4 / edge_growth + 2;
+  max_callers = ipa_fn_summaries->get (node)->size * 4 / edge_growth + 2;
 
   for (e = node->callers; e; e = e->next_caller)
     {
index 6a3b5291c139f81c9f1426dfd7f094b269177d77..0e7499852911e43794c6562a3f99b22b8f2a0aec 100644 (file)
@@ -200,7 +200,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
            {
              gcc_assert (!e->callee->alias);
              if (overall_size)
-               *overall_size -= ipa_fn_summaries->get_create (e->callee)->size;
+               *overall_size -= ipa_fn_summaries->get (e->callee)->size;
              nfunctions_inlined++;
            }
          duplicate = false;
@@ -351,8 +351,8 @@ inline_call (struct cgraph_edge *e, bool update_original,
       reload_optimization_node = true;
     }
 
-  ipa_fn_summary *caller_info = ipa_fn_summaries->get_create (to);
-  ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (callee);
+  ipa_fn_summary *caller_info = ipa_fn_summaries->get (to);
+  ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
   if (!caller_info->fp_expressions && callee_info->fp_expressions)
     {
       caller_info->fp_expressions = true;
@@ -444,7 +444,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
 
   gcc_assert (curr->callee->global.inlined_to == to);
 
-  old_size = ipa_fn_summaries->get_create (to)->size;
+  old_size = ipa_fn_summaries->get (to)->size;
   ipa_merge_fn_summary_after_inlining (e);
   if (e->in_polymorphic_cdtor)
     mark_all_inlined_calls_cdtor (e->callee);
@@ -458,8 +458,8 @@ inline_call (struct cgraph_edge *e, bool update_original,
        work for further inlining into this function.  Before inlining
        the function we inlined to again we expect the caller to update
        the overall summary.  */
-    ipa_fn_summaries->get_create (to)->size += estimated_growth;
-  new_size = ipa_fn_summaries->get_create (to)->size;
+    ipa_fn_summaries->get (to)->size += estimated_growth;
+  new_size = ipa_fn_summaries->get (to)->size;
 
   if (callee->calls_comdat_local)
     to->calls_comdat_local = true;
index 7e4468a7331db3c0cc11fcd62a82c92812e5387e..a62c1ffd3b0164dd3a6e71487ffb685f72be8fd0 100644 (file)
@@ -151,7 +151,7 @@ caller_growth_limits (struct cgraph_edge *e)
   int limit = 0;
   HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
   ipa_fn_summary *info, *what_info;
-  ipa_fn_summary *outer_info = ipa_fn_summaries->get_create (to);
+  ipa_fn_summary *outer_info = ipa_fn_summaries->get (to);
 
   /* Look for function e->caller is inlined to.  While doing
      so work out the largest function body on the way.  As
@@ -163,7 +163,7 @@ caller_growth_limits (struct cgraph_edge *e)
      too much in order to prevent compiler from exploding".  */
   while (true)
     {
-      info = ipa_fn_summaries->get_create (to);
+      info = ipa_fn_summaries->get (to);
       if (limit < info->self_size)
        limit = info->self_size;
       if (stack_size_limit < info->estimated_self_stack_size)
@@ -174,7 +174,7 @@ caller_growth_limits (struct cgraph_edge *e)
        break;
     }
 
-  what_info = ipa_fn_summaries->get_create (what);
+  what_info = ipa_fn_summaries->get (what);
 
   if (limit < what_info->self_size)
     limit = what_info->self_size;
@@ -364,7 +364,8 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
       e->inline_failed = CIF_TARGET_OPTION_MISMATCH;
       inlinable = false;
     }
-  else if (!ipa_fn_summaries->get_create (callee)->inlinable)
+  else if (ipa_fn_summaries->get (callee) == NULL
+          || !ipa_fn_summaries->get (callee)->inlinable)
     {
       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
       inlinable = false;
@@ -426,8 +427,8 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report,
             (DECL_DISREGARD_INLINE_LIMITS (callee->decl)
              && lookup_attribute ("always_inline",
                                   DECL_ATTRIBUTES (callee->decl)));
-      ipa_fn_summary *caller_info = ipa_fn_summaries->get_create (caller);
-      ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (callee);
+      ipa_fn_summary *caller_info = ipa_fn_summaries->get (caller);
+      ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
 
      /* Until GCC 4.9 we did not check the semantics alterning flags
        bellow and inline across optimization boundry.
@@ -530,7 +531,7 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report,
                   > opt_for_fn (caller->decl, optimize)))
        {
          if (estimate_edge_time (e)
-             >= 20 + ipa_call_summaries->get_create (e)->call_stmt_time)
+             >= 20 + ipa_call_summaries->get (e)->call_stmt_time)
            {
              e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
              inlinable = false;
@@ -680,7 +681,7 @@ compute_uninlined_call_time (struct cgraph_edge *edge,
   else
     uninlined_call_time = uninlined_call_time >> 11;
 
-  sreal caller_time = ipa_fn_summaries->get_create (caller)->time;
+  sreal caller_time = ipa_fn_summaries->get (caller)->time;
   return uninlined_call_time + caller_time;
 }
 
@@ -694,7 +695,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
   cgraph_node *caller = (edge->caller->global.inlined_to 
                         ? edge->caller->global.inlined_to
                         : edge->caller);
-  sreal caller_time = ipa_fn_summaries->get_create (caller)->time;
+  sreal caller_time = ipa_fn_summaries->get (caller)->time;
 
   sreal freq = edge->sreal_frequency ();
   if (freq > 0)
@@ -704,7 +705,7 @@ compute_inlined_call_time (struct cgraph_edge *edge,
 
   /* This calculation should match one in ipa-inline-analysis.c
      (estimate_edge_size_and_time).  */
-  time -= (sreal)ipa_call_summaries->get_create (edge)->call_stmt_time * freq;
+  time -= (sreal)ipa_call_summaries->get (edge)->call_stmt_time * freq;
   time += caller_time;
   if (time <= 0)
     time = ((sreal) 1) >> 8;
@@ -756,8 +757,8 @@ 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.ipa ().initialized_p () || !e->maybe_hot_p ()))
-          && ipa_fn_summaries->get_create (callee)->min_size
-               - ipa_call_summaries->get_create (e)->call_stmt_size
+          && ipa_fn_summaries->get (callee)->min_size
+               - ipa_call_summaries->get (e)->call_stmt_size
              > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
     {
       e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
@@ -765,8 +766,8 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
     }
   else if ((DECL_DECLARED_INLINE_P (callee->decl)
            || e->count.ipa ().nonzero_p ())
-          && ipa_fn_summaries->get_create (callee)->min_size
-               - ipa_call_summaries->get_create (e)->call_stmt_size
+          && ipa_fn_summaries->get (callee)->min_size
+               - ipa_call_summaries->get (e)->call_stmt_size
              > 16 * MAX_INLINE_INSNS_SINGLE)
     {
       e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
@@ -1018,7 +1019,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   int growth;
   sreal edge_time, unspec_edge_time;
   struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
-  struct ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (callee);
+  struct ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
   ipa_hints hints;
   cgraph_node *caller = (edge->caller->global.inlined_to 
                         ? edge->caller->global.inlined_to
@@ -1131,7 +1132,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
                  && (!DECL_DECLARED_INLINE_P (edge->callee->decl)
                      || DECL_DECLARED_INLINE_P (caller->decl)))))
        {
-         ipa_fn_summary *caller_info = ipa_fn_summaries->get_create (caller);
+         ipa_fn_summary *caller_info = ipa_fn_summaries->get (caller);
          int caller_growth = caller_info->growth;
 
          /* Only apply the penalty when caller looks like inline candidate,
@@ -1190,7 +1191,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
      of functions fully inlined in program.  */
   else
     {
-      int nest = MIN (ipa_call_summaries->get_create (edge)->loop_depth, 8);
+      int nest = MIN (ipa_call_summaries->get (edge)->loop_depth, 8);
       badness = growth;
 
       /* Decrease badness if call is nested.  */
@@ -1334,7 +1335,7 @@ update_caller_keys (edge_heap_t *heap, struct cgraph_node *node,
   struct cgraph_edge *edge;
   struct ipa_ref *ref;
 
-  if ((!node->alias && !ipa_fn_summaries->get_create (node)->inlinable)
+  if ((!node->alias && !ipa_fn_summaries->get (node)->inlinable)
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->get_uid ()))
@@ -1393,7 +1394,8 @@ 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, e->caller))
-           && ipa_fn_summaries->get_create (callee)->inlinable
+           && ipa_fn_summaries->get (callee) != NULL
+           && ipa_fn_summaries->get (callee)->inlinable
            && avail >= AVAIL_AVAILABLE
            && !bitmap_bit_p (updated_nodes, callee->get_uid ()))
          {
@@ -1769,7 +1771,7 @@ inline_small_functions (void)
            && (node->has_gimple_body_p () || node->thunk.thunk_p)
            && opt_for_fn (node->decl, optimize))
          {
-           struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+           struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
            struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
 
            /* Do not account external functions, they will be optimized out
@@ -1791,7 +1793,7 @@ inline_small_functions (void)
                     n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle)
                  if (opt_for_fn (n2->decl, optimize))
                    {
-                     ipa_fn_summary *info2 = ipa_fn_summaries->get_create (n2);
+                     ipa_fn_summary *info2 = ipa_fn_summaries->get (n2);
                      if (info2->scc_no)
                        break;
                      info2->scc_no = id;
@@ -1952,7 +1954,7 @@ inline_small_functions (void)
          fprintf (dump_file,
                   "\nConsidering %s with %i size\n",
                   callee->dump_name (),
-                  ipa_fn_summaries->get_create (callee)->size);
+                  ipa_fn_summaries->get (callee)->size);
          fprintf (dump_file,
                   " to be inlined into %s in %s:%i\n"
                   " Estimated badness is %f, frequency %.2f.\n",
@@ -2078,7 +2080,7 @@ inline_small_functions (void)
 
       if (dump_file)
        {
-         ipa_fn_summary *s = ipa_fn_summaries->get_create (edge->caller);
+         ipa_fn_summary *s = ipa_fn_summaries->get (edge->caller);
          fprintf (dump_file,
                   " Inlined %s into %s which now has time %f and size %i, "
                   "net change of %+i.\n",
@@ -2220,11 +2222,11 @@ inline_to_all_callers_1 (struct cgraph_node *node, void *data,
          fprintf (dump_file,
                   "\nInlining %s size %i.\n",
                   node->name (),
-                  ipa_fn_summaries->get_create (node)->size);
+                  ipa_fn_summaries->get (node)->size);
          fprintf (dump_file,
                   " Called once from %s %i insns.\n",
                   node->callers->caller->name (),
-                  ipa_fn_summaries->get_create (node->callers->caller)->size);
+                  ipa_fn_summaries->get (node->callers->caller)->size);
        }
 
       /* Remember which callers we inlined to, delaying updating the
@@ -2235,7 +2237,7 @@ inline_to_all_callers_1 (struct cgraph_node *node, void *data,
        fprintf (dump_file,
                 " Inlined into %s which now has %i size\n",
                 caller->name (),
-                ipa_fn_summaries->get_create (caller)->size);
+                ipa_fn_summaries->get (caller)->size);
       if (!(*num_calls)--)
        {
          if (dump_file)
@@ -2276,10 +2278,13 @@ dump_overall_stats (void)
     if (!node->global.inlined_to
        && !node->alias)
       {
-       sreal time = ipa_fn_summaries->get_create (node)->time;
-       sum += time;
-       if (node->count.ipa ().initialized_p ())
-         sum_weighted += time * node->count.ipa ().to_gcov_type ();
+       ipa_fn_summary *s = ipa_fn_summaries->get (node);
+       if (s != NULL)
+         {
+         sum += s->time;
+         if (node->count.ipa ().initialized_p ())
+           sum_weighted += s->time * node->count.ipa ().to_gcov_type ();
+         }
       }
   fprintf (dump_file, "Overall time estimate: "
           "%f weighted by profile: "
@@ -2655,8 +2660,12 @@ 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 (!ipa_fn_summaries->get_create (callee)->inlinable
-         || !e->inline_failed)
+
+      /* We can enounter not-yet-analyzed function during
+        early inlining on callgraphs with strongly
+        connected components.  */
+      ipa_fn_summary *s = ipa_fn_summaries->get (callee);
+      if (s == NULL || !s->inlinable || !e->inline_failed)
        continue;
 
       /* Do not consider functions not declared inline.  */
@@ -2765,6 +2774,9 @@ early_inliner (function *fun)
             statements that don't have inline parameters computed.  */
          for (edge = node->callees; edge; edge = edge->next_callee)
            {
+             /* We can enounter not-yet-analyzed function during
+                early inlining on callgraphs with strongly
+                connected components.  */
              ipa_call_summary *es = ipa_call_summaries->get_create (edge);
              es->call_stmt_size
                = estimate_num_insns (edge->call_stmt, &eni_size_weights);
@@ -2790,11 +2802,14 @@ early_inliner (function *fun)
          for (edge = node->callees; edge; edge = edge->next_callee)
            {
              /* We have no summary for new bound store calls yet.  */
-             ipa_call_summary *es = ipa_call_summaries->get_create (edge);
-             es->call_stmt_size
-               = estimate_num_insns (edge->call_stmt, &eni_size_weights);
-             es->call_stmt_time
-               = estimate_num_insns (edge->call_stmt, &eni_time_weights);
+             ipa_call_summary *es = ipa_call_summaries->get (edge);
+             if (es != NULL)
+               {
+                 es->call_stmt_size
+                   = estimate_num_insns (edge->call_stmt, &eni_size_weights);
+                 es->call_stmt_time
+                   = estimate_num_insns (edge->call_stmt, &eni_time_weights);
+               }
 
              if (edge->callee->decl
                  && !gimple_check_call_matching_types (
index 7500f5438e825a59fa86deea20e361912b3e4078..f921d1bb6f4f6683da60d7dd577b421a5ece9a90 100644 (file)
@@ -345,17 +345,20 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
        case NODE_FREQUENCY_UNLIKELY_EXECUTED:
          break;
        case NODE_FREQUENCY_EXECUTED_ONCE:
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "  Called by %s that is executed once\n",
-                    edge->caller->name ());
-         d->maybe_unlikely_executed = false;
-         if (ipa_call_summaries->get_create (edge)->loop_depth)
-           {
-             d->maybe_executed_once = false;
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               fprintf (dump_file, "  Called in loop\n");
-           }
-         break;
+         {
+           if (dump_file && (dump_flags & TDF_DETAILS))
+             fprintf (dump_file, "  Called by %s that is executed once\n",
+                      edge->caller->name ());
+           d->maybe_unlikely_executed = false;
+           ipa_call_summary *s = ipa_call_summaries->get (edge);
+           if (s != NULL && s->loop_depth)
+             {
+               d->maybe_executed_once = false;
+               if (dump_file && (dump_flags & TDF_DETAILS))
+                 fprintf (dump_file, "  Called in loop\n");
+             }
+           break;
+         }
        case NODE_FREQUENCY_HOT:
        case NODE_FREQUENCY_NORMAL:
          if (dump_file && (dump_flags & TDF_DETAILS))
index daada4d55a58f5e296b3eb1ab3458b7ed2ea331d..000c05ffd89d37bad72301304395a1bc5b437cd0 100644 (file)
@@ -2819,7 +2819,6 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
                                bool speculative)
 {
   struct cgraph_node *callee;
-  struct ipa_call_summary *es = ipa_call_summaries->get_create (ie);
   bool unreachable = false;
 
   if (TREE_CODE (target) == ADDR_EXPR)
@@ -2957,7 +2956,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
         for direct call (adjusted by inline_edge_duplication_hook).  */
       if (ie == orig)
        {
-         es = ipa_call_summaries->get_create (ie);
+         ipa_call_summary *es = ipa_call_summaries->get (ie);
          es->call_stmt_size -= (eni_size_weights.indirect_call_cost
                                 - eni_size_weights.call_cost);
          es->call_stmt_time -= (eni_time_weights.indirect_call_cost
index 9441d2508ab7a8116bb7ded9e4887cd61894466e..4de609e7ca158d38ae11ea48ab4036348deb7e11 100644 (file)
@@ -923,7 +923,7 @@ malloc_candidate_p (function *fun, bool ipa)
          cgraph_edge *cs = node->get_edge (call_stmt);
          if (cs)
            {
-             ipa_call_summary *es = ipa_call_summaries->get_create (cs);
+             ipa_call_summary *es = ipa_call_summaries->get (cs);
              gcc_assert (es);
              es->is_return_callee_uncaptured = true;
            }
@@ -959,7 +959,7 @@ malloc_candidate_p (function *fun, bool ipa)
              cgraph_edge *cs = node->get_edge (call_stmt);
              if (cs)
                {
-                 ipa_call_summary *es = ipa_call_summaries->get_create (cs);
+                 ipa_call_summary *es = ipa_call_summaries->get (cs);
                  gcc_assert (es);
                  es->is_return_callee_uncaptured = true;
                }
index c3771f178bf5a83b18b7ce85a8248ae4c8d31260..0e6440f8997c54b8b92e3c69e04af3ae196271cf 100644 (file)
@@ -1691,7 +1691,8 @@ execute_split_functions (void)
   /* This can be relaxed; function might become inlinable after splitting
      away the uninlinable part.  */
   if (ipa_fn_summaries
-      && !ipa_fn_summaries->get_create (node)->inlinable)
+      && ipa_fn_summaries->get (node)
+      && !ipa_fn_summaries->get (node)->inlinable)
     {
       if (dump_file)
        fprintf (dump_file, "Not splitting: not inlinable.\n");
index aaede9a7264ab7209eac1c5961c1626f65935e1f..67db280d4004f6bd1b196fc484cd9e3285b58a97 100644 (file)
@@ -1,3 +1,10 @@
+2018-06-19  Martin Liska  <mliska@suse.cz>
+
+       * lto-partition.c (add_symbol_to_partition_1): Use symbol_summary::get instead
+        of get_create.
+       (undo_partition): Likewise.
+       (lto_balanced_map): Likewise.
+
 2018-06-19  Martin Liska  <mliska@suse.cz>
 
        * config-lang.in: Remove stagestuff.
index 0ceb1b63f953e7376a473fd1ef24b97a86452893..c7a5710f776c09f852a014fb5d51d595acd6d74e 100644 (file)
@@ -171,7 +171,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
     {
       struct cgraph_edge *e;
       if (!node->alias && c == SYMBOL_PARTITION)
-        part->insns += ipa_fn_summaries->get_create (cnode)->size;
+       part->insns += ipa_fn_summaries->get (cnode)->size;
 
       /* Add all inline clones and callees that are duplicated.  */
       for (e = cnode->callees; e; e = e->next_callee)
@@ -291,7 +291,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
 
       if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node))
           && node->get_partitioning_class () == SYMBOL_PARTITION)
-        partition->insns -= ipa_fn_summaries->get_create (cnode)->size;
+       partition->insns -= ipa_fn_summaries->get (cnode)->size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->aux = (void *)((size_t)node->aux - 1);
     }
@@ -528,7 +528,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
        else
          order.safe_push (node);
        if (!node->alias)
-         total_size += ipa_fn_summaries->get_create (node)->size;
+         total_size += ipa_fn_summaries->get (node)->size;
       }
 
   original_total_size = total_size;
index ebf4b175e71cb68f8a4ef9ada2eedc62f32fe56e..bf32810abd7b010c08add7bad0f86fe2aacad0fc 100644 (file)
@@ -99,6 +99,18 @@ public:
     return get (node->get_uid (), false);
   }
 
+  /* Remove node from summary.  */
+  void remove (cgraph_node *node)
+  {
+    int uid = node->get_uid ();
+    T **v = m_map.get (uid);
+    if (v)
+      {
+       m_map.remove (uid);
+       release (*v);
+      }
+  }
+
   /* Return number of elements handled by data structure.  */
   size_t elements ()
   {
index 494afd830460669ec99631fbd1e8de25840918c0..3e30f6bc3d437a3786a08bb0afae953a01b098b6 100644 (file)
@@ -5458,7 +5458,8 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
     }
 
   if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
-      && ipa_fn_summaries->get_create (node)->size >= MAX_INLINE_INSNS_AUTO)
+      && ipa_fn_summaries->get (node)
+      && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
     {
       if (dump_file)
        fprintf (dump_file, "Function too big to be made truly local.\n");