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
This commit is contained in:
Martin Liska 2016-09-06 16:13:21 +02:00 committed by Martin Liska
parent 209b636edd
commit 7fe76f6ae8
6 changed files with 80 additions and 5 deletions

View 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

View 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

View file

@ -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" } */

View 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);

View 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

View 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