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>
PR target/91298
......
......@@ -863,7 +863,15 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
if (hist->type == HIST_TYPE_TOPN_VALUES
|| 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,
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>
* config/cris/arit.c (DS): Apply attribute __fallthrough__.
......
......@@ -213,6 +213,56 @@ static struct gcov_fn_buffer *fn_buffer;
/* Including system dependent components. */
#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.
Return 0 on success.
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,
struct gcov_summary summary = {};
int error;
gcov_unsigned_t tag;
fn_buffer = 0;
/* Prune current counters before we merge them. */
prune_counters (gi_ptr);
error = gcov_exit_open_gcda_file (gi_ptr, gf);
if (error == -1)
return;
......
......@@ -119,37 +119,35 @@ __gcov_topn_values_profiler_body (gcov_type *counters, gcov_type value,
++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++)
{
if (value == counters[2 * i])
{
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
counters[2 * i + 1]++;
counters[2 * i + 1] += GCOV_TOPN_VALUES;
return;
}
else if (counters[2 * i + 1] == 0)
else if (counters[2 * i + 1] <= 0)
{
/* We found an empty slot. */
counters[2 * i] = value;
counters[2 * i + 1] = 1;
counters[2 * i + 1] = GCOV_TOPN_VALUES;
return;
}
if (counters[2 * i + 1] < counters[2 * sindex + 1])
sindex = i;
}
/* We haven't found an empty slot, then decrement the smallest. */
if (use_atomic)
__atomic_fetch_sub (&counters[2 * sindex + 1], 1, __ATOMIC_RELAXED);
else
counters[2 * sindex + 1]--;
/* We haven't found an empty slot, then decrement all
counter values by one. */
for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
if (use_atomic)
__atomic_fetch_sub (&counters[2 * i + 1], 1, __ATOMIC_RELAXED);
else
counters[2 * i + 1]--;
}
}
#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