public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/kubaneko/heads/histogram)] added histogram profiler and added it to division
@ 2022-07-13 12:49 Ondrej Kubanek
0 siblings, 0 replies; 3+ messages in thread
From: Ondrej Kubanek @ 2022-07-13 12:49 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:5ba98a98033c6a0e4307949dbcb58f9e6621e857
commit 5ba98a98033c6a0e4307949dbcb58f9e6621e857
Author: Ondrej Kubanek <kubanek0ondrej@gmail.com>
Date: Tue Jul 12 15:22:29 2022 +0200
added histogram profiler and added it to division
Diff:
---
gcc/gcov-counter.def | 4 ++++
gcc/profile.cc | 4 ++++
gcc/tree-profile.cc | 37 +++++++++++++++++++++++++++++++++++++
gcc/value-prof.cc | 30 +++++++++++++++++++++++++++++-
gcc/value-prof.h | 2 ++
libgcc/Makefile.in | 3 ++-
libgcc/libgcov-profiler.c | 29 +++++++++++++++++++++++++++++
libgcc/libgcov.h | 1 +
8 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/gcc/gcov-counter.def b/gcc/gcov-counter.def
index 6d2182bd3db..103c2a8c80a 100644
--- a/gcc/gcov-counter.def
+++ b/gcc/gcov-counter.def
@@ -49,3 +49,7 @@ 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)
+
+/* Histogram of values from 1 to 8 and them powers of 2 */
+DEF_GCOV_COUNTER(GCOV_COUNTER_V_HISTOGRAM, "histogram", _add)
+
diff --git a/gcc/profile.cc b/gcc/profile.cc
index a67cce5b199..b7d691d6767 100644
--- a/gcc/profile.cc
+++ b/gcc/profile.cc
@@ -188,6 +188,10 @@ instrument_values (histogram_values values)
case HIST_TYPE_TIME_PROFILE:
gimple_gen_time_profiler (t);
break;
+
+ case HIST_TYPE_HISTOGRAM:
+ gimple_gen_histogram_profiler (hist, t);
+ break;
default:
gcc_unreachable ();
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index 6d40401f86f..50cf40613ce 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
static GTY(()) tree gcov_type_node;
static GTY(()) tree tree_interval_profiler_fn;
static GTY(()) tree tree_pow2_profiler_fn;
+static GTY(()) tree tree_histogram_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;
@@ -119,6 +120,7 @@ gimple_init_gcov_profiler (void)
{
tree interval_profiler_fn_type;
tree pow2_profiler_fn_type;
+ tree histogram_profiler_fn_type;
tree topn_values_profiler_fn_type;
tree gcov_type_ptr;
tree ic_profiler_fn_type;
@@ -161,6 +163,19 @@ gimple_init_gcov_profiler (void)
= tree_cons (get_identifier ("leaf"), NULL,
DECL_ATTRIBUTES (tree_pow2_profiler_fn));
+ /* void (*) (gcov_type *, gcov_type) */
+ histogram_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_ptr, gcov_type_node,
+ NULL_TREE);
+ fn_name = concat ("__gcov_histogram_profiler", fn_suffix, NULL);
+ tree_histogram_profiler_fn = build_fn_decl (fn_name, histogram_profiler_fn_type);
+ free (CONST_CAST (char *, fn_name));
+ TREE_NOTHROW (tree_histogram_profiler_fn) = 1;
+ DECL_ATTRIBUTES (tree_histogram_profiler_fn)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (tree_histogram_profiler_fn));
+
/* void (*) (gcov_type *, gcov_type) */
topn_values_profiler_fn_type
= build_function_type_list (void_type_node,
@@ -228,6 +243,7 @@ gimple_init_gcov_profiler (void)
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_histogram_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);
@@ -336,6 +352,27 @@ gimple_gen_pow2_profiler (histogram_value value, unsigned tag)
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
}
+/* Output instructions as GIMPLE trees to increment the power of two histogram
+ counter. VALUE is the expression whose value is profiled. TAG is the tag
+ of the section for counters. */
+
+void
+gimple_gen_histogram_profiler (histogram_value value, unsigned tag)
+{
+ gimple *stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ tree ref_ptr = tree_coverage_counter_addr (tag, 0);
+ // TODO why does it crash
+ gcall *call;
+ tree val;
+
+ 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_histogram_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_NEW_STMT);
+}
+
/* 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. */
diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc
index 9785c7a03ea..b052d609d73 100644
--- a/gcc/value-prof.cc
+++ b/gcc/value-prof.cc
@@ -247,6 +247,22 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
(int64_t) hist->hvalue.counters[i]);
}
break;
+ case HIST_TYPE_HISTOGRAM:
+ if (hist->hvalue.counters){
+ for (int i=0; i<8; ++i){
+ fprintf (dump_file, "Histogram counter histogram%" PRId64
+ ":%" PRId64 ".\n",
+ (int64_t) i,
+ (int64_t) hist->hvalue.counters[i]);
+ }
+ for (int64_t i=4; i<64; ++i){
+ fprintf (dump_file, "Histogram counter histogram%" PRId64
+ ":%" PRId64 ".\n",
+ (int64_t) 1>>i,
+ (int64_t) hist->hvalue.counters[4+i]);
+ }
+ }
+ break;
case HIST_TYPE_POW2:
if (hist->hvalue.counters)
@@ -372,6 +388,9 @@ stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
ncounters = new_val->hdata.intvl.steps + 2;
break;
+ case HIST_TYPE_HISTOGRAM:
+ ncounters = 69;
+ break;
case HIST_TYPE_POW2:
case HIST_TYPE_AVERAGE:
ncounters = 2;
@@ -1806,12 +1825,16 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
divisor = gimple_assign_rhs2 (stmt);
op0 = gimple_assign_rhs1 (stmt);
- if (TREE_CODE (divisor) == SSA_NAME)
+ if (TREE_CODE (divisor) == SSA_NAME){
/* Check for the case where the divisor is the same value most
of the time. */
values->safe_push (gimple_alloc_histogram_value (cfun,
HIST_TYPE_TOPN_VALUES,
stmt, divisor));
+ values->safe_push (gimple_alloc_histogram_value (cfun,
+ HIST_TYPE_HISTOGRAM,
+ stmt, divisor));
+ }
/* For mod, check whether it is not often a noop (or replaceable by
a few subtractions). */
@@ -1824,6 +1847,7 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
values->safe_push (gimple_alloc_histogram_value (cfun,
HIST_TYPE_POW2,
stmt, divisor));
+
val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
stmt, val);
@@ -1932,6 +1956,10 @@ gimple_find_values_to_profile (histogram_values *values)
hist->n_counters = hist->hdata.intvl.steps + 2;
break;
+
+ case HIST_TYPE_HISTOGRAM:
+ hist->n_counters = 69;
+ break;
case HIST_TYPE_POW2:
hist->n_counters = 2;
break;
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index d852c41f33f..91c46f2accb 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -32,6 +32,7 @@ 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_HISTOGRAM, /* used values histogram */
HIST_TYPE_MAX
};
@@ -99,6 +100,7 @@ extern void gimple_init_gcov_profiler (void);
extern void gimple_gen_edge_profiler (int, edge);
extern void gimple_gen_interval_profiler (histogram_value, unsigned);
extern void gimple_gen_pow2_profiler (histogram_value, unsigned);
+extern void gimple_gen_histogram_profiler (histogram_value, unsigned);
extern void gimple_gen_topn_values_profiler (histogram_value, unsigned);
extern void gimple_gen_ic_profiler (histogram_value, unsigned);
extern void gimple_gen_ic_func_profiler (void);
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 09b3ec8bc2e..5ebb2189027 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -903,7 +903,8 @@ LIBGCOV_PROFILER = _gcov_interval_profiler \
_gcov_ior_profiler \
_gcov_ior_profiler_atomic \
_gcov_indirect_call_profiler_v4 \
- _gcov_time_profiler
+ _gcov_time_profiler \
+ _gcov_histogram_profiler
LIBGCOV_INTERFACE = _gcov_dump _gcov_fork \
_gcov_execl _gcov_execlp \
_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 57617857a93..8229e047b0e 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -26,6 +26,35 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h"
#if !defined(inhibit_libc)
+#ifdef L_gcov_histogram_profiler
+/*
+ * If value is less then 8 we increment corresponding counter
+ * otherwise we take its logarithm and increment corresponding counter
+ */
+
+void
+__gcov_histogram_profiler (gcov_type *counters, gcov_type value)
+{
+ if (value>0 && value<8){
+ counters[value-1]++;
+ }else{
+ int pow2 = 3;
+ while (1 >> pow2 <= value){
+ ++pow2;
+ }
+ // pow2 is first bigger power of 2
+ // we increment closer power of 2
+ if ((1>>pow2+1>>(pow2-1))<<1<value){
+ counters[6+(pow2-3)-1]++;
+ }
+ else{
+ counters[6+(pow2-3)]++;
+ }
+ }
+}
+
+#endif
+
#ifdef L_gcov_interval_profiler
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 40e845ce3ea..235809bacdc 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -318,6 +318,7 @@ extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_interval_profiler_atomic (gcov_type *, gcov_type, int,
unsigned);
+extern void __gcov_histogram_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_topn_values_profiler (gcov_type *, gcov_type);
^ permalink raw reply [flat|nested] 3+ messages in thread
* [gcc(refs/users/kubaneko/heads/histogram)] added histogram profiler and added it to division
@ 2023-02-23 23:20 Ondrej Kubanek
0 siblings, 0 replies; 3+ messages in thread
From: Ondrej Kubanek @ 2023-02-23 23:20 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e6f3908a2e954b5b584213eb87995f163c87b667
commit e6f3908a2e954b5b584213eb87995f163c87b667
Author: Ondrej Kubanek <kubanek0ondrej@gmail.com>
Date: Tue Jul 12 15:22:29 2022 +0200
added histogram profiler and added it to division
Diff:
---
gcc/gcov-counter.def | 4 ++++
gcc/profile.cc | 4 ++++
gcc/tree-profile.cc | 37 +++++++++++++++++++++++++++++++++++++
gcc/value-prof.cc | 30 +++++++++++++++++++++++++++++-
gcc/value-prof.h | 2 ++
libgcc/Makefile.in | 3 ++-
libgcc/libgcov-profiler.c | 29 +++++++++++++++++++++++++++++
libgcc/libgcov.h | 1 +
8 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/gcc/gcov-counter.def b/gcc/gcov-counter.def
index 727ef424181..2b83e80bf61 100644
--- a/gcc/gcov-counter.def
+++ b/gcc/gcov-counter.def
@@ -49,3 +49,7 @@ 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)
+
+/* Histogram of values from 1 to 8 and them powers of 2 */
+DEF_GCOV_COUNTER(GCOV_COUNTER_V_HISTOGRAM, "histogram", _add)
+
diff --git a/gcc/profile.cc b/gcc/profile.cc
index a71800d5ce6..4fa812fcaba 100644
--- a/gcc/profile.cc
+++ b/gcc/profile.cc
@@ -188,6 +188,10 @@ instrument_values (histogram_values values)
case HIST_TYPE_TIME_PROFILE:
gimple_gen_time_profiler (t);
break;
+
+ case HIST_TYPE_HISTOGRAM:
+ gimple_gen_histogram_profiler (hist, t);
+ break;
default:
gcc_unreachable ();
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index ea9d7a23443..868fcb01ef3 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
static GTY(()) tree gcov_type_node;
static GTY(()) tree tree_interval_profiler_fn;
static GTY(()) tree tree_pow2_profiler_fn;
+static GTY(()) tree tree_histogram_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;
@@ -119,6 +120,7 @@ gimple_init_gcov_profiler (void)
{
tree interval_profiler_fn_type;
tree pow2_profiler_fn_type;
+ tree histogram_profiler_fn_type;
tree topn_values_profiler_fn_type;
tree gcov_type_ptr;
tree ic_profiler_fn_type;
@@ -161,6 +163,19 @@ gimple_init_gcov_profiler (void)
= tree_cons (get_identifier ("leaf"), NULL,
DECL_ATTRIBUTES (tree_pow2_profiler_fn));
+ /* void (*) (gcov_type *, gcov_type) */
+ histogram_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_ptr, gcov_type_node,
+ NULL_TREE);
+ fn_name = concat ("__gcov_histogram_profiler", fn_suffix, NULL);
+ tree_histogram_profiler_fn = build_fn_decl (fn_name, histogram_profiler_fn_type);
+ free (CONST_CAST (char *, fn_name));
+ TREE_NOTHROW (tree_histogram_profiler_fn) = 1;
+ DECL_ATTRIBUTES (tree_histogram_profiler_fn)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (tree_histogram_profiler_fn));
+
/* void (*) (gcov_type *, gcov_type) */
topn_values_profiler_fn_type
= build_function_type_list (void_type_node,
@@ -228,6 +243,7 @@ gimple_init_gcov_profiler (void)
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_histogram_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);
@@ -336,6 +352,27 @@ gimple_gen_pow2_profiler (histogram_value value, unsigned tag)
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
}
+/* Output instructions as GIMPLE trees to increment the power of two histogram
+ counter. VALUE is the expression whose value is profiled. TAG is the tag
+ of the section for counters. */
+
+void
+gimple_gen_histogram_profiler (histogram_value value, unsigned tag)
+{
+ gimple *stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ tree ref_ptr = tree_coverage_counter_addr (tag, 0);
+ // TODO why does it crash
+ gcall *call;
+ tree val;
+
+ 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_histogram_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_NEW_STMT);
+}
+
/* 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. */
diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc
index f40e58ac4f2..fe414cbacfd 100644
--- a/gcc/value-prof.cc
+++ b/gcc/value-prof.cc
@@ -247,6 +247,22 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
(int64_t) hist->hvalue.counters[i]);
}
break;
+ case HIST_TYPE_HISTOGRAM:
+ if (hist->hvalue.counters){
+ for (int i=0; i<8; ++i){
+ fprintf (dump_file, "Histogram counter histogram%" PRId64
+ ":%" PRId64 ".\n",
+ (int64_t) i,
+ (int64_t) hist->hvalue.counters[i]);
+ }
+ for (int64_t i=4; i<64; ++i){
+ fprintf (dump_file, "Histogram counter histogram%" PRId64
+ ":%" PRId64 ".\n",
+ (int64_t) 1>>i,
+ (int64_t) hist->hvalue.counters[4+i]);
+ }
+ }
+ break;
case HIST_TYPE_POW2:
if (hist->hvalue.counters)
@@ -364,6 +380,9 @@ stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
ncounters = new_val->hdata.intvl.steps + 2;
break;
+ case HIST_TYPE_HISTOGRAM:
+ ncounters = 69;
+ break;
case HIST_TYPE_POW2:
case HIST_TYPE_AVERAGE:
ncounters = 2;
@@ -1798,12 +1817,16 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
divisor = gimple_assign_rhs2 (stmt);
op0 = gimple_assign_rhs1 (stmt);
- if (TREE_CODE (divisor) == SSA_NAME)
+ if (TREE_CODE (divisor) == SSA_NAME){
/* Check for the case where the divisor is the same value most
of the time. */
values->safe_push (gimple_alloc_histogram_value (cfun,
HIST_TYPE_TOPN_VALUES,
stmt, divisor));
+ values->safe_push (gimple_alloc_histogram_value (cfun,
+ HIST_TYPE_HISTOGRAM,
+ stmt, divisor));
+ }
/* For mod, check whether it is not often a noop (or replaceable by
a few subtractions). */
@@ -1816,6 +1839,7 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
values->safe_push (gimple_alloc_histogram_value (cfun,
HIST_TYPE_POW2,
stmt, divisor));
+
val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
stmt, val);
@@ -1924,6 +1948,10 @@ gimple_find_values_to_profile (histogram_values *values)
hist->n_counters = hist->hdata.intvl.steps + 2;
break;
+
+ case HIST_TYPE_HISTOGRAM:
+ hist->n_counters = 69;
+ break;
case HIST_TYPE_POW2:
hist->n_counters = 2;
break;
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index 0cfd5adb8bc..991f29f8c6b 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -32,6 +32,7 @@ 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_HISTOGRAM, /* used values histogram */
HIST_TYPE_MAX
};
@@ -99,6 +100,7 @@ extern void gimple_init_gcov_profiler (void);
extern void gimple_gen_edge_profiler (int, edge);
extern void gimple_gen_interval_profiler (histogram_value, unsigned);
extern void gimple_gen_pow2_profiler (histogram_value, unsigned);
+extern void gimple_gen_histogram_profiler (histogram_value, unsigned);
extern void gimple_gen_topn_values_profiler (histogram_value, unsigned);
extern void gimple_gen_ic_profiler (histogram_value, unsigned);
extern void gimple_gen_ic_func_profiler (void);
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 6c4dc79ab71..74e3602347a 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -906,7 +906,8 @@ LIBGCOV_PROFILER = _gcov_interval_profiler \
_gcov_ior_profiler \
_gcov_ior_profiler_atomic \
_gcov_indirect_call_profiler_v4 \
- _gcov_time_profiler
+ _gcov_time_profiler \
+ _gcov_histogram_profiler
LIBGCOV_INTERFACE = _gcov_dump _gcov_fork \
_gcov_execl _gcov_execlp \
_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 1e870597d6c..ed5769c284a 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -26,6 +26,35 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h"
#if !defined(inhibit_libc)
+#ifdef L_gcov_histogram_profiler
+/*
+ * If value is less then 8 we increment corresponding counter
+ * otherwise we take its logarithm and increment corresponding counter
+ */
+
+void
+__gcov_histogram_profiler (gcov_type *counters, gcov_type value)
+{
+ if (value>0 && value<8){
+ counters[value-1]++;
+ }else{
+ int pow2 = 3;
+ while (1 >> pow2 <= value){
+ ++pow2;
+ }
+ // pow2 is first bigger power of 2
+ // we increment closer power of 2
+ if ((1>>pow2+1>>(pow2-1))<<1<value){
+ counters[6+(pow2-3)-1]++;
+ }
+ else{
+ counters[6+(pow2-3)]++;
+ }
+ }
+}
+
+#endif
+
#ifdef L_gcov_interval_profiler
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 92df440d401..d3eac74b766 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -317,6 +317,7 @@ extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_interval_profiler_atomic (gcov_type *, gcov_type, int,
unsigned);
+extern void __gcov_histogram_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_topn_values_profiler (gcov_type *, gcov_type);
^ permalink raw reply [flat|nested] 3+ messages in thread
* [gcc(refs/users/kubaneko/heads/histogram)] added histogram profiler and added it to division
@ 2023-02-16 16:26 Ondrej Kubanek
0 siblings, 0 replies; 3+ messages in thread
From: Ondrej Kubanek @ 2023-02-16 16:26 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7d06eb71574d412bf230182b536937a8f385f298
commit 7d06eb71574d412bf230182b536937a8f385f298
Author: Ondrej Kubanek <kubanek0ondrej@gmail.com>
Date: Tue Jul 12 15:22:29 2022 +0200
added histogram profiler and added it to division
Diff:
---
gcc/gcov-counter.def | 4 ++++
gcc/profile.cc | 4 ++++
gcc/tree-profile.cc | 37 +++++++++++++++++++++++++++++++++++++
gcc/value-prof.cc | 30 +++++++++++++++++++++++++++++-
gcc/value-prof.h | 2 ++
libgcc/Makefile.in | 3 ++-
libgcc/libgcov-profiler.c | 29 +++++++++++++++++++++++++++++
libgcc/libgcov.h | 1 +
8 files changed, 108 insertions(+), 2 deletions(-)
diff --git a/gcc/gcov-counter.def b/gcc/gcov-counter.def
index 6d2182bd3db..103c2a8c80a 100644
--- a/gcc/gcov-counter.def
+++ b/gcc/gcov-counter.def
@@ -49,3 +49,7 @@ 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)
+
+/* Histogram of values from 1 to 8 and them powers of 2 */
+DEF_GCOV_COUNTER(GCOV_COUNTER_V_HISTOGRAM, "histogram", _add)
+
diff --git a/gcc/profile.cc b/gcc/profile.cc
index 96121d60711..b9c355f2030 100644
--- a/gcc/profile.cc
+++ b/gcc/profile.cc
@@ -188,6 +188,10 @@ instrument_values (histogram_values values)
case HIST_TYPE_TIME_PROFILE:
gimple_gen_time_profiler (t);
break;
+
+ case HIST_TYPE_HISTOGRAM:
+ gimple_gen_histogram_profiler (hist, t);
+ break;
default:
gcc_unreachable ();
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index 2beb49241f2..d79212afddb 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
static GTY(()) tree gcov_type_node;
static GTY(()) tree tree_interval_profiler_fn;
static GTY(()) tree tree_pow2_profiler_fn;
+static GTY(()) tree tree_histogram_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;
@@ -119,6 +120,7 @@ gimple_init_gcov_profiler (void)
{
tree interval_profiler_fn_type;
tree pow2_profiler_fn_type;
+ tree histogram_profiler_fn_type;
tree topn_values_profiler_fn_type;
tree gcov_type_ptr;
tree ic_profiler_fn_type;
@@ -161,6 +163,19 @@ gimple_init_gcov_profiler (void)
= tree_cons (get_identifier ("leaf"), NULL,
DECL_ATTRIBUTES (tree_pow2_profiler_fn));
+ /* void (*) (gcov_type *, gcov_type) */
+ histogram_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_ptr, gcov_type_node,
+ NULL_TREE);
+ fn_name = concat ("__gcov_histogram_profiler", fn_suffix, NULL);
+ tree_histogram_profiler_fn = build_fn_decl (fn_name, histogram_profiler_fn_type);
+ free (CONST_CAST (char *, fn_name));
+ TREE_NOTHROW (tree_histogram_profiler_fn) = 1;
+ DECL_ATTRIBUTES (tree_histogram_profiler_fn)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (tree_histogram_profiler_fn));
+
/* void (*) (gcov_type *, gcov_type) */
topn_values_profiler_fn_type
= build_function_type_list (void_type_node,
@@ -228,6 +243,7 @@ gimple_init_gcov_profiler (void)
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_histogram_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);
@@ -336,6 +352,27 @@ gimple_gen_pow2_profiler (histogram_value value, unsigned tag)
gsi_insert_before (&gsi, call, GSI_NEW_STMT);
}
+/* Output instructions as GIMPLE trees to increment the power of two histogram
+ counter. VALUE is the expression whose value is profiled. TAG is the tag
+ of the section for counters. */
+
+void
+gimple_gen_histogram_profiler (histogram_value value, unsigned tag)
+{
+ gimple *stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ tree ref_ptr = tree_coverage_counter_addr (tag, 0);
+ // TODO why does it crash
+ gcall *call;
+ tree val;
+
+ 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_histogram_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_NEW_STMT);
+}
+
/* 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. */
diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc
index 9656ce5870d..80b17f56661 100644
--- a/gcc/value-prof.cc
+++ b/gcc/value-prof.cc
@@ -247,6 +247,22 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
(int64_t) hist->hvalue.counters[i]);
}
break;
+ case HIST_TYPE_HISTOGRAM:
+ if (hist->hvalue.counters){
+ for (int i=0; i<8; ++i){
+ fprintf (dump_file, "Histogram counter histogram%" PRId64
+ ":%" PRId64 ".\n",
+ (int64_t) i,
+ (int64_t) hist->hvalue.counters[i]);
+ }
+ for (int64_t i=4; i<64; ++i){
+ fprintf (dump_file, "Histogram counter histogram%" PRId64
+ ":%" PRId64 ".\n",
+ (int64_t) 1>>i,
+ (int64_t) hist->hvalue.counters[4+i]);
+ }
+ }
+ break;
case HIST_TYPE_POW2:
if (hist->hvalue.counters)
@@ -364,6 +380,9 @@ stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
ncounters = new_val->hdata.intvl.steps + 2;
break;
+ case HIST_TYPE_HISTOGRAM:
+ ncounters = 69;
+ break;
case HIST_TYPE_POW2:
case HIST_TYPE_AVERAGE:
ncounters = 2;
@@ -1798,12 +1817,16 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
divisor = gimple_assign_rhs2 (stmt);
op0 = gimple_assign_rhs1 (stmt);
- if (TREE_CODE (divisor) == SSA_NAME)
+ if (TREE_CODE (divisor) == SSA_NAME){
/* Check for the case where the divisor is the same value most
of the time. */
values->safe_push (gimple_alloc_histogram_value (cfun,
HIST_TYPE_TOPN_VALUES,
stmt, divisor));
+ values->safe_push (gimple_alloc_histogram_value (cfun,
+ HIST_TYPE_HISTOGRAM,
+ stmt, divisor));
+ }
/* For mod, check whether it is not often a noop (or replaceable by
a few subtractions). */
@@ -1816,6 +1839,7 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values)
values->safe_push (gimple_alloc_histogram_value (cfun,
HIST_TYPE_POW2,
stmt, divisor));
+
val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
stmt, val);
@@ -1924,6 +1948,10 @@ gimple_find_values_to_profile (histogram_values *values)
hist->n_counters = hist->hdata.intvl.steps + 2;
break;
+
+ case HIST_TYPE_HISTOGRAM:
+ hist->n_counters = 69;
+ break;
case HIST_TYPE_POW2:
hist->n_counters = 2;
break;
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index d852c41f33f..91c46f2accb 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -32,6 +32,7 @@ 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_HISTOGRAM, /* used values histogram */
HIST_TYPE_MAX
};
@@ -99,6 +100,7 @@ extern void gimple_init_gcov_profiler (void);
extern void gimple_gen_edge_profiler (int, edge);
extern void gimple_gen_interval_profiler (histogram_value, unsigned);
extern void gimple_gen_pow2_profiler (histogram_value, unsigned);
+extern void gimple_gen_histogram_profiler (histogram_value, unsigned);
extern void gimple_gen_topn_values_profiler (histogram_value, unsigned);
extern void gimple_gen_ic_profiler (histogram_value, unsigned);
extern void gimple_gen_ic_func_profiler (void);
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 1fe708a93f7..db430e0b6af 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -906,7 +906,8 @@ LIBGCOV_PROFILER = _gcov_interval_profiler \
_gcov_ior_profiler \
_gcov_ior_profiler_atomic \
_gcov_indirect_call_profiler_v4 \
- _gcov_time_profiler
+ _gcov_time_profiler \
+ _gcov_histogram_profiler
LIBGCOV_INTERFACE = _gcov_dump _gcov_fork \
_gcov_execl _gcov_execlp \
_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 57617857a93..8229e047b0e 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -26,6 +26,35 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h"
#if !defined(inhibit_libc)
+#ifdef L_gcov_histogram_profiler
+/*
+ * If value is less then 8 we increment corresponding counter
+ * otherwise we take its logarithm and increment corresponding counter
+ */
+
+void
+__gcov_histogram_profiler (gcov_type *counters, gcov_type value)
+{
+ if (value>0 && value<8){
+ counters[value-1]++;
+ }else{
+ int pow2 = 3;
+ while (1 >> pow2 <= value){
+ ++pow2;
+ }
+ // pow2 is first bigger power of 2
+ // we increment closer power of 2
+ if ((1>>pow2+1>>(pow2-1))<<1<value){
+ counters[6+(pow2-3)-1]++;
+ }
+ else{
+ counters[6+(pow2-3)]++;
+ }
+ }
+}
+
+#endif
+
#ifdef L_gcov_interval_profiler
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index c7545cc746e..c01b5afe04b 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -317,6 +317,7 @@ extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_interval_profiler_atomic (gcov_type *, gcov_type, int,
unsigned);
+extern void __gcov_histogram_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_pow2_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_topn_values_profiler (gcov_type *, gcov_type);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-02-23 23:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-13 12:49 [gcc(refs/users/kubaneko/heads/histogram)] added histogram profiler and added it to division Ondrej Kubanek
2023-02-16 16:26 Ondrej Kubanek
2023-02-23 23:20 Ondrej Kubanek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).