diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c | 41 | ||||
-rw-r--r-- | gcc/tree-profile.c | 42 |
4 files changed, 77 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cdf8b77..7dbe486 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2016-08-10 Martin Liska <mliska@suse.cz> + PR gcov-profile/58306 + * tree-profile.c (gimple_init_edge_profiler): Create conditionally + atomic variants of profile update functions. + +2016-08-10 Martin Liska <mliska@suse.cz> + Cherry picked (and modified) from google-4_7 branch 2012-12-26 Rong Xu <xur@google.com> * common.opt (fprofile-update): Add new flag. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 20bd72a..c9f58fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2016-08-10 Martin Liska <mliska@suse.cz> + PR gcov-profile/58306 + * gcc.dg/tree-prof/val-profiler-threads-1.c: New test. + +2016-08-10 Martin Liska <mliska@suse.cz> + * g++.dg/gcov/gcov-threads-1.C: New test. 2016-08-10 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c new file mode 100644 index 0000000..e9b04a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c @@ -0,0 +1,41 @@ +/* { dg-options "-O0 -pthread -fprofile-update=atomic" } */ +#include <pthread.h> + +#define NUM_THREADS 8 +#define SIZE 1024 +#define ITERATIONS (1000 * 1000) + +char buffer[SIZE]; +char buffer2[SIZE]; + +void *copy_memory(char *dst, char *src, unsigned size) +{ + for (unsigned i = 0; i < ITERATIONS; i++) + { + dst[size % 10] = src[size % 20]; + } +} + +void *foo(void *d) +{ + copy_memory (buffer, buffer2, SIZE); +} + +int main(int argc, char *argv[]) +{ + pthread_t threads[NUM_THREADS]; + int rc; + long t; + for(t=0;t<NUM_THREADS;t++){ + rc = pthread_create(&threads[t], NULL, foo, 0); + if (rc){ + return 1; + } + } + + int retval; + for(t=0;t<NUM_THREADS;t++) + pthread_join (threads[t], (void**)&retval); + + return buffer[10]; +} diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 740f7ab..fdf0201 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -128,9 +128,13 @@ gimple_init_edge_profiler (void) tree average_profiler_fn_type; tree time_profiler_fn_type; const char *profiler_fn_name; + const char *fn_name; if (!gcov_type_node) { + const char *fn_suffix + = flag_profile_update == PROFILE_UPDATE_ATOMIC ? "_atomic" : ""; + gcov_type_node = get_gcov_type (); gcov_type_ptr = build_pointer_type (gcov_type_node); @@ -140,9 +144,10 @@ gimple_init_edge_profiler (void) gcov_type_ptr, gcov_type_node, integer_type_node, unsigned_type_node, NULL_TREE); - tree_interval_profiler_fn - = build_fn_decl ("__gcov_interval_profiler", - interval_profiler_fn_type); + fn_name = concat ("__gcov_interval_profiler", fn_suffix, NULL); + tree_interval_profiler_fn = build_fn_decl (fn_name, + interval_profiler_fn_type); + free (CONST_CAST (char *, fn_name)); TREE_NOTHROW (tree_interval_profiler_fn) = 1; DECL_ATTRIBUTES (tree_interval_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, @@ -153,8 +158,9 @@ gimple_init_edge_profiler (void) = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, NULL_TREE); - tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler", - pow2_profiler_fn_type); + fn_name = concat ("__gcov_pow2_profiler", fn_suffix, NULL); + tree_pow2_profiler_fn = build_fn_decl (fn_name, pow2_profiler_fn_type); + free (CONST_CAST (char *, fn_name)); TREE_NOTHROW (tree_pow2_profiler_fn) = 1; DECL_ATTRIBUTES (tree_pow2_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, @@ -165,9 +171,10 @@ gimple_init_edge_profiler (void) = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, NULL_TREE); - tree_one_value_profiler_fn - = build_fn_decl ("__gcov_one_value_profiler", - one_value_profiler_fn_type); + fn_name = concat ("__gcov_one_value_profiler", fn_suffix, NULL); + tree_one_value_profiler_fn = build_fn_decl (fn_name, + one_value_profiler_fn_type); + free (CONST_CAST (char *, fn_name)); TREE_NOTHROW (tree_one_value_profiler_fn) = 1; DECL_ATTRIBUTES (tree_one_value_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, @@ -197,9 +204,9 @@ gimple_init_edge_profiler (void) time_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, NULL_TREE); - tree_time_profiler_fn - = build_fn_decl ("__gcov_time_profiler", - time_profiler_fn_type); + fn_name = concat ("__gcov_time_profiler", fn_suffix, NULL); + tree_time_profiler_fn = build_fn_decl (fn_name, time_profiler_fn_type); + free (CONST_CAST (char *, fn_name)); TREE_NOTHROW (tree_time_profiler_fn) = 1; DECL_ATTRIBUTES (tree_time_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, @@ -209,16 +216,17 @@ gimple_init_edge_profiler (void) average_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, NULL_TREE); - tree_average_profiler_fn - = build_fn_decl ("__gcov_average_profiler", - average_profiler_fn_type); + fn_name = concat ("__gcov_average_profiler", fn_suffix, NULL); + tree_average_profiler_fn = build_fn_decl (fn_name, + average_profiler_fn_type); + free (CONST_CAST (char *, fn_name)); TREE_NOTHROW (tree_average_profiler_fn) = 1; DECL_ATTRIBUTES (tree_average_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_average_profiler_fn)); - tree_ior_profiler_fn - = build_fn_decl ("__gcov_ior_profiler", - average_profiler_fn_type); + fn_name = concat ("__gcov_ior_profiler", fn_suffix, NULL); + tree_ior_profiler_fn = build_fn_decl (fn_name, average_profiler_fn_type); + free (CONST_CAST (char *, fn_name)); TREE_NOTHROW (tree_ior_profiler_fn) = 1; DECL_ATTRIBUTES (tree_ior_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, |