Patchwork Fix accounting of code growth in recursive inliner

login
register
mail settings
Submitter Jan Hubicka
Date Oct. 25, 2012, 12:24 p.m.
Message ID <20121025122413.GA8023@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/194130/
State New
Headers show

Comments

Jan Hubicka - Oct. 25, 2012, 12:24 p.m.
Hi,
recursive inliner is confusing the cost of inlining function to itself with
cost of inlining the master clone.  After first recursive inlining happened
those are no longer equivalent.
Fixed thus.
Bootstrapped/regtested x86_64-linux, committed.

Honza
	* ipa-inline.c (recursive_inlining): Redirect to master
	clone before testing profitability.

Patch

Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 192788)
+++ ipa-inline.c	(working copy)
@@ -1190,14 +1190,28 @@  recursive_inlining (struct cgraph_edge *
     {
       struct cgraph_edge *curr
 	= (struct cgraph_edge *) fibheap_extract_min (heap);
-      struct cgraph_node *cnode;
-
-      if (estimate_size_after_inlining (node, curr) > limit)
-	break;
+      struct cgraph_node *cnode, *dest = curr->callee;
 
       if (!can_inline_edge_p (curr, true))
 	continue;
 
+      /* MASTER_CLONE is produced in the case we already started modified
+	 the function. Be sure to redirect edge to the original body before
+	 estimating growths otherwise we will be seeing growths after inlining
+	 the already modified body.  */
+      if (master_clone)
+	{
+          cgraph_redirect_edge_callee (curr, master_clone);
+          reset_edge_growth_cache (curr);
+	}
+
+      if (estimate_size_after_inlining (node, curr) > limit)
+	{
+	  cgraph_redirect_edge_callee (curr, dest);
+	  reset_edge_growth_cache (curr);
+	  break;
+	}
+
       depth = 1;
       for (cnode = curr->caller;
 	   cnode->global.inlined_to; cnode = cnode->callers->caller)
@@ -1206,7 +1220,11 @@  recursive_inlining (struct cgraph_edge *
           depth++;
 
       if (!want_inline_self_recursive_call_p (curr, node, false, depth))
-	continue;
+	{
+	  cgraph_redirect_edge_callee (curr, dest);
+	  reset_edge_growth_cache (curr);
+	  continue;
+	}
 
       if (dump_file)
 	{
@@ -1228,9 +1246,10 @@  recursive_inlining (struct cgraph_edge *
 	  for (e = master_clone->callees; e; e = e->next_callee)
 	    if (!e->inline_failed)
 	      clone_inlined_nodes (e, true, false, NULL);
+          cgraph_redirect_edge_callee (curr, master_clone);
+          reset_edge_growth_cache (curr);
 	}
 
-      cgraph_redirect_edge_callee (curr, master_clone);
       inline_call (curr, false, new_edges, &overall_size, true);
       lookup_recursive_calls (node, curr->callee, heap);
       n++;