public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Let IPA-CP make direct callgraph edges it can
@ 2010-08-04 19:14 Martin Jambor
  2010-08-05  8:29 ` Jan Hubicka
  2010-10-30 18:09 ` H.J. Lu
  0 siblings, 2 replies; 3+ messages in thread
From: Martin Jambor @ 2010-08-04 19:14 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jan Hubicka

Hi,

this patch replaces a TODO in IPA-CP saying that if after discovering
constants we should create (actually make direct) any call graph edges
that the inliner can then make use of.  This patch does exactly that
by traversing the indirect edges in a way that is quite similar to
(but a bit simpler than) ipa-prop.c.  

It then makes sure it does not redirect any of these newly direct
edges because they have not been there when analysis was performed and
so that we do not run into issues like PR 42231.  (This then raises a
question whether the flag indirect_inlining_edge should be renamed or
split into two distinct flags.  I have not made up my mind yet but one
of these things should be made solely for the sake of clarity, it
works just as intended now.)

I have bootstrapped and tested this patch on top of the ipa-cp
devirtualization one I have posted a while ago on x86-64-linux without
any problems.  OK for trunk eventually?

Thanks,

Martin


2010-08-03  Martin Jambor  <mjambor@suse.cz>

	* ipa-cp.c (ipcp_discover_new_direct_edges): New function.
	(ipcp_insert_stage): Redirect only edges not flagged with
	indirect_inlining_edge.  Call ipcp_discover_new_direct_edges for all
	discovered constants.

	* testsuite/gcc.dg/ipa/ipcp-ii-1.c: New test.
	* testsuite/g++.dg/ipa/ipcp-ivi-1.C: Likewise.


Index: icln/gcc/ipa-cp.c
===================================================================
--- icln.orig/gcc/ipa-cp.c
+++ icln/gcc/ipa-cp.c
@@ -1269,6 +1269,49 @@ ipcp_const_param_count (struct cgraph_no
   return const_param;
 }
 
+/* Given that a formal parameter of NODE given by INDEX is known to be constant
+   CST, try to find any indirect edges that can be made direct and make them
+   so.  Note that INDEX is the number the parameter at the time of analyzing
+   parameter uses and parameter removals should not be considered for it.  (In
+   fact, the parameter itself has just been removed.)  */
+
+static void
+ipcp_discover_new_direct_edges (struct cgraph_node *node, int index, tree cst)
+{
+  struct cgraph_edge *ie, *next_ie;
+
+  for (ie = node->indirect_calls; ie; ie = next_ie)
+    {
+      struct cgraph_indirect_call_info *ici = ie->indirect_info;
+
+      next_ie = ie->next_callee;
+      if (ici->param_index != index)
+	continue;
+
+      if (ici->polymorphic)
+	{
+	  tree binfo;
+	  HOST_WIDE_INT token;
+
+	  if (TREE_CODE (cst) != ADDR_EXPR)
+	    continue;
+
+	  binfo = gimple_get_relevant_ref_binfo (TREE_OPERAND (cst, 0),
+						 NULL_TREE);
+	  if (!binfo)
+	    continue;
+	  gcc_assert (ie->indirect_info->anc_offset == 0);
+	  token = ie->indirect_info->otr_token;
+	  cst = gimple_fold_obj_type_ref_known_binfo (token, binfo);
+	  if (!cst)
+	    continue;
+	}
+
+      ipa_make_edge_direct_to_target (ie, cst);
+    }
+}
+
+
 /* Propagate the constant parameters found by ipcp_iterate_stage()
    to the function's code.  */
 static void
@@ -1390,7 +1433,8 @@ ipcp_insert_stage (void)
 	node_callers++;
       redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
       for (cs = node->callers; cs != NULL; cs = cs->next_caller)
-	VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
+	if (!cs->indirect_inlining_edge)
+	  VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
 
       /* Redirecting all the callers of the node to the
          new versioned node.  */
@@ -1410,7 +1454,13 @@ ipcp_insert_stage (void)
 		 cgraph_node_name (node), (int)growth, (int)new_size);
       ipcp_init_cloned_node (node, node1);
 
-      /* TODO: We can use indirect inlning info to produce new calls.  */
+      info = IPA_NODE_REF (node);
+      for (i = 0; i < count; i++)
+	{
+	  struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
+	  if (lat->type == IPA_CONST_VALUE)
+	    ipcp_discover_new_direct_edges (node1, i, lat->constant);
+        }
 
       if (dump_file)
 	dump_function_to_file (node1->decl, dump_file, dump_flags);
Index: icln/gcc/testsuite/g++.dg/ipa/ipcp-ivi-1.C
===================================================================
--- /dev/null
+++ icln/gcc/testsuite/g++.dg/ipa/ipcp-ivi-1.C
@@ -0,0 +1,65 @@
+/* Verify that simple virtual calls are inlined even without early
+   inlining.  */
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining"  } */
+
+extern "C" void abort (void);
+
+class A
+{
+public:
+  int data;
+  virtual int foo (int i);
+};
+
+class B : public A
+{
+public:
+  virtual int foo (int i);
+};
+
+class C : public A
+{
+public:
+  virtual int foo (int i);
+};
+
+int A::foo (int i)
+{
+  return i + 1;
+}
+
+int B::foo (int i)
+{
+  return i + 2;
+}
+
+int C::foo (int i)
+{
+  return i + 3;
+}
+
+int __attribute__ ((noinline)) middleman (class A *obj, int i)
+{
+  return obj->foo (i);
+}
+
+int __attribute__ ((noinline,noclone)) get_input(void)
+{
+  return 1;
+}
+
+class B b;
+
+int main (int argc, char *argv[])
+{
+  int i;
+
+  for (i = 0; i < get_input (); i++)
+    if (middleman (&b, get_input ()) != 3)
+      abort ();
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int.*middleman"  "inline"  } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
Index: icln/gcc/testsuite/gcc.dg/ipa/ipcp-ii-1.c
===================================================================
--- /dev/null
+++ icln/gcc/testsuite/gcc.dg/ipa/ipcp-ii-1.c
@@ -0,0 +1,34 @@
+/* Verify that simple indirect calls are inlined even without early
+   inlining..  */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining"  } */
+
+extern void non_existent(int);
+extern void non_existent(int);
+
+static void hooray ()
+{
+  non_existent (1);
+}
+
+static void  __attribute__ ((noinline)) hiphip (void (*f)())
+{
+  f ();
+}
+
+int __attribute__ ((noinline,noclone)) get_input(void)
+{
+  return 1;
+}
+
+int main (int argc, int *argv[])
+{
+  int i;
+
+  for (i = 0; i < get_input (); i++)
+    hiphip (hooray);
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in hiphip.constprop"  "inline"  } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Let IPA-CP make direct callgraph edges it can
  2010-08-04 19:14 [PATCH] Let IPA-CP make direct callgraph edges it can Martin Jambor
@ 2010-08-05  8:29 ` Jan Hubicka
  2010-10-30 18:09 ` H.J. Lu
  1 sibling, 0 replies; 3+ messages in thread
From: Jan Hubicka @ 2010-08-05  8:29 UTC (permalink / raw)
  To: GCC Patches, Jan Hubicka

> Hi,
> 
> this patch replaces a TODO in IPA-CP saying that if after discovering
> constants we should create (actually make direct) any call graph edges
> that the inliner can then make use of.  This patch does exactly that
> by traversing the indirect edges in a way that is quite similar to
> (but a bit simpler than) ipa-prop.c.  
> 
> It then makes sure it does not redirect any of these newly direct
> edges because they have not been there when analysis was performed and
> so that we do not run into issues like PR 42231.  (This then raises a
> question whether the flag indirect_inlining_edge should be renamed or
> split into two distinct flags.  I have not made up my mind yet but one
> of these things should be made solely for the sake of clarity, it
> works just as intended now.)
> 
> I have bootstrapped and tested this patch on top of the ipa-cp
> devirtualization one I have posted a while ago on x86-64-linux without
> any problems.  OK for trunk eventually?
> 
> Thanks,
> 
> Martin
> 
> 
> 2010-08-03  Martin Jambor  <mjambor@suse.cz>
> 
> 	* ipa-cp.c (ipcp_discover_new_direct_edges): New function.
> 	(ipcp_insert_stage): Redirect only edges not flagged with
> 	indirect_inlining_edge.  Call ipcp_discover_new_direct_edges for all
> 	discovered constants.
OK,
thanks!

Honza

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Let IPA-CP make direct callgraph edges it can
  2010-08-04 19:14 [PATCH] Let IPA-CP make direct callgraph edges it can Martin Jambor
  2010-08-05  8:29 ` Jan Hubicka
@ 2010-10-30 18:09 ` H.J. Lu
  1 sibling, 0 replies; 3+ messages in thread
From: H.J. Lu @ 2010-10-30 18:09 UTC (permalink / raw)
  To: GCC Patches, Jan Hubicka

On Wed, Aug 4, 2010 at 12:14 PM, Martin Jambor <mjambor@suse.cz> wrote:
> Hi,
>
> this patch replaces a TODO in IPA-CP saying that if after discovering
> constants we should create (actually make direct) any call graph edges
> that the inliner can then make use of.  This patch does exactly that
> by traversing the indirect edges in a way that is quite similar to
> (but a bit simpler than) ipa-prop.c.
>
> It then makes sure it does not redirect any of these newly direct
> edges because they have not been there when analysis was performed and
> so that we do not run into issues like PR 42231.  (This then raises a
> question whether the flag indirect_inlining_edge should be renamed or
> split into two distinct flags.  I have not made up my mind yet but one
> of these things should be made solely for the sake of clarity, it
> works just as intended now.)
>
> I have bootstrapped and tested this patch on top of the ipa-cp
> devirtualization one I have posted a while ago on x86-64-linux without
> any problems.  OK for trunk eventually?
>
> Thanks,
>
> Martin
>
>
> 2010-08-03  Martin Jambor  <mjambor@suse.cz>
>
>        * ipa-cp.c (ipcp_discover_new_direct_edges): New function.
>        (ipcp_insert_stage): Redirect only edges not flagged with
>        indirect_inlining_edge.  Call ipcp_discover_new_direct_edges for all
>        discovered constants.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46242

-- 
H.J.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-10-30 13:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-04 19:14 [PATCH] Let IPA-CP make direct callgraph edges it can Martin Jambor
2010-08-05  8:29 ` Jan Hubicka
2010-10-30 18:09 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).