Patchwork Fixup indirect edge frequencies

login
register
mail settings
Submitter Martin Jambor
Date July 21, 2010, 1 p.m.
Message ID <20100721130008.GA24181@virgil.arch.suse.de>
Download mbox | patch
Permalink /patch/59438/
State New
Headers show

Comments

Martin Jambor - July 21, 2010, 1 p.m.
Hi,

the patch below adds missing edge frequencies updates which are
necessary for my devirtualization patches not to ICEs when it touches
functions created with cgraph_function_versioning.

Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin

2010-07-20  Martin Jambor  <mjambor@suse.cz>

	* cgraphunit.c (verify_edge_count_and_frequency): New function.
	(verify_cgraph_node): Verify frequencies of indirect edges.
	* tree-inline.c (tree_function_versioning): Update frequencies of
	indirect edges.
Jan Hubicka - July 21, 2010, 7:55 p.m.
> Hi,
> 
> the patch below adds missing edge frequencies updates which are
> necessary for my devirtualization patches not to ICEs when it touches
> functions created with cgraph_function_versioning.
> 
> Bootstrapped and tested on x86_64-linux.  OK for trunk?
> 
> Thanks,
> 
> Martin
> 
> 2010-07-20  Martin Jambor  <mjambor@suse.cz>
> 
> 	* cgraphunit.c (verify_edge_count_and_frequency): New function.
> 	(verify_cgraph_node): Verify frequencies of indirect edges.
> 	* tree-inline.c (tree_function_versioning): Update frequencies of
> 	indirect edges.
OK, thanks!
Honza

Patch

Index: icln/gcc/cgraphunit.c
===================================================================
--- icln.orig/gcc/cgraphunit.c
+++ icln/gcc/cgraphunit.c
@@ -570,6 +570,42 @@  clone_of_p (struct cgraph_node *node, st
 }
 #endif
 
+/* Verify edge E count and frequency.  */
+
+static bool
+verify_edge_count_and_frequency (struct cgraph_edge *e)
+{
+  bool error_found = false;
+  if (e->count < 0)
+    {
+      error ("caller edge count is negative");
+      error_found = true;
+    }
+  if (e->frequency < 0)
+    {
+      error ("caller edge frequency is negative");
+      error_found = true;
+    }
+  if (e->frequency > CGRAPH_FREQ_MAX)
+    {
+      error ("caller edge frequency is too large");
+      error_found = true;
+    }
+  if (gimple_has_body_p (e->caller->decl)
+      && !e->caller->global.inlined_to
+      && (e->frequency
+	  != compute_call_stmt_bb_frequency (e->caller->decl,
+					     gimple_bb (e->call_stmt))))
+    {
+      error ("caller edge frequency %i does not match BB freqency %i",
+	     e->frequency,
+	     compute_call_stmt_bb_frequency (e->caller->decl,
+					     gimple_bb (e->call_stmt)));
+      error_found = true;
+    }
+  return error_found;
+}
+
 /* Verify cgraph nodes of given cgraph node.  */
 DEBUG_FUNCTION void
 verify_cgraph_node (struct cgraph_node *node)
@@ -635,33 +671,8 @@  verify_cgraph_node (struct cgraph_node *
     }
   for (e = node->callers; e; e = e->next_caller)
     {
-      if (e->count < 0)
-	{
-	  error ("caller edge count is negative");
-	  error_found = true;
-	}
-      if (e->frequency < 0)
-	{
-	  error ("caller edge frequency is negative");
-	  error_found = true;
-	}
-      if (e->frequency > CGRAPH_FREQ_MAX)
-	{
-	  error ("caller edge frequency is too large");
-	  error_found = true;
-	}
-      if (gimple_has_body_p (e->caller->decl)
-          && !e->caller->global.inlined_to
-          && (e->frequency
-	      != compute_call_stmt_bb_frequency (e->caller->decl,
-						 gimple_bb (e->call_stmt))))
-	{
-	  error ("caller edge frequency %i does not match BB freqency %i",
-	  	 e->frequency,
-		 compute_call_stmt_bb_frequency (e->caller->decl,
-						 gimple_bb (e->call_stmt)));
-	  error_found = true;
-	}
+      if (verify_edge_count_and_frequency (e))
+	error_found = true;
       if (!e->inline_failed)
 	{
 	  if (node->global.inlined_to
@@ -684,6 +695,9 @@  verify_cgraph_node (struct cgraph_node *
 	    error_found = true;
 	  }
     }
+  for (e = node->indirect_calls; e; e = e->next_callee)
+    if (verify_edge_count_and_frequency (e))
+      error_found = true;
   if (!node->callers && node->global.inlined_to)
     {
       error ("inlined_to pointer is set but no predecessors found");
Index: icln/gcc/tree-inline.c
===================================================================
--- icln.orig/gcc/tree-inline.c
+++ icln/gcc/tree-inline.c
@@ -5184,7 +5184,15 @@  tree_function_versioning (tree old_decl,
       for (e = new_version_node->callees; e; e = e->next_callee)
 	{
 	  basic_block bb = gimple_bb (e->call_stmt);
-	  e->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
+	  e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
+							 bb);
+	  e->count = bb->count;
+	}
+      for (e = new_version_node->indirect_calls; e; e = e->next_callee)
+	{
+	  basic_block bb = gimple_bb (e->call_stmt);
+	  e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
+							 bb);
 	  e->count = bb->count;
 	}
     }