From 1b309ca5edddd6bf8051993876df5f123394bc79 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 3 Jul 2019 14:42:02 +0200 Subject: [PATCH] Support N values in libgcov for single value counter type. 2019-07-03 Martin Liska * gcc.dg/tree-prof/val-prof-2.c: Update scanned pattern as we do now better. 2019-07-03 Martin Liska * libgcov-merge.c (merge_single_value_set): Support N values. * libgcov-profiler.c (__gcov_one_value_profiler_body): Likewise. From-SVN: r273004 --- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c | 5 +-- libgcc/ChangeLog | 5 +++ libgcc/libgcov-merge.c | 48 +++++++++++---------- libgcc/libgcov-profiler.c | 42 ++++++++++++++---- 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 + + * gcc.dg/tree-prof/val-prof-2.c: Update scanned pattern + as we do now better. + 2019-07-03 Eric Botcazou * 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 + + * libgcov-merge.c (merge_single_value_set): Support N values. + * libgcov-profiler.c (__gcov_one_value_profiler_body): Likewise. + 2019-06-27 Ilia Diachkov * 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 -- 2.30.2