Smart relaxation of TOP N counter.

	PR tree-optimization/92924
	* profile.c (compute_value_histograms): Divide
	all counter values.
	PR tree-optimization/92924
	* libgcov-driver.c (prune_topn_counter): New.
	(prune_counters): Likewise.
	(dump_one_gcov): Prune a run-time counter.
	* libgcov-profiler.c (__gcov_topn_values_profiler_body):
	For a known value, add GCOV_TOPN_VALUES to value.
	Otherwise, decrement all counters by one.
parent f96af171
2020-01-22 Martin Liska <mliska@suse.cz>
PR tree-optimization/92924
* profile.c (compute_value_histograms): Divide
all counter values.
2020-01-22 Jakub Jelinek <jakub@redhat.com> 2020-01-22 Jakub Jelinek <jakub@redhat.com>
PR target/91298 PR target/91298
......
...@@ -863,7 +863,15 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum, ...@@ -863,7 +863,15 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
if (hist->type == HIST_TYPE_TOPN_VALUES if (hist->type == HIST_TYPE_TOPN_VALUES
|| hist->type == HIST_TYPE_INDIR_CALL) || hist->type == HIST_TYPE_INDIR_CALL)
sort_hist_values (hist); {
/* Each count value is multiplied by GCOV_TOPN_VALUES. */
if (hist->hvalue.counters[2] != -1)
for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
hist->hvalue.counters[2 * i + 2]
= RDIV (hist->hvalue.counters[2 * i + 2], GCOV_TOPN_VALUES);
sort_hist_values (hist);
}
/* Time profiler counter is not related to any statement, /* Time profiler counter is not related to any statement,
so that we have to read the counter and set the value to so that we have to read the counter and set the value to
......
2020-01-22 Martin Liska <mliska@suse.cz>
PR tree-optimization/92924
* libgcov-driver.c (prune_topn_counter): New.
(prune_counters): Likewise.
(dump_one_gcov): Prune a run-time counter.
* libgcov-profiler.c (__gcov_topn_values_profiler_body):
For a known value, add GCOV_TOPN_VALUES to value.
Otherwise, decrement all counters by one.
2020-01-18 Hans-Peter Nilsson <hp@axis.com> 2020-01-18 Hans-Peter Nilsson <hp@axis.com>
* config/cris/arit.c (DS): Apply attribute __fallthrough__. * config/cris/arit.c (DS): Apply attribute __fallthrough__.
......
...@@ -213,6 +213,56 @@ static struct gcov_fn_buffer *fn_buffer; ...@@ -213,6 +213,56 @@ static struct gcov_fn_buffer *fn_buffer;
/* Including system dependent components. */ /* Including system dependent components. */
#include "libgcov-driver-system.c" #include "libgcov-driver-system.c"
/* Prune TOP N value COUNTERS. It's needed in order to preserve
reproducibility of builds. */
static void
prune_topn_counter (gcov_type *counters, gcov_type all)
{
if (counters[1] == -1)
return;
for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
if (counters[2 * i + 1] < all)
{
counters[2 * i] = 0;
counters[2 * i + 1] = 0;
}
}
}
/* Prune counters so that they are ready to store or merge. */
static void
prune_counters (struct gcov_info *gi)
{
for (unsigned i = 0; i < gi->n_functions; i++)
{
const struct gcov_fn_info *gfi = gi->functions[i];
const struct gcov_ctr_info *ci = gfi->ctrs;
for (unsigned j = 0; j < GCOV_COUNTERS; j++)
{
if (gi->merge[j] == NULL)
continue;
if (gi->merge[j] == __gcov_merge_topn)
{
gcc_assert (!(ci->num % GCOV_TOPN_VALUES_COUNTERS));
for (unsigned k = 0; k < (ci->num / GCOV_TOPN_VALUES_COUNTERS);
k++)
{
gcov_type *counters
= ci->values + (k * GCOV_TOPN_VALUES_COUNTERS);
prune_topn_counter (counters + 1, *counters);
}
}
ci++;
}
}
}
/* This function merges counters in GI_PTR to an existing gcda file. /* This function merges counters in GI_PTR to an existing gcda file.
Return 0 on success. Return 0 on success.
Return -1 on error. In this case, caller will goto read_fatal. */ Return -1 on error. In this case, caller will goto read_fatal. */
...@@ -429,9 +479,11 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf, ...@@ -429,9 +479,11 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
struct gcov_summary summary = {}; struct gcov_summary summary = {};
int error; int error;
gcov_unsigned_t tag; gcov_unsigned_t tag;
fn_buffer = 0; fn_buffer = 0;
/* Prune current counters before we merge them. */
prune_counters (gi_ptr);
error = gcov_exit_open_gcda_file (gi_ptr, gf); error = gcov_exit_open_gcda_file (gi_ptr, gf);
if (error == -1) if (error == -1)
return; return;
......
...@@ -119,37 +119,35 @@ __gcov_topn_values_profiler_body (gcov_type *counters, gcov_type value, ...@@ -119,37 +119,35 @@ __gcov_topn_values_profiler_body (gcov_type *counters, gcov_type value,
++counters; ++counters;
/* We have GCOV_TOPN_VALUES as we can keep multiple values
next to each other. */
unsigned sindex = 0;
for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++) for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{ {
if (value == counters[2 * i]) if (value == counters[2 * i])
{ {
if (use_atomic) if (use_atomic)
__atomic_fetch_add (&counters[2 * i + 1], 1, __ATOMIC_RELAXED); __atomic_fetch_add (&counters[2 * i + 1], GCOV_TOPN_VALUES,
__ATOMIC_RELAXED);
else else
counters[2 * i + 1]++; counters[2 * i + 1] += GCOV_TOPN_VALUES;
return; return;
} }
else if (counters[2 * i + 1] == 0) else if (counters[2 * i + 1] <= 0)
{ {
/* We found an empty slot. */ /* We found an empty slot. */
counters[2 * i] = value; counters[2 * i] = value;
counters[2 * i + 1] = 1; counters[2 * i + 1] = GCOV_TOPN_VALUES;
return; return;
} }
if (counters[2 * i + 1] < counters[2 * sindex + 1])
sindex = i;
} }
/* We haven't found an empty slot, then decrement the smallest. */ /* We haven't found an empty slot, then decrement all
if (use_atomic) counter values by one. */
__atomic_fetch_sub (&counters[2 * sindex + 1], 1, __ATOMIC_RELAXED); for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
else {
counters[2 * sindex + 1]--; if (use_atomic)
__atomic_fetch_sub (&counters[2 * i + 1], 1, __ATOMIC_RELAXED);
else
counters[2 * i + 1]--;
}
} }
#ifdef L_gcov_topn_values_profiler #ifdef L_gcov_topn_values_profiler
......
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