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