public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
To: Richard Biener <richard.guenther@gmail.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] gcov: Fix -fprofile-update=atomic
Date: Thu, 15 Dec 2022 09:34:17 +0100	[thread overview]
Message-ID: <2d6f0cf1-f979-b3a6-6daa-81fc0882a1d7@embedded-brains.de> (raw)
In-Reply-To: <CAFiYyc0V=5RDhF-ofOgaMcbC6UeaxC8E5j-uhrduGQpzzqUqyw@mail.gmail.com>

On 13/12/2022 15:30, Richard Biener wrote:
> On Fri, Dec 9, 2022 at 2:56 PM Sebastian Huber
> <sebastian.huber@embedded-brains.de>  wrote:
>> The code coverage support uses counters to determine which edges in the control
>> flow graph were executed.  If a counter overflows, then the code coverage
>> information is invalid.  Therefore the counter type should be a 64-bit integer.
>> In multithreaded applications, it is important that the counter increments are
>> atomic.  This is not the case by default.  The user can enable atomic counter
>> increments through the -fprofile-update=atomic and
>> -fprofile-update=prefer-atomic options.
>>
>> If the hardware supports 64-bit atomic operations, then everything is fine.  If
>> not and -fprofile-update=prefer-atomic was chosen by the user, then non-atomic
>> counter increments will be used.  However, if the hardware does not support the
>> required atomic operations and -fprofile-atomic=update was chosen by the user,
>> then a warning was issued and as a forced fall-back to non-atomic operations
>> was done.  This is probably not what a user wants.  There is still hardware on
>> the market which does not have atomic operations and is used for multithreaded
>> applications.  A user which selects -fprofile-update=atomic wants consistent
>> code coverage data and not random data.
>>
>> This patch removes the fall-back to non-atomic operations for
>> -fprofile-update=atomic.  If atomic operations in hardware are not available,
>> then a library call to libatomic is emitted.  To mitigate potential performance
>> issues an optimization for systems which only support 32-bit atomic operations
>> is provided.  Here, the edge counter increments are done like this:
>>
>>    low = __atomic_add_fetch_4 (&counter.low, 1, MEMMODEL_RELAXED);
>>    high_inc = low == 0 ? 1 : 0;
>>    __atomic_add_fetch_4 (&counter.high, high_inc, MEMMODEL_RELAXED);
> You check for compare_and_swapsi and the old code checks
> TYPE_PRECISION (gcov_type_node) > 32 to determine whether 8 byte or 4 byte
> gcov_type is used.  But you do not seem to handle the case where
> neither SImode nor DImode atomic operations are available?  Can we instead
> do
> 
>    if (gcov_type_size == 4)
>      can_support_atomic4
>        = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
>    else if (gcov_type_size == 8)
>      can_support_atomic8
>        = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
> 
>    if (flag_profile_update == PROFILE_UPDATE_ATOMIC
>        && !can_support_atomic4 && !can_support_atomic8)
>      {
>        warning (0, "target does not support atomic profile update, "
>                 "single mode is selected");
>        flag_profile_update = PROFILE_UPDATE_SINGLE;
>      }
> 
> thus retain the diagnostic & fallback for this case?  

No, if you select -fprofile-update=atomic, then the updates shall be 
atomic from my point of view. If a fallback is acceptable, then you can 
use -fprofile-update=prefer-atomic. Using the fallback in 
-fprofile-update=atomic is a bug which prevents the use of gcov for 
multi-threaded applications on the lower end targets which do not have 
atomic operations in hardware.

> The existing
> code also suggests
> there might be targets with HImode or TImode counters?

Sorry, I don't know.

> 
> In another mail you mentioned that for gen_time_profiler this doesn't
> work but its
> code relies on flag_profile_update as well.  So do we need to split the flag
> somehow, or continue using the PROFILE_UPDATE_SINGLE fallback when
> we are doing more than just edge profiling?

If atomic operations are not available in hardware, then with this patch 
calls to libatomic are emitted. In gen_time_profiler() this is not an 
issue at all, since the atomic increment is only done if counters[0] == 
0 (if I read the code correctly).

For example for

void f(void) {}

we get on riscv:

gcc --coverage -O2 -S -o - test.c -fprofile-update=atomic

         lui     a4,%hi(__gcov0.f)
         li      a3,1
         addi    a4,a4,%lo(__gcov0.f)
         amoadd.w a5,a3,0(a4)
         lui     a4,%hi(__gcov0.f+4)
         addi    a5,a5,1
         seqz    a5,a5
         addi    a4,a4,%lo(__gcov0.f+4)
         amoadd.w zero,a5,0(a4)
         ret

gcc --coverage -O2 -S -o - test.c -fprofile-update=atomic -mbig-endian

         lui     a4,%hi(__gcov0.f+4)
         li      a3,1
         addi    a4,a4,%lo(__gcov0.f+4)
         amoadd.w a5,a3,0(a4)
         lui     a4,%hi(__gcov0.f)
         addi    a5,a5,1
         seqz    a5,a5
         addi    a4,a4,%lo(__gcov0.f)
         amoadd.w zero,a5,0(a4)
         ret

gcc --coverage -O2 -S -o - test.c -fprofile-update=atomic -march=rv64g 
-mabi=lp64

         lui     a5,%hi(__gcov0.f)
         li      a4,1
         addi    a5,a5,%lo(__gcov0.f)
         amoadd.d zero,a4,0(a5)
         ret

gcc --coverage -O2 -S -o - test.c -fprofile-update=atomic -march=rv32id

         lui     a0,%hi(__gcov0.f)
         li      a3,0
         li      a1,1
         li      a2,0
         addi    a0,a0,%lo(__gcov0.f)
         tail    __atomic_fetch_add_8

gcc --coverage -O2 -S -o - test.c -fprofile-update=prefer-atomic 
-march=rv32id

         lui     a4,%hi(__gcov0.f)
         lw      a5,%lo(__gcov0.f)(a4)
         lw      a2,%lo(__gcov0.f+4)(a4)
         addi    a3,a5,1
         sltu    a5,a3,a5
         add     a5,a5,a2
         sw      a3,%lo(__gcov0.f)(a4)
         sw      a5,%lo(__gcov0.f+4)(a4)
         ret

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

  reply	other threads:[~2022-12-15  8:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-09 13:56 Sebastian Huber
2022-12-13 14:30 ` Richard Biener
2022-12-15  8:34   ` Sebastian Huber [this message]
2022-12-16  9:47     ` Richard Biener
2022-12-16 10:39       ` Sebastian Huber
2022-12-16 12:09         ` Richard Biener
2022-12-16 13:01           ` Sebastian Huber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2d6f0cf1-f979-b3a6-6daa-81fc0882a1d7@embedded-brains.de \
    --to=sebastian.huber@embedded-brains.de \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).