summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/profile-update-warning.c7
-rw-r--r--gcc/tree-profile.c35
-rw-r--r--libgcc/ChangeLog7
-rw-r--r--libgcc/libgcov-profiler.c23
6 files changed, 80 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 87910e44201..e23891e5155 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-09-06 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/77378
+ PR gcov-profile/77466
+ * tree-profile.c (tree_profiling): Detect whether target can use
+ -fprofile-update=atomic.
+
2016-09-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77479
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9fcda6e77a0..80905adf314 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-06 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/77378
+ PR gcov-profile/77466
+ * gcc.dg/profile-update-warning.c: New test.
+
2016-09-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77479
diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c b/gcc/testsuite/gcc.dg/profile-update-warning.c
new file mode 100644
index 00000000000..0614fad960f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 -m32" } */
+
+int main(int argc, char *argv[])
+{
+ return 0;
+} /* { dg-warning "target does not support atomic profile update, single mode is selected" } */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 622869ebb27..69b48e59be4 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -528,6 +528,20 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
}
+#ifndef HAVE_sync_compare_and_swapsi
+#define HAVE_sync_compare_and_swapsi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapsi
+#define HAVE_atomic_compare_and_swapsi 0
+#endif
+
+#ifndef HAVE_sync_compare_and_swapdi
+#define HAVE_sync_compare_and_swapdi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapdi
+#define HAVE_atomic_compare_and_swapdi 0
+#endif
+
/* Profile all functions in the callgraph. */
static unsigned int
@@ -535,6 +549,27 @@ tree_profiling (void)
{
struct cgraph_node *node;
+ /* Verify whether we can utilize atomic update operations. */
+ if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
+ {
+ bool can_support = false;
+ unsigned HOST_WIDE_INT gcov_type_size
+ = tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
+ if (gcov_type_size == 4)
+ can_support
+ = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
+ else if (gcov_type_size == 8)
+ can_support
+ = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
+
+ if (!can_support)
+ {
+ warning (0, "target does not support atomic profile update, "
+ "single mode is selected");
+ flag_profile_update = PROFILE_UPDATE_SINGLE;
+ }
+ }
+
/* This is a small-ipa pass that gets called only once, from
cgraphunit.c:ipa_passes(). */
gcc_assert (symtab->state == IPA_SSA);
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index d5ecf7776a7..8ad8ef5802d 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-09-06 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/77378
+ PR gcov-profile/77466
+ * libgcov-profiler.c: Use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{4,8} to
+ conditionaly enable/disable *_atomic functions.
+
2016-08-26 Joseph Myers <joseph@codesourcery.com>
* config.host (i[34567]86-*-* | x86_64-*-*): Enable TFmode soft-fp
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 70a821dc625..d9217b9885b 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -26,6 +26,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h"
#if !defined(inhibit_libc)
+/* 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
+#define GCOV_SUPPORTS_ATOMIC 1
+#else
+#define GCOV_SUPPORTS_ATOMIC 0
+#endif
+#endif
+
#ifdef L_gcov_interval_profiler
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
@@ -46,7 +57,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value,
}
#endif
-#ifdef L_gcov_interval_profiler_atomic
+#if defined(L_gcov_interval_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
@@ -80,7 +91,7 @@ __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#ifdef L_gcov_pow2_profiler_atomic
+#if defined(L_gcov_pow2_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
COUNTERS[0] is incremented. Function is thread-safe. */
@@ -134,7 +145,7 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#ifdef L_gcov_one_value_profiler_atomic
+#if defined(L_gcov_one_value_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
/* Update one value profilers (COUNTERS) for a given VALUE.
@@ -342,6 +353,7 @@ __gcov_time_profiler (gcov_type* counters)
counters[0] = ++function_counter;
}
+#if GCOV_SUPPORTS_ATOMIC
/* Sets corresponding COUNTERS if there is no value.
Function is thread-safe. */
@@ -352,6 +364,7 @@ __gcov_time_profiler_atomic (gcov_type* counters)
counters[0] = __atomic_add_fetch (&function_counter, 1, MEMMODEL_RELAXED);
}
#endif
+#endif
#ifdef L_gcov_average_profiler
@@ -366,7 +379,7 @@ __gcov_average_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#ifdef L_gcov_average_profiler_atomic
+#if defined(L_gcov_average_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
to saturate up. Function is thread-safe. */
@@ -388,7 +401,7 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#ifdef L_gcov_ior_profiler_atomic
+#if defined(L_gcov_ior_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
/* Bitwise-OR VALUE into COUNTER. Function is thread-safe. */
void