This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Speed-up indirect-call instrumentation
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Martin Li?ka <mliska at suse dot cz>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jan Hubicka <hubicka at ucw dot cz>
- Date: Fri, 9 Jun 2017 14:21:42 +0200
- Subject: Re: [PATCH] Speed-up indirect-call instrumentation
- Authentication-results: sourceware.org; auth=none
- References: <fc4af520-5e2d-734c-1493-bf05777b1d62@suse.cz>
> Hello.
>
> I discussed with Honza possibility to speed-up instrumentation that we do for
> indirect call target tracking. By direct emission of:
>
> if (__gcov_indirect_call_callee != NULL)
> __gcov_indirect_call_profiler_v2 (profile_id, ¤t_function_decl);
>
> we can save reduce # of execution of __gcov_indirect_call_profiler_v2 function.
> I measured that tramp3d (-O2 -fprofile-generate) goes from 7.1s to 6.3s.
>
> Apart from that I slightly change probability for direct instrumentation of
> time profiler.
>
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>
> Ready to be installed?
OK, Thanks!
Honza
> Martin
> >From 178b505b99499bb620492507684f85dd604172c9 Mon Sep 17 00:00:00 2001
> From: marxin <mliska@suse.cz>
> Date: Fri, 9 Jun 2017 11:18:44 +0200
> Subject: [PATCH] Speed-up indirect-call instrumentation
>
> gcc/ChangeLog:
>
> 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.
>
> libgcc/ChangeLog:
>
> 2017-06-09 Martin Liska <mliska@suse.cz>
>
> * libgcov-profiler.c (__gcov_indirect_call_profiler_v2):
> Reset __gcov_indirect_call_callee to NULL.
> ---
> gcc/tree-profile.c | 59 ++++++++++++++++++++++++++++++++++-------------
> libgcc/libgcov-profiler.c | 2 ++
> 2 files changed, 45 insertions(+), 16 deletions(-)
>
> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
> index a49ec37f8bb..f5c06684402 100644
> --- a/gcc/tree-profile.c
> +++ b/gcc/tree-profile.c
> @@ -388,6 +388,13 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
> stmt1: __gcov_indirect_call_counters = get_relevant_counter_ptr ();
> stmt2: tmp1 = (void *) (indirect call argument value)
> 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);
> @@ -410,9 +417,7 @@ void
> gimple_gen_ic_func_profiler (void)
> {
> struct cgraph_node * c_node = cgraph_node::get (current_function_decl);
> - gimple_stmt_iterator gsi;
> gcall *stmt1;
> - gassign *stmt2;
> tree tree_uid, cur_func, void0;
>
> if (c_node->only_called_directly_p ())
> @@ -420,13 +425,43 @@ gimple_gen_ic_func_profiler (void)
>
> 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:
>
> - stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
> - ¤t_function_decl)
> - */
> - gsi = gsi_after_labels (split_edge (single_succ_edge
> - (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
> + if (__gcov_indirect_call_callee != NULL)
> + __gcov_indirect_call_profiler_v2 (profile_id, ¤t_function_decl);
> +
> + The function __gcov_indirect_call_profiler_v2 is responsible for
> + 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,
> build_addr (current_function_decl),
> @@ -438,13 +473,6 @@ gimple_gen_ic_func_profiler (void)
> stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
> tree_uid, cur_func);
> 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.
> @@ -458,11 +486,10 @@ gimple_gen_time_profiler (unsigned tag, unsigned base)
> 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));
> - split_edge (single_succ_edge (update_bb));
>
> edge true_edge = single_succ_edge (cond_bb);
> true_edge->flags = EDGE_TRUE_VALUE;
> - true_edge->probability = PROB_VERY_UNLIKELY;
> + true_edge->probability = PROB_UNLIKELY;
> edge e
> = make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
> e->probability = REG_BR_PROB_BASE - true_edge->probability;
> diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
> index 067d762c2af..e4570a01318 100644
> --- a/libgcc/libgcov-profiler.c
> +++ b/libgcc/libgcov-profiler.c
> @@ -336,6 +336,8 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
> || (__LIBGCC_VTABLE_USES_DESCRIPTORS__ && __gcov_indirect_call_callee
> && *(void **) cur_func == *(void **) __gcov_indirect_call_callee))
> __gcov_one_value_profiler_body (__gcov_indirect_call_counters, value, 0);
> +
> + __gcov_indirect_call_callee = NULL;
> }
> #endif
>
> --
> 2.13.0
>