+2019-07-03 Martin Liska <mliska@suse.cz>
+
+ * gcov-counter.def (GCOV_COUNTER_V_SINGLE): Remove.
+ (GCOV_COUNTER_V_TOPN): New.
+ (GCOV_COUNTER_V_INDIR): Use _topn.
+ * gcov-io.h (GCOV_DISK_SINGLE_VALUES): Remove.
+ (GCOV_TOPN_VALUES): New.
+ (GCOV_SINGLE_VALUE_COUNTERS): Remove.
+ (GCOV_TOPN_VALUES_COUNTERS): New.
+ * profile.c (instrument_values): Use HIST_TYPE_TOPN_VALUES.
+ * tree-profile.c:
+ (gimple_init_gcov_profiler): Rename variables from one_value
+ to topn_values.
+ (gimple_gen_one_value_profiler): Remove.
+ (gimple_gen_topn_values_profiler): New function.
+ * value-prof.c (dump_histogram_value): Use TOPN_VALUES
+ names instead of SINGLE_VALUE.
+ (stream_out_histogram_value): Likewise.
+ (stream_in_histogram_value): Likewise.
+ (get_most_common_single_value): Likewise.
+ (gimple_divmod_fixed_value_transform): Likewise.
+ (gimple_stringops_transform): Likewise.
+ (gimple_divmod_values_to_profile): Likewise.
+ (gimple_stringops_values_to_profile): Likewise.
+ (gimple_find_values_to_profile): Likewise.
+ * value-prof.h (enum hist_type): Rename to TOPN.
+ (gimple_gen_one_value_profiler): Remove.
+ (gimple_gen_topn_values_profiler): New.
+
2019-07-03 Eric Botcazou <ebotcazou@adacore.com>
* dwarf2out.c (add_scalar_info): Add back refererence to existing DIE
DEF_GCOV_COUNTER(GCOV_COUNTER_V_POW2, "pow2", _add)
/* The most common value of expression. */
-DEF_GCOV_COUNTER(GCOV_COUNTER_V_SINGLE, "single", _single)
+DEF_GCOV_COUNTER(GCOV_COUNTER_V_TOPN, "topn", _topn)
/* The most common indirect address. */
-DEF_GCOV_COUNTER(GCOV_COUNTER_V_INDIR, "indirect_call", _single)
+DEF_GCOV_COUNTER(GCOV_COUNTER_V_INDIR, "indirect_call", _topn)
/* Compute average value passed to the counter. */
DEF_GCOV_COUNTER(GCOV_COUNTER_AVERAGE, "average", _add)
#define GCOV_N_VALUE_COUNTERS \
(GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
-/* Number of single value histogram values that live
- on disk representation. */
-#define GCOV_DISK_SINGLE_VALUES 4
+/* Number of top N value histogram. */
+#define GCOV_TOPN_VALUES 4
/* Total number of single value counters. */
-#define GCOV_SINGLE_VALUE_COUNTERS (2 * GCOV_DISK_SINGLE_VALUES + 1)
+#define GCOV_TOPN_VALUES_COUNTERS (2 * GCOV_TOPN_VALUES + 1)
/* Convert a counter index to a tag. */
#define GCOV_TAG_FOR_COUNTER(COUNT) \
gimple_gen_pow2_profiler (hist, t, 0);
break;
- case HIST_TYPE_SINGLE_VALUE:
- gimple_gen_one_value_profiler (hist, t, 0);
+ case HIST_TYPE_TOPN_VALUES:
+ gimple_gen_topn_values_profiler (hist, t, 0);
break;
case HIST_TYPE_INDIR_CALL:
static GTY(()) tree gcov_type_node;
static GTY(()) tree tree_interval_profiler_fn;
static GTY(()) tree tree_pow2_profiler_fn;
-static GTY(()) tree tree_one_value_profiler_fn;
+static GTY(()) tree tree_topn_values_profiler_fn;
static GTY(()) tree tree_indirect_call_profiler_fn;
static GTY(()) tree tree_average_profiler_fn;
static GTY(()) tree tree_ior_profiler_fn;
{
tree interval_profiler_fn_type;
tree pow2_profiler_fn_type;
- tree one_value_profiler_fn_type;
+ tree topn_values_profiler_fn_type;
tree gcov_type_ptr;
tree ic_profiler_fn_type;
tree average_profiler_fn_type;
DECL_ATTRIBUTES (tree_pow2_profiler_fn));
/* void (*) (gcov_type *, gcov_type) */
- one_value_profiler_fn_type
+ topn_values_profiler_fn_type
= build_function_type_list (void_type_node,
gcov_type_ptr, gcov_type_node,
NULL_TREE);
- fn_name = concat ("__gcov_one_value_profiler_v2", fn_suffix, NULL);
- tree_one_value_profiler_fn = build_fn_decl (fn_name,
- one_value_profiler_fn_type);
+ fn_name = concat ("__gcov_topn_values_profiler", fn_suffix, NULL);
+ tree_topn_values_profiler_fn
+ = build_fn_decl (fn_name, topn_values_profiler_fn_type);
- TREE_NOTHROW (tree_one_value_profiler_fn) = 1;
- DECL_ATTRIBUTES (tree_one_value_profiler_fn)
+ TREE_NOTHROW (tree_topn_values_profiler_fn) = 1;
+ DECL_ATTRIBUTES (tree_topn_values_profiler_fn)
= tree_cons (get_identifier ("leaf"), NULL,
- DECL_ATTRIBUTES (tree_one_value_profiler_fn));
+ DECL_ATTRIBUTES (tree_topn_values_profiler_fn));
init_ic_make_global_vars ();
late, we need to initialize them by hand. */
DECL_ASSEMBLER_NAME (tree_interval_profiler_fn);
DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
- DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
+ DECL_ASSEMBLER_NAME (tree_topn_values_profiler_fn);
DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
}
-/* Output instructions as GIMPLE trees for code to find the most common value.
- VALUE is the expression whose value is profiled. TAG is the tag of the
- section for counters, BASE is offset of the counter position. */
+/* Output instructions as GIMPLE trees for code to find the most N common
+ values. VALUE is the expression whose value is profiled. TAG is the tag
+ of the section for counters, BASE is offset of the counter position. */
void
-gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
+gimple_gen_topn_values_profiler (histogram_value value, unsigned tag,
+ unsigned base)
{
gimple *stmt = value->hvalue.stmt;
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
true, NULL_TREE, true, GSI_SAME_STMT);
val = prepare_instrumented_value (&gsi, value);
- call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
+ call = gimple_build_call (tree_topn_values_profiler_fn, 2, ref_ptr, val);
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
}
(int64_t) hist->hvalue.counters[0]);
break;
- case HIST_TYPE_SINGLE_VALUE:
+ case HIST_TYPE_TOPN_VALUES:
case HIST_TYPE_INDIR_CALL:
if (hist->hvalue.counters)
{
fprintf (dump_file,
- (hist->type == HIST_TYPE_SINGLE_VALUE
- ? "Single value counter " : "Indirect call counter"));
+ (hist->type == HIST_TYPE_TOPN_VALUES
+ ? "Top N value counter " : "Indirect call counter"));
if (hist->hvalue.counters)
{
fprintf (dump_file, "all: %" PRId64 ", values: ",
(int64_t) hist->hvalue.counters[0]);
- for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
+ for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
fprintf (dump_file, "[%" PRId64 ":%" PRId64 "]",
(int64_t) hist->hvalue.counters[2 * i + 1],
(int64_t) hist->hvalue.counters[2 * i + 2]);
- if (i != GCOV_DISK_SINGLE_VALUES - 1)
+ if (i != GCOV_TOPN_VALUES - 1)
fprintf (dump_file, ", ");
}
fprintf (dump_file, ".\n");
/* When user uses an unsigned type with a big value, constant converted
to gcov_type (a signed type) can be negative. */
gcov_type value = hist->hvalue.counters[i];
- if (hist->type == HIST_TYPE_SINGLE_VALUE && i > 0)
+ if (hist->type == HIST_TYPE_TOPN_VALUES && i > 0)
;
else
gcc_assert (value >= 0);
ncounters = 2;
break;
- case HIST_TYPE_SINGLE_VALUE:
+ case HIST_TYPE_TOPN_VALUES:
case HIST_TYPE_INDIR_CALL:
- ncounters = GCOV_SINGLE_VALUE_COUNTERS;
+ ncounters = GCOV_TOPN_VALUES_COUNTERS;
break;
case HIST_TYPE_IOR:
return tmp2;
}
-/* Return most common value of SINGLE_VALUE histogram. If
+/* Return most common value of TOPN_VALUE histogram. If
there's a unique value, return true and set VALUE and COUNT
arguments. */
gcov_type read_all = hist->hvalue.counters[0];
- for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
+ for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
gcov_type v = hist->hvalue.counters[2 * i + 1];
gcov_type c = hist->hvalue.counters[2 * i + 2];
return false;
histogram = gimple_histogram_value_of_type (cfun, stmt,
- HIST_TYPE_SINGLE_VALUE);
+ HIST_TYPE_TOPN_VALUES);
if (!histogram)
return false;
return false;
histogram = gimple_histogram_value_of_type (cfun, stmt,
- HIST_TYPE_SINGLE_VALUE);
+ HIST_TYPE_TOPN_VALUES);
if (!histogram)
return false;
/* Check for the case where the divisor is the same value most
of the time. */
values->quick_push (gimple_alloc_histogram_value (cfun,
- HIST_TYPE_SINGLE_VALUE,
+ HIST_TYPE_TOPN_VALUES,
stmt, divisor));
/* For mod, check whether it is not often a noop (or replaceable by
if (TREE_CODE (blck_size) != INTEGER_CST)
{
values->safe_push (gimple_alloc_histogram_value (cfun,
- HIST_TYPE_SINGLE_VALUE,
+ HIST_TYPE_TOPN_VALUES,
stmt, blck_size));
values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
stmt, blck_size));
hist->n_counters = 2;
break;
- case HIST_TYPE_SINGLE_VALUE:
- hist->n_counters = GCOV_SINGLE_VALUE_COUNTERS;
- break;
-
+ case HIST_TYPE_TOPN_VALUES:
case HIST_TYPE_INDIR_CALL:
- hist->n_counters = GCOV_SINGLE_VALUE_COUNTERS;
+ hist->n_counters = GCOV_TOPN_VALUES_COUNTERS;
break;
case HIST_TYPE_TIME_PROFILE:
HIST_TYPE_INTERVAL, /* Measures histogram of values inside a specified
interval. */
HIST_TYPE_POW2, /* Histogram of power of 2 values. */
- HIST_TYPE_SINGLE_VALUE, /* Tries to identify the value that is (almost)
- always constant. */
+ HIST_TYPE_TOPN_VALUES, /* Tries to identify the N most common values. */
HIST_TYPE_INDIR_CALL, /* Tries to identify the function that is (almost)
called in indirect call */
HIST_TYPE_AVERAGE, /* Compute average value (sum of all values). */
extern void gimple_gen_edge_profiler (int, edge);
extern void gimple_gen_interval_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_pow2_profiler (histogram_value, unsigned, unsigned);
-extern void gimple_gen_one_value_profiler (histogram_value, unsigned, unsigned);
+extern void gimple_gen_topn_values_profiler (histogram_value, unsigned,
+ unsigned);
extern void gimple_gen_ic_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_ic_func_profiler (void);
extern void gimple_gen_time_profiler (unsigned, unsigned);
+2019-07-03 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Use topn_values instead of one_value names.
+ * libgcov-merge.c (__gcov_merge_single): Move to ...
+ (__gcov_merge_topn): ... this.
+ (merge_single_value_set): Move to ...
+ (merge_topn_values_set): ... this.
+ * libgcov-profiler.c (__gcov_one_value_profiler_body): Move to
+ ...
+ (__gcov_topn_values_profiler_body): ... this.
+ (__gcov_one_value_profiler_v2): Move to ...
+ (__gcov_topn_values_profiler): ... this.
+ (__gcov_one_value_profiler_v2_atomic): Move to ...
+ (__gcov_topn_values_profiler_atomic): ... this.
+ (__gcov_indirect_call_profiler_v4): Remove.
+ * libgcov-util.c (__gcov_single_counter_op): Move to ...
+ (__gcov_topn_counter_op): ... this.
+ * libgcov.h (L_gcov_merge_single): Remove.
+ (L_gcov_merge_topn): New.
+ (__gcov_merge_single): Remove.
+ (__gcov_merge_topn): New.
+ (__gcov_one_value_profiler_v2): Move to ..
+ (__gcov_topn_values_profiler): ... this.
+ (__gcov_one_value_profiler_v2_atomic): Move to ...
+ (__gcov_topn_values_profiler_atomic): ... this.
+
2019-07-03 Martin Liska <mliska@suse.cz>
* libgcov-merge.c (merge_single_value_set): Support N values.
# Build libgcov components.
-LIBGCOV_MERGE = _gcov_merge_add _gcov_merge_single \
+LIBGCOV_MERGE = _gcov_merge_add _gcov_merge_topn \
_gcov_merge_ior _gcov_merge_time_profile
LIBGCOV_PROFILER = _gcov_interval_profiler \
_gcov_interval_profiler_atomic \
_gcov_pow2_profiler \
_gcov_pow2_profiler_atomic \
- _gcov_one_value_profiler_v2 \
- _gcov_one_value_profiler_v2_atomic \
+ _gcov_topn_values_profiler \
+ _gcov_topn_values_profiler_atomic \
_gcov_average_profiler \
_gcov_average_profiler_atomic \
_gcov_ior_profiler \
unsigned n_counters __attribute__ ((unused))) {}
#endif
-#ifdef L_gcov_merge_single
-void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
- unsigned n_counters __attribute__ ((unused))) {}
+#ifdef L_gcov_merge_topn
+void __gcov_merge_topn (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
#endif
#else
}
#endif /* L_gcov_merge_time_profile */
-#ifdef L_gcov_merge_single
+#ifdef L_gcov_merge_topn
static void
-merge_single_value_set (gcov_type *counters)
+merge_topn_values_set (gcov_type *counters)
{
/* First value is number of total executions of the profiler. */
gcov_type all = gcov_get_counter_ignore_scaling (-1);
++counters;
/* Read all part values. */
- gcov_type read_counters[2 * GCOV_DISK_SINGLE_VALUES];
+ gcov_type read_counters[2 * GCOV_TOPN_VALUES];
- for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
+ for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
read_counters[2 * i] = gcov_get_counter_target ();
read_counters[2 * i + 1] = gcov_get_counter_ignore_scaling (-1);
return;
}
- for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
+ for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
if (read_counters[2 * i + 1] == 0)
return;
unsigned j;
- for (j = 0; j < GCOV_DISK_SINGLE_VALUES; j++)
+ for (j = 0; j < GCOV_TOPN_VALUES; j++)
{
if (counters[2 * j] == read_counters[2 * i])
{
}
/* We haven't found a slot, bail out. */
- if (j == GCOV_DISK_SINGLE_VALUES)
+ if (j == GCOV_TOPN_VALUES)
{
counters[1] = -1;
return;
-- counter
*/
void
-__gcov_merge_single (gcov_type *counters, unsigned n_counters)
+__gcov_merge_topn (gcov_type *counters, unsigned n_counters)
{
- gcc_assert (!(n_counters % GCOV_SINGLE_VALUE_COUNTERS));
+ gcc_assert (!(n_counters % GCOV_TOPN_VALUES_COUNTERS));
- for (unsigned i = 0; i < (n_counters / GCOV_SINGLE_VALUE_COUNTERS); i++)
- merge_single_value_set (counters + (i * GCOV_SINGLE_VALUE_COUNTERS));
+ for (unsigned i = 0; i < (n_counters / GCOV_TOPN_VALUES_COUNTERS); i++)
+ merge_topn_values_set (counters + (i * GCOV_TOPN_VALUES_COUNTERS));
}
-#endif /* L_gcov_merge_single */
+#endif /* L_gcov_merge_topn */
#endif /* inhibit_libc */
#endif
-/* Tries to determine the most common value among its inputs. Checks if the
- value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
- is incremented. If this is not the case and COUNTERS[1] is not zero,
- COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
- VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
- function is called more than 50% of the time with one value, this value
- will be in COUNTERS[0] in the end. */
+/* Tries to determine N most commons value among its inputs. */
static inline void
-__gcov_one_value_profiler_body (gcov_type *counters, gcov_type value,
- int use_atomic)
+__gcov_topn_values_profiler_body (gcov_type *counters, gcov_type value,
+ int use_atomic)
{
if (use_atomic)
__atomic_fetch_add (&counters[0], 1, __ATOMIC_RELAXED);
++counters;
- /* We have GCOV_DISK_SINGLE_VALUES as we can keep multiple values
+ /* We have GCOV_TOPN_VALUES as we can keep multiple values
next to each other. */
unsigned sindex = 0;
- for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
+ for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
{
if (value == counters[2 * i])
{
counters[2 * sindex + 1]--;
}
-#ifdef L_gcov_one_value_profiler_v2
+#ifdef L_gcov_topn_values_profiler
void
-__gcov_one_value_profiler_v2 (gcov_type *counters, gcov_type value)
+__gcov_topn_values_profiler (gcov_type *counters, gcov_type value)
{
- __gcov_one_value_profiler_body (counters, value, 0);
+ __gcov_topn_values_profiler_body (counters, value, 0);
}
#endif
-#if defined(L_gcov_one_value_profiler_v2_atomic) && GCOV_SUPPORTS_ATOMIC
+#if defined(L_gcov_topn_values_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
/* Update one value profilers (COUNTERS) for a given VALUE.
https://gcc.gnu.org/ml/gcc-patches/2016-08/msg00024.html. */
void
-__gcov_one_value_profiler_v2_atomic (gcov_type *counters, gcov_type value)
+__gcov_topn_values_profiler_atomic (gcov_type *counters, gcov_type value)
{
- __gcov_one_value_profiler_body (counters, value, 1);
+ __gcov_topn_values_profiler_body (counters, value, 1);
}
#endif
if (cur_func == __gcov_indirect_call.callee
|| (__LIBGCC_VTABLE_USES_DESCRIPTORS__
&& *(void **) cur_func == *(void **) __gcov_indirect_call.callee))
- __gcov_one_value_profiler_body (__gcov_indirect_call.counters, value, 0);
+ __gcov_topn_values_profiler_body (__gcov_indirect_call.counters, value, 0);
__gcov_indirect_call.callee = NULL;
}
/* Do nothing. */
}
-/* Performing FN upon single counters. */
+/* Performing FN upon TOP N counters. */
static void
-__gcov_single_counter_op (gcov_type *counters, unsigned n_counters,
- counter_op_fn fn, void *data1, void *data2)
+__gcov_topn_counter_op (gcov_type *counters, unsigned n_counters,
+ counter_op_fn fn, void *data1, void *data2)
{
unsigned i, n_measures;
#define L_gcov 1
#define L_gcov_merge_add 1
-#define L_gcov_merge_single 1
+#define L_gcov_merge_topn 1
#define L_gcov_merge_ior 1
#define L_gcov_merge_time_profile 1
/* The merge function to select the minimum valid counter value. */
extern void __gcov_merge_time_profile (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
-/* The merge function to choose the most common value. */
-extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+/* The merge function to choose the most common N values. */
+extern void __gcov_merge_topn (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The merge function that just ors the counters together. */
extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
unsigned);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler_atomic (gcov_type *, gcov_type);
-extern void __gcov_one_value_profiler_v2 (gcov_type *, gcov_type);
-extern void __gcov_one_value_profiler_v2_atomic (gcov_type *, gcov_type);
+extern void __gcov_topn_values_profiler (gcov_type *, gcov_type);
+extern void __gcov_topn_values_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_indirect_call_profiler_v4 (gcov_type, void *);
extern void __gcov_time_profiler (gcov_type *);
extern void __gcov_time_profiler_atomic (gcov_type *);