Skip to content
Snippets Groups Projects
Commit 20a3c74c authored by Sebastian Huber's avatar Sebastian Huber
Browse files

gcov: Improve -fprofile-update=atomic

The code coverage support uses counters to determine which edges in the control
flow graph were executed.  If a counter overflows, then the code coverage
information is invalid.  Therefore the counter type should be a 64-bit integer.
In multi-threaded applications, it is important that the counter increments are
atomic.  This is not the case by default.  The user can enable atomic counter
increments through the -fprofile-update=atomic and
-fprofile-update=prefer-atomic options.

If the target supports 64-bit atomic operations, then everything is fine.  If
not and -fprofile-update=prefer-atomic was chosen by the user, then non-atomic
counter increments will be used.  However, if the target does not support the
required atomic operations and -fprofile-atomic=update was chosen by the user,
then a warning was issued and as a forced fallback to non-atomic operations was
done.  This is probably not what a user wants.  There is still hardware on the
market which does not have atomic operations and is used for multi-threaded
applications.  A user which selects -fprofile-update=atomic wants consistent
code coverage data and not random data.

This patch removes the fallback to non-atomic operations for
-fprofile-update=atomic the target platform supports libatomic.  To
mitigate potential performance issues an optimization for systems which
only support 32-bit atomic operations is provided.  Here, the edge
counter increments are done like this:

  low = __atomic_add_fetch_4 (&counter.low, 1, MEMMODEL_RELAXED);
  high_inc = low == 0 ? 1 : 0;
  __atomic_add_fetch_4 (&counter.high, high_inc, MEMMODEL_RELAXED);

In gimple_gen_time_profiler() this split operation cannot be used, since the
updated counter value is also required.  Here, a library call is emitted.  This
is not a performance issue since the update is only done if counters[0] == 0.

gcc/c-family/ChangeLog:

	* c-cppbuiltin.cc (c_cpp_builtins):  Define
	__LIBGCC_HAVE_LIBATOMIC for libgcov.

gcc/ChangeLog:

	* doc/invoke.texi (-fprofile-update): Clarify default method.  Document
	the atomic method behaviour.
	* tree-profile.cc (enum counter_update_method): New.
	(counter_update): Likewise.
	(gen_counter_update): Use counter_update_method.  Split the
	atomic counter update in two 32-bit atomic operations if
	necessary.
	(tree_profiling): Select counter_update_method.

libgcc/ChangeLog:

	* libgcov.h (GCOV_SUPPORTS_ATOMIC): Always define it.
	Set it also to 1, if __LIBGCC_HAVE_LIBATOMIC is defined.
parent a350a74d
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment