diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-07 23:35:08 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-07 23:35:08 +0000 |
commit | a844747e95c56ae5a8a46158b9839fbeb3678a34 (patch) | |
tree | 5a2cf1b3029c089f24f53c39f669d1c5d9579e03 /gcc/ipa-inline.c | |
parent | c98120f01786b08bb96bc85bf9c4884fc6a3f2c2 (diff) | |
download | gcc-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.c | 69 |
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; |