Remove indirect call top N counter type.

2019-06-07  Martin Liska  <mliska@suse.cz>

	* doc/invoke.texi: Remove param.
	* gcov-counter.def (GCOV_COUNTER_ICALL_TOPNV):
	Remove.
	* gcov-io.h (GCOV_ICALL_TOPN_VAL): Likewise.
	(GCOV_ICALL_TOPN_NCOUNTS): Likewise.
	* params.def (PARAM_INDIR_CALL_TOPN_PROFILE): Likewise.
	* profile.c (instrument_values): Remove
	HIST_TYPE_INDIR_CALL_TOPN.
	* tree-profile.c (init_ic_make_global_vars):
	Always build __gcov_indirect_call only.
	(gimple_init_gcov_profiler): Remove usage
	of PARAM_INDIR_CALL_TOPN_PROFILE.
	(gimple_gen_ic_profiler): Likewise.
	* value-prof.c (dump_histogram_value): Likewise.
	(stream_in_histogram_value): Likewise.
	(gimple_indirect_call_to_profile): Likewise.
	(gimple_find_values_to_profile): Likewise.
	* value-prof.h (enum hist_type): Likewise.
2019-06-07  Martin Liska  <mliska@suse.cz>

	* Makefile.in: Remove usage of
	_gcov_merge_icall_topn.
	* libgcov-driver.c (gcov_sort_n_vals): Remove.
	(gcov_sort_icall_topn_counter): Likewise.
	(gcov_sort_topn_counter_arrays): Likewise.
	(dump_one_gcov): Remove call to gcov_sort_topn_counter_arrays.
	* libgcov-merge.c (__gcov_merge_icall_topn): Remove.
	* libgcov-profiler.c (__gcov_topn_value_profiler_body):
	Likewise.
	(GCOV_ICALL_COUNTER_CLEAR_THRESHOLD): Remove.
	(struct indirect_call_tuple): Remove.
	(__gcov_indirect_call_topn_profiler): Remove.
	* libgcov-util.c (__gcov_icall_topn_counter_op): Remove.
	* libgcov.h (gcov_sort_n_vals): Remove.
	(L_gcov_merge_icall_topn): Likewise.
	(__gcov_merge_icall_topn): Likewise.
	(__gcov_indirect_call_topn_profiler): Likewise.

From-SVN: r272030
This commit is contained in:
Martin Liska 2019-06-07 08:41:58 +02:00 committed by Martin Liska
parent cc261f66c2
commit e37333bad7
16 changed files with 46 additions and 370 deletions

View File

@ -1,3 +1,24 @@
2019-06-07 Martin Liska <mliska@suse.cz>
* doc/invoke.texi: Remove param.
* gcov-counter.def (GCOV_COUNTER_ICALL_TOPNV):
Remove.
* gcov-io.h (GCOV_ICALL_TOPN_VAL): Likewise.
(GCOV_ICALL_TOPN_NCOUNTS): Likewise.
* params.def (PARAM_INDIR_CALL_TOPN_PROFILE): Likewise.
* profile.c (instrument_values): Remove
HIST_TYPE_INDIR_CALL_TOPN.
* tree-profile.c (init_ic_make_global_vars):
Always build __gcov_indirect_call only.
(gimple_init_gcov_profiler): Remove usage
of PARAM_INDIR_CALL_TOPN_PROFILE.
(gimple_gen_ic_profiler): Likewise.
* value-prof.c (dump_histogram_value): Likewise.
(stream_in_histogram_value): Likewise.
(gimple_indirect_call_to_profile): Likewise.
(gimple_find_values_to_profile): Likewise.
* value-prof.h (enum hist_type): Likewise.
2019-06-07 Martin Liska <mliska@suse.cz>
* tree-ssa-loop.c (get_lsm_tmp_name): Return at the end of the

View File

@ -12140,9 +12140,6 @@ will not try to thread through its block.
Maximum number of nested calls to search for control dependencies
during uninitialized variable analysis.
@item indir-call-topn-profile
Track top N target addresses in indirect-call profile.
@item max-once-peeled-insns
The maximum number of insns of a peeled loop that rolls only once.

View File

@ -49,6 +49,3 @@ DEF_GCOV_COUNTER(GCOV_COUNTER_IOR, "ior", _ior)
/* Time profile collecting first run of a function */
DEF_GCOV_COUNTER(GCOV_TIME_PROFILER, "time_profiler", _time_profile)
/* Top N value tracking for indirect calls. */
DEF_GCOV_COUNTER(GCOV_COUNTER_ICALL_TOPNV, "indirect_call_topn", _icall_topn)

View File

@ -266,12 +266,6 @@ GCOV_COUNTERS
#define GCOV_N_VALUE_COUNTERS \
(GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
/* The number of hottest callees to be tracked. */
#define GCOV_ICALL_TOPN_VAL 2
/* The number of counter entries per icall callsite. */
#define GCOV_ICALL_TOPN_NCOUNTS (1 + GCOV_ICALL_TOPN_VAL * 4)
/* Convert a counter index to a tag. */
#define GCOV_TAG_FOR_COUNTER(COUNT) \
(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))

View File

@ -992,14 +992,6 @@ 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_v3 which tracks single target. */
DEFPARAM (PARAM_INDIR_CALL_TOPN_PROFILE,
"indir-call-topn-profile",
"Track top N 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",

View File

@ -172,7 +172,6 @@ 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;

View File

@ -101,11 +101,7 @@ init_ic_make_global_vars (void)
ic_tuple_var
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier (
(PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
"__gcov_indirect_call_topn" :
"__gcov_indirect_call")),
tuple_type);
get_identifier ("__gcov_indirect_call"), tuple_type);
TREE_PUBLIC (ic_tuple_var) = 1;
DECL_ARTIFICIAL (ic_tuple_var) = 1;
DECL_INITIAL (ic_tuple_var) = NULL;
@ -187,8 +183,6 @@ gimple_init_gcov_profiler (void)
ptr_type_node,
NULL_TREE);
profiler_fn_name = "__gcov_indirect_call_profiler_v3";
if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE))
profiler_fn_name = "__gcov_indirect_call_topn_profiler";
tree_indirect_call_profiler_fn
= build_fn_decl (profiler_fn_name, ic_profiler_fn_type);
@ -376,12 +370,6 @@ 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);

View File

@ -316,22 +316,6 @@ 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 ();
}
@ -416,10 +400,6 @@ stream_in_histogram_value (struct lto_input_block *ib, gimple *stmt)
ncounters = 1;
break;
case HIST_TYPE_INDIR_CALL_TOPN:
ncounters = (GCOV_ICALL_TOPN_VAL << 2) + 1;
break;
case HIST_TYPE_MAX:
gcc_unreachable ();
}
@ -1865,12 +1845,8 @@ gimple_indirect_call_to_profile (gimple *stmt, histogram_values *values)
values->reserve (3);
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));
values->quick_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
stmt, callee));
return;
}
@ -1971,10 +1947,6 @@ 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 ();
}

View File

@ -33,8 +33,6 @@ 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
};

View File

@ -1,3 +1,23 @@
2019-06-07 Martin Liska <mliska@suse.cz>
* Makefile.in: Remove usage of
_gcov_merge_icall_topn.
* libgcov-driver.c (gcov_sort_n_vals): Remove.
(gcov_sort_icall_topn_counter): Likewise.
(gcov_sort_topn_counter_arrays): Likewise.
(dump_one_gcov): Remove call to gcov_sort_topn_counter_arrays.
* libgcov-merge.c (__gcov_merge_icall_topn): Remove.
* libgcov-profiler.c (__gcov_topn_value_profiler_body):
Likewise.
(GCOV_ICALL_COUNTER_CLEAR_THRESHOLD): Remove.
(struct indirect_call_tuple): Remove.
(__gcov_indirect_call_topn_profiler): Remove.
* libgcov-util.c (__gcov_icall_topn_counter_op): Remove.
* libgcov.h (gcov_sort_n_vals): Remove.
(L_gcov_merge_icall_topn): Likewise.
(__gcov_merge_icall_topn): Likewise.
(__gcov_indirect_call_topn_profiler): Likewise.
2019-06-06 Iain Sandoe <iain@sandoe.co.uk>
* config/rs6000/t-darwin: Ensure that the unwinder is built with

View File

@ -888,7 +888,7 @@ include $(iterator)
# Build libgcov components.
LIBGCOV_MERGE = _gcov_merge_add _gcov_merge_single \
_gcov_merge_ior _gcov_merge_time_profile _gcov_merge_icall_topn
_gcov_merge_ior _gcov_merge_time_profile
LIBGCOV_PROFILER = _gcov_interval_profiler \
_gcov_interval_profiler_atomic \
_gcov_pow2_profiler \
@ -900,8 +900,7 @@ LIBGCOV_PROFILER = _gcov_interval_profiler \
_gcov_ior_profiler \
_gcov_ior_profiler_atomic \
_gcov_indirect_call_profiler_v3 \
_gcov_time_profiler \
_gcov_indirect_call_topn_profiler
_gcov_time_profiler
LIBGCOV_INTERFACE = _gcov_dump _gcov_flush _gcov_fork \
_gcov_execl _gcov_execlp \
_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset

View File

@ -415,84 +415,6 @@ merge_summary (int run_counted, struct gcov_summary *summary,
}
}
/* Sort N entries in VALUE_ARRAY in descending order.
Each entry in VALUE_ARRAY has two values. The sorting
is based on the second value. */
GCOV_LINKAGE void
gcov_sort_n_vals (gcov_type *value_array, int n)
{
int j, k;
for (j = 2; j < n; j += 2)
{
gcov_type cur_ent[2];
cur_ent[0] = value_array[j];
cur_ent[1] = value_array[j + 1];
k = j - 2;
while (k >= 0 && value_array[k + 1] < cur_ent[1])
{
value_array[k + 2] = value_array[k];
value_array[k + 3] = value_array[k+1];
k -= 2;
}
value_array[k + 2] = cur_ent[0];
value_array[k + 3] = cur_ent[1];
}
}
/* Sort the profile counters for all indirect call sites. Counters
for each call site are allocated in array COUNTERS. */
static void
gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
{
int i;
gcov_type *values;
int n = counters->num;
gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
values = counters->values;
for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
{
gcov_type *value_array = &values[i + 1];
gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
}
}
/* Sort topn indirect_call profile counters in GI_PTR. */
static void
gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr)
{
unsigned int i;
int f_ix;
const struct gcov_fn_info *gfi_ptr;
const struct gcov_ctr_info *ci_ptr;
if (!gi_ptr->merge[GCOV_COUNTER_ICALL_TOPNV])
return;
for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
{
gfi_ptr = gi_ptr->functions[f_ix];
ci_ptr = gfi_ptr->ctrs;
for (i = 0; i < GCOV_COUNTERS; i++)
{
if (!gi_ptr->merge[i])
continue;
if (i == GCOV_COUNTER_ICALL_TOPNV)
{
gcov_sort_icall_topn_counter (ci_ptr);
break;
}
ci_ptr++;
}
}
}
/* Dump the coverage counts for one gcov_info object. We merge with existing
counts when possible, to avoid growing the .da files ad infinitum. We use
this program's checksum to make sure we only accumulate whole program
@ -510,8 +432,6 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
fn_buffer = 0;
gcov_sort_topn_counter_arrays (gi_ptr);
error = gcov_exit_open_gcda_file (gi_ptr, gf);
if (error == -1)
return;

View File

@ -122,66 +122,4 @@ __gcov_merge_single (gcov_type *counters, unsigned n_counters)
}
#endif /* L_gcov_merge_single */
#ifdef L_gcov_merge_icall_topn
/* The profile merging function used for merging indirect call counts
This function is given array COUNTERS of N_COUNTERS old counters and it
reads the same number of counters from the gcov file. */
void
__gcov_merge_icall_topn (gcov_type *counters, unsigned n_counters)
{
unsigned i, j, k, m;
gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS));
for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS)
{
gcov_type *value_array = &counters[i + 1];
unsigned tmp_size = 2 * (GCOV_ICALL_TOPN_NCOUNTS - 1);
gcov_type *tmp_array
= (gcov_type *) alloca (tmp_size * sizeof (gcov_type));
for (j = 0; j < tmp_size; j++)
tmp_array[j] = 0;
for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2)
{
tmp_array[j] = value_array[j];
tmp_array[j + 1] = value_array [j + 1];
}
/* Skip the number_of_eviction entry. */
gcov_get_counter ();
for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
{
int found = 0;
gcov_type global_id = gcov_get_counter_target ();
gcov_type call_count = gcov_get_counter ();
for (m = 0; m < j; m += 2)
{
if (tmp_array[m] == global_id)
{
found = 1;
tmp_array[m + 1] += call_count;
break;
}
}
if (!found)
{
tmp_array[j] = global_id;
tmp_array[j + 1] = call_count;
j += 2;
}
}
/* Now sort the temp array */
gcov_sort_n_vals (tmp_array, j);
/* Now copy back the top half of the temp array */
for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
{
value_array[k] = tmp_array[k];
value_array[k + 1] = tmp_array[k + 1];
}
}
}
#endif /* L_gcov_merge_icall_topn */
#endif /* inhibit_libc */

View File

@ -163,139 +163,6 @@ __gcov_one_value_profiler_atomic (gcov_type *counters, gcov_type value)
}
#endif
#ifdef L_gcov_indirect_call_topn_profiler
/* Tries to keep track the most frequent N values in the counters where
N is specified by parameter TOPN_VAL. To track top N values, 2*N counter
entries are used.
counter[0] --- the accumative count of the number of times one entry in
in the counters gets evicted/replaced due to limited capacity.
When this value reaches a threshold, the bottom N values are
cleared.
counter[1] through counter[2*N] records the top 2*N values collected so far.
Each value is represented by two entries: count[2*i+1] is the ith value, and
count[2*i+2] is the number of times the value is seen. */
static void
__gcov_topn_value_profiler_body (gcov_type *counters, gcov_type value)
{
unsigned i, found = 0, have_zero_count = 0;
gcov_type *entry;
gcov_type *lfu_entry = &counters[1];
gcov_type *value_array = &counters[1];
gcov_type *num_eviction = &counters[0];
gcov_unsigned_t topn_val = GCOV_ICALL_TOPN_VAL;
/* There are 2*topn_val values tracked, each value takes two slots in the
counter array. */
for (i = 0; i < (topn_val << 2); i += 2)
{
entry = &value_array[i];
if (entry[0] == value)
{
entry[1]++ ;
found = 1;
break;
}
else if (entry[1] == 0)
{
lfu_entry = entry;
have_zero_count = 1;
}
else if (entry[1] < lfu_entry[1])
lfu_entry = entry;
}
if (found)
return;
/* lfu_entry is either an empty entry or an entry
with lowest count, which will be evicted. */
lfu_entry[0] = value;
lfu_entry[1] = 1;
#define GCOV_ICALL_COUNTER_CLEAR_THRESHOLD 3000
/* Too many evictions -- time to clear bottom entries to
avoid hot values bumping each other out. */
if (!have_zero_count
&& ++*num_eviction >= GCOV_ICALL_COUNTER_CLEAR_THRESHOLD)
{
unsigned i, j;
gcov_type *p, minv;
gcov_type* tmp_cnts
= (gcov_type *)alloca (topn_val * sizeof (gcov_type));
*num_eviction = 0;
for (i = 0; i < topn_val; i++)
tmp_cnts[i] = 0;
/* Find the largest topn_val values from the group of
2*topn_val values and put them into tmp_cnts. */
for (i = 0; i < 2 * topn_val; i += 2)
{
p = 0;
for (j = 0; j < topn_val; j++)
{
if (!p || tmp_cnts[j] < *p)
p = &tmp_cnts[j];
}
if (value_array[i + 1] > *p)
*p = value_array[i + 1];
}
minv = tmp_cnts[0];
for (j = 1; j < topn_val; j++)
{
if (tmp_cnts[j] < minv)
minv = tmp_cnts[j];
}
/* Zero out low value entries. */
for (i = 0; i < 2 * topn_val; i += 2)
{
if (value_array[i + 1] < minv)
{
value_array[i] = 0;
value_array[i + 1] = 0;
}
}
}
}
/* These two variables are used to actually track caller and callee. Keep
them in TLS memory so races are not common (they are written to often).
The variables are set directly by GCC instrumented code, so declaration
here must match one in tree-profile.c. */
#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
__thread
#endif
struct indirect_call_tuple __gcov_indirect_call_topn;
#ifdef TARGET_VTABLE_USES_DESCRIPTORS
#define VTABLE_USES_DESCRIPTORS 1
#else
#define VTABLE_USES_DESCRIPTORS 0
#endif
/* This fucntion is instrumented at function entry to track topn indirect
calls to CUR_FUNC. */
void
__gcov_indirect_call_topn_profiler (gcov_type value, void* cur_func)
{
void *callee_func = __gcov_indirect_call_topn.callee;
/* If the C++ virtual tables contain function descriptors then one
function may have multiple descriptors and we need to dereference
the descriptors to see if they point to the same function. */
if (cur_func == callee_func
|| (VTABLE_USES_DESCRIPTORS && callee_func
&& *(void **) cur_func == *(void **) callee_func))
__gcov_topn_value_profiler_body (__gcov_indirect_call_topn.counters, value);
}
#endif
#ifdef L_gcov_indirect_call_profiler_v3
/* These two variables are used to actually track caller and callee. Keep

View File

@ -740,25 +740,6 @@ __gcov_single_counter_op (gcov_type *counters, unsigned n_counters,
}
}
/* Performing FN upon indirect-call profile counters. */
static void
__gcov_icall_topn_counter_op (gcov_type *counters, unsigned n_counters,
counter_op_fn fn, void *data1, void *data2)
{
unsigned i;
gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS));
for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS)
{
unsigned j;
gcov_type *value_array = &counters[i + 1];
for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2)
value_array[j + 1] = fn (value_array[j + 1], data1, data2);
}
}
/* Scaling the counter value V by multiplying *(float*) DATA1. */
static gcov_type

View File

@ -102,7 +102,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#define gcov_read_unsigned __gcov_read_unsigned
#define gcov_read_counter __gcov_read_counter
#define gcov_read_summary __gcov_read_summary
#define gcov_sort_n_vals __gcov_sort_n_vals
#else /* IN_GCOV_TOOL */
/* About the host. */
@ -130,7 +129,6 @@ typedef unsigned gcov_position_t;
#define L_gcov_merge_single 1
#define L_gcov_merge_ior 1
#define L_gcov_merge_time_profile 1
#define L_gcov_merge_icall_topn 1
extern gcov_type gcov_read_counter_mem ();
extern unsigned gcov_get_merge_weight ();
@ -267,9 +265,6 @@ extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The merge function that just ors the counters together. */
extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The merge function is used for topn indirect call counters. */
extern void __gcov_merge_icall_topn (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The profiler functions. */
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_interval_profiler_atomic (gcov_type *, gcov_type, int,
@ -285,8 +280,6 @@ extern void __gcov_average_profiler (gcov_type *, gcov_type);
extern void __gcov_average_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_ior_profiler (gcov_type *, gcov_type);
extern void __gcov_ior_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_indirect_call_topn_profiler (gcov_type, void *);
extern void gcov_sort_n_vals (gcov_type *, int);
#ifndef inhibit_libc
/* The wrappers around some library functions.. */