summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-05 14:00:46 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-05 14:00:46 +0000
commit3172b7bf16975923d59a1b4646444ea18b31a2e6 (patch)
tree75c6f6529140bc6332176723a9911440e6cf9481 /gcc/ipa-inline-analysis.c
parent57337fec9b4a70c3f34aaaa65ae238206aa0e3db (diff)
downloadgcc-3172b7bf16975923d59a1b4646444ea18b31a2e6.tar.gz
* ipa-inline.c (compute_uninlined_call_time,
compute_inlined_call_time): New functions. (RELATIVE_TIME_BENEFIT_RANGE): New macro. (relative_time_benefit): Rewrite. (edge_badness): Rewrite path with guessed profile and estimated profile. * ipa-inline.h (INLINE_HINT_declared_inline, INLINE_HINT_cross_module): New hints. (struct inline_summary): Add GROWTH filed. * ipa-inline-analysis.c (dump_inline_hints): Update. (reset_inline_summary): Update. (dump_inline_summary): Update. (will_be_nonconstant_predicate): Cleanup to use gimple_store_p and gimple_assign_load_p predicates. (estimate_node_size_and_time): Drop INLINE_HINT_declared_inline hint. (simple_edge_hints): New function. (do_estimate_edge_time): Return time of invocation of callee rather than the time scaled by edge frequency; update hints code. (do_estimate_edge_hints): Update. (do_estimate_growth): Cleanup. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193161 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r--gcc/ipa-inline-analysis.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 9db7f1c0958..595cb682a5b 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -649,6 +649,16 @@ dump_inline_hints (FILE *f, inline_hints hints)
hints &= ~INLINE_HINT_in_scc;
fprintf (f, " in_scc");
}
+ if (hints & INLINE_HINT_cross_module)
+ {
+ hints &= ~INLINE_HINT_cross_module;
+ fprintf (f, " cross_module");
+ }
+ if (hints & INLINE_HINT_declared_inline)
+ {
+ hints &= ~INLINE_HINT_declared_inline;
+ fprintf (f, " declared_inline");
+ }
gcc_assert (!hints);
}
@@ -983,6 +993,7 @@ reset_inline_summary (struct cgraph_node *node)
info->stack_frame_offset = 0;
info->size = 0;
info->time = 0;
+ info->growth = 0;
info->scc_no = 0;
if (info->loop_iterations)
{
@@ -1375,6 +1386,9 @@ dump_inline_summary (FILE * f, struct cgraph_node *node)
(int) s->estimated_self_stack_size);
fprintf (f, " global stack: %i\n",
(int) s->estimated_stack_size);
+ if (s->growth)
+ fprintf (f, " estimated growth:%i\n",
+ (int) s->growth);
if (s->scc_no)
fprintf (f, " In SCC: %i\n",
(int) s->scc_no);
@@ -1977,10 +1991,11 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
return p;
/* Stores will stay anyway. */
- if (gimple_vdef (stmt))
+ if (gimple_store_p (stmt))
return p;
- is_load = gimple_vuse (stmt) != NULL;
+ is_load = gimple_assign_load_p (stmt);
+
/* Loads can be optimized when the value is known. */
if (is_load)
{
@@ -2857,6 +2872,8 @@ estimate_node_size_and_time (struct cgraph_node *node,
hints |=INLINE_HINT_loop_stride;
if (info->scc_no)
hints |= INLINE_HINT_in_scc;
+ if (DECL_DECLARED_INLINE_P (node->symbol.decl))
+ hints |= INLINE_HINT_declared_inline;
estimate_calls_size_and_time (node, &size, &time, &hints, possible_truths,
known_vals, known_binfos, known_aggs);
@@ -2865,7 +2882,6 @@ estimate_node_size_and_time (struct cgraph_node *node,
time = RDIV (time, INLINE_TIME_SCALE);
size = RDIV (size, INLINE_SIZE_SCALE);
-
if (dump_file
&& (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\n size:%i time:%i\n", (int)size, (int)time);
@@ -3315,6 +3331,26 @@ inline_update_overall_summary (struct cgraph_node *node)
info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE;
}
+/* Return hints derrived from EDGE. */
+int
+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
+ && !cgraph_edge_recursive_p (edge))
+ hints |= INLINE_HINT_same_scc;
+
+ if (to->symbol.lto_file_data && edge->callee->symbol.lto_file_data
+ && to->symbol.lto_file_data != edge->callee->symbol.lto_file_data)
+ hints |= INLINE_HINT_cross_module;
+
+ return hints;
+}
+
/* Estimate the time cost for the caller when inlining EDGE.
Only to be called via estimate_edge_time, that handles the
caching mechanism.
@@ -3328,7 +3364,6 @@ do_estimate_edge_time (struct cgraph_edge *edge)
int time;
int size;
inline_hints hints;
- gcov_type ret;
struct cgraph_node *callee;
clause_t clause;
VEC (tree, heap) *known_vals;
@@ -3347,33 +3382,26 @@ do_estimate_edge_time (struct cgraph_edge *edge)
VEC_free (tree, heap, known_vals);
VEC_free (tree, heap, known_binfos);
VEC_free (ipa_agg_jump_function_p, heap, known_aggs);
-
- ret = RDIV ((gcov_type)time * edge->frequency,
- CGRAPH_FREQ_BASE);
+ gcc_checking_assert (size >= 0);
+ gcc_checking_assert (time >= 0);
/* When caching, update the cache entry. */
if (edge_growth_cache)
{
- struct cgraph_node *to = (edge->caller->global.inlined_to
- ? edge->caller->global.inlined_to
- : edge->caller);
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache)
<= edge->uid)
VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache,
cgraph_edge_max_uid);
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).time
- = ret + (ret >= 0);
+ = time + (time >= 0);
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size
= size + (size >= 0);
- if (inline_summary (to)->scc_no
- && inline_summary (to)->scc_no == inline_summary (callee)->scc_no
- && !cgraph_edge_recursive_p (edge))
- hints |= INLINE_HINT_same_scc;
+ hints |= simple_edge_hints (edge);
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints
= hints + 1;
}
- return ret;
+ return time;
}
@@ -3430,9 +3458,6 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
VEC (tree, heap) *known_vals;
VEC (tree, heap) *known_binfos;
VEC (ipa_agg_jump_function_p, heap) *known_aggs;
- struct cgraph_node *to = (edge->caller->global.inlined_to
- ? edge->caller->global.inlined_to
- : edge->caller);
/* When we do caching, use do_estimate_edge_time to populate the entry. */
@@ -3458,10 +3483,7 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
VEC_free (tree, heap, known_vals);
VEC_free (tree, heap, known_binfos);
VEC_free (ipa_agg_jump_function_p, heap, known_aggs);
- if (inline_summary (to)->scc_no
- && inline_summary (to)->scc_no == inline_summary (callee)->scc_no
- && !cgraph_edge_recursive_p (edge))
- hints |= INLINE_HINT_same_scc;
+ hints |= simple_edge_hints (edge);
return hints;
}
@@ -3549,10 +3571,11 @@ do_estimate_growth (struct cgraph_node *node)
return zero or negative growths. */
if (d.self_recursive)
d.growth = d.growth < info->size ? info->size : d.growth;
+ else if (DECL_EXTERNAL (node->symbol.decl))
+ ;
else
{
- if (!DECL_EXTERNAL (node->symbol.decl)
- && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
+ if (cgraph_will_be_removed_from_program_if_no_direct_calls (node))
d.growth -= info->size;
/* COMDAT functions are very often not shared across multiple units
since they come from various template instantiations.