From 0a7501658c43bba75e8130f250ae6445eab0ea9f Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Tue, 7 Oct 2014 04:06:12 +0000 Subject: [PATCH] params.def (PARAM_INDIR_CALL_TOPN_PROFILE): New param. 2014-10-06 Rong Xu * gcc/params.def (PARAM_INDIR_CALL_TOPN_PROFILE): New param. * gcc/tree-profile.c: (params.h): New include. (init_ic_make_global_vars): Make __gcov_indirect_call_topn_callee and __gcov_indirect_call_topn_counters for indirect_call_topn_profile. (gimple_init_edge_profiler): New decls for __gcov_indirect_call_topn_profiler. (gimple_gen_ic_profiler): Generate the correct profiler call. (gimple_gen_ic_func_profiler): Fix format. * gcc/value-prof.c (params.h): New include. (dump_histogram_value): Hanlde indirect_call_topn counters. (stream_in_histogram_value): Ditto. (gimple_indirect_call_to_profile): Use indirect_call_topn profile when PARAM_INDIR_CALL_TOPN_PROFILE is set. (gimple_find_values_to_profile): Hanlde indirect_call_topn counters. * gcc/value-prof.h (enum hist_type): Histrogram type for indirect_call_topn counters. * gcc/profile.c (instrument_values): Instrument indirect_call_topn counters. From-SVN: r215963 --- gcc/params.def | 8 ++++++++ gcc/profile.c | 1 + gcc/tree-profile.c | 26 ++++++++++++++++++++------ gcc/value-prof.c | 42 ++++++++++++++++++++++++++++++++++++------ gcc/value-prof.h | 2 ++ 5 files changed, 67 insertions(+), 12 deletions(-) diff --git a/gcc/params.def b/gcc/params.def index aefdd071f7a..beff7e63212 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -882,6 +882,14 @@ DEFPARAM (PARAM_PROFILE_FUNC_INTERNAL_ID, "use internal function id in profile lookup", 0, 0, 1) +/* When the parameter is 1, track the most frequent N target + addresses in indirect-call profile. This disables + indirect_call_profiler_v2 which tracks single target. */ +DEFPARAM (PARAM_INDIR_CALL_TOPN_PROFILE, + "indir-call-topn-profile", + "track topn target addresses in indirect-call profile", + 0, 0, 1) + /* Avoid SLP vectorization of large basic blocks. */ DEFPARAM (PARAM_SLP_MAX_INSNS_IN_BB, "slp-max-insns-in-bb", diff --git a/gcc/profile.c b/gcc/profile.c index 7d8b54c4b4e..6be8a030fc6 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -183,6 +183,7 @@ instrument_values (histogram_values values) break; case HIST_TYPE_INDIR_CALL: + case HIST_TYPE_INDIR_CALL_TOPN: gimple_gen_ic_profiler (hist, t, 0); break; diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index ba90196c7ce..48d13a22d34 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "tree-cfgcleanup.h" #include "tree-nested.h" +#include "params.h" static GTY(()) tree gcov_type_node; static GTY(()) tree tree_interval_profiler_fn; @@ -101,7 +102,10 @@ init_ic_make_global_vars (void) { ic_void_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, - get_identifier ("__gcov_indirect_call_callee"), + 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; @@ -131,7 +135,10 @@ init_ic_make_global_vars (void) { ic_gcov_type_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, - get_identifier ("__gcov_indirect_call_counters"), + 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; @@ -226,8 +233,10 @@ gimple_init_edge_profiler (void) ptr_void, NULL_TREE); tree_indirect_call_profiler_fn - = build_fn_decl ("__gcov_indirect_call_profiler_v2", - ic_profiler_fn_type); + = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? + "__gcov_indirect_call_topn_profiler": + "__gcov_indirect_call_profiler_v2"), + ic_profiler_fn_type); } TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) @@ -398,6 +407,12 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) gimple_stmt_iterator gsi = gsi_for_stmt (stmt); tree ref_ptr = tree_coverage_counter_addr (tag, base); + if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) && + tag == GCOV_COUNTER_V_INDIR) || + (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) && + tag == GCOV_COUNTER_ICALL_TOPNV)) + return; + ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, true, NULL_TREE, true, GSI_SAME_STMT); @@ -442,8 +457,7 @@ gimple_gen_ic_func_profiler (void) 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)))); + gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)))); cur_func = force_gimple_operand_gsi (&gsi, build_addr (current_function_decl, diff --git a/gcc/value-prof.c b/gcc/value-prof.c index e3579678b71..37710ca6da6 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "tree-nested.h" #include "hash-set.h" +#include "params.h" /* In this file value profile based optimizations are placed. Currently the following optimizations are implemented (for more detailed descriptions @@ -359,6 +360,22 @@ dump_histogram_value (FILE *dump_file, histogram_value hist) } fprintf (dump_file, ".\n"); break; + case HIST_TYPE_INDIR_CALL_TOPN: + fprintf (dump_file, "Indirect call topn "); + if (hist->hvalue.counters) + { + int i; + + fprintf (dump_file, "accu:%"PRId64, hist->hvalue.counters[0]); + for (i = 1; i < (GCOV_ICALL_TOPN_VAL << 2); i += 2) + { + fprintf (dump_file, " target:%"PRId64 " value:%"PRId64, + (int64_t) hist->hvalue.counters[i], + (int64_t) hist->hvalue.counters[i+1]); + } + } + fprintf (dump_file, ".\n"); + break; case HIST_TYPE_MAX: gcc_unreachable (); } @@ -432,9 +449,14 @@ stream_in_histogram_value (struct lto_input_block *ib, gimple stmt) break; case HIST_TYPE_IOR: - case HIST_TYPE_TIME_PROFILE: + case HIST_TYPE_TIME_PROFILE: ncounters = 1; break; + + case HIST_TYPE_INDIR_CALL_TOPN: + ncounters = (GCOV_ICALL_TOPN_VAL << 2) + 1; + break; + case HIST_TYPE_MAX: gcc_unreachable (); } @@ -1920,8 +1942,12 @@ gimple_indirect_call_to_profile (gimple stmt, histogram_values *values) values->reserve (3); - values->quick_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL, - stmt, callee)); + values->quick_push (gimple_alloc_histogram_value ( + cfun, + PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? + HIST_TYPE_INDIR_CALL_TOPN : + HIST_TYPE_INDIR_CALL, + stmt, callee)); return; } @@ -2011,9 +2037,9 @@ gimple_find_values_to_profile (histogram_values *values) hist->n_counters = 3; break; - case HIST_TYPE_TIME_PROFILE: - hist->n_counters = 1; - break; + case HIST_TYPE_TIME_PROFILE: + hist->n_counters = 1; + break; case HIST_TYPE_AVERAGE: hist->n_counters = 2; @@ -2023,6 +2049,10 @@ gimple_find_values_to_profile (histogram_values *values) hist->n_counters = 1; break; + case HIST_TYPE_INDIR_CALL_TOPN: + hist->n_counters = GCOV_ICALL_TOPN_NCOUNTS; + break; + default: gcc_unreachable (); } diff --git a/gcc/value-prof.h b/gcc/value-prof.h index 9d2c3516d22..00a89fab2a4 100644 --- a/gcc/value-prof.h +++ b/gcc/value-prof.h @@ -35,6 +35,8 @@ enum hist_type HIST_TYPE_AVERAGE, /* Compute average value (sum of all values). */ HIST_TYPE_IOR, /* Used to compute expected alignment. */ HIST_TYPE_TIME_PROFILE, /* Used for time profile */ + HIST_TYPE_INDIR_CALL_TOPN, /* Tries to identify the top N most frequently + called functions in indirect call. */ HIST_TYPE_MAX }; -- 2.30.2