+2017-05-23 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline-analysis.c (cgraph_2edge_hook_list, cgraph_edge_hook_list,
+ inline_edge_removal_hook, inline_edge_duplication_hook): Remove.
+ (inline_edge_summary_vec): Turn into ...
+ (ipa_call_summaries): ... this one.
+ (redirect_to_unreachable, edge_set_predicate,
+ evaluate_properties_for_edge, inline_summary_alloc,
+ reset_ipa_call_summary, reset_inline_summary,
+ inline_summary_t::duplicate): Update.
+ (inline_edge_duplication_hook): Turn to ...
+ (ipa_call_summary_t::duplicate): ... this one.
+ (inline_edge_removal_hook): Turn to ...
+ (ipa_call_summary_t::remove): ... this one.
+ (dump_inline_edge_summary): Turn to ...
+ (dump_ipa_call_summary): ... this one.
+ (estimate_function_body_sizes): Update.
+ (inline_update_callee_summaries): Update.
+ (remap_edge_change_prob): Update.
+ (remap_edge_summaries): Update.
+ (inline_merge_summary): Update.
+ (do_estimate_edge_time): Update.
+ (inline_generate_summary): Update.
+ (inline_read_section): Update.
+ (inline_read_summary): Update.
+ (inline_free_summary): Update.
+ * ipa-inline.c (can_inline_edge_p): Update.
+ (compute_inlined_call_time): Update.
+ (want_inline_small_function_p): Update.
+ (edge_badness): Update.
+ (early_inliner): Update.
+ * ipa-inline.h (inline_edge_summary): Turn to ...
+ (ipa_call_summary): ... this one.
+ (ipa_call_summary_t): New class.
+ (inline_edge_summary_t, inline_edge_summary_vec): Remove.
+ (ipa_call_summaries): New.
+ (inline_edge_summary): Remove.
+ (estimate_edge_growth): Update.
+ * ipa-profile.c (ipa_propagate_frequency_1): Update.
+ * ipa-prop.c (ipa_make_edge_direct_to_target): Update.
+ * ipa-split.c (execute_split_functions): Update.
+ * ipa.c (symbol_table::remove_unreachable_nodes): Update.
+
2017-05-23 Tom de Vries <tom@codesourcery.com>
* doc/sourcebuild.texi (Effective-Target Keywords, Other hardware
current_function_decl) == NULL)
return false;
- compute_inline_parameters (cgraph_node::get (current_function_decl), true);
+ compute_fn_summary (cgraph_node::get (current_function_decl), true);
bool has_vpt = false;
FOR_EACH_BB_FN (bb, cfun)
static void
early_inline ()
{
- compute_inline_parameters (cgraph_node::get (current_function_decl), true);
+ compute_fn_summary (cgraph_node::get (current_function_decl), true);
unsigned todo = early_inliner (cfun);
if (todo & TODO_update_ssa_any)
update_ssa (TODO_update_ssa);
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
cgraph_edge::rebuild_edges ();
- compute_inline_parameters (cgraph_node::get (current_function_decl), true);
+ compute_fn_summary (cgraph_node::get (current_function_decl), true);
pop_cfun ();
}
/* True if this decl is a dispatcher for function versions. */
unsigned dispatcher_function : 1;
/* True if this decl calls a COMDAT-local function. This is set up in
- compute_inline_parameters and inline_call. */
+ compute_fn_summary and inline_call. */
unsigned calls_comdat_local : 1;
/* True if node has been created by merge operation in IPA-ICF. */
unsigned icf_merged: 1;
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
if ((state == IPA_SSA || state == IPA_SSA_AFTER_INLINING)
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
- g->get_passes ()->execute_early_local_passes ();
- else if (inline_summaries != NULL)
- compute_inline_parameters (node, true);
+ {
+ bool summaried_computed = ipa_fn_summaries != NULL;
+ g->get_passes ()->execute_early_local_passes ();
+ /* Early passes compure inline parameters to do inlining
+ and splitting. This is redundant for functions added late.
+ Just throw away whatever it did. */
+ if (!summaried_computed)
+ inline_free_summary ();
+ }
+ else if (ipa_fn_summaries != NULL)
+ compute_fn_summary (node, true);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
pop_cfun ();
init_caller_stats (&stats);
node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
- if (inline_summaries->get (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",
for (ie = node->indirect_calls; ie; ie = ie->next_callee)
{
struct cgraph_node *callee;
- struct inline_summary *isummary;
+ struct ipa_fn_summary *isummary;
enum availability avail;
tree target;
bool speculative;
callee = callee->function_symbol (&avail);
if (avail < AVAIL_AVAILABLE)
continue;
- isummary = inline_summaries->get (callee);
+ isummary = ipa_fn_summaries->get (callee);
if (!isummary->inlinable)
continue;
/* Return time bonus incurred because of HINTS. */
static int
-hint_time_bonus (inline_hints hints)
+hint_time_bonus (ipa_hints hints)
{
int result = 0;
if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
{
int size, time_benefit;
sreal time, base_time;
- inline_hints hints;
+ ipa_hints hints;
estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
known_aggs_ptrs, &size, &time,
|| (removable_params_cost && node->local.can_change_signature))
{
struct caller_statistics stats;
- inline_hints hints;
+ ipa_hints hints;
sreal time, base_time;
int size;
initialize_node_lattices (node);
}
if (node->definition && !node->alias)
- overall_size += inline_summaries->get (node)->self_size;
+ overall_size += ipa_fn_summaries->get (node)->self_size;
if (node->count > max_count)
max_count = node->count;
}
}
/* Turning calls to direct calls will improve overall summary. */
if (found)
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
}
/* Vector of pointers which for linked lists of clones of an original crgaph
}
}
if (update)
- inline_update_overall_summary (n);
+ ipa_update_overall_fn_summary (n);
}
if (warn_suggest_final_methods || warn_suggest_final_types)
{
For each call
- call statement size, time and how often the parameters change
- inline_summary data structures store above information locally (i.e.
+ ipa_fn_summary data structures store above information locally (i.e.
parameters of the function itself) and globally (i.e. parameters of
the function created by applying all the inline decisions already
present in the callgraph).
- We provide access to the inline_summary data structure and
+ We provide access to the ipa_fn_summary data structure and
basic logic updating the parameters when inlining is performed.
The summaries are context sensitive. Context means
we use predicates.
estimate_edge_size_and_time can be used to query
- function size/time in the given context. inline_merge_summary merges
+ function size/time in the given context. ipa_merge_fn_summary_after_inlining merges
properties of caller and callee after inlining.
Finally pass_inline_parameters is exported. This is used to drive
#include "gimplify.h"
/* Summaries. */
-function_summary <inline_summary *> *inline_summaries;
+function_summary <ipa_fn_summary *> *ipa_fn_summaries;
call_summary <ipa_call_summary *> *ipa_call_summaries;
/* Edge predicates goes here. */
static object_allocator<predicate> edge_predicate_pool ("edge predicates");
-/* Dump inline hints. */
+/* Dump IPA hints. */
void
-dump_inline_hints (FILE *f, inline_hints hints)
+ipa_dump_hints (FILE *f, ipa_hints hints)
{
if (!hints)
return;
- fprintf (f, "inline hints:");
+ fprintf (f, "IPA hints:");
if (hints & INLINE_HINT_indirect_call)
{
hints &= ~INLINE_HINT_indirect_call;
will get optimized out in specialized clones of the function. */
void
-inline_summary::account_size_time (int size, sreal time,
+ipa_fn_summary::account_size_time (int size, sreal time,
const predicate &exec_pred,
const predicate &nonconst_pred_in)
{
{
fprintf (dump_file,
"\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
- ((double) size) / INLINE_SIZE_SCALE,
+ ((double) size) / ipa_fn_summary::size_scale,
(time.to_double ()), found ? "" : "new ");
exec_pred.dump (dump_file, conds, 0);
if (exec_pred != nonconst_pred)
edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
{
/* If the edge is determined to be never executed, redirect it
- to BUILTIN_UNREACHABLE to save inliner from inlining into it. */
+ to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
+ be optimized out. */
if (predicate && *predicate == false
/* When handling speculative edges, we need to do the redirection
just once. Do it always on the direct edge, so we do not
{
clause_t clause = inline_p ? 0 : 1 << predicate::not_inlined_condition;
clause_t nonspec_clause = 1 << predicate::not_inlined_condition;
- struct inline_summary *info = inline_summaries->get (node);
+ struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
int i;
struct condition *c;
vec<ipa_agg_jump_function_p> *known_aggs_ptr)
{
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
- struct inline_summary *info = inline_summaries->get (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;
}
-/* Allocate the inline summary vector or resize it to cover all cgraph nodes. */
+/* Allocate the function summary. */
static void
-inline_summary_alloc (void)
+ipa_fn_summary_alloc (void)
{
- if (!inline_summaries)
- inline_summaries = inline_summary_t::create_ggc (symtab);
- if (!ipa_call_summaries)
- ipa_call_summaries = new ipa_call_summary_t (symtab, false);
+ gcc_checking_assert (!ipa_fn_summaries);
+ ipa_fn_summaries = ipa_fn_summary_t::create_ggc (symtab);
+ 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
-inline_summary::reset (struct cgraph_node *node)
+ipa_fn_summary::reset (struct cgraph_node *node)
{
struct cgraph_edge *e;
/* Hook that is called by cgraph.c when a node is removed. */
void
-inline_summary_t::remove (cgraph_node *node, inline_summary *info)
+ipa_fn_summary_t::remove (cgraph_node *node, ipa_fn_summary *info)
{
info->reset (node);
}
/* Hook that is called by cgraph.c when a node is duplicated. */
void
-inline_summary_t::duplicate (cgraph_node *src,
+ipa_fn_summary_t::duplicate (cgraph_node *src,
cgraph_node *dst,
- inline_summary *,
- inline_summary *info)
+ ipa_fn_summary *,
+ ipa_fn_summary *info)
{
- inline_summary_alloc ();
- memcpy (info, inline_summaries->get (src), sizeof (inline_summary));
+ memcpy (info, ipa_fn_summaries->get (src), sizeof (ipa_fn_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);
new_predicate = es->predicate->remap_after_duplication
(possible_truths);
if (new_predicate == false && *es->predicate != false)
- optimized_out_size += es->call_stmt_size * INLINE_SIZE_SCALE;
+ optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
edge_set_predicate (edge, &new_predicate);
}
new_predicate = es->predicate->remap_after_duplication
(possible_truths);
if (new_predicate == false && *es->predicate != false)
- optimized_out_size += es->call_stmt_size * INLINE_SIZE_SCALE;
+ optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
edge_set_predicate (edge, &new_predicate);
}
remap_hint_predicate_after_duplication (&info->loop_iterations,
}
}
if (!dst->global.inlined_to)
- inline_update_overall_summary (dst);
+ ipa_update_overall_fn_summary (dst);
}
static void
dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
- struct inline_summary *info)
+ struct ipa_fn_summary *info)
{
struct cgraph_edge *edge;
for (edge = node->callees; edge; edge = edge->next_callee)
? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
indent, "", es->loop_depth, edge->frequency,
es->call_stmt_size, es->call_stmt_time,
- (int) inline_summaries->get (callee)->size / INLINE_SIZE_SCALE,
- (int) inline_summaries->get (callee)->estimated_stack_size);
+ (int) ipa_fn_summaries->get (callee)->size / ipa_fn_summary::size_scale,
+ (int) ipa_fn_summaries->get (callee)->estimated_stack_size);
if (es->predicate)
{
fprintf (f, "%*sStack frame offset %i, callee self size %i,"
" callee size %i\n",
indent + 2, "",
- (int) inline_summaries->get (callee)->stack_frame_offset,
- (int) inline_summaries->get (callee)->estimated_self_stack_size,
- (int) inline_summaries->get (callee)->estimated_stack_size);
+ (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);
dump_ipa_call_summary (f, indent + 2, callee, info);
}
}
void
-dump_inline_summary (FILE *f, struct cgraph_node *node)
+ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
{
if (node->definition)
{
- struct inline_summary *s = inline_summaries->get (node);
+ struct ipa_fn_summary *s = ipa_fn_summaries->get (node);
size_time_entry *e;
int i;
- fprintf (f, "Inline summary for %s/%i", node->name (),
+ fprintf (f, "IPA function summary for %s/%i", node->name (),
node->order);
if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
fprintf (f, " always_inline");
for (i = 0; vec_safe_iterate (s->size_time_table, i, &e); i++)
{
fprintf (f, " size:%f, time:%f",
- (double) e->size / INLINE_SIZE_SCALE,
+ (double) e->size / ipa_fn_summary::size_scale,
e->time.to_double ());
if (e->exec_predicate != true)
{
}
DEBUG_FUNCTION void
-debug_inline_summary (struct cgraph_node *node)
+ipa_debug_fn_summary (struct cgraph_node *node)
{
- dump_inline_summary (stderr, node);
+ ipa_dump_fn_summary (stderr, node);
}
void
-dump_inline_summaries (FILE *f)
+ipa_dump_fn_summaries (FILE *f)
{
struct cgraph_node *node;
FOR_EACH_DEFINED_FUNCTION (node)
if (!node->global.inlined_to)
- dump_inline_summary (f, node);
+ ipa_dump_fn_summary (f, node);
}
/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
static void
set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
- struct inline_summary *summary,
+ struct ipa_fn_summary *summary,
basic_block bb)
{
gimple *last;
static void
set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
- struct inline_summary *summary,
+ struct ipa_fn_summary *summary,
basic_block bb)
{
gimple *lastg;
static void
compute_bb_predicates (struct ipa_func_body_info *fbi,
struct cgraph_node *node,
- struct inline_summary *summary)
+ struct ipa_fn_summary *summary)
{
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
bool done = false;
static predicate
will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
- struct inline_summary *summary,
+ struct ipa_fn_summary *summary,
tree expr,
vec<predicate> nonconstant_names)
{
static predicate
will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
- struct inline_summary *summary,
+ struct ipa_fn_summary *summary,
gimple *stmt,
vec<predicate> nonconstant_names)
{
static bool
phi_result_unknown_predicate (struct ipa_node_params *info,
- inline_summary *summary, basic_block bb,
+ ipa_fn_summary *summary, basic_block bb,
predicate *p,
vec<predicate> nonconstant_names)
{
NONCONSTANT_NAMES, if possible. */
static void
-predicate_for_phi_result (struct inline_summary *summary, gphi *phi,
+predicate_for_phi_result (struct ipa_fn_summary *summary, gphi *phi,
predicate *p,
vec<predicate> nonconstant_names)
{
/* Return predicate specifying when array index in access OP becomes non-constant. */
static predicate
-array_index_predicate (inline_summary *info,
+array_index_predicate (ipa_fn_summary *info,
vec< predicate> nonconstant_names, tree op)
{
predicate p = false;
return false;
}
-/* Compute function body size parameters for NODE.
- When EARLY is true, we compute only simple summaries without
- non-trivial predicates to drive the early inliner. */
+/* Analyze function body for NODE.
+ EARLY indicates run from early optimization pipeline. */
static void
-estimate_function_body_sizes (struct cgraph_node *node, bool early)
+analyze_function_body (struct cgraph_node *node, bool early)
{
sreal time = 0;
/* Estimate static overhead for function prologue/epilogue and alignment. */
basic_block bb;
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
int freq;
- struct inline_summary *info = inline_summaries->get (node);
+ struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
predicate bb_predicate;
struct ipa_func_body_info fbi;
vec<predicate> nonconstant_names = vNULL;
info->account_size_time (0, 0, bb_predicate, bb_predicate);
bb_predicate = predicate::not_inlined ();
- info->account_size_time (2 * INLINE_SIZE_SCALE, 0, bb_predicate,
+ info->account_size_time (2 * ipa_fn_summary::size_scale, 0, bb_predicate,
bb_predicate);
if (fbi.info)
}
}
}
- set_hint_predicate (&inline_summaries->get (node)->array_index, array_index);
+ set_hint_predicate (&ipa_fn_summaries->get (node)->array_index, array_index);
time = time / CGRAPH_FREQ_BASE;
free (order);
}
free (body);
}
- set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
+ set_hint_predicate (&ipa_fn_summaries->get (node)->loop_iterations,
loop_iterations);
- set_hint_predicate (&inline_summaries->get (node)->loop_stride,
+ set_hint_predicate (&ipa_fn_summaries->get (node)->loop_stride,
loop_stride);
scev_finalize ();
}
e->aux = NULL;
}
}
- inline_summaries->get (node)->time = time;
- inline_summaries->get (node)->self_size = size;
+ ipa_fn_summaries->get (node)->time = time;
+ ipa_fn_summaries->get (node)->self_size = size;
nonconstant_names.release ();
ipa_release_body_info (&fbi);
if (opt_for_fn (node->decl, optimize))
if (dump_file)
{
fprintf (dump_file, "\n");
- dump_inline_summary (dump_file, node);
+ ipa_dump_fn_summary (dump_file, node);
}
}
-/* Compute parameters of functions used by inliner.
- EARLY is true when we compute parameters for the early inliner */
+/* Compute function summary.
+ EARLY is true when we compute parameters during early opts. */
void
-compute_inline_parameters (struct cgraph_node *node, bool early)
+compute_fn_summary (struct cgraph_node *node, bool early)
{
HOST_WIDE_INT self_stack_size;
struct cgraph_edge *e;
- struct inline_summary *info;
+ struct ipa_fn_summary *info;
gcc_assert (!node->global.inlined_to);
- inline_summary_alloc ();
+ if (!ipa_fn_summaries)
+ ipa_fn_summary_alloc ();
- info = inline_summaries->get (node);
+ info = ipa_fn_summaries->get (node);
info->reset (node);
/* Estimate the stack size for the function if we're optimizing. */
node->local.can_change_signature = false;
es->call_stmt_size = eni_size_weights.call_cost;
es->call_stmt_time = eni_time_weights.call_cost;
- info->account_size_time (INLINE_SIZE_SCALE * 2, 2, t, t);
+ info->account_size_time (ipa_fn_summary::size_scale * 2, 2, t, t);
t = predicate::not_inlined ();
- info->account_size_time (2 * INLINE_SIZE_SCALE, 0, t, t);
- inline_update_overall_summary (node);
+ info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
+ ipa_update_overall_fn_summary (node);
info->self_size = info->size;
/* We can not inline instrumentation clones. */
if (node->thunk.add_pointer_bounds_args)
node->local.can_change_signature = false;
break;
}
- estimate_function_body_sizes (node, early);
+ analyze_function_body (node, early);
pop_cfun ();
}
for (e = node->callees; e; e = e->next_callee)
info->estimated_stack_size = info->estimated_self_stack_size;
/* Code above should compute exactly the same result as
- inline_update_overall_summary but because computation happens in
+ ipa_update_overall_fn_summary but because computation happens in
different order the roundoff errors result in slight changes. */
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
gcc_assert (info->size == info->self_size);
}
current_function_decl. */
static unsigned int
-compute_inline_parameters_for_current (void)
+compute_fn_summary_for_current (void)
{
- compute_inline_parameters (cgraph_node::get (current_function_decl), true);
+ compute_fn_summary (cgraph_node::get (current_function_decl), true);
return 0;
}
opt_pass * clone () { return new pass_inline_parameters (m_ctxt); }
virtual unsigned int execute (function *)
{
- return compute_inline_parameters_for_current ();
+ return compute_fn_summary_for_current ();
}
}; // class pass_inline_parameters
{
tree target;
struct cgraph_node *callee;
- struct inline_summary *isummary;
+ struct ipa_fn_summary *isummary;
enum availability avail;
bool speculative;
callee = callee->function_symbol (&avail);
if (avail < AVAIL_AVAILABLE)
return false;
- isummary = inline_summaries->get (callee);
+ isummary = ipa_fn_summaries->get (callee);
return isummary->inlinable;
}
vec<tree> known_vals,
vec<ipa_polymorphic_call_context> known_contexts,
vec<ipa_agg_jump_function_p> known_aggs,
- inline_hints *hints)
+ ipa_hints *hints)
{
struct ipa_call_summary *es = ipa_call_summaries->get (e);
int call_size = es->call_stmt_size;
known_vals, known_contexts, known_aggs)
&& hints && e->maybe_hot_p ())
*hints |= INLINE_HINT_indirect_call;
- cur_size = call_size * INLINE_SIZE_SCALE;
+ cur_size = call_size * ipa_fn_summary::size_scale;
*size += cur_size;
if (min_size)
*min_size += cur_size;
static void
estimate_calls_size_and_time (struct cgraph_node *node, int *size,
int *min_size, sreal *time,
- inline_hints *hints,
+ ipa_hints *hints,
clause_t possible_truths,
vec<tree> known_vals,
vec<ipa_polymorphic_call_context> known_contexts,
int *ret_size, int *ret_min_size,
sreal *ret_time,
sreal *ret_nonspecialized_time,
- inline_hints *ret_hints,
+ ipa_hints *ret_hints,
vec<inline_param_summary>
inline_param_summary)
{
- struct inline_summary *info = inline_summaries->get (node);
+ struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
size_time_entry *e;
int size = 0;
sreal time = 0;
int min_size = 0;
- inline_hints hints = 0;
+ ipa_hints hints = 0;
int i;
if (dump_file && (dump_flags & TDF_DETAILS))
if (DECL_DECLARED_INLINE_P (node->decl))
hints |= INLINE_HINT_declared_inline;
- size = RDIV (size, INLINE_SIZE_SCALE);
- min_size = RDIV (min_size, INLINE_SIZE_SCALE);
+ size = RDIV (size, ipa_fn_summary::size_scale);
+ min_size = RDIV (min_size, ipa_fn_summary::size_scale);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\n size:%i time:%f nonspec time:%f\n", (int) size,
vec<ipa_agg_jump_function_p> known_aggs,
int *ret_size, sreal *ret_time,
sreal *ret_nonspec_time,
- inline_hints *hints)
+ ipa_hints *hints)
{
clause_t clause, nonspec_clause;
inline_update_callee_summaries (struct cgraph_node *node, int depth)
{
struct cgraph_edge *e;
- struct inline_summary *callee_info = inline_summaries->get (node);
- struct inline_summary *caller_info = inline_summaries->get (node->callers->caller);
+ struct ipa_fn_summary *callee_info = ipa_fn_summaries->get (node);
+ struct ipa_fn_summary *caller_info = ipa_fn_summaries->get (node->callers->caller);
HOST_WIDE_INT peak;
callee_info->stack_frame_offset
+ caller_info->estimated_self_stack_size;
peak = callee_info->stack_frame_offset
+ callee_info->estimated_self_stack_size;
- if (inline_summaries->get (node->global.inlined_to)->estimated_stack_size < peak)
- inline_summaries->get (node->global.inlined_to)->estimated_stack_size = peak;
+ 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_propagate_frequency (node);
for (e = node->callees; e; e = e->next_callee)
{
static void
remap_edge_summaries (struct cgraph_edge *inlined_edge,
struct cgraph_node *node,
- struct inline_summary *info,
- struct inline_summary *callee_info,
+ struct ipa_fn_summary *info,
+ struct ipa_fn_summary *callee_info,
vec<int> operand_map,
vec<int> offset_map,
clause_t possible_truths,
/* 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 (struct ipa_fn_summary *info,
+ struct ipa_fn_summary *callee_info,
predicate **hint,
vec<int> operand_map,
vec<int> offset_map,
/* We inlined EDGE. Update summary of the function we inlined into. */
void
-inline_merge_summary (struct cgraph_edge *edge)
+ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
{
- struct inline_summary *callee_info = inline_summaries->get (edge->callee);
+ struct 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 inline_summary *info = inline_summaries->get (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;
offset_map.release ();
}
-/* For performance reasons inline_merge_summary is not updating overall size
+/* For performance reasons ipa_merge_fn_summary_after_inlining is not updating overall size
and time. Recompute it. */
void
-inline_update_overall_summary (struct cgraph_node *node)
+ipa_update_overall_fn_summary (struct cgraph_node *node)
{
- struct inline_summary *info = inline_summaries->get (node);
+ struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
size_time_entry *e;
int i;
&info->time, NULL,
~(clause_t) (1 << predicate::false_condition),
vNULL, vNULL, vNULL);
- info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE;
+ info->size = (info->size + ipa_fn_summary::size_scale / 2) / ipa_fn_summary::size_scale;
}
node->name (), node->order);
if (opt_for_fn (node->decl, optimize) && !node->thunk.thunk_p)
inline_indirect_intraprocedural_analysis (node);
- compute_inline_parameters (node, false);
+ compute_fn_summary (node, false);
if (!optimize)
{
struct cgraph_edge *e;
/* Called when new function is inserted to callgraph late. */
void
-inline_summary_t::insert (struct cgraph_node *node, inline_summary *)
+ipa_fn_summary_t::insert (struct cgraph_node *node, ipa_fn_summary *)
{
inline_analyze_function (node);
}
if (!optimize && !flag_generate_lto && !flag_generate_offload && !flag_wpa)
return;
- if (!inline_summaries)
- inline_summaries = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+ ipa_fn_summary_alloc ();
- inline_summaries->enable_insertion_hook ();
+ ipa_fn_summaries->enable_insertion_hook ();
ipa_register_cgraph_hooks ();
inline_free_summary ();
{
unsigned int index;
struct cgraph_node *node;
- struct inline_summary *info;
+ struct ipa_fn_summary *info;
lto_symtab_encoder_t encoder;
struct bitpack_d bp;
struct cgraph_edge *e;
encoder = file_data->symtab_node_encoder;
node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
index));
- info = inline_summaries->get (node);
+ info = ipa_fn_summaries->get (node);
info->estimated_stack_size
= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
read_ipa_call_summary (&ib, e);
}
- lto_free_section_data (file_data, LTO_section_inline_summary, NULL, data,
+ lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data,
len);
lto_data_in_delete (data_in);
}
struct lto_file_decl_data *file_data;
unsigned int j = 0;
- inline_summary_alloc ();
+ ipa_fn_summary_alloc ();
while ((file_data = file_data_vec[j++]))
{
size_t len;
const char *data = lto_get_section_data (file_data,
- LTO_section_inline_summary,
+ LTO_section_ipa_fn_summary,
NULL, &len);
if (data)
inline_read_section (file_data, data, len);
ipa_prop_read_jump_functions ();
}
- gcc_assert (inline_summaries);
- inline_summaries->enable_insertion_hook ();
+ gcc_assert (ipa_fn_summaries);
+ ipa_fn_summaries->enable_insertion_hook ();
}
void
inline_write_summary (void)
{
- struct output_block *ob = create_output_block (LTO_section_inline_summary);
+ struct output_block *ob = create_output_block (LTO_section_ipa_fn_summary);
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
unsigned int count = 0;
int i;
cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
if (cnode && cnode->definition && !cnode->alias)
{
- struct inline_summary *info = inline_summaries->get (cnode);
+ struct ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
struct bitpack_d bp;
struct cgraph_edge *edge;
int i;
return;
FOR_EACH_DEFINED_FUNCTION (node)
if (!node->alias)
- inline_summaries->get (node)->reset (node);
- inline_summaries->release ();
- inline_summaries = NULL;
+ ipa_fn_summaries->get (node)->reset (node);
+ ipa_fn_summaries->release ();
+ ipa_fn_summaries = NULL;
ipa_call_summaries->release ();
delete ipa_call_summaries;
ipa_call_summaries = NULL;
#include "ipa-predicate.h"
-/* Inline hints are reasons why inline heuristics should preffer inlining given
+/* Hints are reasons why IPA heuristics should preffer specializing given
function. They are represtented as bitmap of the following values. */
-enum inline_hints_vals {
- /* When inlining turns indirect call into a direct call,
+enum ipa_hints_vals {
+ /* When specialization turns indirect call into a direct call,
it is good idea to do so. */
INLINE_HINT_indirect_call = 1,
/* Inlining may make loop iterations or loop stride known. It is good idea
win. */
INLINE_HINT_in_scc = 16,
/* If function is declared inline by user, it may be good idea to inline
- it. */
+ it. Set by simple_edge_hints in ipa-inline-analysis.c. */
INLINE_HINT_declared_inline = 32,
/* Programs are usually still organized for non-LTO compilation and thus
if functions are in different modules, inlining may not be so important.
- */
+ Set by simple_edge_hints in ipa-inline-analysis.c. */
INLINE_HINT_cross_module = 64,
/* If array indexes of loads/stores become known there may be room for
further optimization. */
INLINE_HINT_known_hot = 256
};
-typedef int inline_hints;
+typedef int ipa_hints;
/* Simple description of whether a memory load or a condition refers to a load
from an aggregate and if so, how and where from in the aggregate.
bool by_ref;
};
-/* Represnetation of function body size and time depending on the inline
+/* Representation of function body size and time depending on the call
context. We keep simple array of record, every containing of predicate
- and time/size to account.
-
- We keep values scaled up, so fractional sizes can be accounted. */
-#define INLINE_SIZE_SCALE 2
+ and time/size to account. */
struct GTY(()) size_time_entry
{
/* Predicate for code to be executed. */
};
/* Function inlining information. */
-struct GTY(()) inline_summary
+struct GTY(()) ipa_fn_summary
{
/* Information about the function body itself. */
/* Estimated stack frame consumption by the function. */
HOST_WIDE_INT estimated_stack_size;
- /* Expected offset of the stack frame of inlined function. */
+ /* Expected offset of the stack frame of function. */
HOST_WIDE_INT stack_frame_offset;
/* Estimated size of the function after inlining. */
sreal GTY((skip)) time;
/* Keep all field empty so summary dumping works during its computation.
This is useful for debugging. */
- inline_summary ()
+ ipa_fn_summary ()
: estimated_self_stack_size (0), self_size (0), min_size (0),
inlinable (false), contains_cilk_spawn (false), single_caller (false),
fp_expressions (false), estimated_stack_size (false),
/* Record time and size under given predicates. */
void account_size_time (int, sreal, const predicate &, const predicate &);
- /* Reset inline summary to empty state. */
+ /* 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;
};
-class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
+class GTY((user)) ipa_fn_summary_t: public function_summary <ipa_fn_summary *>
{
public:
- inline_summary_t (symbol_table *symtab, bool ggc):
- function_summary <inline_summary *> (symtab, ggc) {}
+ ipa_fn_summary_t (symbol_table *symtab, bool ggc):
+ function_summary <ipa_fn_summary *> (symtab, ggc) {}
- static inline_summary_t *create_ggc (symbol_table *symtab)
+ static ipa_fn_summary_t *create_ggc (symbol_table *symtab)
{
- struct inline_summary_t *summary = new (ggc_alloc <inline_summary_t> ())
- inline_summary_t(symtab, true);
+ struct ipa_fn_summary_t *summary = new (ggc_alloc <ipa_fn_summary_t> ())
+ ipa_fn_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 insert (cgraph_node *, ipa_fn_summary *);
+ virtual void remove (cgraph_node *node, ipa_fn_summary *);
virtual void duplicate (cgraph_node *src, cgraph_node *dst,
- inline_summary *src_data, inline_summary *dst_data);
+ ipa_fn_summary *src_data, ipa_fn_summary *dst_data);
};
-extern GTY(()) function_summary <inline_summary *> *inline_summaries;
+extern GTY(()) function_summary <ipa_fn_summary *> *ipa_fn_summaries;
/* Information kept about callgraph edges. */
struct ipa_call_summary
extern call_summary <ipa_call_summary *> *ipa_call_summaries;
/* In ipa-fnsummary.c */
-void debug_inline_summary (struct cgraph_node *);
-void dump_inline_summaries (FILE *f);
-void dump_inline_summary (FILE *f, struct cgraph_node *node);
-void dump_inline_hints (FILE *f, inline_hints);
+void ipa_debug_fn_summary (struct cgraph_node *);
+void ipa_dump_fn_summaries (FILE *f);
+void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node);
+void ipa_dump_hints (FILE *f, ipa_hints);
void inline_generate_summary (void);
void inline_read_summary (void);
void inline_write_summary (void);
void inline_free_summary (void);
void inline_analyze_function (struct cgraph_node *node);
-int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
vec<tree>,
vec<ipa_polymorphic_call_context>,
vec<ipa_agg_jump_function_p>,
int *, sreal *, sreal *,
- inline_hints *);
-void inline_merge_summary (struct cgraph_edge *edge);
-void inline_update_overall_summary (struct cgraph_node *node);
-void compute_inline_parameters (struct cgraph_node *, bool);
-bool inline_account_function_p (struct cgraph_node *node);
+ ipa_hints *);
+void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
+void ipa_update_overall_fn_summary (struct cgraph_node *node);
+void compute_fn_summary (struct cgraph_node *, bool);
void evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
int *ret_size, int *ret_min_size,
sreal *ret_time,
sreal *ret_nonspecialized_time,
- inline_hints *ret_hints,
+ ipa_hints *ret_hints,
vec<inline_param_summary>
inline_param_summary);
fprintf (dump_file,
"can not create wrapper of stdarg function.\n");
}
- else if (inline_summaries
- && inline_summaries->get (alias)->self_size <= 2)
+ else if (ipa_fn_summaries
+ && ipa_fn_summaries->get (alias)->self_size <= 2)
{
if (dump_file)
fprintf (dump_file, "Wrapper creation is not "
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 (inline_summaries->get (to)->scc_no
- && inline_summaries->get (to)->scc_no
- == inline_summaries->get (callee)->scc_no
+ if (ipa_fn_summaries->get (to)->scc_no
+ && ipa_fn_summaries->get (to)->scc_no
+ == ipa_fn_summaries->get (callee)->scc_no
&& !edge->recursive_p ())
hints |= INLINE_HINT_same_scc;
{
sreal time, nonspec_time;
int size;
- inline_hints hints;
+ ipa_hints hints;
struct cgraph_node *callee;
clause_t clause, nonspec_clause;
vec<tree> known_vals;
/* When caching, update the cache entry. */
if (edge_growth_cache.exists ())
{
- inline_summaries->get (edge->callee)->min_size = min_size;
+ ipa_fn_summaries->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;
/* Estimate the growth of the caller when inlining EDGE.
Only to be called via estimate_edge_size. */
-inline_hints
+ipa_hints
do_estimate_edge_hints (struct cgraph_edge *edge)
{
- inline_hints hints;
+ ipa_hints hints;
struct cgraph_node *callee;
clause_t clause, nonspec_clause;
vec<tree> known_vals;
struct ipa_call_summary *es = ipa_call_summaries->get (edge);
if (!es->predicate || *es->predicate != false)
{
- int size = inline_summaries->get (node)->size + estimate_edge_growth (edge);
+ int size = ipa_fn_summaries->get (node)->size + estimate_edge_growth (edge);
gcc_assert (size >= 0);
return size;
}
- return inline_summaries->get (node)->size;
+ return ipa_fn_summaries->get (node)->size;
}
estimate_growth (struct cgraph_node *node)
{
struct growth_data d = { node, false, false, 0 };
- struct inline_summary *info = inline_summaries->get (node);
+ struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
node->call_for_symbol_and_aliases (do_estimate_growth_1, &d, true);
|| node->address_taken)
return true;
- max_callers = inline_summaries->get (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)
{
{
gcc_assert (!e->callee->alias);
if (overall_size)
- *overall_size -= inline_summaries->get (e->callee)->size;
+ *overall_size -= ipa_fn_summaries->get (e->callee)->size;
nfunctions_inlined++;
}
duplicate = false;
indirect edges are discovered in the process, add them to NEW_EDGES, unless
it is NULL. If UPDATE_OVERALL_SUMMARY is false, do not bother to recompute overall
size of caller after inlining. Caller is required to eventually do it via
- inline_update_overall_summary.
+ ipa_update_overall_fn_summary.
If callee_removed is non-NULL, set it to true if we removed callee node.
Return true iff any new callgraph edges were discovered as a
reload_optimization_node = true;
}
- inline_summary *caller_info = inline_summaries->get (to);
- inline_summary *callee_info = inline_summaries->get (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;
gcc_assert (curr->callee->global.inlined_to == to);
- old_size = inline_summaries->get (to)->size;
- inline_merge_summary (e);
+ 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);
if (opt_for_fn (e->caller->decl, optimize))
new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
check_speculations (e->callee);
if (update_overall_summary)
- inline_update_overall_summary (to);
+ ipa_update_overall_fn_summary (to);
else
/* Update self size by the estimate so overall function growth limits
work for further inlining into this function. Before inlining
the function we inlined to again we expect the caller to update
the overall summary. */
- inline_summaries->get (to)->size += estimated_growth;
- new_size = inline_summaries->get (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;
See PR 65654. */
#if 0
/* Verify that estimated growth match real growth. Allow off-by-one
- error due to INLINE_SIZE_SCALE roudoff errors. */
+ error due to ipa_fn_summary::size_scale roudoff errors. */
gcc_assert (!update_overall_summary || !overall_size || new_edges_found
|| abs (estimated_growth - (new_size - old_size)) <= 1
|| speculation_removed
*overall_size += new_size - old_size;
ncalls_inlined++;
- /* This must happen after inline_merge_summary that rely on jump
+ /* This must happen after ipa_merge_fn_summary_after_inlining that rely on jump
functions of callee to not be updated. */
return new_edges_found;
}
int newsize;
int limit = 0;
HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
- inline_summary *info, *what_info, *outer_info = inline_summaries->get (to);
+ ipa_fn_summary *info, *what_info, *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
too much in order to prevent compiler from exploding". */
while (true)
{
- info = inline_summaries->get (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)
break;
}
- what_info = inline_summaries->get (what);
+ what_info = ipa_fn_summaries->get (what);
if (limit < what_info->self_size)
limit = what_info->self_size;
e->inline_failed = CIF_TARGET_OPTION_MISMATCH;
inlinable = false;
}
- else if (!inline_summaries->get (callee)->inlinable)
+ else if (!ipa_fn_summaries->get (callee)->inlinable)
{
e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
inlinable = false;
(DECL_DISREGARD_INLINE_LIMITS (callee->decl)
&& lookup_attribute ("always_inline",
DECL_ATTRIBUTES (callee->decl)));
- inline_summary *caller_info = inline_summaries->get (caller);
- inline_summary *callee_info = inline_summaries->get (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.
else
uninlined_call_time = uninlined_call_time >> 11;
- sreal caller_time = inline_summaries->get (caller)->time;
+ sreal caller_time = ipa_fn_summaries->get (caller)->time;
return uninlined_call_time + caller_time;
}
cgraph_node *caller = (edge->caller->global.inlined_to
? edge->caller->global.inlined_to
: edge->caller);
- sreal caller_time = inline_summaries->get (caller)->time;
+ sreal caller_time = ipa_fn_summaries->get (caller)->time;
if (edge->count && caller->count)
time *= (sreal)edge->count / caller->count;
MAX_INLINE_INSNS_SINGLE 16-fold for inline functions. */
else if ((!DECL_DECLARED_INLINE_P (callee->decl)
&& (!e->count || !e->maybe_hot_p ()))
- && inline_summaries->get (callee)->min_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))
{
want_inline = false;
}
else if ((DECL_DECLARED_INLINE_P (callee->decl) || e->count)
- && inline_summaries->get (callee)->min_size
+ && ipa_fn_summaries->get (callee)->min_size
- ipa_call_summaries->get (e)->call_stmt_size
> 16 * MAX_INLINE_INSNS_SINGLE)
{
else
{
int growth = estimate_edge_growth (e);
- inline_hints hints = estimate_edge_hints (e);
+ ipa_hints hints = estimate_edge_hints (e);
bool big_speedup = big_speedup_p (e);
if (growth <= 0)
int growth;
sreal edge_time, unspec_edge_time;
struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
- struct inline_summary *callee_info = inline_summaries->get (callee);
- inline_hints hints;
+ 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
: edge->caller);
growth,
edge_time.to_double (),
unspec_edge_time.to_double ());
- dump_inline_hints (dump_file, hints);
+ ipa_dump_hints (dump_file, hints);
if (big_speedup_p (edge))
fprintf (dump_file, " big_speedup");
fprintf (dump_file, "\n");
&& (!DECL_DECLARED_INLINE_P (edge->callee->decl)
|| DECL_DECLARED_INLINE_P (caller->decl)))))
{
- struct inline_summary *caller_info = inline_summaries->get (caller);
+ struct 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,
struct cgraph_edge *edge;
struct ipa_ref *ref;
- if ((!node->alias && !inline_summaries->get (node)->inlinable)
+ if ((!node->alias && !ipa_fn_summaries->get (node)->inlinable)
|| node->global.inlined_to)
return;
if (!bitmap_set_bit (updated_nodes, node->uid))
don't need updating. */
if (e->inline_failed
&& (callee = e->callee->ultimate_alias_target (&avail, e->caller))
- && inline_summaries->get (callee)->inlinable
+ && ipa_fn_summaries->get (callee)->inlinable
&& avail >= AVAIL_AVAILABLE
&& !bitmap_bit_p (updated_nodes, callee->uid))
{
fprintf (dump_file,
"\n Inlined %i times, "
"body grown from size %i to %i, time %f to %f\n", n,
- inline_summaries->get (master_clone)->size,
- inline_summaries->get (node)->size,
- inline_summaries->get (master_clone)->time.to_double (),
- inline_summaries->get (node)->time.to_double ());
+ 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 ());
/* 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
spec_rem += edge->count;
edge->resolve_speculation ();
reset_edge_caches (where);
- inline_update_overall_summary (where);
+ ipa_update_overall_fn_summary (where);
update_caller_keys (edge_heap, where,
updated_nodes, NULL);
update_callee_keys (edge_heap, where,
if (!node->alias && node->analyzed
&& (node->has_gimple_body_p () || node->thunk.thunk_p))
{
- struct inline_summary *info = inline_summaries->get (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
for (n2 = node; n2;
n2 = ((struct ipa_dfs_info *) node->aux)->next_cycle)
{
- struct inline_summary *info2 = inline_summaries->get (n2);
+ struct ipa_fn_summary *info2 = ipa_fn_summaries->get (n2);
if (info2->scc_no)
break;
info2->scc_no = id;
{
struct cgraph_node *where = node->global.inlined_to
? node->global.inlined_to : node;
- inline_update_overall_summary (where);
+ ipa_update_overall_fn_summary (where);
reset_edge_caches (where);
update_caller_keys (&edge_heap, where,
updated_nodes, NULL);
fprintf (dump_file,
"\nConsidering %s/%i with %i size\n",
callee->name (), callee->order,
- inline_summaries->get (callee)->size);
+ ipa_fn_summaries->get (callee)->size);
fprintf (dump_file,
" to be inlined into %s/%i in %s:%i\n"
" Estimated badness is %f, frequency %.2f.\n",
"net change of %+i.\n",
edge->callee->name (),
edge->caller->name (),
- inline_summaries->get (edge->caller)->time.to_double (),
- inline_summaries->get (edge->caller)->size,
+ ipa_fn_summaries->get (edge->caller)->time.to_double (),
+ ipa_fn_summaries->get (edge->caller)->size,
overall_size - old_size);
}
if (min_size > overall_size)
node->aux = NULL;
if (!node->global.inlined_to)
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
}
/* Inline NODE to all callers. Worker for cgraph_for_node_and_aliases.
fprintf (dump_file,
"\nInlining %s size %i.\n",
node->name (),
- inline_summaries->get (node)->size);
+ ipa_fn_summaries->get (node)->size);
fprintf (dump_file,
" Called once from %s %i insns.\n",
node->callers->caller->name (),
- inline_summaries->get (node->callers->caller)->size);
+ ipa_fn_summaries->get (node->callers->caller)->size);
}
/* Remember which callers we inlined to, delaying updating the
fprintf (dump_file,
" Inlined into %s which now has %i size\n",
caller->name (),
- inline_summaries->get (caller)->size);
+ ipa_fn_summaries->get (caller)->size);
if (!(*num_calls)--)
{
if (dump_file)
we have a lot of calls to the same function. */
for (hash_set<cgraph_node *>::iterator i = callers.begin ();
i != callers.end (); ++i)
- inline_update_overall_summary (*i);
+ ipa_update_overall_fn_summary (*i);
return res;
}
if (!node->global.inlined_to
&& !node->alias)
{
- sreal time = inline_summaries->get (node)->time;
+ sreal time = ipa_fn_summaries->get (node)->time;
sum += time;
sum_weighted += time * node->count;
}
order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
if (dump_file)
- dump_inline_summaries (dump_file);
+ ipa_dump_fn_summaries (dump_file);
nnodes = ipa_reverse_postorder (order);
struct cgraph_node *where = node->global.inlined_to
? node->global.inlined_to : node;
reset_edge_caches (where);
- inline_update_overall_summary (where);
+ ipa_update_overall_fn_summary (where);
}
if (want_inline_function_to_all_callers_p (node, cold))
{
}
if (dump_file)
- dump_inline_summaries (dump_file);
+ ipa_dump_fn_summaries (dump_file);
/* In WPA we use inline summaries for partitioning process. */
if (!flag_wpa)
inline_free_summary ();
inlined = true;
}
if (inlined)
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
return inlined;
}
for (e = node->callees; e; e = e->next_callee)
{
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
- if (!inline_summaries->get (callee)->inlinable
+ if (!ipa_fn_summaries->get (callee)->inlinable
|| !e->inline_failed)
continue;
}
if (inlined)
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
return inlined;
}
es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_time_weights);
}
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
inlined = false;
timevar_pop (TV_INTEGRATION);
}
}
}
if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1)
- inline_update_overall_summary (node);
+ ipa_update_overall_fn_summary (node);
timevar_pop (TV_INTEGRATION);
iterations++;
inlined = false;
{
sreal time, nonspec_time;
int size;
- inline_hints hints;
+ ipa_hints hints;
};
extern vec<edge_growth_cache_entry> edge_growth_cache;
/* In ipa-inline-analysis.c */
int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
-void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
- vec<tree>,
- vec<ipa_polymorphic_call_context>,
- vec<ipa_agg_jump_function_p>,
- int *, sreal *, sreal *,
- inline_hints *);
int estimate_growth (struct cgraph_node *);
bool growth_likely_positive (struct cgraph_node *, int);
int do_estimate_edge_size (struct cgraph_edge *edge);
sreal do_estimate_edge_time (struct cgraph_edge *edge);
-inline_hints do_estimate_edge_hints (struct cgraph_edge *edge);
+ipa_hints do_estimate_edge_hints (struct cgraph_edge *edge);
void initialize_growth_caches (void);
void free_growth_caches (void);
/* Return estimated callee runtime increase after inlining
EDGE. */
-static inline inline_hints
+static inline ipa_hints
estimate_edge_hints (struct cgraph_edge *edge)
{
- inline_hints ret;
+ ipa_hints ret;
if ((int)edge_growth_cache.length () <= edge->uid
|| !(ret = edge_growth_cache[edge->uid].hints))
return do_estimate_edge_hints (edge);
/* Translate all conditions from callee representation into caller
representation and symbolically evaluate predicate THIS into new predicate.
- INFO is inline_summary of function we are adding predicate into, CALLEE_INFO
+ INFO is ipa_fn_summary of function we are adding predicate into, CALLEE_INFO
is summary of function predicate P is from. OPERAND_MAP is array giving
callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is clausule of all
callee conditions that may be true in caller context. TOPLEV_PREDICATE is
for other purposes). */
predicate
-predicate::remap_after_inlining (struct inline_summary *info,
- struct inline_summary *callee_info,
+predicate::remap_after_inlining (struct ipa_fn_summary *info,
+ struct ipa_fn_summary *callee_info,
vec<int> operand_map,
vec<int> offset_map,
clause_t possible_truths,
It can be NULL, which means this not a load from an aggregate. */
predicate
-add_condition (struct inline_summary *summary, int operand_num,
+add_condition (struct ipa_fn_summary *summary, int operand_num,
HOST_WIDE_INT size, struct agg_position_info *aggpos,
enum tree_code code, tree val)
{
predicate remap_after_duplication (clause_t);
/* Return predicate equal to THIS after inlining. */
- predicate remap_after_inlining (struct inline_summary *,
- struct inline_summary *,
+ predicate remap_after_inlining (struct ipa_fn_summary *,
+ struct ipa_fn_summary *,
vec<int>, vec<int>, clause_t, const predicate &);
void stream_in (struct lto_input_block *);
};
void dump_condition (FILE *f, conditions conditions, int cond);
-predicate add_condition (struct inline_summary *summary, int operand_num,
+predicate add_condition (struct ipa_fn_summary *summary, int operand_num,
HOST_WIDE_INT size, struct agg_position_info *aggpos,
enum tree_code code, tree val);
}
}
if (update)
- inline_update_overall_summary (n);
+ ipa_update_overall_fn_summary (n);
}
if (node_map_initialized)
del_node_map ();
}
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
- compute_inline_parameters (node, true);
+ compute_fn_summary (node, true);
}
/* Execute function splitting pass. */
}
/* This can be relaxed; function might become inlinable after splitting
away the uninlinable part. */
- if (inline_summaries
- && !inline_summaries->get (node)->inlinable)
+ if (ipa_fn_summaries
+ && !ipa_fn_summaries->get (node)->inlinable)
{
if (dump_file)
fprintf (dump_file, "Not splitting: not inlinable.\n");
}
if (!preserve_body)
src->release_body ();
- inline_update_overall_summary (dst);
+ ipa_update_overall_fn_summary (dst);
}
/* TODO: if there is no match, we can scale up. */
src->decl = oldsrcdecl;
target->order);
}
edge = edge->make_direct (target);
- if (inline_summaries)
- inline_update_overall_summary (node);
+ if (ipa_fn_summaries)
+ ipa_update_overall_fn_summary (node);
else if (edge->call_stmt)
{
edge->redirect_call_stmt_to_callee ();
namespace {
-const pass_data pass_data_ipa_free_inline_summary =
+const pass_data pass_data_ipa_free_fn_summary =
{
SIMPLE_IPA_PASS, /* type */
"free-inline-summary", /* name */
( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
};
-class pass_ipa_free_inline_summary : public simple_ipa_opt_pass
+class pass_ipa_free_fn_summary : public simple_ipa_opt_pass
{
public:
- pass_ipa_free_inline_summary (gcc::context *ctxt)
- : simple_ipa_opt_pass (pass_data_ipa_free_inline_summary, ctxt)
+ pass_ipa_free_fn_summary (gcc::context *ctxt)
+ : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary, ctxt)
{}
/* opt_pass methods: */
return 0;
}
-}; // class pass_ipa_free_inline_summary
+}; // class pass_ipa_free_fn_summary
} // anon namespace
simple_ipa_opt_pass *
-make_pass_ipa_free_inline_summary (gcc::context *ctxt)
+make_pass_ipa_free_fn_summary (gcc::context *ctxt)
{
- return new pass_ipa_free_inline_summary (ctxt);
+ return new pass_ipa_free_fn_summary (ctxt);
}
/* Generate and emit a static constructor or destructor. WHICH must
LTO_section_symtab_nodes,
LTO_section_opts,
LTO_section_cgraph_opt_sum,
- LTO_section_inline_summary,
+ LTO_section_ipa_fn_summary,
LTO_section_ipcp_transform,
LTO_section_ipa_icf,
LTO_section_offload_table,
{
struct cgraph_edge *e;
if (!node->alias)
- part->insns += inline_summaries->get (cnode)->self_size;
+ part->insns += ipa_fn_summaries->get (cnode)->self_size;
/* Add all inline clones and callees that are duplicated. */
for (e = cnode->callees; e; e = e->next_callee)
partition->initializers_visited = NULL;
if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
- partition->insns -= inline_summaries->get (cnode)->self_size;
+ partition->insns -= ipa_fn_summaries->get (cnode)->self_size;
lto_symtab_encoder_delete_node (partition->encoder, node);
node->aux = (void *)((size_t)node->aux - 1);
}
else
order[n_nodes++] = node;
if (!node->alias)
- total_size += inline_summaries->get (node)->size;
+ total_size += ipa_fn_summaries->get (node)->size;
}
original_total_size = total_size;
&& noreorder[noreorder_pos]->order < current_order)
{
if (!noreorder[noreorder_pos]->alias)
- total_size -= inline_summaries->get (noreorder[noreorder_pos])->size;
+ total_size -= ipa_fn_summaries->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_summaries->get (order[i])->size;
+ total_size -= ipa_fn_summaries->get (order[i])->size;
/* Once we added a new node to the partition, we also want to add
NEXT_PASS (pass_target_clone);
NEXT_PASS (pass_ipa_chkp_produce_thunks);
NEXT_PASS (pass_ipa_auto_profile);
- NEXT_PASS (pass_ipa_free_inline_summary);
NEXT_PASS (pass_ipa_tree_profile);
PUSH_INSERT_PASSES_WITHIN (pass_ipa_tree_profile)
NEXT_PASS (pass_feedback_split_functions);
POP_INSERT_PASSES ()
+ NEXT_PASS (pass_ipa_free_fn_summary);
NEXT_PASS (pass_ipa_increase_alignment);
NEXT_PASS (pass_ipa_tm);
NEXT_PASS (pass_ipa_lower_emutls);
*ctxt);
extern ipa_opt_pass_d *make_pass_ipa_inline (gcc::context *ctxt);
extern simple_ipa_opt_pass *make_pass_ipa_free_lang_data (gcc::context *ctxt);
-extern simple_ipa_opt_pass *make_pass_ipa_free_inline_summary (gcc::context
- *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_free_fn_summary (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_cp (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_icf (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_devirt (gcc::context *ctxt);
for (cs = node->callers; cs; cs = cs->next_caller)
if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
&& gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
- compute_inline_parameters (cs->caller, true);
+ compute_fn_summary (cs->caller, true);
BITMAP_FREE (recomputed_callers);
return true;
}
if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
- && inline_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
+ && 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");