aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2023-11-14 21:36:51 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2023-11-18 12:45:15 +0100
commit20a3c74c347429c109bc7002285b735be83f6a0b (patch)
tree73ccca0643ffc4957012fb20838ded2a9516eb7c /libgcc
parenta350a74d6113e3a84943266eb691275951c109d9 (diff)
downloadgcc-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.h10
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