aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-profile.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2018-10-04 14:41:14 +0200
committerMartin Liska <marxin@gcc.gnu.org>2018-10-04 12:41:14 +0000
commit3edbcdbead288664d874dd3a2e0d8ada4c565af0 (patch)
treee312a412289bc88a481440b075cfa23d7989e321 /gcc/tree-profile.c
parent668f8d452697359a150bd651149c75109f66eb06 (diff)
downloadgcc-3edbcdbead288664d874dd3a2e0d8ada4c565af0.zip
gcc-3edbcdbead288664d874dd3a2e0d8ada4c565af0.tar.gz
gcc-3edbcdbead288664d874dd3a2e0d8ada4c565af0.tar.bz2
Fix divergence in indirect profiling (PR gcov-profile/84107).
2018-10-04 Martin Liska <mliska@suse.cz> PR gcov-profile/84107 * tree-profile.c (init_ic_make_global_vars): Remove ic_void_ptr_var and ic_gcov_type_ptr_var. Come up with new ic_tuple* variables. Emit __gcov_indirect_call{,_topn} variables. (gimple_gen_ic_profiler): Access the variable and emit gimple. (gimple_gen_ic_func_profiler): Access __gcov_indirect_call.callee field. (gimple_init_gcov_profiler): Use ptr_type_node. * value-prof.c (gimple_ic): Use ptr_type_node. 2018-10-04 Martin Liska <mliska@suse.cz> PR gcov-profile/84107 * libgcov-profiler.c (__gcov_indirect_call): Change type to indirect_call_tuple. (struct indirect_call_tuple): New struct. (__gcov_indirect_call_topn_profiler): Change type. (__gcov_indirect_call_profiler_v2): Use the new variables. * libgcov.h (struct indirect_call_tuple): New struct definition. From-SVN: r264840
Diffstat (limited to 'gcc/tree-profile.c')
-rw-r--r--gcc/tree-profile.c84
1 files changed, 46 insertions, 38 deletions
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index f96bd4b..d8f2a3b 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -53,6 +53,8 @@ along with GCC; see the file COPYING3. If not see
#include "stringpool.h"
#include "attribs.h"
#include "tree-pretty-print.h"
+#include "langhooks.h"
+#include "stor-layout.h"
static GTY(()) tree gcov_type_node;
static GTY(()) tree tree_interval_profiler_fn;
@@ -64,9 +66,9 @@ static GTY(()) tree tree_ior_profiler_fn;
static GTY(()) tree tree_time_profiler_counter;
-static GTY(()) tree ic_void_ptr_var;
-static GTY(()) tree ic_gcov_type_ptr_var;
-static GTY(()) tree ptr_void;
+static GTY(()) tree ic_tuple_var;
+static GTY(()) tree ic_tuple_counters_field;
+static GTY(()) tree ic_tuple_callee_field;
/* Do initialization work for the edge profiler. */
@@ -80,39 +82,35 @@ init_ic_make_global_vars (void)
{
tree gcov_type_ptr;
- ptr_void = build_pointer_type (void_type_node);
+ gcov_type_ptr = build_pointer_type (get_gcov_type ());
- ic_void_ptr_var
- = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier (
- (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
- "__gcov_indirect_call_topn_callee" :
- "__gcov_indirect_call_callee")),
- ptr_void);
- TREE_PUBLIC (ic_void_ptr_var) = 1;
- DECL_EXTERNAL (ic_void_ptr_var) = 1;
- TREE_STATIC (ic_void_ptr_var) = 1;
- DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
- DECL_INITIAL (ic_void_ptr_var) = NULL;
- if (targetm.have_tls)
- set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var));
+ tree tuple_type = lang_hooks.types.make_type (RECORD_TYPE);
- gcov_type_ptr = build_pointer_type (get_gcov_type ());
+ /* callee */
+ ic_tuple_callee_field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
+ ptr_type_node);
- ic_gcov_type_ptr_var
+ /* counters */
+ ic_tuple_counters_field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ NULL_TREE, gcov_type_ptr);
+ DECL_CHAIN (ic_tuple_counters_field) = ic_tuple_callee_field;
+
+ finish_builtin_struct (tuple_type, "indirect_call_tuple",
+ ic_tuple_counters_field, NULL_TREE);
+
+ ic_tuple_var
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier (
(PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
- "__gcov_indirect_call_topn_counters" :
- "__gcov_indirect_call_counters")),
- gcov_type_ptr);
- TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
- DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
- TREE_STATIC (ic_gcov_type_ptr_var) = 1;
- DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
- DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
+ "__gcov_indirect_call_topn" :
+ "__gcov_indirect_call")),
+ tuple_type);
+ TREE_PUBLIC (ic_tuple_var) = 1;
+ DECL_ARTIFICIAL (ic_tuple_var) = 1;
+ DECL_INITIAL (ic_tuple_var) = NULL;
+ DECL_EXTERNAL (ic_tuple_var) = 1;
if (targetm.have_tls)
- set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var));
+ set_decl_tls_model (ic_tuple_var, decl_default_tls_model (tuple_type));
}
/* Create the type and function decls for the interface with gcov. */
@@ -185,7 +183,7 @@ gimple_init_gcov_profiler (void)
ic_profiler_fn_type
= build_function_type_list (void_type_node,
gcov_type_node,
- ptr_void,
+ ptr_type_node,
NULL_TREE);
profiler_fn_name = "__gcov_indirect_call_profiler_v2";
if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE))
@@ -388,22 +386,29 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
/* Insert code:
- stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
+ stmt1: __gcov_indirect_call.counters = get_relevant_counter_ptr ();
stmt2: tmp1 = (void *) (indirect call argument value)
- stmt3: __gcov_indirect_call_callee = tmp1;
+ stmt3: __gcov_indirect_call.callee = tmp1;
Example:
f_1 = foo;
- __gcov_indirect_call_counters = &__gcov4.main[0];
+ __gcov_indirect_call.counters = &__gcov4.main[0];
PROF_9 = f_1;
__gcov_indirect_call_callee = PROF_9;
_4 = f_1 ();
*/
- stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
- tmp1 = make_temp_ssa_name (ptr_void, NULL, "PROF");
+ tree gcov_type_ptr = build_pointer_type (get_gcov_type ());
+
+ tree counter_ref = build3 (COMPONENT_REF, gcov_type_ptr,
+ ic_tuple_var, ic_tuple_counters_field, NULL_TREE);
+
+ stmt1 = gimple_build_assign (counter_ref, ref_ptr);
+ tmp1 = make_temp_ssa_name (ptr_type_node, NULL, "PROF");
stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
- stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2));
+ tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
+ ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
+ stmt3 = gimple_build_assign (callee_ref, tmp1);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
@@ -459,9 +464,12 @@ gimple_gen_ic_func_profiler (void)
resetting __gcov_indirect_call_callee to NULL. */
gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
- void0 = build_int_cst (build_pointer_type (void_type_node), 0);
+ void0 = build_int_cst (ptr_type_node, 0);
+
+ tree callee_ref = build3 (COMPONENT_REF, ptr_type_node,
+ ic_tuple_var, ic_tuple_callee_field, NULL_TREE);
- tree ref = force_gimple_operand_gsi (&gsi, ic_void_ptr_var, true, NULL_TREE,
+ tree ref = force_gimple_operand_gsi (&gsi, callee_ref, true, NULL_TREE,
true, GSI_SAME_STMT);
gcond *cond = gimple_build_cond (NE_EXPR, ref,