diff options
Diffstat (limited to 'gcc/ipa-inline.h')
-rw-r--r-- | gcc/ipa-inline.h | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h index 824a6c50350..839bc237f2a 100644 --- a/gcc/ipa-inline.h +++ b/gcc/ipa-inline.h @@ -28,11 +28,28 @@ along with GCC; see the file COPYING3. If not see typedef struct GTY(()) condition { + /* If agg_contents is set, this is the offset from which the used data was + loaded. */ + HOST_WIDE_INT offset; tree val; int operand_num; - enum tree_code code; + ENUM_BITFIELD(tree_code) code : 16; + /* Set if the used data were loaded from an aggregate parameter or from + data received by reference. */ + unsigned agg_contents : 1; + /* If agg_contents is set, this differentiates between loads from data + passed by reference and by value. */ + unsigned by_ref : 1; } condition; +/* Inline hints are reasons why inline heuristics should preffer inlining given function. + They are represtented as bitmap of the following values. */ +enum inline_hints_vals { + INLINE_HINT_indirect_call = 1, + INLINE_HINT_loop_iterations = 2 +}; +typedef int inline_hints; + DEF_VEC_O (condition); DEF_VEC_ALLOC_O (condition, gc); @@ -102,6 +119,10 @@ struct GTY(()) inline_summary merged during inlining. */ conditions conds; VEC(size_time_entry,gc) *entry; + + /* Predicate on when some loop in the function sbecomes to have known + bounds. */ + struct predicate * GTY((skip)) loop_iterations; }; @@ -149,6 +170,7 @@ extern VEC(inline_edge_summary_t,heap) *inline_edge_summary_vec; typedef struct edge_growth_cache_entry { int time, size; + inline_hints hints; } edge_growth_cache_entry; DEF_VEC_O(edge_growth_cache_entry); DEF_VEC_ALLOC_O(edge_growth_cache_entry,heap); @@ -159,10 +181,11 @@ extern VEC(edge_growth_cache_entry,heap) *edge_growth_cache; /* In ipa-inline-analysis.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_summary (FILE *f, struct cgraph_node *node); +void dump_inline_hints (FILE *f, inline_hints); void inline_generate_summary (void); void inline_read_summary (void); -void inline_write_summary (cgraph_node_set, varpool_node_set); +void inline_write_summary (void); void inline_free_summary (void); void initialize_inline_failed (struct cgraph_edge *); int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *); @@ -173,14 +196,16 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *, int *, int *); int do_estimate_growth (struct cgraph_node *); void inline_merge_summary (struct cgraph_edge *edge); +void inline_update_overall_summary (struct cgraph_node *node); int do_estimate_edge_growth (struct cgraph_edge *edge); int do_estimate_edge_time (struct cgraph_edge *edge); +inline_hints do_estimate_edge_hints (struct cgraph_edge *edge); void initialize_growth_caches (void); void free_growth_caches (void); void compute_inline_parameters (struct cgraph_node *, bool); /* In ipa-inline-transform.c */ -bool inline_call (struct cgraph_edge *, bool, VEC (cgraph_edge_p, heap) **, int *); +bool inline_call (struct cgraph_edge *, bool, VEC (cgraph_edge_p, heap) **, int *, bool); unsigned int inline_transform (struct cgraph_node *); void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *); @@ -190,13 +215,13 @@ extern int nfunctions_inlined; static inline struct inline_summary * inline_summary (struct cgraph_node *node) { - return VEC_index (inline_summary_t, inline_summary_vec, node->uid); + return &VEC_index (inline_summary_t, inline_summary_vec, node->uid); } static inline struct inline_edge_summary * inline_edge_summary (struct cgraph_edge *edge) { - return VEC_index (inline_edge_summary_t, + return &VEC_index (inline_edge_summary_t, inline_edge_summary_vec, edge->uid); } @@ -225,7 +250,7 @@ estimate_edge_growth (struct cgraph_edge *edge) if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid || !(ret = VEC_index (edge_growth_cache_entry, edge_growth_cache, - edge->uid)->size)) + edge->uid).size)) return do_estimate_edge_growth (edge); return ret - (ret > 0); } @@ -241,12 +266,28 @@ estimate_edge_time (struct cgraph_edge *edge) if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid || !(ret = VEC_index (edge_growth_cache_entry, edge_growth_cache, - edge->uid)->time)) + edge->uid).time)) return do_estimate_edge_time (edge); return ret - (ret > 0); } +/* Return estimated callee runtime increase after inlning + EDGE. */ + +static inline inline_hints +estimate_edge_hints (struct cgraph_edge *edge) +{ + inline_hints ret; + if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid + || !(ret = VEC_index (edge_growth_cache_entry, + edge_growth_cache, + edge->uid).hints)) + return do_estimate_edge_time (edge); + return ret - 1; +} + + /* Reset cached value for NODE. */ static inline void @@ -263,7 +304,7 @@ reset_edge_growth_cache (struct cgraph_edge *edge) { if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) > edge->uid) { - struct edge_growth_cache_entry zero = {0, 0}; - VEC_replace (edge_growth_cache_entry, edge_growth_cache, edge->uid, &zero); + struct edge_growth_cache_entry zero = {0, 0, 0}; + VEC_replace (edge_growth_cache_entry, edge_growth_cache, edge->uid, zero); } } |