params.def (PARAM_INDIR_CALL_TOPN_PROFILE): New param.
2014-10-06 Rong Xu <xur@google.com> * 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
This commit is contained in:
parent
afe0c5ee91
commit
0a7501658c
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue