diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-14 21:36:51 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-18 12:45:15 +0100 |
commit | 20a3c74c347429c109bc7002285b735be83f6a0b (patch) | |
tree | 73ccca0643ffc4957012fb20838ded2a9516eb7c /libgcc | |
parent | a350a74d6113e3a84943266eb691275951c109d9 (diff) | |
download | gcc-20a3c74c347429c109bc7002285b735be83f6a0b.zip gcc-20a3c74c347429c109bc7002285b735be83f6a0b.tar.gz gcc-20a3c74c347429c109bc7002285b735be83f6a0b.tar.bz2 |
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.
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/libgcov.h | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index 763118e..d04c070 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -95,18 +95,14 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI))); #define GCOV_LOCKED_WITH_LOCKING 0 #endif -#ifndef GCOV_SUPPORTS_ATOMIC /* Detect whether target can support atomic update of profilers. */ -#if __SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 -#define GCOV_SUPPORTS_ATOMIC 1 -#else -#if __SIZEOF_LONG_LONG__ == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 +#if (__SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || \ + (__SIZEOF_LONG_LONG__ == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || \ + defined (__LIBGCC_HAVE_LIBATOMIC) #define GCOV_SUPPORTS_ATOMIC 1 #else #define GCOV_SUPPORTS_ATOMIC 0 #endif -#endif -#endif /* In libgcov we need these functions to be extern, so prefix them with __gcov. In libgcov they must also be hidden so that the instance in |