Detect whether target can use -fprofile-update=atomic
authorMartin Liska <mliska@suse.cz>
Tue, 6 Sep 2016 14:13:21 +0000 (16:13 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 6 Sep 2016 14:13:21 +0000 (14:13 +0000)
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.
PR gcov-profile/77378
PR gcov-profile/77466
* tree-profile.c (tree_profiling): Detect whether target can use
-fprofile-update=atomic.
PR gcov-profile/77378
PR gcov-profile/77466
* gcc.dg/profile-update-warning.c: New test.

From-SVN: r240008

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/profile-update-warning.c [new file with mode: 0644]
gcc/tree-profile.c
libgcc/ChangeLog
libgcc/libgcov-profiler.c

index 87910e442016a7a2af47fc18f8c1008aa3c29943..e23891e51552fc76dd374f597fe5eb4d5c1ffe9e 100644 (file)
@@ -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
index 9fcda6e77a08f127328490552873886c738f721c..80905adf31473fa47d4df18189e4622efd91bb0f 100644 (file)
@@ -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 (file)
index 0000000..0614fad
--- /dev/null
@@ -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" } */
index 622869ebb27f00f881be60ec57fd9fb56898f8f4..69b48e59be412a98c33699621432915b12b4c190 100644 (file)
@@ -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);
index d5ecf7776a79eee3c3bfdc6edaaafe445cf31eb4..8ad8ef5802db740f2a712995c392d537c11b7cc6 100644 (file)
@@ -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
index 70a821dc6257eb98e4aa89df0a9bbd5c4d4241c4..d9217b9885b0854343df6a6baccac340df964e2d 100644 (file)
@@ -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