Patchwork Fix ipa-devirt-11.C on AIX part 3

login
register
mail settings
Submitter Jan Hubicka
Date Sept. 6, 2013, 3:02 p.m.
Message ID <20130906150250.GB4841@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/273216/
State New
Headers show

Comments

Jan Hubicka - Sept. 6, 2013, 3:02 p.m.
Hi,
this patch makes inlining of functions called once to work even if they are called
by alias.

Bootstrapped/regtested x86_64-linux, comitted.

	PR middle-end/58094
	* ipa-inline.c (has_caller_p): New function.
	(want_inline_function_to_all_callers_p): Use it.
	(sum_callers, inline_to_all_callers): Break out from ...
	(ipa_inline): ... here.

Patch

Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 202334)
+++ ipa-inline.c	(working copy)
@@ -750,6 +750,15 @@  check_caller_edge (struct cgraph_node *n
           && node->callers != edge);
 }
 
+/* If NODE has a caller, return true.  */
+
+static bool
+has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+{
+  if (node->callers)
+    return true;
+  return false;
+}
 
 /* Decide if inlining NODE would reduce unit size by eliminating
    the offline copy of function.  
@@ -763,7 +772,7 @@  want_inline_function_to_all_callers_p (s
    bool has_hot_call = false;
 
    /* Does it have callers?  */
-   if (!node->callers)
+   if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
      return false;
    /* Already inlined?  */
    if (function->global.inlined_to)
@@ -1892,6 +1901,60 @@  flatten_function (struct cgraph_node *no
     inline_update_overall_summary (node);
 }
 
+/* Count number of callers of NODE and store it into DATA (that
+   points to int.  Worker for cgraph_for_node_and_aliases.  */
+
+static bool
+sum_callers (struct cgraph_node *node, void *data)
+{
+  struct cgraph_edge *e;
+  int *num_calls = (int *)data;
+
+  for (e = node->callers; e; e = e->next_caller)
+    (*num_calls)++;
+  return false;
+}
+
+/* Inline NODE to all callers.  Worker for cgraph_for_node_and_aliases.
+   DATA points to number of calls originally found so we avoid infinite
+   recursion.  */
+
+static bool
+inline_to_all_callers (struct cgraph_node *node, void *data)
+{
+  int *num_calls = (int *)data;
+  while (node->callers && !node->global.inlined_to)
+    {
+      struct cgraph_node *caller = node->callers->caller;
+
+      if (dump_file)
+	{
+	  fprintf (dump_file,
+		   "\nInlining %s size %i.\n",
+		   cgraph_node_name (node),
+		   inline_summary (node)->size);
+	  fprintf (dump_file,
+		   " Called once from %s %i insns.\n",
+		   cgraph_node_name (node->callers->caller),
+		   inline_summary (node->callers->caller)->size);
+	}
+
+      inline_call (node->callers, true, NULL, NULL, true);
+      if (dump_file)
+	fprintf (dump_file,
+		 " Inlined into %s which now has %i size\n",
+		 cgraph_node_name (caller),
+		 inline_summary (caller)->size);
+      if (!(*num_calls)--)
+	{
+	  if (dump_file)
+	    fprintf (dump_file, "New calls found; giving up.\n");
+	  break;
+	}
+    }
+  return false;
+}
+
 /* Decide on the inlining.  We do so in the topological order to avoid
    expenses on updating data structures.  */
 
@@ -2003,39 +2066,11 @@  ipa_inline (void)
 	      && want_inline_function_to_all_callers_p (node, cold))
 	    {
 	      int num_calls = 0;
-	      struct cgraph_edge *e;
-	      for (e = node->callers; e; e = e->next_caller)
-		num_calls++;
-	      while (node->callers && !node->global.inlined_to)
-		{
-		  struct cgraph_node *caller = node->callers->caller;
-
-		  if (dump_file)
-		    {
-		      fprintf (dump_file,
-			       "\nInlining %s size %i.\n",
-			       cgraph_node_name (node),
-			       inline_summary (node)->size);
-		      fprintf (dump_file,
-			       " Called once from %s %i insns.\n",
-			       cgraph_node_name (node->callers->caller),
-			       inline_summary (node->callers->caller)->size);
-		    }
-
-		  inline_call (node->callers, true, NULL, NULL, true);
-		  remove_functions = true;
-		  if (dump_file)
-		    fprintf (dump_file,
-			     " Inlined into %s which now has %i size\n",
-			     cgraph_node_name (caller),
-			     inline_summary (caller)->size);
-		  if (!num_calls--)
-		    {
-		      if (dump_file)
-			fprintf (dump_file, "New calls found; giving up.\n");
-		      break;
-		    }
-		}
+	      cgraph_for_node_and_aliases (node, sum_callers,
+					   &num_calls, true);
+	      cgraph_for_node_and_aliases (node, inline_to_all_callers,
+					   &num_calls, true);
+	      remove_functions = true;
 	    }
 	}
     }