This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix inlining glitch
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 24 Jul 2011 19:12:51 +0200
- Subject: [patch] Fix inlining glitch
Hi,
we sometimes get messages like this in Ada:
prime-mc2-other.adb: In function 'PRIME.MC2.OTHER.DO_SOMETHING':
prime-mc2.adb:2:4: warning: inlining failed in call
to 'PRIME.MC2.GET_INPUT_VALUE.PART': non-call exception handling mismatch
[-Winline]
prime-mc2-other.adb:3:4: warning: called from here [-Winline]
Since this is for a pure Ada program, it's unexpected. This stems from virtual
cloning: cgraph_create_virtual_clone creates the virtual clone and does:
DECL_STRUCT_FUNCTION (new_decl) = NULL;
so the can_throw_non_call_exceptions flag isn't preserved and can_inline_edge_p
is fooled into thinking that it cannot inline.
It's probably better not to fiddle with virtual cloning so the attached patch
teaches can_inline_edge_p to look into DECL_STRUCT_FUNCTION of the original
nodes if it is dealing with virtual clones.
Tested on i586-suse-linux, OK for the mainline?
2011-07-24 Eric Botcazou <ebotcazou@adacore.com>
* ipa-inline.c (can_inline_edge_p): Look into DECL_STRUCT_FUNCTION of
original nodes if we are dealing with virtual clones.
--
Eric Botcazou
Index: ipa-inline.c
===================================================================
--- ipa-inline.c (revision 176622)
+++ ipa-inline.c (working copy)
@@ -238,9 +238,20 @@ can_inline_edge_p (struct cgraph_edge *e
{
bool inlinable = true;
enum availability avail;
- struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, &avail);
+ struct cgraph_node *callee
+ = cgraph_function_or_thunk_node (e->callee, &avail);
tree caller_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (e->caller->decl);
- tree callee_tree = callee ? DECL_FUNCTION_SPECIFIC_OPTIMIZATION (callee->decl) : NULL;
+ tree callee_tree
+ = callee ? DECL_FUNCTION_SPECIFIC_OPTIMIZATION (callee->decl) : NULL;
+ struct function *caller_cfun = DECL_STRUCT_FUNCTION (e->caller->decl);
+ struct function *callee_cfun
+ = callee ? DECL_STRUCT_FUNCTION (callee->decl) : NULL;
+
+ if (!caller_cfun && e->caller->clone_of)
+ caller_cfun = DECL_STRUCT_FUNCTION (e->caller->clone_of->decl);
+
+ if (!callee_cfun && callee && callee->clone_of)
+ callee_cfun = DECL_STRUCT_FUNCTION (callee->clone_of->decl);
gcc_assert (e->inline_failed);
@@ -277,12 +288,8 @@ can_inline_edge_p (struct cgraph_edge *e
caller cannot.
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 (callee->decl)
- && DECL_STRUCT_FUNCTION
- (callee->decl)->can_throw_non_call_exceptions
- && !(DECL_STRUCT_FUNCTION (e->caller->decl)
- && DECL_STRUCT_FUNCTION
- (e->caller->decl)->can_throw_non_call_exceptions))
+ else if (callee_cfun && callee_cfun->can_throw_non_call_exceptions
+ && !(caller_cfun && caller_cfun->can_throw_non_call_exceptions))
{
e->inline_failed = CIF_NON_CALL_EXCEPTIONS;
inlinable = false;