Patchwork [PR,55078] Let indirect inlining look at ipa-cp lattices

login
register
mail settings
Submitter Martin Jambor
Date Dec. 6, 2012, 12:34 p.m.
Message ID <20121206123414.GA13140@virgil.arch.suse.de>
Download mbox | patch
Permalink /patch/204215/
State New
Headers show

Comments

Martin Jambor - Dec. 6, 2012, 12:34 p.m.
Hi,

the patch below re-stores a check in the inlining machinery that makes
sure growth estimates match the reality after inlining.  However, in
order to do that, I had to teach indirect inlining to look at IPA-CP
data because that's what the inlining estimates do.  Even though this
makes indirect inlining slightly more powerful, the change is not big
and so I hope it qualifies even though we are in stage 3 now.

The patch has passed bootstrap and testing on x86_64-linux.  OK for
trunk?

Thanks,

Martin


2012-12-05  Martin Jambor  <mjambor@suse.cz>

	PR middle-end/55078
	* ipa-inline-transform.c (inline_call): Turn #if 0 to #ifdef
	ENABLE_CHECKING.
	* ipa-prop.c (try_make_edge_direct_simple_call): Use
	ipa_value_from_jfunc.
	(try_make_edge_direct_virtual_call): Likewise.
	(update_indirect_edges_after_inlining): Lookup new_root_info and pass
	it to the functions above.
Jan Hubicka - Dec. 6, 2012, 7:59 p.m.
> Hi,
> 
> the patch below re-stores a check in the inlining machinery that makes
> sure growth estimates match the reality after inlining.  However, in
> order to do that, I had to teach indirect inlining to look at IPA-CP
> data because that's what the inlining estimates do.  Even though this
> makes indirect inlining slightly more powerful, the change is not big
> and so I hope it qualifies even though we are in stage 3 now.
> 
> The patch has passed bootstrap and testing on x86_64-linux.  OK for
> trunk?
> 
> Thanks,
> 
> Martin
> 
> 
> 2012-12-05  Martin Jambor  <mjambor@suse.cz>
> 
> 	PR middle-end/55078
> 	* ipa-inline-transform.c (inline_call): Turn #if 0 to #ifdef
> 	ENABLE_CHECKING.
> 	* ipa-prop.c (try_make_edge_direct_simple_call): Use
> 	ipa_value_from_jfunc.
> 	(try_make_edge_direct_virtual_call): Likewise.
> 	(update_indirect_edges_after_inlining): Lookup new_root_info and pass
> 	it to the functions above.

The patch is OK.
I think it would make sense to have it in stage3, Richi/Jakub can you comment
from RM perspective?

Honza
Richard Guenther - Dec. 7, 2012, 8:35 a.m.
On Thu, 6 Dec 2012, Jan Hubicka wrote:

> > Hi,
> > 
> > the patch below re-stores a check in the inlining machinery that makes
> > sure growth estimates match the reality after inlining.  However, in
> > order to do that, I had to teach indirect inlining to look at IPA-CP
> > data because that's what the inlining estimates do.  Even though this
> > makes indirect inlining slightly more powerful, the change is not big
> > and so I hope it qualifies even though we are in stage 3 now.
> > 
> > The patch has passed bootstrap and testing on x86_64-linux.  OK for
> > trunk?
> > 
> > Thanks,
> > 
> > Martin
> > 
> > 
> > 2012-12-05  Martin Jambor  <mjambor@suse.cz>
> > 
> > 	PR middle-end/55078
> > 	* ipa-inline-transform.c (inline_call): Turn #if 0 to #ifdef
> > 	ENABLE_CHECKING.
> > 	* ipa-prop.c (try_make_edge_direct_simple_call): Use
> > 	ipa_value_from_jfunc.
> > 	(try_make_edge_direct_virtual_call): Likewise.
> > 	(update_indirect_edges_after_inlining): Lookup new_root_info and pass
> > 	it to the functions above.
> 
> The patch is OK.
> I think it would make sense to have it in stage3, Richi/Jakub can you comment
> from RM perspective?

It fixes a bug and thus is appropriate for stage3 by the rulebook.

Thanks,
Richard.

Patch

Index: src/gcc/ipa-inline-transform.c
===================================================================
--- src.orig/gcc/ipa-inline-transform.c
+++ src/gcc/ipa-inline-transform.c
@@ -211,8 +211,7 @@  inline_call (struct cgraph_edge *e, bool
   struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
   bool new_edges_found = false;
 
-  /* FIXME: re-enable once ipa-cp problem is fixed.  */
-#if 0
+#ifdef ENABLE_CHECKING
   int estimated_growth = estimate_edge_growth (e);
   bool predicated = inline_edge_summary (e)->predicate != NULL;
 #endif
@@ -260,8 +259,8 @@  inline_call (struct cgraph_edge *e, bool
   if (update_overall_summary)
    inline_update_overall_summary (to);
   new_size = inline_summary (to)->size;
-  /* FIXME: re-enable once ipa-cp problem is fixed.  */
-#if 0
+
+#ifdef ENABLE_CHECKING
   /* Verify that estimated growth match real growth.  Allow off-by-one
      error due to INLINE_SIZE_SCALE roudoff errors.  */
   gcc_assert (!update_overall_summary || !overall_size
@@ -270,7 +269,7 @@  inline_call (struct cgraph_edge *e, bool
 		 wrong, we should remove them from callgraph.  */
 	      || predicated);
 #endif
-   
+
   /* Account the change of overall unit size; external functions will be
      removed and are thus not accounted.  */
   if (overall_size
Index: src/gcc/ipa-prop.c
===================================================================
--- src.orig/gcc/ipa-prop.c
+++ src/gcc/ipa-prop.c
@@ -2187,49 +2187,46 @@  ipa_find_agg_cst_for_param (struct ipa_a
 /* Try to find a destination for indirect edge IE that corresponds to a simple
    call or a call of a member function pointer and where the destination is a
    pointer formal parameter described by jump function JFUNC.  If it can be
-   determined, return the newly direct edge, otherwise return NULL.  */
+   determined, return the newly direct edge, otherwise return NULL.
+   NEW_ROOT_INFO is the node info that JFUNC lattices are relative to.  */
 
 static struct cgraph_edge *
 try_make_edge_direct_simple_call (struct cgraph_edge *ie,
-				  struct ipa_jump_func *jfunc)
+				  struct ipa_jump_func *jfunc,
+				  struct ipa_node_params *new_root_info)
 {
   tree target;
 
   if (ie->indirect_info->agg_contents)
-    {
-      target = ipa_find_agg_cst_for_param (&jfunc->agg,
-					   ie->indirect_info->offset,
-					   ie->indirect_info->by_ref);
-      if (!target)
-	return NULL;
-    }
+    target = ipa_find_agg_cst_for_param (&jfunc->agg,
+					 ie->indirect_info->offset,
+					 ie->indirect_info->by_ref);
   else
-    {
-      if (jfunc->type != IPA_JF_CONST)
-	return NULL;
-      target = ipa_get_jf_constant (jfunc);
-    }
+    target = ipa_value_from_jfunc (new_root_info, jfunc);
+  if (!target)
+    return NULL;
   return ipa_make_edge_direct_to_target (ie, target);
 }
 
-/* Try to find a destination for indirect edge IE that corresponds to a
-   virtual call based on a formal parameter which is described by jump
-   function JFUNC and if it can be determined, make it direct and return the
-   direct edge.  Otherwise, return NULL.  */
+/* Try to find a destination for indirect edge IE that corresponds to a virtual
+   call based on a formal parameter which is described by jump function JFUNC
+   and if it can be determined, make it direct and return the direct edge.
+   Otherwise, return NULL.  NEW_ROOT_INFO is the node info that JFUNC lattices
+   are relative to.  */
 
 static struct cgraph_edge *
 try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
-				   struct ipa_jump_func *jfunc)
+				   struct ipa_jump_func *jfunc,
+				   struct ipa_node_params *new_root_info)
 {
   tree binfo, target;
 
-  if (jfunc->type != IPA_JF_KNOWN_TYPE)
+  binfo = ipa_value_from_jfunc (new_root_info, jfunc);
+
+  if (!binfo || TREE_CODE (binfo) != TREE_BINFO)
     return NULL;
 
-  binfo = TYPE_BINFO (ipa_get_jf_known_type_base_type (jfunc));
-  gcc_checking_assert (binfo);
-  binfo = get_binfo_at_offset (binfo, ipa_get_jf_known_type_offset (jfunc)
-			       + ie->indirect_info->offset,
+  binfo = get_binfo_at_offset (binfo, ie->indirect_info->offset,
 			       ie->indirect_info->otr_type);
   if (binfo)
     target = gimple_get_virt_method_for_binfo (ie->indirect_info->otr_token,
@@ -2256,10 +2253,14 @@  update_indirect_edges_after_inlining (st
 {
   struct ipa_edge_args *top;
   struct cgraph_edge *ie, *next_ie, *new_direct_edge;
+  struct ipa_node_params *new_root_info;
   bool res = false;
 
   ipa_check_create_edge_args ();
   top = IPA_EDGE_REF (cs);
+  new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
+				? cs->caller->global.inlined_to
+				: cs->caller);
 
   for (ie = node->indirect_calls; ie; ie = next_ie)
     {
@@ -2309,9 +2310,11 @@  update_indirect_edges_after_inlining (st
 	continue;
 
       if (ici->polymorphic)
-	new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc);
+	new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc,
+							     new_root_info);
       else
-	new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc);
+	new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
+							    new_root_info);
 
       if (new_direct_edge)
 	{