Hello.

Currently, we utilize pow2 profile histogram to track gimple STMTs like this: 
ssa_name_x % value.

void
__gcov_pow2_profiler (gcov_type *counters, gcov_type value)
{
  if (value & (value - 1))
    counters[0]++;
  else
    counters[1]++;
}

Although __gcov_pow2_profiler function wrongly handles 0 (which is not power of 
two), it's impossible
to write a test-case which would not expose a division by zero. As one can 
potentially use the same profiler
for a different purpose, I would like to fix it. Apart from that, we've got a 
small bug in a dump function
of the POW2 histograms.

Survives make check -k -j10 RUNTESTFLAGS="tree-prof.exp"
Ready for trunk?

Thanks,
Martin
>From 5c1173eec8bb6a16d2a570e845075c6e868a26f9 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Mon, 8 Aug 2016 18:44:19 +0200
Subject: [PATCH] Fix POW2 histogram

gcc/testsuite/ChangeLog:

2016-08-08  Martin Liska  <mli...@suse.cz>

	* gcc.dg/tree-prof/val-prof-8.c: New test.

gcc/ChangeLog:

2016-08-08  Martin Liska  <mli...@suse.cz>

	* value-prof.c (dump_histogram_value): Swap pow2 and non-pow2
	values.

libgcc/ChangeLog:

2016-08-08  Martin Liska  <mli...@suse.cz>

	* libgcov-profiler.c (__gcov_pow2_profiler): Consider 0 as not
	power of two.
---
 gcc/testsuite/gcc.dg/tree-prof/val-prof-8.c | 19 +++++++++++++++++++
 gcc/value-prof.c                            |  4 ++--
 libgcc/libgcov-profiler.c                   |  2 +-
 3 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-prof/val-prof-8.c

diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-8.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-8.c
new file mode 100644
index 0000000..2c505e3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-8.c
@@ -0,0 +1,19 @@
+/* { dg-options "-O0 -fdump-ipa-profile" } */
+
+int
+main (int argc, char **argv)
+{
+  unsigned u = (argc - 1);
+  int counter = 0;
+
+  for (unsigned i = 0; i < 100; i++)
+  {
+    unsigned x = i < 10 ? 16 : 15;
+    counter += u % x;
+  }
+
+  return counter;
+}
+
+/* autofdo does not do value profiling so far */
+/* { dg-final-use-not-autofdo { scan-ipa-dump "Pow2 counter pow2:10 nonpow2:90." "profile" } } */
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 2976a86..0527c2c 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -264,8 +264,8 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
 	{
 	   fprintf (dump_file, "pow2:%" PRId64
 		    " nonpow2:%" PRId64,
-		    (int64_t) hist->hvalue.counters[0],
-		    (int64_t) hist->hvalue.counters[1]);
+		    (int64_t) hist->hvalue.counters[1],
+		    (int64_t) hist->hvalue.counters[0]);
 	}
       fprintf (dump_file, ".\n");
       break;
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index e947188..6da8a94 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -53,7 +53,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value,
 void
 __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
 {
-  if (value & (value - 1))
+  if (value == 0 || (value & (value - 1)))
     counters[0]++;
   else
     counters[1]++;
-- 
2.9.2

Reply via email to