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
@ 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

* [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

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 --
2023-02-23 23:20 [gcc(refs/users/kubaneko/heads/histogram)] added histogram profiler and added it to division Ondrej Kubanek
  -- strict thread matches above, loose matches on Subject: below --
2023-02-16 16:26 Ondrej Kubanek
2022-07-13 12:49 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).