summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2019-07-03 14:42:02 +0200
committerMartin Liska <marxin@gcc.gnu.org>2019-07-03 12:42:02 +0000
commit1b309ca5edddd6bf8051993876df5f123394bc79 (patch)
tree403bccc3950ad5d8c2f3b4fd08e0d79ed37327c2
parente157be919b83177d57666234cd19f6b042140ac1 (diff)
Support N values in libgcov for single value counter type.
2019-07-03 Martin Liska <mliska@suse.cz> * gcc.dg/tree-prof/val-prof-2.c: Update scanned pattern as we do now better. 2019-07-03 Martin Liska <mliska@suse.cz> * libgcov-merge.c (merge_single_value_set): Support N values. * libgcov-profiler.c (__gcov_one_value_profiler_body): Likewise. From-SVN: r273004
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c5
-rw-r--r--libgcc/ChangeLog5
-rw-r--r--libgcc/libgcov-merge.c48
-rw-r--r--libgcc/libgcov-profiler.c42
5 files changed, 70 insertions, 35 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 656b589c0b8..0214647af97 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-07-03 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/tree-prof/val-prof-2.c: Update scanned pattern
+ as we do now better.
+
2019-07-03 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/debug1.ads: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c
index 8cb3c64fd17..b3bbadfeb40 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c
@@ -25,8 +25,5 @@ main ()
return 0;
}
/* autofdo does not do value profiling so far */
-/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: mod power of 2" "profile" } } */
-/* This is part of code checking that n is power of 2, so we are sure that the transformation
- didn't get optimized out. */
-/* { dg-final-use-not-autofdo { scan-tree-dump "n_\[0-9\]* \\+ (4294967295|0x0*ffffffff)" "optimized"} } */
+/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: div/mod by constant 256" "profile" } } */
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index d69e55efdd0..90183dcb393 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,8 @@
+2019-07-03 Martin Liska <mliska@suse.cz>
+
+ * libgcov-merge.c (merge_single_value_set): Support N values.
+ * libgcov-profiler.c (__gcov_one_value_profiler_body): Likewise.
+
2019-06-27 Ilia Diachkov <ilia.diachkov@optimitech.com>
* Makefile.in (USE_TM_CLONE_REGISTRY): New.
diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c
index f778cc4b6b7..84367005663 100644
--- a/libgcc/libgcov-merge.c
+++ b/libgcc/libgcov-merge.c
@@ -89,49 +89,53 @@ __gcov_merge_time_profile (gcov_type *counters, unsigned n_counters)
static void
merge_single_value_set (gcov_type *counters)
{
- unsigned j;
- gcov_type value, counter;
-
/* First value is number of total executions of the profiler. */
gcov_type all = gcov_get_counter_ignore_scaling (-1);
counters[0] += all;
++counters;
+ /* Read all part values. */
+ gcov_type read_counters[2 * GCOV_DISK_SINGLE_VALUES];
+
for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
{
- value = gcov_get_counter_target ();
- counter = gcov_get_counter_ignore_scaling (-1);
+ read_counters[2 * i] = gcov_get_counter_target ();
+ read_counters[2 * i + 1] = gcov_get_counter_ignore_scaling (-1);
+ }
- if (counter == -1)
- {
- counters[1] = -1;
- /* We can't return as we need to read all counters. */
- continue;
- }
- else if (counter == 0 || counters[1] == -1)
- {
- /* We can't return as we need to read all counters. */
- continue;
- }
+ if (read_counters[1] == -1)
+ {
+ counters[1] = -1;
+ return;
+ }
+
+ for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
+ {
+ if (read_counters[2 * i + 1] == 0)
+ return;
+ unsigned j;
for (j = 0; j < GCOV_DISK_SINGLE_VALUES; j++)
{
- if (counters[2 * j] == value)
+ if (counters[2 * j] == read_counters[2 * i])
{
- counters[2 * j + 1] += counter;
+ counters[2 * j + 1] += read_counters[2 * i + 1];
break;
}
else if (counters[2 * j + 1] == 0)
{
- counters[2 * j] = value;
- counters[2 * j + 1] = counter;
+ counters[2 * j] += read_counters[2 * i];
+ counters[2 * j + 1] += read_counters[2 * i + 1];
break;
}
}
- /* We haven't found a free slot for the value, mark overflow. */
+ /* We haven't found a slot, bail out. */
if (j == GCOV_DISK_SINGLE_VALUES)
- counters[1] = -1;
+ {
+ counters[1] = -1;
+ return;
+ }
}
}
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 9ba65b90df3..04d6f9c0e40 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -118,20 +118,44 @@ static inline void
__gcov_one_value_profiler_body (gcov_type *counters, gcov_type value,
int use_atomic)
{
- if (value == counters[1])
- counters[2]++;
- else if (counters[2] == 0)
+ if (use_atomic)
+ __atomic_fetch_add (&counters[0], 1, __ATOMIC_RELAXED);
+ else
+ counters[0]++;
+
+ ++counters;
+
+ /* We have GCOV_DISK_SINGLE_VALUES as we can keep multiple values
+ next to each other. */
+ unsigned sindex = 0;
+
+ for (unsigned i = 0; i < GCOV_DISK_SINGLE_VALUES; i++)
{
- counters[2] = 1;
- counters[1] = value;
+ if (value == counters[2 * i])
+ {
+ if (use_atomic)
+ __atomic_fetch_add (&counters[2 * i + 1], 1, __ATOMIC_RELAXED);
+ else
+ counters[2 * i + 1]++;
+ return;
+ }
+ else if (counters[2 * i + 1] == 0)
+ {
+ /* We found an empty slot. */
+ counters[2 * i] = value;
+ counters[2 * i + 1] = 1;
+ return;
+ }
+
+ if (counters[2 * i + 1] < counters[2 * sindex + 1])
+ sindex = i;
}
- else
- counters[2]--;
+ /* We haven't found an empty slot, then decrement the smallest. */
if (use_atomic)
- __atomic_fetch_add (&counters[0], 1, __ATOMIC_RELAXED);
+ __atomic_fetch_sub (&counters[2 * sindex + 1], 1, __ATOMIC_RELAXED);
else
- counters[0]++;
+ counters[2 * sindex + 1]--;
}
#ifdef L_gcov_one_value_profiler_v2