This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] 3.0 profile.c fix for C++ EH, nonlocal gotos


On July 9 I submitted a fix for the trunk, which was applied a couple
of days later, that fixes a problem with profiling information that
has just been reported against 3.0 as other/3810.  The submission of
the patch for the mainline includes more information about the problems
and how they were fixed; see
http://gcc.gnu.org/ml/gcc-patches/2001-07/msg00508.html.

Here's the 3.0 version of the fix.  The test case is for nonlocal gotos
in C, not for C++, but there's currently no framework for testing gcov
with C++.  I recently submitted a patch to allow more C gcov testing,
and when I get feedback about that I'll submit a similar one for testing
gcov with C++.

This has been bootstrapped and tested against 3.0 snapshot 20010716 on
i686-pc-linux-gnu.  I don't have write permission for CVS or for GNATS.

Janis

2001-07-27  Janis Johnson  <janis@us.ibm.com>

	* profile.c (branch_prob): Fix .bbg info for computed gotos
	  and C++ EH code.

(for testsuite ChangeLog)

2001-07-27  Janis Johnson < janis@us.ibm.com>

	* gcc.misc-tests/gcov-3.c: New test.

--- gcc/profile.c.orig	Sat Jul  7 13:11:32 2001
+++ gcc/profile.c	Sat Jul  7 13:20:44 2001
@@ -100,6 +100,7 @@
 
 static int total_num_blocks;
 static int total_num_edges;
+static int total_num_edges_ignored;
 static int total_num_edges_instrumented;
 static int total_num_blocks_created;
 static int total_num_passes;
@@ -532,7 +533,7 @@
 branch_prob ()
 {
   int i;
-  int num_edges;
+  int num_edges, ignored_edges;
   struct edge_info *edge_infos;
   struct edge_list *el;
 
@@ -619,6 +620,7 @@
   edge_infos = (struct edge_info *)
     xcalloc (num_edges, sizeof (struct edge_info));
 
+  ignored_edges = 0;
   for (i = 0 ; i < num_edges ; i++)
     {
       edge e = INDEX_EDGE (el, i);
@@ -628,17 +630,12 @@
       /* Mark edges we've replaced by fake edges above as ignored.  */
       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
 	  && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
-	EDGE_INFO (e)->ignore = 1;
+	{
+	  EDGE_INFO (e)->ignore = 1;
+	  ignored_edges++;
+	}
     }
 
-  total_num_blocks += n_basic_blocks + 2;
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
-
-  total_num_edges += num_edges;
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "%d edges\n", num_edges);
-
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif
@@ -715,6 +712,31 @@
 
   find_spanning_tree (el);
 
+  /* Fake edges that are not on the tree will not be instrumented, so
+     mark them ignored. */
+  for (i = 0; i < num_edges; i++)
+    {
+      edge e = INDEX_EDGE (el, i);
+      struct edge_info *inf = EDGE_INFO (e);
+      if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
+	{
+	  inf->ignore = 1;
+	  ignored_edges++;
+	}
+    }
+
+  total_num_blocks += n_basic_blocks + 2;
+  if (rtl_dump_file)
+    fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
+
+  total_num_edges += num_edges;
+  if (rtl_dump_file)
+    fprintf (rtl_dump_file, "%d edges\n", num_edges);
+
+  total_num_edges_ignored += ignored_edges;
+  if (rtl_dump_file)
+    fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
+
   /* Create a .bbg file from which gcov can reconstruct the basic block
      graph.  First output the number of basic blocks, and then for every
      edge output the source and target basic block numbers.
@@ -726,7 +748,7 @@
 
       /* The plus 2 stands for entry and exit block.  */
       __write_long (n_basic_blocks + 2, bbg_file, 4);
-      __write_long (num_edges + 1, bbg_file, 4);
+      __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
 
       for (i = 0; i < n_basic_blocks + 1; i++)
 	{
@@ -747,7 +769,7 @@
 		  flag_bits = 0;
 		  if (i->on_tree)
 		    flag_bits |= 0x1;
-		  if (e->flags & EDGE_ABNORMAL)
+		  if (e->flags & EDGE_FAKE)
 		    flag_bits |= 0x2;
 		  if (e->flags & EDGE_FALLTHRU)
 		    flag_bits |= 0x4;
@@ -943,6 +965,7 @@
 
   total_num_blocks = 0;
   total_num_edges = 0;
+  total_num_edges_ignored = 0;
   total_num_edges_instrumented = 0;
   total_num_blocks_created = 0;
   total_num_passes = 0;
@@ -988,6 +1011,8 @@
       fprintf (rtl_dump_file, "Total number of blocks: %d\n",
 	       total_num_blocks);
       fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
+      fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
+	       total_num_edges_ignored);
       fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
 	       total_num_edges_instrumented);
       fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
--- gcc/testsuite/gcc.misc-tests/gcov-3.c.orig	Sat Jul  7 13:21:52 2001
+++ gcc/testsuite/gcc.misc-tests/gcov-3.c	Sat Jul  7 13:21:17 2001
@@ -0,0 +1,45 @@
+/* Test Gcov with computed gotos.
+   This is the same as test gcc.c-torture/execute/980526-1.c */
+
+/* { dg-options "-fprofile-arcs -ftest-coverage" } */
+/* { dg-do run { target native } } */
+
+int expect_do1 = 1, expect_do2 = 2;
+ 
+static int doit(int x){
+  __label__ lbl1;
+  __label__ lbl2;
+  static int jtab_init = 0;
+  static void *jtab[2];
+ 
+  if(!jtab_init) {
+    jtab[0] = &&lbl1;
+    jtab[1] = &&lbl2;
+    jtab_init = 1;
+  }
+  goto *jtab[x];
+lbl1:
+  return 1;
+lbl2:
+  return 2;
+}
+ 
+static void do1(void) {
+  if (doit(0) != expect_do1)
+    abort ();
+}
+ 
+static void do2(void){
+  if (doit(1) != expect_do2)
+    abort ();
+}
+ 
+int main(void){			/* count(1) */
+#ifndef NO_LABEL_VALUES
+  do1();
+  do2();
+#endif
+  exit(0);			/* count(1) */
+}
+
+/* { dg-final { run-gcov gcov-3.c } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]