mirror of git://gcc.gnu.org/git/gcc.git
Cherry-pick fprofile-generate-atomic from google/gcc-4_9
Cherry picked (and modified) from google-4_7 branch 2012-12-26 Rong Xu <xur@google.com> * common.opt (fprofile-update): Add new flag. * coretypes.h: Define enum profile_update. * doc/invoke.texi: Document -fprofile-update. * gcov-io.h: Declare GCOV_TYPE_ATOMIC_FETCH_ADD and GCOV_TYPE_ATOMIC_FETCH_ADD_FN. * tree-profile.c (gimple_init_edge_profiler): Generate also atomic profiler update. (gimple_gen_edge_profiler): Likewise. * g++.dg/gcov/gcov-threads-1.C: New test. From-SVN: r239323
This commit is contained in:
parent
5a39e998c8
commit
22063dbc90
|
|
@ -1,3 +1,16 @@
|
|||
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.
|
||||
* coretypes.h: Define enum profile_update.
|
||||
* doc/invoke.texi: Document -fprofile-update.
|
||||
* gcov-io.h: Declare GCOV_TYPE_ATOMIC_FETCH_ADD and
|
||||
GCOV_TYPE_ATOMIC_FETCH_ADD_FN.
|
||||
* tree-profile.c (gimple_init_edge_profiler): Generate
|
||||
also atomic profiler update.
|
||||
(gimple_gen_edge_profiler): Likewise.
|
||||
|
||||
2016-08-10 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* toplev.c (finalize): Set aux_info_file, asm_out_file, and
|
||||
|
|
|
|||
|
|
@ -1916,6 +1916,19 @@ fprofile-correction
|
|||
Common Report Var(flag_profile_correction)
|
||||
Enable correction of flow inconsistent profile data input.
|
||||
|
||||
fprofile-update=
|
||||
Common Joined RejectNegative Enum(profile_update) Var(flag_profile_update) Init(PROFILE_UPDATE_SINGLE)
|
||||
-fprofile-update=[single|atomic] Set the profile update method.
|
||||
|
||||
Enum
|
||||
Name(profile_update) Type(enum profile_update) UnknownError(unknown profile update method %qs)
|
||||
|
||||
EnumValue
|
||||
Enum(profile_update) String(single) Value(PROFILE_UPDATE_SINGLE)
|
||||
|
||||
EnumValue
|
||||
Enum(profile_update) String(atomic) Value(PROFILE_UPDATE_ATOMIC)
|
||||
|
||||
fprofile-generate
|
||||
Common
|
||||
Enable common options for generating profile info for profile feedback directed optimizations.
|
||||
|
|
|
|||
|
|
@ -174,6 +174,12 @@ enum offload_abi {
|
|||
OFFLOAD_ABI_ILP32
|
||||
};
|
||||
|
||||
/* Types of profile update methods. */
|
||||
enum profile_update {
|
||||
PROFILE_UPDATE_SINGLE,
|
||||
PROFILE_UPDATE_ATOMIC
|
||||
};
|
||||
|
||||
/* Types of unwind/exception handling info that can be generated. */
|
||||
|
||||
enum unwind_info_type
|
||||
|
|
|
|||
|
|
@ -9933,6 +9933,18 @@ the profile feedback data files. See @option{-fprofile-dir}.
|
|||
To optimize the program based on the collected profile information, use
|
||||
@option{-fprofile-use}. @xref{Optimize Options}, for more information.
|
||||
|
||||
@item -fprofile-update=@var{method}
|
||||
@opindex fprofile-update
|
||||
|
||||
Alter the update method for an application instrumented for profile
|
||||
feedback based optimization. The @var{method} argument should be one of
|
||||
@samp{single} or @samp{atomic}. The first one is useful for single-threaded
|
||||
applications, while the second one prevents profile corruption by emitting
|
||||
thread-safe code.
|
||||
|
||||
@strong{Warning:} When an application does not properly join all threads
|
||||
(or creates an detached thread), a profile file can be still corrupted.
|
||||
|
||||
@item -fsanitize=address
|
||||
@opindex fsanitize=address
|
||||
Enable AddressSanitizer, a fast memory error detector.
|
||||
|
|
|
|||
|
|
@ -164,6 +164,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
#ifndef GCC_GCOV_IO_H
|
||||
#define GCC_GCOV_IO_H
|
||||
|
||||
#if LONG_LONG_TYPE_SIZE > 32
|
||||
#define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_8
|
||||
#define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_8
|
||||
#else
|
||||
#define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_4
|
||||
#define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_4
|
||||
#endif
|
||||
|
||||
#ifndef IN_LIBGCOV
|
||||
/* About the host */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
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>
|
||||
|
||||
PR target/71873
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/* { dg-options "-fprofile-arcs -ftest-coverage -pthread -fprofile-update=atomic" } */
|
||||
/* { dg-do run { target native } } */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define NR 5
|
||||
|
||||
pthread_mutex_t cndMs[NR];
|
||||
static void *ContentionNoDeadlock_thread(void *start)
|
||||
{
|
||||
for (uint32_t k = 0; k < 100000; ++k) /* count(500005) */
|
||||
{
|
||||
int starti = *(int*)start; /* count(500000) */
|
||||
for (uint32_t i = starti; i < NR; ++i)
|
||||
pthread_mutex_lock (&cndMs[i]);
|
||||
for (int32_t i = NR - 1; i >= starti; --i)
|
||||
pthread_mutex_unlock (&cndMs[i]);
|
||||
}
|
||||
}
|
||||
int main(int argc, char **argv) {
|
||||
for (unsigned i = 0; i < NR; i++)
|
||||
cndMs[i] = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
pthread_t t[NR];
|
||||
int ids[NR];
|
||||
|
||||
for (int i = 0; i < NR; i++)
|
||||
{
|
||||
ids[i] = i;
|
||||
int r = pthread_create (&t[i], NULL, ContentionNoDeadlock_thread, &ids[i]);
|
||||
assert (r == 0); /* count(5) */
|
||||
}
|
||||
|
||||
int ret;
|
||||
for (int i = 0; i < NR; i++)
|
||||
{
|
||||
int r = pthread_join (t[i], (void**)&ret);
|
||||
assert (r == 0); /* count(5) */
|
||||
}
|
||||
|
||||
return 0; /* count(1) */
|
||||
}
|
||||
|
||||
/* { dg-final { run-gcov gcov-threads-1.C } } */
|
||||
|
|
@ -127,6 +127,7 @@ gimple_init_edge_profiler (void)
|
|||
tree ic_profiler_fn_type;
|
||||
tree average_profiler_fn_type;
|
||||
tree time_profiler_fn_type;
|
||||
const char *profiler_fn_name;
|
||||
|
||||
if (!gcov_type_node)
|
||||
{
|
||||
|
|
@ -180,11 +181,12 @@ gimple_init_edge_profiler (void)
|
|||
gcov_type_node,
|
||||
ptr_void,
|
||||
NULL_TREE);
|
||||
profiler_fn_name = "__gcov_indirect_call_profiler_v2";
|
||||
if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE))
|
||||
profiler_fn_name = "__gcov_indirect_call_topn_profiler";
|
||||
|
||||
tree_indirect_call_profiler_fn
|
||||
= build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
|
||||
"__gcov_indirect_call_topn_profiler":
|
||||
"__gcov_indirect_call_profiler_v2"),
|
||||
ic_profiler_fn_type);
|
||||
= build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
|
||||
|
||||
TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
|
||||
DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
|
||||
|
|
@ -241,23 +243,38 @@ gimple_init_edge_profiler (void)
|
|||
void
|
||||
gimple_gen_edge_profiler (int edgeno, edge e)
|
||||
{
|
||||
tree ref, one, gcov_type_tmp_var;
|
||||
gassign *stmt1, *stmt2, *stmt3;
|
||||
tree one;
|
||||
|
||||
ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
|
||||
one = build_int_cst (gcov_type_node, 1);
|
||||
|
||||
if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
|
||||
{
|
||||
/* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
|
||||
tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
|
||||
gcall *stmt
|
||||
= gimple_build_call (builtin_decl_explicit (GCOV_TYPE_ATOMIC_FETCH_ADD),
|
||||
3, addr, one,
|
||||
build_int_cst (integer_type_node,
|
||||
MEMMODEL_RELAXED));
|
||||
gsi_insert_on_edge (e, stmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
|
||||
tree gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
|
||||
NULL, "PROF_edge_counter");
|
||||
gassign *stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
|
||||
gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
|
||||
NULL, "PROF_edge_counter");
|
||||
stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
|
||||
gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node,
|
||||
NULL, "PROF_edge_counter");
|
||||
stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
|
||||
gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR,
|
||||
gimple_assign_lhs (stmt1), one);
|
||||
stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2));
|
||||
gassign *stmt3 = gimple_build_assign (unshare_expr (ref),
|
||||
gimple_assign_lhs (stmt2));
|
||||
gsi_insert_on_edge (e, stmt1);
|
||||
gsi_insert_on_edge (e, stmt2);
|
||||
gsi_insert_on_edge (e, stmt3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Emits code to get VALUE to instrument at GSI, and returns the
|
||||
variable containing the value. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue