gcov: option to instrument whole basic block graph, no use of spanning tree optimization

Message ID 20101109084031.GA9381@laptop-hbl.localdomain
State New
Headers show

Commit Message

Holger Blasum Nov. 9, 2010, 8:40 a.m.
Hello Ralf,

On Mon, Nov 08, 2010 at 08:09:56PM +0100, Ralf Wildenhues wrote:
> here's a syntactic-only review:

... points taken, fixed in attached patch (combining both previous ones). 

Note: this way of amending the documentation I think would easily allow 
to add another option for e.g. adding/switching to e.g. atomic counter 
incrementation once that is included (which of course I would welcome).



Index: gcc/doc/gcov.texi
--- gcc/doc/gcov.texi	(revision 166453)
+++ gcc/doc/gcov.texi	(working copy)
@@ -41,6 +41,9 @@ 
 * Gcov Intro::                  Introduction to gcov.
 * Invoking Gcov::               How to use gcov.
 * Gcov and Optimization::       Using gcov with GCC optimization.
+* Counter Size::                Counter size.
+* Multithreaded Programs::      Collecting Coverage Data 
+                                 from Multithreaded Programs.
 * Gcov Data Files::             The files used by gcov.
 * Cross-profiling::             Data file relocation.
 @end menu
@@ -512,6 +515,34 @@ 
 coverage of all the uses of the inline function will be shown for the
 same source lines, the line counts themselves might seem inconsistent.
+@node Counter Size
+@section Counter Size
+Counters are implemented as a 64-bit value which means that overflow
+would occur only after @math{2^{64}} steps through a program path.
+Overflow usually can be ruled out by ascertaining that coverage
+run time times CPU speed is less than @math{2^{64}}.
+@node Multithreaded Programs
+@section Collecting Coverage Data from Multithreaded Programs
+As the implementation of threads and context switching depends on
+the operational environment, it is hard to implement a truly portable
+coverage for multithreaded programs at the compiler level.  So
+@command{gcov} will not be faithful in multithreaded programs.  If,
+during compilation, the additional option @option{-fprofile-whole-graph}
+is specified, then @command{gcov} will use a representation of
+the whole basic block graph instead of the otherwise optimal
+spanning tree optimization.  That means that the compiled program
+will use more memory but is more robust than when the spanning tree
+optimization is used.  In the absence of counter overflow that
+implies that coverage in multithreaded programs is conservatively
+estimated: it may be underreported but in particular this option
+ensures that a non-zero coverage value means that the path has been
+taken and conversely that if a path has been taken the coverage value
+is non-zero.  (This property still can be useful if one wants test
 @c man end
 @node Gcov Data Files
Index: gcc/opts.c
--- gcc/opts.c	(revision 166453)
+++ gcc/opts.c	(working copy)
@@ -2018,6 +2018,10 @@ 
 	flag_gcse_after_reload = value;
+    case OPT_fprofile_whole_graph:
+      flag_profile_whole_graph = 1;
+      break;
     case OPT_fprofile_generate_:
       profile_data_prefix = xstrdup (arg);
       value = true;
Index: gcc/profile.c
--- gcc/profile.c	(revision 166453)
+++ gcc/profile.c	(working copy)
@@ -1020,7 +1020,8 @@ 
      on the spanning tree.  We insert as many abnormal and critical edges
      as possible to minimize number of edge splits necessary.  */
-  find_spanning_tree (el);
+  if (!flag_profile_whole_graph)
+    find_spanning_tree (el);
   /* Fake edges that are not on the tree will not be instrumented, so
      mark them ignored.  */
Index: gcc/common.opt
--- gcc/common.opt	(revision 166453)
+++ gcc/common.opt	(working copy)
@@ -1299,6 +1299,10 @@ 
 Common Report Var(flag_profile_values)
 Insert code to profile values of expressions
+Common RejectNegative Var(flag_profile_whole_graph,0)
+Whole basic block graph for profiling instead of spanning tree (needs more memory, but better approximation for multithreading)