aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authormarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-12-22 09:33:05 +0000
committermarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-12-22 09:33:05 +0000
commitb4bae7a0459ca9c988875c58b9984c62f20723a0 (patch)
treeb8e0ce83d590d0efa7b87b19dae00bd2d2a422a0 /gcc/ipa-inline-analysis.c
parent2cc80ac37074949b269d06bd7b3b8e61932eb0be (diff)
symbol_summary is used for inline_summary.
* lto-partition.c (add_symbol_to_partition_1): New inline_summaries is used. (undo_partition): Likewise. (lto_balanced_map): Likewise. * cgraphunit.c (symbol_table::process_new_functions): New inline_summaries is used. * ipa-cp.c (ipcp_cloning_candidate_p): Likewise. (devirtualization_time_bonus): Likewise. (estimate_local_effects): Likewise. (ipcp_propagate_stage): Likewise. * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Likewise. (evaluate_properties_for_edge): Likewise. (inline_summary_alloc): Likewise. (reset_inline_summary): New inline_summary argument is introduced. (inline_summary_t::remove): New function. (inline_summary_t::duplicate): Likewise. (dump_inline_edge_summary): New inline_summaries is used. (dump_inline_summary): Likewise. (estimate_function_body_sizes): Likewise. (compute_inline_parameters): Likewise. (estimate_edge_devirt_benefit): Likewise. (estimate_node_size_and_time): Likewise. (inline_update_callee_summaries): Likewise. (inline_merge_summary): Likewise. (inline_update_overall_summary): Likewise. (simple_edge_hints): Likewise. (do_estimate_edge_time): Likewise. (estimate_time_after_inlining): Likewise. (estimate_size_after_inlining): Likewise. (do_estimate_growth): Likewise. (growth_likely_positive): Likewise. (inline_generate_summary): Likewise. (inline_read_section): Likewise. (inline_read_summary): Likewise. (inline_write_summary): Likewise. (inline_free_summary): Likewise. * ipa-inline-transform.c (clone_inlined_nodes): Likewise. (inline_call): Likewise. * ipa-inline.c (caller_growth_limits): Likewise. (can_inline_edge_p): Likewise. (want_early_inline_function_p): Likewise. (compute_uninlined_call_time): Likewise. (compute_inlined_call_time): Likewise. (big_speedup_p): Likewise. (want_inline_small_function_p): Likewise. (edge_badness): Likewise. (update_caller_keys): Likewise. (update_callee_keys): Likewise. (recursive_inlining): Likewise. (inline_small_functions): Likewise. (inline_to_all_callers): Likewise. (dump_overall_stats): Likewise. (early_inline_small_functions): Likewise. * ipa-inline.h: New class inline_summary_t replaces vec<inline_summary_t>. * ipa-split.c (execute_split_functions): New inline_summaries is used. * ipa.c (walk_polymorphic_call_targets): Likewise. * tree-sra.c (ipa_sra_preliminary_function_checks): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219006 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r--gcc/ipa-inline-analysis.c155
1 files changed, 65 insertions, 90 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 888d6e35f85..7da373ec3b6 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -148,21 +148,15 @@ enum predicate_conditions
#define CHANGED IDENTIFIER_NODE
/* Holders of ipa cgraph hooks: */
-static struct cgraph_node_hook_list *function_insertion_hook_holder;
-static struct cgraph_node_hook_list *node_removal_hook_holder;
-static struct cgraph_2node_hook_list *node_duplication_hook_holder;
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-static void inline_node_removal_hook (struct cgraph_node *, void *);
-static void inline_node_duplication_hook (struct cgraph_node *,
- struct cgraph_node *, void *);
static void inline_edge_removal_hook (struct cgraph_edge *, void *);
static void inline_edge_duplication_hook (struct cgraph_edge *,
struct cgraph_edge *, void *);
/* VECtor holding inline summaries.
In GGC memory because conditions might point to constant trees. */
-vec<inline_summary_t, va_gc> *inline_summary_vec;
+function_summary <inline_summary *> *inline_summaries;
vec<inline_edge_summary_t> inline_edge_summary_vec;
/* Cached node/edge growths. */
@@ -828,7 +822,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
known_aggs)
{
clause_t clause = inline_p ? 0 : 1 << predicate_not_inlined_condition;
- struct inline_summary *info = inline_summary (node);
+ struct inline_summary *info = inline_summaries->get (node);
int i;
struct condition *c;
@@ -910,7 +904,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
vec<ipa_agg_jump_function_p> *known_aggs_ptr)
{
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
- struct inline_summary *info = inline_summary (callee);
+ struct inline_summary *info = inline_summaries->get (callee);
vec<tree> known_vals = vNULL;
vec<ipa_agg_jump_function_p> known_aggs = vNULL;
@@ -986,21 +980,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
static void
inline_summary_alloc (void)
{
- if (!node_removal_hook_holder)
- node_removal_hook_holder =
- symtab->add_cgraph_removal_hook (&inline_node_removal_hook, NULL);
if (!edge_removal_hook_holder)
edge_removal_hook_holder =
symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
- if (!node_duplication_hook_holder)
- node_duplication_hook_holder =
- symtab->add_cgraph_duplication_hook (&inline_node_duplication_hook, NULL);
if (!edge_duplication_hook_holder)
edge_duplication_hook_holder =
symtab->add_edge_duplication_hook (&inline_edge_duplication_hook, NULL);
- if (vec_safe_length (inline_summary_vec) <= (unsigned) symtab->cgraph_max_uid)
- vec_safe_grow_cleared (inline_summary_vec, symtab->cgraph_max_uid + 1);
+ if (!inline_summaries)
+ inline_summaries = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
if (inline_edge_summary_vec.length () <= (unsigned) symtab->edges_max_uid)
inline_edge_summary_vec.safe_grow_cleared (symtab->edges_max_uid + 1);
if (!edge_predicate_pool)
@@ -1030,9 +1019,9 @@ reset_inline_edge_summary (struct cgraph_edge *e)
data from previous run so they are not cumulated. */
static void
-reset_inline_summary (struct cgraph_node *node)
+reset_inline_summary (struct cgraph_node *node,
+ inline_summary *info)
{
- struct inline_summary *info = inline_summary (node);
struct cgraph_edge *e;
info->self_size = info->self_time = 0;
@@ -1068,16 +1057,10 @@ reset_inline_summary (struct cgraph_node *node)
/* Hook that is called by cgraph.c when a node is removed. */
-static void
-inline_node_removal_hook (struct cgraph_node *node,
- void *data ATTRIBUTE_UNUSED)
+void
+inline_summary_t::remove (cgraph_node *node, inline_summary *info)
{
- struct inline_summary *info;
- if (vec_safe_length (inline_summary_vec) <= (unsigned) node->uid)
- return;
- info = inline_summary (node);
- reset_inline_summary (node);
- memset (info, 0, sizeof (inline_summary_t));
+ reset_inline_summary (node, info);
}
/* Remap predicate P of former function to be predicate of duplicated function.
@@ -1127,16 +1110,14 @@ remap_hint_predicate_after_duplication (struct predicate **p,
/* Hook that is called by cgraph.c when a node is duplicated. */
-
-static void
-inline_node_duplication_hook (struct cgraph_node *src,
- struct cgraph_node *dst,
- ATTRIBUTE_UNUSED void *data)
+void
+inline_summary_t::duplicate (cgraph_node *src,
+ cgraph_node *dst,
+ inline_summary *,
+ inline_summary *info)
{
- struct inline_summary *info;
inline_summary_alloc ();
- info = inline_summary (dst);
- memcpy (info, inline_summary (src), sizeof (struct inline_summary));
+ memcpy (info, inline_summaries->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);
@@ -1357,8 +1338,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_summaries->get (callee)->size / INLINE_SIZE_SCALE,
+ (int) inline_summaries->get (callee)->estimated_stack_size);
if (es->predicate)
{
@@ -1384,9 +1365,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_summaries->get (callee)->stack_frame_offset,
+ (int) inline_summaries->get (callee)->estimated_self_stack_size,
+ (int) inline_summaries->get (callee)->estimated_stack_size);
dump_inline_edge_summary (f, indent + 2, callee, info);
}
}
@@ -1414,7 +1395,7 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
{
if (node->definition)
{
- struct inline_summary *s = inline_summary (node);
+ struct inline_summary *s = inline_summaries->get (node);
size_time_entry *e;
int i;
fprintf (f, "Inline summary for %s/%i", node->name (),
@@ -2227,7 +2208,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)
{
@@ -2316,7 +2297,7 @@ predicate_for_phi_result (struct inline_summary *summary, gphi *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 ();
@@ -2471,7 +2452,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
basic_block bb;
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
int freq;
- struct inline_summary *info = inline_summary (node);
+ struct inline_summary *info = inline_summaries->get (node);
struct predicate bb_predicate;
struct ipa_node_params *parms_info = NULL;
vec<predicate_t> nonconstant_names = vNULL;
@@ -2717,7 +2698,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_summaries->get (node)->array_index, array_index);
time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
if (time > MAX_TIME)
time = MAX_TIME;
@@ -2805,9 +2786,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_summaries->get (node)->loop_iterations,
loop_iterations);
- set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
+ set_hint_predicate (&inline_summaries->get (node)->loop_stride, loop_stride);
scev_finalize ();
}
FOR_ALL_BB_FN (bb, my_function)
@@ -2825,8 +2806,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_summaries->get (node)->self_time = time;
+ inline_summaries->get (node)->self_size = size;
nonconstant_names.release ();
if (opt_for_fn (node->decl, optimize) && !early)
{
@@ -2855,8 +2836,8 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
inline_summary_alloc ();
- info = inline_summary (node);
- reset_inline_summary (node);
+ info = inline_summaries->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
@@ -3024,7 +3005,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_summaries->get (callee);
return isummary->inlinable;
}
@@ -3136,7 +3117,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
vec<inline_param_summary>
inline_param_summary)
{
- struct inline_summary *info = inline_summary (node);
+ struct inline_summary *info = inline_summaries->get (node);
size_time_entry *e;
int size = 0;
int time = 0;
@@ -3353,8 +3334,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);
+ struct inline_summary *callee_info = inline_summaries->get (node);
+ struct inline_summary *caller_info = inline_summaries->get (node->callers->caller);
HOST_WIDE_INT peak;
callee_info->stack_frame_offset
@@ -3362,8 +3343,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_summaries->get (node->global.inlined_to)->estimated_stack_size < peak)
+ inline_summaries->get (node->global.inlined_to)->estimated_stack_size = peak;
ipa_propagate_frequency (node);
for (e = node->callees; e; e = e->next_callee)
{
@@ -3523,10 +3504,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);
+ struct inline_summary *callee_info = inline_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_summary (to);
+ struct inline_summary *info = inline_summaries->get (to);
clause_t clause = 0; /* not_inline is known to be false. */
size_time_entry *e;
vec<int> operand_map = vNULL;
@@ -3635,7 +3616,7 @@ inline_merge_summary (struct cgraph_edge *edge)
void
inline_update_overall_summary (struct cgraph_node *node)
{
- struct inline_summary *info = inline_summary (node);
+ struct inline_summary *info = inline_summaries->get (node);
size_time_entry *e;
int i;
@@ -3662,8 +3643,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_summaries->get (to)->scc_no
+ && inline_summaries->get (to)->scc_no == inline_summaries->get (edge->callee)->scc_no
&& !edge->recursive_p ())
hints |= INLINE_HINT_same_scc;
@@ -3723,7 +3704,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_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 + (time >= 0);
@@ -3825,14 +3806,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_summaries->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_summaries->get (node)->time;
}
@@ -3846,11 +3827,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_summaries->get (node)->size + estimate_edge_growth (edge);
gcc_assert (size >= 0);
return size;
}
- return inline_summary (node)->size;
+ return inline_summaries->get (node)->size;
}
@@ -3890,7 +3871,7 @@ int
do_estimate_growth (struct cgraph_node *node)
{
struct growth_data d = { node, 0, false };
- struct inline_summary *info = inline_summary (node);
+ struct inline_summary *info = inline_summaries->get (node);
node->call_for_symbol_thunks_and_aliases (do_estimate_growth_1, &d, true);
@@ -3963,7 +3944,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_summaries->get (node)->size * 4 / edge_growth + 2;
for (e = node->callers; e; e = e->next_caller)
{
@@ -4026,13 +4007,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 (struct cgraph_node *node, inline_summary *)
{
inline_analyze_function (node);
}
-
/* Note function body size. */
void
@@ -4045,8 +4025,10 @@ inline_generate_summary (void)
if (!optimize && !flag_generate_lto && !flag_generate_offload && !flag_wpa)
return;
- function_insertion_hook_holder =
- symtab->add_cgraph_insertion_hook (&add_new_function, NULL);
+ if (!inline_summaries)
+ inline_summaries = (inline_summary_t*) inline_summary_t::create_ggc (symtab);
+
+ inline_summaries->enable_insertion_hook ();
ipa_register_cgraph_hooks ();
inline_free_summary ();
@@ -4140,7 +4122,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_summaries->get (node);
info->estimated_stack_size
= info->estimated_self_stack_size = streamer_read_uhwi (&ib);
@@ -4229,8 +4211,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_summaries);
+ inline_summaries->enable_insertion_hook ();
}
@@ -4296,7 +4279,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);
+ struct inline_summary *info = inline_summaries->get (node);
struct bitpack_d bp;
struct cgraph_edge *edge;
int i;
@@ -4357,18 +4340,9 @@ void
inline_free_summary (void)
{
struct cgraph_node *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;
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;
@@ -4376,8 +4350,9 @@ inline_free_summary (void)
return;
FOR_EACH_DEFINED_FUNCTION (node)
if (!node->alias)
- reset_inline_summary (node);
- vec_free (inline_summary_vec);
+ reset_inline_summary (node, inline_summaries->get (node));
+ inline_summaries->release ();
+ inline_summaries = NULL;
inline_edge_summary_vec.release ();
if (edge_predicate_pool)
free_alloc_pool (edge_predicate_pool);