Commit 4f751c54 by Martin Liska Committed by Martin Liska

Speed-up indirect-call instrumentation

2017-06-09  Martin Liska  <mliska@suse.cz>

	* tree-profile.c (gimple_gen_ic_profiler): Update comment.
	(gimple_gen_ic_func_profiler): Emit direct comparison
	of __gcov_indirect_call_callee with NULL.
	(gimple_gen_time_profiler): Change probability from
	PROB_VERY_UNLIKELY to PROB_UNLIKELY.
2017-06-09  Martin Liska  <mliska@suse.cz>

	* libgcov-profiler.c (__gcov_indirect_call_profiler_v2):
	Reset __gcov_indirect_call_callee to NULL.

From-SVN: r249058
parent f05d82a7
2017-06-09 Martin Liska <mliska@suse.cz>
* tree-profile.c (gimple_gen_ic_profiler): Update comment.
(gimple_gen_ic_func_profiler): Emit direct comparison
of __gcov_indirect_call_callee with NULL.
(gimple_gen_time_profiler): Change probability from
PROB_VERY_UNLIKELY to PROB_UNLIKELY.
2017-06-09 Jan Hubicka <hubicka@ucw.cz> 2017-06-09 Jan Hubicka <hubicka@ucw.cz>
* profile.c (edge_gcov_counts): Turn to pointer. * profile.c (edge_gcov_counts): Turn to pointer.
......
...@@ -388,6 +388,13 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) ...@@ -388,6 +388,13 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
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) 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];
PROF_9 = f_1;
__gcov_indirect_call_callee = PROF_9;
_4 = f_1 ();
*/ */
stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
...@@ -410,9 +417,7 @@ void ...@@ -410,9 +417,7 @@ void
gimple_gen_ic_func_profiler (void) gimple_gen_ic_func_profiler (void)
{ {
struct cgraph_node * c_node = cgraph_node::get (current_function_decl); struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
gimple_stmt_iterator gsi;
gcall *stmt1; gcall *stmt1;
gassign *stmt2;
tree tree_uid, cur_func, void0; tree tree_uid, cur_func, void0;
if (c_node->only_called_directly_p ()) if (c_node->only_called_directly_p ())
...@@ -420,13 +425,43 @@ gimple_gen_ic_func_profiler (void) ...@@ -420,13 +425,43 @@ gimple_gen_ic_func_profiler (void)
gimple_init_gcov_profiler (); gimple_init_gcov_profiler ();
basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
basic_block cond_bb = split_edge (single_succ_edge (entry));
basic_block update_bb = split_edge (single_succ_edge (cond_bb));
edge true_edge = single_succ_edge (cond_bb);
true_edge->flags = EDGE_TRUE_VALUE;
int probability;
if (DECL_VIRTUAL_P (current_function_decl))
probability = PROB_VERY_LIKELY;
else
probability = PROB_UNLIKELY;
true_edge->probability = probability;
edge e = make_edge (cond_bb, single_succ_edge (update_bb)->dest,
EDGE_FALSE_VALUE);
e->probability = REG_BR_PROB_BASE - true_edge->probability;
/* Insert code: /* Insert code:
stmt1: __gcov_indirect_call_profiler_v2 (profile_id, if (__gcov_indirect_call_callee != NULL)
&current_function_decl) __gcov_indirect_call_profiler_v2 (profile_id, &current_function_decl);
*/
gsi = gsi_after_labels (split_edge (single_succ_edge The function __gcov_indirect_call_profiler_v2 is responsible for
(ENTRY_BLOCK_PTR_FOR_FN (cfun)))); 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);
tree ref = force_gimple_operand_gsi (&gsi, ic_void_ptr_var, true, NULL_TREE,
true, GSI_SAME_STMT);
gcond *cond = gimple_build_cond (NE_EXPR, ref,
void0, NULL, NULL);
gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
gsi = gsi_after_labels (update_bb);
cur_func = force_gimple_operand_gsi (&gsi, cur_func = force_gimple_operand_gsi (&gsi,
build_addr (current_function_decl), build_addr (current_function_decl),
...@@ -438,13 +473,6 @@ gimple_gen_ic_func_profiler (void) ...@@ -438,13 +473,6 @@ gimple_gen_ic_func_profiler (void)
stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2, stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
tree_uid, cur_func); tree_uid, cur_func);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
/* Set __gcov_indirect_call_callee to 0,
so that calls from other modules won't get misattributed
to the last caller of the current callee. */
void0 = build_int_cst (build_pointer_type (void_type_node), 0);
stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
} }
/* Output instructions as GIMPLE tree at the beginning for each function. /* Output instructions as GIMPLE tree at the beginning for each function.
...@@ -458,11 +486,10 @@ gimple_gen_time_profiler (unsigned tag, unsigned base) ...@@ -458,11 +486,10 @@ gimple_gen_time_profiler (unsigned tag, unsigned base)
basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun); basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
basic_block cond_bb = split_edge (single_succ_edge (entry)); basic_block cond_bb = split_edge (single_succ_edge (entry));
basic_block update_bb = split_edge (single_succ_edge (cond_bb)); basic_block update_bb = split_edge (single_succ_edge (cond_bb));
split_edge (single_succ_edge (update_bb));
edge true_edge = single_succ_edge (cond_bb); edge true_edge = single_succ_edge (cond_bb);
true_edge->flags = EDGE_TRUE_VALUE; true_edge->flags = EDGE_TRUE_VALUE;
true_edge->probability = PROB_VERY_UNLIKELY; true_edge->probability = PROB_UNLIKELY;
edge e edge e
= make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE); = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
e->probability = REG_BR_PROB_BASE - true_edge->probability; e->probability = REG_BR_PROB_BASE - true_edge->probability;
......
2017-06-09 Martin Liska <mliska@suse.cz>
* libgcov-profiler.c (__gcov_indirect_call_profiler_v2):
Reset __gcov_indirect_call_callee to NULL.
2017-06-08 Olivier Hainque <hainque@adacore.com> 2017-06-08 Olivier Hainque <hainque@adacore.com>
* config/t-vxworks (LIBGCC2_INCLUDES): Add path to wrn/coreip to * config/t-vxworks (LIBGCC2_INCLUDES): Add path to wrn/coreip to
......
...@@ -336,6 +336,8 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func) ...@@ -336,6 +336,8 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
|| (__LIBGCC_VTABLE_USES_DESCRIPTORS__ && __gcov_indirect_call_callee || (__LIBGCC_VTABLE_USES_DESCRIPTORS__ && __gcov_indirect_call_callee
&& *(void **) cur_func == *(void **) __gcov_indirect_call_callee)) && *(void **) cur_func == *(void **) __gcov_indirect_call_callee))
__gcov_one_value_profiler_body (__gcov_indirect_call_counters, value, 0); __gcov_one_value_profiler_body (__gcov_indirect_call_counters, value, 0);
__gcov_indirect_call_callee = NULL;
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment