From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7880) id 6EB02385041D; Wed, 13 Jul 2022 12:49:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6EB02385041D Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Ondrej Kubanek To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/kubaneko/heads/histogram)] added histogram profiler and added it to division X-Act-Checkin: gcc X-Git-Author: Ondrej Kubanek X-Git-Refname: refs/users/kubaneko/heads/histogram X-Git-Oldrev: f0ccbe10f152b55fb809264d2ae11c724ab09ff6 X-Git-Newrev: 5ba98a98033c6a0e4307949dbcb58f9e6621e857 Message-Id: <20220713124921.6EB02385041D@sourceware.org> Date: Wed, 13 Jul 2022 12:49:21 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jul 2022 12:49:21 -0000 https://gcc.gnu.org/g:5ba98a98033c6a0e4307949dbcb58f9e6621e857 commit 5ba98a98033c6a0e4307949dbcb58f9e6621e857 Author: Ondrej Kubanek 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, 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);