Commit 7fe76f6a by Martin Liska Committed by Martin Liska

Detect whether target can use -fprofile-update=atomic

	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
parent 209b636e
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> 2016-09-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77479 PR tree-optimization/77479
......
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> 2016-09-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77479 PR tree-optimization/77479
......
/* { 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" } */
...@@ -528,6 +528,20 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) ...@@ -528,6 +528,20 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
gsi_insert_before (&gsi, call, GSI_NEW_STMT); 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. */ /* Profile all functions in the callgraph. */
static unsigned int static unsigned int
...@@ -535,6 +549,27 @@ tree_profiling (void) ...@@ -535,6 +549,27 @@ tree_profiling (void)
{ {
struct cgraph_node *node; 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 /* This is a small-ipa pass that gets called only once, from
cgraphunit.c:ipa_passes(). */ cgraphunit.c:ipa_passes(). */
gcc_assert (symtab->state == IPA_SSA); gcc_assert (symtab->state == IPA_SSA);
......
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> 2016-08-26 Joseph Myers <joseph@codesourcery.com>
* config.host (i[34567]86-*-* | x86_64-*-*): Enable TFmode soft-fp * config.host (i[34567]86-*-* | x86_64-*-*): Enable TFmode soft-fp
......
...@@ -26,6 +26,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -26,6 +26,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h" #include "libgcov.h"
#if !defined(inhibit_libc) #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 #ifdef L_gcov_interval_profiler
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below corresponding counter in COUNTERS. If the VALUE is above or below
...@@ -46,7 +57,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value, ...@@ -46,7 +57,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value,
} }
#endif #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 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below corresponding counter in COUNTERS. If the VALUE is above or below
the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
...@@ -80,7 +91,7 @@ __gcov_pow2_profiler (gcov_type *counters, gcov_type value) ...@@ -80,7 +91,7 @@ __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
} }
#endif #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 /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
COUNTERS[0] is incremented. Function is thread-safe. */ COUNTERS[0] is incremented. Function is thread-safe. */
...@@ -134,7 +145,7 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value) ...@@ -134,7 +145,7 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
} }
#endif #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. /* Update one value profilers (COUNTERS) for a given VALUE.
...@@ -342,6 +353,7 @@ __gcov_time_profiler (gcov_type* counters) ...@@ -342,6 +353,7 @@ __gcov_time_profiler (gcov_type* counters)
counters[0] = ++function_counter; counters[0] = ++function_counter;
} }
#if GCOV_SUPPORTS_ATOMIC
/* Sets corresponding COUNTERS if there is no value. /* Sets corresponding COUNTERS if there is no value.
Function is thread-safe. */ Function is thread-safe. */
...@@ -352,6 +364,7 @@ __gcov_time_profiler_atomic (gcov_type* counters) ...@@ -352,6 +364,7 @@ __gcov_time_profiler_atomic (gcov_type* counters)
counters[0] = __atomic_add_fetch (&function_counter, 1, MEMMODEL_RELAXED); counters[0] = __atomic_add_fetch (&function_counter, 1, MEMMODEL_RELAXED);
} }
#endif #endif
#endif
#ifdef L_gcov_average_profiler #ifdef L_gcov_average_profiler
...@@ -366,7 +379,7 @@ __gcov_average_profiler (gcov_type *counters, gcov_type value) ...@@ -366,7 +379,7 @@ __gcov_average_profiler (gcov_type *counters, gcov_type value)
} }
#endif #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 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
to saturate up. Function is thread-safe. */ to saturate up. Function is thread-safe. */
...@@ -388,7 +401,7 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value) ...@@ -388,7 +401,7 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value)
} }
#endif #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. */ /* Bitwise-OR VALUE into COUNTER. Function is thread-safe. */
void void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment