gcc: Gcov and Optimization

1 
1 10.3 Using 'gcov' with GCC Optimization
1 =======================================
1 
1 If you plan to use 'gcov' to help optimize your code, you must first
1 compile your program with two special GCC options: '-fprofile-arcs
1 -ftest-coverage'.  Aside from that, you can use any other GCC options;
1 but if you want to prove that every single line in your program was
1 executed, you should not compile with optimization at the same time.  On
1 some machines the optimizer can eliminate some simple code lines by
1 combining them with other lines.  For example, code like this:
1 
1      if (a != b)
1        c = 1;
1      else
1        c = 0;
1 
1 can be compiled into one instruction on some machines.  In this case,
1 there is no way for 'gcov' to calculate separate execution counts for
1 each line because there isn't separate code for each line.  Hence the
1 'gcov' output looks like this if you compiled the program with
1 optimization:
1 
1            100:   12:if (a != b)
1            100:   13:  c = 1;
1            100:   14:else
1            100:   15:  c = 0;
1 
1  The output shows that this block of code, combined by optimization,
1 executed 100 times.  In one sense this result is correct, because there
1 was only one instruction representing all four of these lines.  However,
1 the output does not indicate how many times the result was 0 and how
1 many times the result was 1.
1 
1  Inlineable functions can create unexpected line counts.  Line counts
1 are shown for the source code of the inlineable function, but what is
1 shown depends on where the function is inlined, or if it is not inlined
1 at all.
1 
1  If the function is not inlined, the compiler must emit an out of line
1 copy of the function, in any object file that needs it.  If 'fileA.o'
1 and 'fileB.o' both contain out of line bodies of a particular inlineable
1 function, they will also both contain coverage counts for that function.
1 When 'fileA.o' and 'fileB.o' are linked together, the linker will, on
1 many systems, select one of those out of line bodies for all calls to
1 that function, and remove or ignore the other.  Unfortunately, it will
1 not remove the coverage counters for the unused function body.  Hence
1 when instrumented, all but one use of that function will show zero
1 counts.
1 
1  If the function is inlined in several places, the block structure in
1 each location might not be the same.  For instance, a condition might
1 now be calculable at compile time in some instances.  Because the
1 coverage of all the uses of the inline function will be shown for the
1 same source lines, the line counts themselves might seem inconsistent.
1 
1  Long-running applications can use the '__gcov_reset' and '__gcov_dump'
1 facilities to restrict profile collection to the program region of
1 interest.  Calling '__gcov_reset(void)' will clear all profile counters
1 to zero, and calling '__gcov_dump(void)' will cause the profile
1 information collected at that point to be dumped to '.gcda' output
1 files.  Instrumented applications use a static destructor with priority
1 99 to invoke the '__gcov_dump' function.  Thus '__gcov_dump' is executed
1 after all user defined static destructors, as well as handlers
1 registered with 'atexit'.  If an executable loads a dynamic shared
1 object via dlopen functionality, '-Wl,--dynamic-list-data' is needed to
1 dump all profile data.
1