diff options
author | Martin Liska <mliska@suse.cz> | 2016-08-10 15:11:42 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2016-08-10 13:11:42 +0000 |
commit | 22063dbc90d0eb8a7cc7939e0941899f90b403db (patch) | |
tree | bca16f60942cfafd651fca3cbf08a464365e76b9 /gcc/tree-profile.c | |
parent | 5a39e998c8a89b26a74b9fb0b5bc17fa8b55d274 (diff) | |
download | gcc-22063dbc90d0eb8a7cc7939e0941899f90b403db.zip gcc-22063dbc90d0eb8a7cc7939e0941899f90b403db.tar.gz gcc-22063dbc90d0eb8a7cc7939e0941899f90b403db.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-profile.c')
-rw-r--r-- | gcc/tree-profile.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 39fe15f..740f7ab 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.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,22 +243,37 @@ 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); - 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, - gimple_assign_lhs (stmt1), one); - 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); + + 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"); + gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR, + gimple_assign_lhs (stmt1), one); + 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 |