> > gcc/ChangeLog: > > 2018-04-24 Martin Liska <mli...@suse.cz> > > * config/i386/i386.c (ix86_can_inline_p): Use get_create instead > of get. > * hsa-common.c (hsa_summary_t::link_functions): Likewise. > (hsa_register_kernel): Likewise. > * hsa-common.h (hsa_gpu_implementation_p): Likewise. > * hsa-gen.c (hsa_get_host_function): Likewise. > (get_brig_function_name): Likewise. > (generate_hsa): Likewise. > (pass_gen_hsail::execute): Likewise. > * ipa-cp.c (ipcp_cloning_candidate_p): Likewise. > (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_fn_summary::reset): Likewise. > (ipa_fn_summary_t::duplicate): Likewise. > (dump_ipa_call_summary): Likewise. > (ipa_dump_fn_summary): Likewise. > (analyze_function_body): Likewise. > (compute_fn_summary): Likewise. > (estimate_edge_devirt_benefit): Likewise. > (estimate_edge_size_and_time): Likewise. > (estimate_calls_size_and_time): Likewise. > (estimate_node_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. > (ipa_update_overall_fn_summary): Likewise. > (read_ipa_call_summary): Likewise. > (inline_read_section): Likewise. > (write_ipa_call_summary): Likewise. > (ipa_fn_summary_write): Likewise. > (ipa_free_fn_summary): Likewise. > * ipa-hsa.c (process_hsa_functions): Likewise. > (ipa_hsa_write_summary): Likewise. > (ipa_hsa_read_section): Likewise. > * ipa-icf.c (sem_function::merge): Likewise. > * ipa-inline-analysis.c (simple_edge_hints): Likewise. > (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. > (recursive_inlining): Likewise. > (inline_small_functions): Likewise. > (inline_to_all_callers_1): Likewise. > (dump_overall_stats): Likewise. > (early_inline_small_functions): Likewise. > (early_inliner): Likewise. > * ipa-inline.h (estimate_edge_growth): Likewise. > * ipa-profile.c (ipa_propagate_frequency_1): Likewise. > * ipa-prop.c (ipa_make_edge_direct_to_target): Likewise. > * ipa-prop.h (IPA_NODE_REF): Likewise. > (IPA_EDGE_REF): Likewise. > * ipa-pure-const.c (malloc_candidate_p): Likewise. > (propagate_malloc): Likewise. > * ipa-split.c (execute_split_functions): Likewise. > * symbol-summary.h: Rename get to get_create. > (get): Likewise. > (get_create): Likewise. > * tree-sra.c (ipa_sra_preliminary_function_checks): Likewise. > > gcc/lto/ChangeLog: > > 2018-04-24 Martin Liska <mli...@suse.cz> > > * lto-partition.c (add_symbol_to_partition_1): Use get_create instead > of get. > (undo_partition): Likewise. > (lto_balanced_map): Likewise. > --- > gcc/config/i386/i386.c | 2 +- > gcc/hsa-common.c | 6 +-- > gcc/hsa-common.h | 3 +- > gcc/hsa-gen.c | 11 +++-- > gcc/ipa-cp.c | 6 +-- > gcc/ipa-fnsummary.c | 112 > ++++++++++++++++++++++++--------------------- > gcc/ipa-hsa.c | 12 ++--- > gcc/ipa-icf.c | 2 +- > gcc/ipa-inline-analysis.c | 21 +++++---- > gcc/ipa-inline-transform.c | 12 ++--- > gcc/ipa-inline.c | 72 +++++++++++++++-------------- > gcc/ipa-inline.h | 4 +- > gcc/ipa-profile.c | 2 +- > gcc/ipa-prop.c | 4 +- > gcc/ipa-prop.h | 4 +- > gcc/ipa-pure-const.c | 6 +-- > gcc/ipa-split.c | 2 +- > gcc/lto/lto-partition.c | 6 +-- > gcc/symbol-summary.h | 22 +++++---- > gcc/tree-sra.c | 2 +- > 20 files changed, 162 insertions(+), 149 deletions(-) >
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > index 0c7a6b7d98f..cba192e6cfb 100644 > --- a/gcc/config/i386/i386.c > +++ b/gcc/config/i386/i386.c > @@ -5803,7 +5803,7 @@ 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 > + || ipa_fn_summaries->get_create > (cgraph_node::get (callee))->fp_expressions)) > ret = false; Creating would be bug here (because we will set fp_expressions to 0). > diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c > index e868b9c2623..f682ee30dec 100644 > --- a/gcc/ipa-cp.c > +++ b/gcc/ipa-cp.c > @@ -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 (node)->self_size < stats.n_calls) > + if (ipa_fn_summaries->get_create (node)->self_size < stats.n_calls) It would also imply bug here (because self_size would be 0) > { > if (dump_file) > fprintf (dump_file, "Considering %s for cloning; code might shrink.\n", > @@ -2601,7 +2601,7 @@ devirtualization_time_bonus (struct cgraph_node *node, > callee = callee->function_symbol (&avail); > if (avail < AVAIL_AVAILABLE) > continue; > - isummary = ipa_fn_summaries->get (callee); > + isummary = ipa_fn_summaries->get_create (callee); > if (!isummary->inlinable) > continue; > > @@ -3306,7 +3306,7 @@ ipcp_propagate_stage (struct ipa_topo_info *topo) > initialize_node_lattices (node); > } > if (node->definition && !node->alias) > - overall_size += ipa_fn_summaries->get (node)->self_size; > + overall_size += ipa_fn_summaries->get_create (node)->self_size; In those two it also should always exist. > max_count = max_count.max (node->count.ipa ()); > } > > diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c > index bdf9ba1c921..8a6c5d0b5d8 100644 > --- a/gcc/ipa-fnsummary.c > +++ b/gcc/ipa-fnsummary.c > @@ -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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (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 (node); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (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 (callee); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); In all those cases we should also summary built or something is wrong earlier. > int i, count = ipa_get_cs_argument_count (args); > > if (e->caller->global.inlined_to) > @@ -583,9 +583,9 @@ ipa_fn_summary::reset (struct cgraph_node *node) > vec_free (conds); > vec_free (size_time_table); > for (e = node->callees; e; e = e->next_callee) > - ipa_call_summaries->get (e)->reset (); > + ipa_call_summaries->get_create (e)->reset (); > for (e = node->indirect_calls; e; e = e->next_callee) > - ipa_call_summaries->get (e)->reset (); > + ipa_call_summaries->get_create (e)->reset (); You can turn this into do-nothing if get returns NULL. > fp_expressions = false; > } > > @@ -625,7 +625,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src, > ipa_fn_summary *, > ipa_fn_summary *info) > { > - memcpy (info, ipa_fn_summaries->get (src), sizeof (ipa_fn_summary)); > + memcpy (info, ipa_fn_summaries->get_create (src), sizeof (ipa_fn_summary)); Probably all uses in duplication as well - we first compute all summaries and then keep them built across duplications so non-existing summary should not happen. > /* TODO: as an optimization, we may avoid copying conditions > that are known to be false or true. */ > info->conds = vec_safe_copy (info->conds); > @@ -700,7 +700,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src, > for (edge = dst->callees; edge; edge = next) > { > predicate new_predicate; > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > next = edge->next_callee; > > if (!edge->inline_failed) > @@ -719,7 +719,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src, > for (edge = dst->indirect_calls; edge; edge = next) > { > predicate new_predicate; > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > next = edge->next_callee; > > gcc_checking_assert (edge->inline_failed); > @@ -813,7 +813,7 @@ 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 (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); Dump summary probably should early exit if summary does not exist. It could otherwise make compiler to diverge whether you dump or not. > struct cgraph_node *callee = edge->callee->ultimate_alias_target (); > int i; > > @@ -825,8 +825,9 @@ dump_ipa_call_summary (FILE *f, int indent, struct > cgraph_node *node, > ? "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 (callee)->size / > ipa_fn_summary::size_scale, > - (int) ipa_fn_summaries->get (callee)->estimated_stack_size); > + (int) (ipa_fn_summaries->get_create (callee)->size > + / ipa_fn_summary::size_scale), > + (int) ipa_fn_summaries->get_create > (callee)->estimated_stack_size); > > if (es->predicate) > { > @@ -849,18 +850,19 @@ dump_ipa_call_summary (FILE *f, int indent, struct > cgraph_node *node, > } > if (!edge->inline_failed) > { > + ipa_fn_summary *s = ipa_fn_summaries->get_create (callee); > fprintf (f, "%*sStack frame offset %i, callee self size %i," > " callee size %i\n", > indent + 2, "", > - (int) ipa_fn_summaries->get (callee)->stack_frame_offset, > - (int) ipa_fn_summaries->get > (callee)->estimated_self_stack_size, > - (int) ipa_fn_summaries->get (callee)->estimated_stack_size); > + (int) s->stack_frame_offset, > + (int) s->estimated_self_stack_size, > + (int) s->estimated_stack_size); > dump_ipa_call_summary (f, indent + 2, callee, info); > } > } > for (edge = node->indirect_calls; edge; edge = edge->next_callee) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i" > " time: %2i", > indent, "", > @@ -883,7 +885,7 @@ ipa_dump_fn_summary (FILE *f, struct cgraph_node *node) > { > if (node->definition) > { > - struct ipa_fn_summary *s = ipa_fn_summaries->get (node); > + struct ipa_fn_summary *s = ipa_fn_summaries->get_create (node); Same here. > size_time_entry *e; > int i; > fprintf (f, "IPA function summary for %s/%i", node->name (), > @@ -2009,7 +2011,7 @@ analyze_function_body (struct cgraph_node *node, bool > early) > basic_block bb; > struct function *my_function = DECL_STRUCT_FUNCTION (node->decl); > sreal freq; > - struct ipa_fn_summary *info = ipa_fn_summaries->get (node); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node); This makes sense - we build summary here. > predicate bb_predicate; > struct ipa_func_body_info fbi; > vec<predicate> nonconstant_names = vNULL; > @@ -2177,7 +2179,7 @@ analyze_function_body (struct cgraph_node *node, bool > early) > && !gimple_call_internal_p (stmt)) > { > struct cgraph_edge *edge = node->get_edge (stmt); > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + ipa_call_summary *es = ipa_call_summaries->get_create (edge); and here it also makes sense. > > /* Special case: results of BUILT_IN_CONSTANT_P will be always > resolved as constant. We however don't want to optimize > @@ -2275,7 +2277,8 @@ analyze_function_body (struct cgraph_node *node, bool > early) > } > } > } > - set_hint_predicate (&ipa_fn_summaries->get (node)->array_index, > array_index); > + set_hint_predicate (&ipa_fn_summaries->get_create (node)->array_index, > + array_index); > free (order); > > if (nonconstant_names.exists () && !early) > @@ -2360,9 +2363,9 @@ analyze_function_body (struct cgraph_node *node, bool > early) > } > free (body); > } > - set_hint_predicate (&ipa_fn_summaries->get (node)->loop_iterations, > + set_hint_predicate (&ipa_fn_summaries->get_create > (node)->loop_iterations, > loop_iterations); > - set_hint_predicate (&ipa_fn_summaries->get (node)->loop_stride, > + set_hint_predicate (&ipa_fn_summaries->get_create (node)->loop_stride, > loop_stride); > scev_finalize (); > } > @@ -2381,8 +2384,8 @@ analyze_function_body (struct cgraph_node *node, bool > early) > e->aux = NULL; > } > } > - ipa_fn_summaries->get (node)->time = time; > - ipa_fn_summaries->get (node)->self_size = size; > + ipa_fn_summaries->get_create (node)->time = time; > + ipa_fn_summaries->get_create (node)->self_size = size; Here you re-use the existing info pointer for all of the above. > nonconstant_names.release (); > ipa_release_body_info (&fbi); > if (opt_for_fn (node->decl, optimize)) > @@ -2416,7 +2419,7 @@ compute_fn_summary (struct cgraph_node *node, bool > early) > if (!ipa_fn_summaries) > ipa_fn_summary_alloc (); > > - info = ipa_fn_summaries->get (node); > + info = ipa_fn_summaries->get_create (node); > info->reset (node); I guess things would make more snese with info = ipa_fn_summaries->get (node); if (info) info->reset (node); else info = ipa_fn_summaries->get_create (node); > > /* Estimate the stack size for the function if we're optimizing. */ > @@ -2428,7 +2431,7 @@ compute_fn_summary (struct cgraph_node *node, bool > early) > > if (node->thunk.thunk_p) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (node->callees); > + ipa_call_summary *es = ipa_call_summaries->get_create (node->callees); This is fine. > predicate t = true; > > node->local.can_change_signature = false; > @@ -2572,7 +2575,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 (callee); > + isummary = ipa_fn_summaries->get_create (callee); > return isummary->inlinable; > } > > @@ -2591,7 +2594,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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); Again, if summary is missing, we have bug. > int call_size = es->call_stmt_size; > int call_time = es->call_stmt_time; > int cur_size; > @@ -2628,7 +2631,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, > int *size, > struct cgraph_edge *e; > for (e = node->callees; e; e = e->next_callee) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); Here too. > > /* Do not care about zero sized builtins. */ > if (e->inline_failed && !es->call_stmt_size) > @@ -2659,7 +2662,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, > int *size, > } > for (e = node->indirect_calls; e; e = e->next_callee) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); Here too. > if (!es->predicate > || es->predicate->evaluate (possible_truths)) > estimate_edge_size_and_time (e, size, > @@ -2694,7 +2697,7 @@ estimate_node_size_and_time (struct cgraph_node *node, > vec<inline_param_summary> > inline_param_summary) > { > - struct ipa_fn_summary *info = ipa_fn_summaries->get (node); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node); And here ;) > size_time_entry *e; > int size = 0; > sreal time = 0; > @@ -2848,8 +2851,9 @@ static void > inline_update_callee_summaries (struct cgraph_node *node, int depth) > { > struct cgraph_edge *e; > - struct ipa_fn_summary *callee_info = ipa_fn_summaries->get (node); > - struct ipa_fn_summary *caller_info = ipa_fn_summaries->get > (node->callers->caller); > + ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (node); > + ipa_fn_summary *caller_info > + = ipa_fn_summaries->get_create (node->callers->caller); > HOST_WIDE_INT peak; > > callee_info->stack_frame_offset > @@ -2857,17 +2861,19 @@ 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 (ipa_fn_summaries->get (node->global.inlined_to)->estimated_stack_size > < peak) > - ipa_fn_summaries->get (node->global.inlined_to)->estimated_stack_size > = peak; > + > + ipa_fn_summary *s = ipa_fn_summaries->get_create (node->global.inlined_to); > + if (s->estimated_stack_size < peak) > + s->estimated_stack_size = peak; > ipa_propagate_frequency (node); > for (e = node->callees; e; e = e->next_callee) > { > if (!e->inline_failed) > inline_update_callee_summaries (e->callee, depth); > - ipa_call_summaries->get (e)->loop_depth += depth; > + ipa_call_summaries->get_create (e)->loop_depth += depth; > } > for (e = node->indirect_calls; e; e = e->next_callee) > - ipa_call_summaries->get (e)->loop_depth += depth; > + ipa_call_summaries->get_create (e)->loop_depth += depth; > } Also in this function all summaries should be pre-existing. > > /* Update change_prob of EDGE after INLINED_EDGE has been inlined. > @@ -2884,9 +2890,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 (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > struct ipa_call_summary *inlined_es > - = ipa_call_summaries->get (inlined_edge); > + = ipa_call_summaries->get_create (inlined_edge); > > for (i = 0; i < ipa_get_cs_argument_count (args); i++) > { > @@ -2933,7 +2939,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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); > predicate p; > next = e->next_callee; > > @@ -2959,7 +2965,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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); > predicate p; > next = e->next_callee; > > @@ -3009,10 +3015,10 @@ remap_hint_predicate (struct ipa_fn_summary *info, > void > ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge) > { > - struct ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee); > + ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (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 (to); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (to); > clause_t clause = 0; /* not_inline is known to be false. */ > size_time_entry *e; > vec<int> operand_map = vNULL; > @@ -3020,7 +3026,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 (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > > if (es->predicate) > toplev_predicate = *es->predicate; > @@ -3109,8 +3115,8 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge > *edge) > &callee_info->array_index, > operand_map, offset_map, clause, &toplev_predicate); > > - inline_update_callee_summaries (edge->callee, > - ipa_call_summaries->get (edge)->loop_depth); > + ipa_call_summary *s = ipa_call_summaries->get_create (edge); > + inline_update_callee_summaries (edge->callee, s->loop_depth); > > /* We do not maintain predicates of inlined edges, free it. */ > edge_set_predicate (edge, &true_p); > @@ -3126,7 +3132,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge > *edge) > void > ipa_update_overall_fn_summary (struct cgraph_node *node) > { > - struct ipa_fn_summary *info = ipa_fn_summaries->get (node); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node); > size_time_entry *e; > int i; All of the remap and merge logic should be remaping to new edge summary and the source edge should be existing. > > @@ -3224,7 +3230,7 @@ ipa_fn_summary_generate (void) > static void > read_ipa_call_summary (struct lto_input_block *ib, struct cgraph_edge *e) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); > predicate p; > int length, i; > > @@ -3283,7 +3289,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 = ipa_fn_summaries->get (node); > + info = ipa_fn_summaries->get_create (node); > > info->estimated_stack_size > = info->estimated_self_stack_size = streamer_read_uhwi (&ib); > @@ -3384,7 +3390,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 (e); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (e); > int i; > > streamer_write_uhwi (ob, es->call_stmt_size); > @@ -3432,7 +3438,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 (cnode); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (cnode); Writting non-existiend summaries is also bug :) > struct bitpack_d bp; > struct cgraph_edge *edge; > int i; > @@ -3507,7 +3513,7 @@ ipa_free_fn_summary (void) > return; > FOR_EACH_DEFINED_FUNCTION (node) > if (!node->alias) > - ipa_fn_summaries->get (node)->reset (node); > + ipa_fn_summaries->get_create (node)->reset (node); And creating one just to free it as well. > ipa_fn_summaries->release (); > ipa_fn_summaries = NULL; > ipa_call_summaries->release (); > diff --git a/gcc/ipa-hsa.c b/gcc/ipa-hsa.c > index 1df273c7f28..90d193fe517 100644 > --- a/gcc/ipa-hsa.c > +++ b/gcc/ipa-hsa.c Probably Martin Jambor can comment on ipa-hsa. > diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c > index f974d9f769f..36d1708365b 100644 > --- a/gcc/ipa-icf.c > +++ b/gcc/ipa-icf.c > @@ -1199,7 +1199,7 @@ sem_function::merge (sem_item *alias_item) > "can not create wrapper of stdarg function.\n"); > } > else if (ipa_fn_summaries > - && ipa_fn_summaries->get (alias)->self_size <= 2) > + && ipa_fn_summaries->get_create (alias)->self_size <= 2) Sumamry should exist here. > { > if (dump_file) > fprintf (dump_file, "Wrapper creation is not " > diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c > index bcdca5b13aa..c4f904730e6 100644 > --- a/gcc/ipa-inline-analysis.c > +++ b/gcc/ipa-inline-analysis.c > @@ -125,9 +125,9 @@ simple_edge_hints (struct cgraph_edge *edge) > struct cgraph_node *to = (edge->caller->global.inlined_to > ? edge->caller->global.inlined_to : edge->caller); > struct cgraph_node *callee = edge->callee->ultimate_alias_target (); > - if (ipa_fn_summaries->get (to)->scc_no > - && ipa_fn_summaries->get (to)->scc_no > - == ipa_fn_summaries->get (callee)->scc_no > + if (ipa_fn_summaries->get_create (to)->scc_no > + && ipa_fn_summaries->get_create (to)->scc_no > + == ipa_fn_summaries->get_create (callee)->scc_no As discucsed earlier, we can skip some gets here by remembering it and we should have both summaries defined already. > && !edge->recursive_p ()) > hints |= INLINE_HINT_same_scc; > > @@ -157,7 +157,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 (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > int min_size; > > callee = edge->callee->ultimate_alias_target (); > @@ -190,7 +190,7 @@ do_estimate_edge_time (struct cgraph_edge *edge) > /* When caching, update the cache entry. */ > if (edge_growth_cache.exists ()) > { > - ipa_fn_summaries->get (edge->callee)->min_size = min_size; > + ipa_fn_summaries->get_create (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; > @@ -293,14 +293,15 @@ int > estimate_size_after_inlining (struct cgraph_node *node, > struct cgraph_edge *edge) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (edge); > + ipa_fn_summary *s = ipa_fn_summaries->get_create (node); > if (!es->predicate || *es->predicate != false) > { > - int size = ipa_fn_summaries->get (node)->size + estimate_edge_growth > (edge); > + int size = s->size + estimate_edge_growth (edge); > gcc_assert (size >= 0); > return size; > } > - return ipa_fn_summaries->get (node)->size; > + return s->size; > } > > > @@ -349,7 +350,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 (node); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node); > > node->call_for_symbol_and_aliases (do_estimate_growth_1, &d, true); > > @@ -424,7 +425,7 @@ growth_likely_positive (struct cgraph_node *node, > || node->address_taken) > return true; > > - max_callers = ipa_fn_summaries->get (node)->size * 4 / edge_growth + 2; > + max_callers = ipa_fn_summaries->get_create (node)->size * 4 / edge_growth > + 2; > > for (e = node->callers; e; e = e->next_caller) > { All of above also have chance to work only if summaries are already present. > diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c > index b9ae174da30..6a3b5291c13 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, > { > gcc_assert (!e->callee->alias); > if (overall_size) > - *overall_size -= ipa_fn_summaries->get (e->callee)->size; > + *overall_size -= ipa_fn_summaries->get_create (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 (to); > - ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee); > + ipa_fn_summary *caller_info = ipa_fn_summaries->get_create (to); > + ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (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 (to)->size; > + old_size = ipa_fn_summaries->get_create (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 (to)->size += estimated_growth; > - new_size = ipa_fn_summaries->get (to)->size; > + ipa_fn_summaries->get_create (to)->size += estimated_growth; > + new_size = ipa_fn_summaries->get_create (to)->size; > > if (callee->calls_comdat_local) > to->calls_comdat_local = true; Here things would break too if summaries was not known. > diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c > index b7f213f2eb7..b015db07d15 100644 > --- a/gcc/ipa-inline.c > +++ b/gcc/ipa-inline.c > @@ -150,7 +150,8 @@ caller_growth_limits (struct cgraph_edge *e) > int newsize; > int limit = 0; > HOST_WIDE_INT stack_size_limit = 0, inlined_stack; > - ipa_fn_summary *info, *what_info, *outer_info = ipa_fn_summaries->get (to); > + ipa_fn_summary *info, *what_info; > + ipa_fn_summary *outer_info = ipa_fn_summaries->get_create (to); > > /* Look for function e->caller is inlined to. While doing > so work out the largest function body on the way. As > @@ -162,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 (to); > + info = ipa_fn_summaries->get_create (to); > if (limit < info->self_size) > limit = info->self_size; > if (stack_size_limit < info->estimated_self_stack_size) > @@ -173,7 +174,7 @@ caller_growth_limits (struct cgraph_edge *e) > break; > } > > - what_info = ipa_fn_summaries->get (what); > + what_info = ipa_fn_summaries->get_create (what); > > if (limit < what_info->self_size) > limit = what_info->self_size; > @@ -363,7 +364,7 @@ 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 (callee)->inlinable) > + else if (!ipa_fn_summaries->get_create (callee)->inlinable) > { > e->inline_failed = CIF_FUNCTION_NOT_INLINABLE; > inlinable = false; > @@ -425,8 +426,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 (caller); > - ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee); > + ipa_fn_summary *caller_info = ipa_fn_summaries->get_create (caller); > + ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (callee); > > /* Until GCC 4.9 we did not check the semantics alterning flags > bellow and inline across optimization boundry. > @@ -529,7 +530,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 (e)->call_stmt_time) > + >= 20 + ipa_call_summaries->get_create (e)->call_stmt_time) > { > e->inline_failed = CIF_OPTIMIZATION_MISMATCH; > inlinable = false; > @@ -679,7 +680,7 @@ compute_uninlined_call_time (struct cgraph_edge *edge, > else > uninlined_call_time = uninlined_call_time >> 11; > > - sreal caller_time = ipa_fn_summaries->get (caller)->time; > + sreal caller_time = ipa_fn_summaries->get_create (caller)->time; > return uninlined_call_time + caller_time; > } > > @@ -693,7 +694,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 (caller)->time; > + sreal caller_time = ipa_fn_summaries->get_create (caller)->time; > > sreal freq = edge->sreal_frequency (); > if (freq > 0) > @@ -703,7 +704,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 (edge)->call_stmt_time * freq; > + time -= (sreal)ipa_call_summaries->get_create (edge)->call_stmt_time * > freq; > time += caller_time; > if (time <= 0) > time = ((sreal) 1) >> 8; > @@ -755,8 +756,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 (callee)->min_size > - - ipa_call_summaries->get (e)->call_stmt_size > + && ipa_fn_summaries->get_create (callee)->min_size > + - ipa_call_summaries->get_create (e)->call_stmt_size > > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO)) > { > e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT; > @@ -764,8 +765,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 (callee)->min_size > - - ipa_call_summaries->get (e)->call_stmt_size > + && ipa_fn_summaries->get_create (callee)->min_size > + - ipa_call_summaries->get_create (e)->call_stmt_size > > 16 * MAX_INLINE_INSNS_SINGLE) > { > e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl) > @@ -1017,7 +1018,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 (callee); > + struct ipa_fn_summary *callee_info = ipa_fn_summaries->get_create (callee); > ipa_hints hints; > cgraph_node *caller = (edge->caller->global.inlined_to > ? edge->caller->global.inlined_to I think in those checks there is only can_* predicates that can be called for non-existing summary by flattening and early inliner. In this case they shouldnot create new summary but simply return false, because function is not inlinable by early inliner. All other cases thorough-ipa-inline should never create new summary because that happesn in ipa-fnsummaries. > @@ -1130,7 +1131,7 @@ edge_badness (struct cgraph_edge *edge, bool dump) > && (!DECL_DECLARED_INLINE_P (edge->callee->decl) > || DECL_DECLARED_INLINE_P (caller->decl))))) > { > - struct ipa_fn_summary *caller_info = ipa_fn_summaries->get (caller); > + ipa_fn_summary *caller_info = ipa_fn_summaries->get_create (caller); > int caller_growth = caller_info->growth; > > /* Only apply the penalty when caller looks like inline candidate, > @@ -1189,7 +1190,7 @@ edge_badness (struct cgraph_edge *edge, bool dump) > of functions fully inlined in program. */ > else > { > - int nest = MIN (ipa_call_summaries->get (edge)->loop_depth, 8); > + int nest = MIN (ipa_call_summaries->get_create (edge)->loop_depth, 8); > badness = growth; > > /* Decrease badness if call is nested. */ > @@ -1332,7 +1333,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 (node)->inlinable) > + if ((!node->alias && !ipa_fn_summaries->get_create (node)->inlinable) > || node->global.inlined_to) > return; > if (!bitmap_set_bit (updated_nodes, node->uid)) > @@ -1391,7 +1392,7 @@ update_callee_keys (edge_heap_t *heap, struct > cgraph_node *node, > don't need updating. */ > if (e->inline_failed > && (callee = e->callee->ultimate_alias_target (&avail, e->caller)) > - && ipa_fn_summaries->get (callee)->inlinable > + && ipa_fn_summaries->get_create (callee)->inlinable > && avail >= AVAIL_AVAILABLE > && !bitmap_bit_p (updated_nodes, callee->uid)) > { > @@ -1558,10 +1559,10 @@ recursive_inlining (struct cgraph_edge *edge, > fprintf (dump_file, > "\n Inlined %i times, " > "body grown from size %i to %i, time %f to %f\n", n, > - ipa_fn_summaries->get (master_clone)->size, > - ipa_fn_summaries->get (node)->size, > - ipa_fn_summaries->get (master_clone)->time.to_double (), > - ipa_fn_summaries->get (node)->time.to_double ()); > + ipa_fn_summaries->get_create (master_clone)->size, > + ipa_fn_summaries->get_create (node)->size, > + ipa_fn_summaries->get_create (master_clone)->time.to_double (), > + ipa_fn_summaries->get_create (node)->time.to_double ()); > > /* 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 > @@ -1763,7 +1764,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 (node); > + struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node); > struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux; > > /* Do not account external functions, they will be optimized out > @@ -1785,7 +1786,7 @@ inline_small_functions (void) > n2 = ((struct ipa_dfs_info *) n2->aux)->next_cycle) > if (opt_for_fn (n2->decl, optimize)) > { > - struct ipa_fn_summary *info2 = ipa_fn_summaries->get (n2); > + ipa_fn_summary *info2 = ipa_fn_summaries->get_create (n2); > if (info2->scc_no) > break; > info2->scc_no = id; > @@ -1944,7 +1945,7 @@ inline_small_functions (void) > fprintf (dump_file, > "\nConsidering %s with %i size\n", > callee->dump_name (), > - ipa_fn_summaries->get (callee)->size); > + ipa_fn_summaries->get_create (callee)->size); > fprintf (dump_file, > " to be inlined into %s in %s:%i\n" > " Estimated badness is %f, frequency %.2f.\n", > @@ -2070,13 +2071,14 @@ inline_small_functions (void) > > if (dump_file) > { > + ipa_fn_summary *s = ipa_fn_summaries->get_create (edge->caller); > fprintf (dump_file, > " Inlined %s into %s which now has time %f and size %i, " > "net change of %+i.\n", > xstrdup_for_dump (edge->callee->name ()), > xstrdup_for_dump (edge->caller->name ()), > - ipa_fn_summaries->get (edge->caller)->time.to_double (), > - ipa_fn_summaries->get (edge->caller)->size, > + s->time.to_double (), > + s->size, > overall_size - old_size); > } > if (min_size > overall_size) > @@ -2211,11 +2213,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 (node)->size); > + ipa_fn_summaries->get_create (node)->size); > fprintf (dump_file, > " Called once from %s %i insns.\n", > node->callers->caller->name (), > - ipa_fn_summaries->get (node->callers->caller)->size); > + ipa_fn_summaries->get_create (node->callers->caller)->size); > } > > /* Remember which callers we inlined to, delaying updating the > @@ -2226,7 +2228,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 (caller)->size); > + ipa_fn_summaries->get_create (caller)->size); > if (!(*num_calls)--) > { > if (dump_file) > @@ -2267,7 +2269,7 @@ dump_overall_stats (void) > if (!node->global.inlined_to > && !node->alias) > { > - sreal time = ipa_fn_summaries->get (node)->time; > + 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 (); > @@ -2646,7 +2648,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 (!ipa_fn_summaries->get (callee)->inlinable > + if (!ipa_fn_summaries->get_create (callee)->inlinable > || !e->inline_failed) > continue; > > @@ -2763,7 +2765,7 @@ early_inliner (function *fun) > statements that don't have inline parameters computed. */ > for (edge = node->callees; edge; edge = edge->next_callee) > { > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + 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 > @@ -2788,7 +2790,7 @@ early_inliner (function *fun) > for (edge = node->callees; edge; edge = edge->next_callee) > { > /* We have no summary for new bound store calls yet. */ > - struct ipa_call_summary *es = ipa_call_summaries->get (edge); > + 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 > diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h > index 8279264a7cf..e8ae206d7b7 100644 > --- a/gcc/ipa-inline.h > +++ b/gcc/ipa-inline.h > @@ -81,10 +81,10 @@ estimate_edge_size (struct cgraph_edge *edge) > static inline int > estimate_edge_growth (struct cgraph_edge *edge) > { > - gcc_checking_assert (ipa_call_summaries->get (edge)->call_stmt_size > + gcc_checking_assert (ipa_call_summaries->get_create (edge)->call_stmt_size > || !edge->callee->analyzed); > return (estimate_edge_size (edge) > - - ipa_call_summaries->get (edge)->call_stmt_size); > + - ipa_call_summaries->get_create (edge)->call_stmt_size); Also should not accept non-existing summaries. > } > > /* Return estimated callee runtime increase after inlining > diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c > index 1ab838aca2a..7500f5438e8 100644 > --- a/gcc/ipa-profile.c > +++ b/gcc/ipa-profile.c > @@ -349,7 +349,7 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void > *data) > fprintf (dump_file, " Called by %s that is executed once\n", > edge->caller->name ()); > d->maybe_unlikely_executed = false; > - if (ipa_call_summaries->get (edge)->loop_depth) > + if (ipa_call_summaries->get_create (edge)->loop_depth) Neither here :) > { > d->maybe_executed_once = false; > if (dump_file && (dump_flags & TDF_DETAILS)) > diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c > index 19d55cda009..c725b30c33d 100644 > --- a/gcc/ipa-prop.c > +++ b/gcc/ipa-prop.c > @@ -2818,7 +2818,7 @@ 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 (ie); > + struct ipa_call_summary *es = ipa_call_summaries->get_create (ie); > bool unreachable = false; > > if (TREE_CODE (target) == ADDR_EXPR) > @@ -2956,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 (ie); > + es = ipa_call_summaries->get_create (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 I am not 100% sure here as they may be called after summaries are released, but in that case ipa-call_summaries will probably be NULL so function will ICE. So again, get should be safe. > diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h > index dc45cea9c71..6fd31598261 100644 > --- a/gcc/ipa-prop.h > +++ b/gcc/ipa-prop.h > @@ -654,8 +654,8 @@ extern GTY(()) vec<ipcp_transformation_summary, va_gc> > *ipcp_transformations; > > /* Return the associated parameter/argument info corresponding to the given > node/edge. */ > -#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get (NODE)) > -#define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get (EDGE)) > +#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get_create (NODE)) > +#define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get_create (EDGE)) It is bit more on Martin, but perhaps we could go away from uppercase macros and get bit more C++ style here. > /* This macro checks validity of index returned by > ipa_get_param_decl_index function. */ > #define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1) > diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c > index 567b615fb60..1f624965f1a 100644 > --- a/gcc/ipa-pure-const.c > +++ b/gcc/ipa-pure-const.c > @@ -965,7 +965,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 (cs); > + ipa_call_summary *es = ipa_call_summaries->get_create (cs); > gcc_assert (es); > es->is_return_callee_uncaptured = true; > } > @@ -998,7 +998,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 (cs); > + ipa_call_summary *es = ipa_call_summaries->get_create (cs); > gcc_assert (es); > es->is_return_callee_uncaptured = true; > } > @@ -1955,7 +1955,7 @@ propagate_malloc (void) > vec<cgraph_node *> callees = vNULL; > for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee) > { > - ipa_call_summary *es = ipa_call_summaries->get (cs); > + ipa_call_summary *es = ipa_call_summaries->get_create (cs); > if (es && es->is_return_callee_uncaptured) > callees.safe_push (cs->callee); > } Again silently creating summary is a bug. may run into non-existing summaries and in that case > diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c > index b03ae02924a..6ab2e139f03 100644 > --- a/gcc/ipa-split.c > +++ b/gcc/ipa-split.c > @@ -1765,7 +1765,7 @@ 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 (node)->inlinable) > + && !ipa_fn_summaries->get_create (node)->inlinable) Likewise. > { > if (dump_file) > fprintf (dump_file, "Not splitting: not inlinable.\n"); > diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c > index fd796e12a2d..76086a2ba2e 100644 > --- a/gcc/lto/lto-partition.c > +++ b/gcc/lto/lto-partition.c > @@ -172,7 +172,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 (cnode)->size; > + part->insns += ipa_fn_summaries->get_create (cnode)->size; > > /* Add all inline clones and callees that are duplicated. */ > for (e = cnode->callees; e; e = e->next_callee) > @@ -297,7 +297,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 (cnode)->size; > + partition->insns -= ipa_fn_summaries->get_create (cnode)->size; > lto_symtab_encoder_delete_node (partition->encoder, node); > node->aux = (void *)((size_t)node->aux - 1); > } > @@ -536,7 +536,7 @@ lto_balanced_map (int n_lto_partitions, int > max_partition_size) > else > order[n_nodes++] = node; > if (!node->alias) > - total_size += ipa_fn_summaries->get (node)->size; > + total_size += ipa_fn_summaries->get_create (node)->size; > } > > original_total_size = total_size; Likewise. > diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h > index a73472ef0ae..7ba769739ee 100644 > --- a/gcc/symbol-summary.h > +++ b/gcc/symbol-summary.h > @@ -86,11 +86,12 @@ public: > /* Release an item that is stored within map. */ > void release (T *item); > > - /* Getter for summary callgraph node pointer. */ > - T* get (cgraph_node *node) > + /* Getter for summary callgraph node pointer. If a summary for a node > + does not exist it will be created. */ > + T* get_create (cgraph_node *node) > { > gcc_checking_assert (node->summary_uid); > - return get (node->summary_uid); > + return get_create (node->summary_uid); > } > > /* Return number of elements handled by data structure. */ > @@ -135,7 +136,7 @@ private: > typedef int_hash <int, 0, -1> map_hash; > > /* Getter for summary callgraph ID. */ > - T* get (int uid); > + T* get_create (int uid); > > /* Indicates if insertion hook is enabled. */ > bool m_insertion_enabled; > @@ -214,7 +215,7 @@ function_summary<T *>::symtab_insertion (cgraph_node > *node, void *data) > function_summary *summary = (function_summary <T *> *) (data); > > if (summary->m_insertion_enabled) > - summary->insert (node, summary->get (node)); > + summary->insert (node, summary->get_create (node)); > } > > template <typename T> > @@ -260,7 +261,7 @@ function_summary<T *>::symtab_duplication (cgraph_node > *node, > > template <typename T> > T* > -function_summary<T *>::get (int uid) > +function_summary<T *>::get_create (int uid) > { > bool existed; > T **v = &m_map.get_or_insert (uid, &existed); > @@ -357,10 +358,11 @@ public: > /* Release an item that is stored within map. */ > void release (T *item); > > - /* Getter for summary callgraph edge pointer. */ > - T* get (cgraph_edge *edge) > + /* Getter for summary callgraph edge pointer. > + If a summary for an edge does not exist, it will be created. */ > + T* get_create (cgraph_edge *edge) > { > - return get (hashable_uid (edge)); > + return get_create (hashable_uid (edge)); > } > > /* Return number of elements handled by data structure. */ > @@ -390,7 +392,7 @@ private: > typedef int_hash <int, 0, -1> map_hash; > > /* Getter for summary callgraph ID. */ > - T* get (int uid) > + T* get_create (int uid) > { > bool existed; > T **v = &m_map.get_or_insert (uid, &existed); > diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c > index b513676152f..09d56d10e7f 100644 > --- a/gcc/tree-sra.c > +++ b/gcc/tree-sra.c > @@ -5458,7 +5458,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node > *node) > } > > if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl)) > - && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO) > + && ipa_fn_summaries->get_create (node)->size >= MAX_INLINE_INSNS_AUTO) > { > if (dump_file) > fprintf (dump_file, "Function too big to be made truly local.\n"); I think rather than proactively changing all get into get_create, I would preffer doing that just enough to fix bootstrap and adding FIXME in odd places. The whole philospphy of fn summaries is that they gets created by analyze_function and then are kept up to date. So nothing except for analyze_function or duplication hooks should be creating summaries at its own. Honza