diff mbox

Work harder to find DECL_STRUCT_FUNCTION

Message ID 2181135.6JNuHbnjBK@polaris
State New
Headers show

Commit Message

Eric Botcazou Oct. 6, 2014, 9:52 a.m. UTC
Hi,

you can have chains of clone functions in the callgraph but can_inline_edge_p 
stops at the first clone when it is looking for DECL_STRUCT_FUNCTION, which 
can fool the following conditions in the predicate.

Tested on x86_64-suse-linux, OK for the mainline?


2014-10-06  Eric Botcazou  <ebotcazou@adacore.com>

	* ipa-inline.c (can_inline_edge_p): Recurse on clones to find the
	DECL_STRUCT_FUNCTION of the original node.

Comments

Richard Biener Oct. 6, 2014, 11:30 a.m. UTC | #1
On Mon, Oct 6, 2014 at 11:52 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,
>
> you can have chains of clone functions in the callgraph but can_inline_edge_p
> stops at the first clone when it is looking for DECL_STRUCT_FUNCTION, which
> can fool the following conditions in the predicate.
>
> Tested on x86_64-suse-linux, OK for the mainline?

I wonder if this is worth abstracting into a callee_fn () cgraph edge method?

Honzas call.

Thanks,
Richard.

>
> 2014-10-06  Eric Botcazou  <ebotcazou@adacore.com>
>
>         * ipa-inline.c (can_inline_edge_p): Recurse on clones to find the
>         DECL_STRUCT_FUNCTION of the original node.
>
>
> --
> Eric Botcazou
Eric Botcazou Oct. 7, 2014, 7:43 a.m. UTC | #2
> I wonder if this is worth abstracting into a callee_fn () cgraph edge
> method?

That would rather be a cgraph node method without "callee" in the name since 
we also apply it to callers, something like:

struct function *cgraph_node::cfun (void)

and the code in can_inline_edge_p would just be:

  struct function *caller_cfun = e->caller->cfun ();
  struct function *callee_cfun = callee ? callee->cfun () : NULL;
Richard Biener Oct. 7, 2014, 7:51 a.m. UTC | #3
On Tue, Oct 7, 2014 at 9:43 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> I wonder if this is worth abstracting into a callee_fn () cgraph edge
>> method?
>
> That would rather be a cgraph node method without "callee" in the name since
> we also apply it to callers, something like:
>
> struct function *cgraph_node::cfun (void)
>
> and the code in can_inline_edge_p would just be:
>
>   struct function *caller_cfun = e->caller->cfun ();
>   struct function *callee_cfun = callee ? callee->cfun () : NULL;

Ah, ok.  Yes agreed - but without the 'c' (nothing is "current" here IMHO).
Maybe ->get_fun () to be consistent with other method names.

I'll pre-approve a patch to do that.

Thanks,
Richard.

> --
> Eric Botcazou
Jan Hubicka Oct. 7, 2014, 5:41 p.m. UTC | #4
> On Mon, Oct 6, 2014 at 11:52 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> > Hi,
> >
> > you can have chains of clone functions in the callgraph but can_inline_edge_p
> > stops at the first clone when it is looking for DECL_STRUCT_FUNCTION, which
> > can fool the following conditions in the predicate.
> >
> > Tested on x86_64-suse-linux, OK for the mainline?
> 
> I wonder if this is worth abstracting into a callee_fn () cgraph edge method?
> 
> Honzas call.

I would rather fix can_inline_edge_p to not use DECL_STRUCT_FUNCTION - it is not
available during WPA and thus all the code using it is wrong.  The 
non_call_exceptions code has FIXME explaining that, I see that someone added cilk.
It should be easy to move these flags to cgraph node itself - originally I did not
want to duplicate it and worried about performance implications.

Honza
> 
> Thanks,
> Richard.
> 
> >
> > 2014-10-06  Eric Botcazou  <ebotcazou@adacore.com>
> >
> >         * ipa-inline.c (can_inline_edge_p): Recurse on clones to find the
> >         DECL_STRUCT_FUNCTION of the original node.
> >
> >
> > --
> > Eric Botcazou
diff mbox

Patch

Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 215843)
+++ ipa-inline.c	(working copy)
@@ -276,12 +276,24 @@  can_inline_edge_p (struct cgraph_edge *e
   struct function *caller_cfun = DECL_STRUCT_FUNCTION (e->caller->decl);
   struct function *callee_cfun
     = callee ? DECL_STRUCT_FUNCTION (callee->decl) : NULL;
+  struct cgraph_node *n;
 
-  if (!caller_cfun && e->caller->clone_of)
-    caller_cfun = DECL_STRUCT_FUNCTION (e->caller->clone_of->decl);
+  n = e->caller;
+  while (!caller_cfun && n->clone_of)
+    {
+      n = n->clone_of;
+      caller_cfun = DECL_STRUCT_FUNCTION (n->decl);
+    }
 
-  if (!callee_cfun && callee && callee->clone_of)
-    callee_cfun = DECL_STRUCT_FUNCTION (callee->clone_of->decl);
+  if (callee)
+    {
+      n = callee;
+      while (!callee_cfun && n->clone_of)
+	{
+	  n = n->clone_of;
+	  callee_cfun = DECL_STRUCT_FUNCTION (n->decl);
+	}
+    }
 
   gcc_assert (e->inline_failed);