aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/ipa-inline.c
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-04-22 13:33:12 -0700
committerBen Cheng <bccheng@google.com>2014-04-22 13:33:12 -0700
commite3cc64dec20832769406aa38cde83c7dd4194bf4 (patch)
treeef8e39be37cfe0cb69d850043b7924389ff17164 /gcc-4.9/gcc/ipa-inline.c
parentf33c7b3122b1d7950efa88067c9a156229ba647b (diff)
downloadtoolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.tar.gz
toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.tar.bz2
toolchain_gcc-e3cc64dec20832769406aa38cde83c7dd4194bf4.zip
[4.9] GCC 4.9.0 official release refresh
Change-Id: Ic99a7da8b44b789a48aeec93b33e93944d6e6767
Diffstat (limited to 'gcc-4.9/gcc/ipa-inline.c')
-rw-r--r--gcc-4.9/gcc/ipa-inline.c95
1 files changed, 45 insertions, 50 deletions
diff --git a/gcc-4.9/gcc/ipa-inline.c b/gcc-4.9/gcc/ipa-inline.c
index f6f97f87e..405181940 100644
--- a/gcc-4.9/gcc/ipa-inline.c
+++ b/gcc-4.9/gcc/ipa-inline.c
@@ -573,6 +573,24 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
want_inline = false;
}
+ /* Do fast and conservative check if the function can be good
+ inline cnadidate. At themoment we allow inline hints to
+ promote non-inline function to inline and we increase
+ MAX_INLINE_INSNS_SINGLE 16fold for inline functions. */
+ else if (!DECL_DECLARED_INLINE_P (callee->decl)
+ && inline_summary (callee)->min_size - inline_edge_summary (e)->call_stmt_size
+ > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
+ {
+ e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
+ want_inline = false;
+ }
+ else if (DECL_DECLARED_INLINE_P (callee->decl)
+ && inline_summary (callee)->min_size - inline_edge_summary (e)->call_stmt_size
+ > 16 * MAX_INLINE_INSNS_SINGLE)
+ {
+ e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
+ want_inline = false;
+ }
else
{
int growth = estimate_edge_growth (e);
@@ -585,56 +603,26 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
hints suggests that inlining given function is very profitable. */
else if (DECL_DECLARED_INLINE_P (callee->decl)
&& growth >= MAX_INLINE_INSNS_SINGLE
- && !big_speedup
- && !(hints & (INLINE_HINT_indirect_call
- | INLINE_HINT_loop_iterations
- | INLINE_HINT_array_index
- | INLINE_HINT_loop_stride)))
+ && ((!big_speedup
+ && !(hints & (INLINE_HINT_indirect_call
+ | INLINE_HINT_loop_iterations
+ | INLINE_HINT_array_index
+ | INLINE_HINT_loop_stride)))
+ || growth >= MAX_INLINE_INSNS_SINGLE * 16))
{
e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
want_inline = false;
}
- /* Before giving up based on fact that caller size will grow, allow
- functions that are called few times and eliminating the offline
- copy will lead to overall code size reduction.
- Not all of these will be handled by subsequent inlining of functions
- called once: in particular weak functions are not handled or funcitons
- that inline to multiple calls but a lot of bodies is optimized out.
- Finally we want to inline earlier to allow inlining of callbacks.
-
- This is slightly wrong on aggressive side: it is entirely possible
- that function is called many times with a context where inlining
- reduces code size and few times with a context where inlining increase
- code size. Resoluting growth estimate will be negative even if it
- would make more sense to keep offline copy and do not inline into the
- call sites that makes the code size grow.
-
- When badness orders the calls in a way that code reducing calls come
- first, this situation is not a problem at all: after inlining all
- "good" calls, we will realize that keeping the function around is
- better. */
- else if (growth <= MAX_INLINE_INSNS_SINGLE
- /* Unlike for functions called once, we play unsafe with
- COMDATs. We can allow that since we know functions
- in consideration are small (and thus risk is small) and
- moreover grow estimates already accounts that COMDAT
- functions may or may not disappear when eliminated from
- current unit. With good probability making aggressive
- choice in all units is going to make overall program
- smaller.
-
- Consequently we ask cgraph_can_remove_if_no_direct_calls_p
- instead of
- cgraph_will_be_removed_from_program_if_no_direct_calls */
- && !DECL_EXTERNAL (callee->decl)
- && cgraph_can_remove_if_no_direct_calls_p (callee)
- && estimate_growth (callee) <= 0)
- ;
else if (!DECL_DECLARED_INLINE_P (callee->decl)
&& !flag_inline_functions)
{
- e->inline_failed = CIF_NOT_DECLARED_INLINED;
- want_inline = false;
+ /* growth_likely_positive is expensive, always test it last. */
+ if (growth >= MAX_INLINE_INSNS_SINGLE
+ || growth_likely_positive (callee, growth))
+ {
+ e->inline_failed = CIF_NOT_DECLARED_INLINED;
+ want_inline = false;
+ }
}
/* Apply MAX_INLINE_INSNS_AUTO limit for functions not declared inline
Upgrade it to MAX_INLINE_INSNS_SINGLE when hints suggests that
@@ -649,11 +637,18 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
MAX_INLINE_INSNS_SINGLE)
: MAX_INLINE_INSNS_AUTO))
{
- e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
- want_inline = false;
+ /* growth_likely_positive is expensive, always test it last. */
+ if (growth >= MAX_INLINE_INSNS_SINGLE
+ || growth_likely_positive (callee, growth))
+ {
+ e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
+ want_inline = false;
+ }
}
/* If call is cold, do not inline when function body would grow. */
- else if (!cgraph_maybe_hot_edge_p (e))
+ else if (!cgraph_maybe_hot_edge_p (e)
+ && (growth >= MAX_INLINE_INSNS_SINGLE
+ || growth_likely_positive (callee, growth)))
{
e->inline_failed = CIF_UNLIKELY_CALL;
want_inline = false;
@@ -1388,7 +1383,7 @@ recursive_inlining (struct cgraph_edge *edge,
/* We need original clone to copy around. */
master_clone = cgraph_clone_node (node, node->decl,
node->count, CGRAPH_FREQ_BASE,
- false, vNULL, true, NULL);
+ false, vNULL, true, NULL, NULL);
for (e = master_clone->callees; e; e = e->next_callee)
if (!e->inline_failed)
clone_inlined_nodes (e, true, false, NULL, CGRAPH_FREQ_BASE);
@@ -1685,7 +1680,7 @@ inline_small_functions (void)
edge = (struct cgraph_edge *) fibheap_extract_min (edge_heap);
gcc_assert (edge->aux);
edge->aux = NULL;
- if (!edge->inline_failed)
+ if (!edge->inline_failed || !edge->callee->analyzed)
continue;
/* Be sure that caches are maintained consistent.
@@ -1723,14 +1718,12 @@ inline_small_functions (void)
inline_summary (callee)->size);
fprintf (dump_file,
" to be inlined into %s/%i in %s:%i\n"
- " Estimated growth after inlined into all is %+i insns.\n"
" Estimated badness is %i, frequency %.2f.\n",
edge->caller->name (), edge->caller->order,
flag_wpa ? "unknown"
: gimple_filename ((const_gimple) edge->call_stmt),
flag_wpa ? -1
: gimple_lineno ((const_gimple) edge->call_stmt),
- estimate_growth (callee),
badness,
edge->frequency / (double)CGRAPH_FREQ_BASE);
if (edge->count)
@@ -2318,6 +2311,8 @@ early_inliner (void)
edge->call_stmt, edge->callee->decl, false))
edge->call_stmt_cannot_inline_p = true;
}
+ if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1)
+ inline_update_overall_summary (node);
timevar_pop (TV_INTEGRATION);
iterations++;
inlined = false;