diff mbox

Fix FDO inliner ICE

Message ID 20110420010614.GD27564@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka April 20, 2011, 1:06 a.m. UTC
Hi,
while cleaning up the way small functions inliner populate the heap I made simple
thinko trying to compute summary information used for badness and the badness
values themselves in one loop.  Since only FDO badness computation depends on summaries
this has passed my non-FDO testing.

profilebootstrapped&regtested x86_64-linux, comitted.

Honza

	* ipa-inline-transform.c (save_inline_function_body): Add comments.
	* ipa-inline.c (inline_small_functions): Compute summaries first, populate
	heap later.
diff mbox

Patch

Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c	(revision 172740)
+++ ipa-inline-transform.c	(working copy)
@@ -253,6 +253,9 @@  save_inline_function_body (struct cgraph
   /* Now node in question has no clones.  */
   node->clones = NULL;
 
+  /* Inline clones share decl with the function they are cloned
+     from.  Walk the whole clone tree and redirect them all to the
+     new decl.  */
   if (first_clone->clones)
     for (n = first_clone->clones; n != first_clone;)
       {
@@ -275,6 +278,8 @@  save_inline_function_body (struct cgraph
   tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL,
 			    NULL, NULL);
 
+  /* The function will be short lived and removed after we inline all the clones,
+     but make it internal so we won't confuse ourself.  */
   DECL_EXTERNAL (first_clone->decl) = 0;
   DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE;
   TREE_PUBLIC (first_clone->decl) = 0;
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 172740)
+++ ipa-inline.c	(working copy)
@@ -1127,22 +1127,18 @@  inline_small_functions (void)
 	     "\nDeciding on inlining of small functions.  Starting with size %i.\n",
 	     initial_size);
 
-  /* Populate the heeap with all edges we might inline.
-     While doing so compute overall unit size and other global
-     parameters used by badness metrics.  */
+  /* Compute overall unit size and other global parameters used by badness
+     metrics.  */
 
   max_count = 0;
   max_benefit = 0;
+
   for (node = cgraph_nodes; node; node = node->next)
     if (node->analyzed
 	&& !node->global.inlined_to)
       {
 	struct inline_summary *info = inline_summary (node);
 
-	if (dump_file)
-	  fprintf (dump_file, "Enqueueing calls of %s/%i.\n",
-		   cgraph_node_name (node), node->uid);
-
 	info->estimated_growth = INT_MIN;
 
 	if (!DECL_EXTERNAL (node->decl))
@@ -1156,20 +1152,34 @@  inline_small_functions (void)
 	      max_count = edge->count;
 	    if (max_benefit < benefit)
 	      max_benefit = benefit;
-	    if (edge->inline_failed
-		&& can_inline_edge_p (edge, true)
-		&& want_inline_small_function_p (edge, true)
-		&& edge->inline_failed)
-	      {
-		gcc_assert (!edge->aux);
-		update_edge_key (heap, edge);
-	      }
 	   }
       }
 
   overall_size = initial_size;
   max_size = compute_max_insns (overall_size);
   min_size = overall_size;
+
+  /* Populate the heeap with all edges we might inline.  */
+
+  for (node = cgraph_nodes; node; node = node->next)
+    if (node->analyzed
+	&& !node->global.inlined_to)
+      {
+	if (dump_file)
+	  fprintf (dump_file, "Enqueueing calls of %s/%i.\n",
+		   cgraph_node_name (node), node->uid);
+
+	for (edge = node->callers; edge; edge = edge->next_caller)
+	  if (edge->inline_failed
+	      && can_inline_edge_p (edge, true)
+	      && want_inline_small_function_p (edge, true)
+	      && edge->inline_failed)
+	    {
+	      gcc_assert (!edge->aux);
+	      update_edge_key (heap, edge);
+	    }
+      }
+
   gcc_assert (in_lto_p
 	      || !max_count
 	      || (profile_info && flag_branch_probabilities));