diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-30 14:08:03 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-30 14:08:03 +0000 |
commit | 6f60f0b6c6fb72967889f6a3e7a5ce20c325733b (patch) | |
tree | f8a79be03ab3f9bdbe5c053e8f6b97f09a0b90fe | |
parent | 06240b6f2eb94da0295bb1c121376b95b15c0ddd (diff) | |
download | gcc-6f60f0b6c6fb72967889f6a3e7a5ce20c325733b.tar.gz |
* ipa-inline.c (can_inline_edge_p): Disregard limits when
inlining into function with flatten attribute.
(want_inline_small_function_p): Be more realistic about inlining
cold calls where callee size grows.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@173216 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 44 |
2 files changed, 48 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb69c09771c..2d7deb984e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2011-04-30 Jan Hubicka <jh@suse.cz> + * ipa-inline.c (can_inline_edge_p): Disregard limits when + inlining into function with flatten attribute. + (want_inline_small_function_p): Be more realistic about inlining + cold calls where callee size grows. + +2011-04-30 Jan Hubicka <jh@suse.cz> + * cgraph.c (cgraph_create_virtual_clone): Clear constructor/destructor flags. diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 1194785acaa..4665c82ac88 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -272,9 +272,11 @@ can_inline_edge_p (struct cgraph_edge *e, bool report) FIXME: this is obviously wrong for LTO where STRUCT_FUNCTION is missing. Move the flag into cgraph node or mirror it in the inline summary. */ else if (DECL_STRUCT_FUNCTION (e->callee->decl) - && DECL_STRUCT_FUNCTION (e->callee->decl)->can_throw_non_call_exceptions + && DECL_STRUCT_FUNCTION + (e->callee->decl)->can_throw_non_call_exceptions && !(DECL_STRUCT_FUNCTION (e->caller->decl) - && DECL_STRUCT_FUNCTION (e->caller->decl)->can_throw_non_call_exceptions)) + && DECL_STRUCT_FUNCTION + (e->caller->decl)->can_throw_non_call_exceptions)) { e->inline_failed = CIF_NON_CALL_EXCEPTIONS; inlinable = false; @@ -288,6 +290,11 @@ can_inline_edge_p (struct cgraph_edge *e, bool report) } /* Check if caller growth allows the inlining. */ else if (!DECL_DISREGARD_INLINE_LIMITS (e->callee->decl) + && !lookup_attribute ("flatten", + DECL_ATTRIBUTES + (e->caller->global.inlined_to + ? e->caller->global.inlined_to->decl + : e->caller->decl)) && !caller_growth_limits (e)) inlinable = false; /* Don't inline a function with a higher optimization level than the @@ -468,8 +475,39 @@ 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. + + 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) - && estimate_growth (e->callee) > 0) + && (DECL_EXTERNAL (e->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 (e->callee) + || estimate_growth (e->callee) > 0)) { e->inline_failed = CIF_UNLIKELY_CALL; want_inline = false; |