summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-07 23:35:08 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2012-01-07 23:35:08 +0000
commita844747e95c56ae5a8a46158b9839fbeb3678a34 (patch)
tree5a2cf1b3029c089f24f53c39f669d1c5d9579e03 /gcc/ipa-inline.c
parentc98120f01786b08bb96bc85bf9c4884fc6a3f2c2 (diff)
downloadgcc-a844747e95c56ae5a8a46158b9839fbeb3678a34.tar.gz
PR tree-optimization/51680
* ipa-inline.c (want_inline_small_function_p): Be more lax on functions whose inlining reduce unit size. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182983 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r--gcc/ipa-inline.c69
1 files changed, 38 insertions, 31 deletions
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 14bd89a67bc..b5c1db0932b 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -482,6 +482,42 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
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)
{
@@ -494,39 +530,10 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
want_inline = false;
}
- /* If call is cold, do not inline when function body would grow.
- Still inline when the overall unit size will shrink because the offline
- copy of function being eliminated.
+ /* If call is cold, do not inline when function body would grow. */
+ else if (!cgraph_maybe_hot_edge_p (e))
- 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 (!cgraph_maybe_hot_edge_p (e)
- && (DECL_EXTERNAL (callee->decl)
-
- /* 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 */
-
- || !cgraph_can_remove_if_no_direct_calls_p (callee)
- || estimate_growth (callee) > 0))
{
e->inline_failed = CIF_UNLIKELY_CALL;
want_inline = false;