This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]