aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-profile.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2016-08-10 15:11:42 +0200
committerMartin Liska <marxin@gcc.gnu.org>2016-08-10 13:11:42 +0000
commit22063dbc90d0eb8a7cc7939e0941899f90b403db (patch)
treebca16f60942cfafd651fca3cbf08a464365e76b9 /gcc/tree-profile.c
parent5a39e998c8a89b26a74b9fb0b5bc17fa8b55d274 (diff)
downloadgcc-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.c53
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