From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: Jason Merrill <jason@redhat.com>,
"Richard Earnshaw (lists)" <Richard.Earnshaw@arm.com>,
"gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>,
Nathan Sidwell <nathan@acm.org>,
Christophe Lyon <christophe.lyon@linaro.org>
Subject: Re: [PATCH] Avoid atomic for guard acquire when that is expensive
Date: Sat, 5 Dec 2020 13:37:41 +0100 [thread overview]
Message-ID: <AM6PR03MB5170F6B2C134ABDFAAED5DE2E4F00@AM6PR03MB5170.eurprd03.prod.outlook.com> (raw)
In-Reply-To: <76600a88-7a4e-bd74-aefd-88e713a9ead9@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 3096 bytes --]
On 12/2/20 7:57 PM, Jason Merrill wrote:
> On 12/1/20 1:28 PM, Bernd Edlinger wrote:
>> On 11/24/20 11:10 PM, Jason Merrill wrote:
>>> On 11/22/20 3:05 AM, Bernd Edlinger wrote:
>>>> Hi,
>>>>
>>>> this avoids the need to use -fno-threadsafe-statics on
>>>> arm-none-eabi or working around that problem by supplying
>>>> a dummy __sync_synchronize function which might
>>>> just lead to silent code failure of the worst kind
>>>> (non-reproducable, racy) at runtime, as was pointed out
>>>> on previous discussions here.
>>>>
>>>> When the atomic access involves a call to __sync_synchronize
>>>> it is better to call __cxa_guard_acquire unconditionally,
>>>> since it handles the atomics too, or is a non-threaded
>>>> implementation when there is no gthread support for this target.
>>>>
>>>> This fixes also a bug for the ARM EABI big-endian target,
>>>> that is, previously the wrong bit was checked.
>>>
>>> Instead of a new target macro, can't you follow fold_builtin_atomic_always_lock_free/can_atomic_load_p?
>>
>> Yes, thanks, that should work too.
>> Would you like this better?
>
>> +is_atomic_expensive_p (machine_mode mode)
>> +{
>> + if (!flag_inline_atomics)
>> + return false;
>
> Why not true?
>
Ooops...
Yes, I ought to return true here.
I must have made a mistake when I tested the last version of this patch,
sorry for the confusion.
>> + if (!can_compare_and_swap_p (mode, false) || !can_atomic_load_p (mode))
>> + return false;
>
> This also seems backwards; I'd think we want to return false if either of those tests are true. Or maybe just can_atomic_load_p, and not bother about compare-and-swap.
>
Yes, you are right.
Unfortuately can_atomic_load_p is too weak, since it does not cover
the memory barrier.
And can_compare_and_swap_p (..., false) is actually a bit too strong,
but if it returns true, we should be able to use any atomic without
need for a library call.
>> + tree type = targetm.cxx.guard_mask_bit ()
>> + ? TREE_TYPE (guard) : char_type_node;
>> +
>> + if (is_atomic_expensive_p (TYPE_MODE (type)))
>> + guard = integer_zero_node;
>> + else
>> + guard = build_atomic_load_type (guard, MEMMODEL_ACQUIRE, type);
>
> It should still work to load a single byte, it just needs to be the least-significant byte. And this isn't an EABI issue; it looks like the non-EABI code is also broken for big-endian targets, both the atomic load and the normal load in get_guard_bits.
>
I think the non-EABI code is always using bit 0 in the first byte,
by using the endian-neutral #define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1).
Only ARM EABI uses bit 0 in byte 3 if big-endian and bit 0 in byte 0 otherwise.
For all other targets when _GLIBCXX_USE_FUTEX is defined,
__cxa_guard_XXX accesses the value as int* while the memory
is a 64-bit long, so I could imagine that is an aliasing violation.
But nothing that needs to be fixed immediately.
Attached is the corrected patch.
Tested again on arm-none-eabi with arm-sim.
Is it OK for trunk?
Thanks
Bernd.
> Jason
>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Avoid-atomic-for-guard-acquire-when-that-is-expensiv.patch --]
[-- Type: text/x-patch; name="0001-Avoid-atomic-for-guard-acquire-when-that-is-expensiv.patch", Size: 3073 bytes --]
From c1a6dcaa906113cba0dc88e36460a65aba35ec38 Mon Sep 17 00:00:00 2001
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
Date: Tue, 1 Dec 2020 18:54:48 +0100
Subject: [PATCH] Avoid atomic for guard acquire when that is expensive
When the atomic access involves a call to __sync_synchronize
it is better to call __cxa_guard_acquire unconditionally,
since it handles the atomics too, or is a non-threaded
implementation when there is no gthread support for this target.
This fixes also a bug for the ARM EABI big-endian target,
that is, previously the wrong bit was checked.
2020-11-22 Bernd Edlinger <bernd.edlinger@hotmail.de>
* decl2.c: (is_atomic_expensive_p): New helper function.
(build_atomic_load_byte): Rename to...
(build_atomic_load_type): ... and add new parameter type.
(get_guard_cond): Skip the atomic here if that is expensive.
Use the correct type for the atomic load on certain targets.
---
gcc/cp/decl2.c | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1bc7b7e..c7ddcc9 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "c-family/c-ada-spec.h"
#include "asan.h"
+#include "optabs-query.h"
/* Id for dumping the raw trees. */
int raw_dump_id;
@@ -3297,18 +3298,34 @@ get_guard (tree decl)
return guard;
}
+/* Returns true if accessing the GUARD atomic is expensive,
+ i.e. involves a call to __sync_synchronize or similar.
+ In this case let __cxa_guard_acquire handle the atomics. */
+
+static bool
+is_atomic_expensive_p (machine_mode mode)
+{
+ if (!flag_inline_atomics)
+ return true;
+
+ if (!can_compare_and_swap_p (mode, false) || !can_atomic_load_p (mode))
+ return true;
+
+ return false;
+}
+
/* Return an atomic load of src with the appropriate memory model. */
static tree
-build_atomic_load_byte (tree src, HOST_WIDE_INT model)
+build_atomic_load_type (tree src, HOST_WIDE_INT model, tree type)
{
- tree ptr_type = build_pointer_type (char_type_node);
+ tree ptr_type = build_pointer_type (type);
tree mem_model = build_int_cst (integer_type_node, model);
tree t, addr, val;
unsigned int size;
int fncode;
- size = tree_to_uhwi (TYPE_SIZE_UNIT (char_type_node));
+ size = tree_to_uhwi (TYPE_SIZE_UNIT (type));
fncode = BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1;
t = builtin_decl_implicit ((enum built_in_function) fncode);
@@ -3351,7 +3368,15 @@ get_guard_cond (tree guard, bool thread_safe)
if (!thread_safe)
guard = get_guard_bits (guard);
else
- guard = build_atomic_load_byte (guard, MEMMODEL_ACQUIRE);
+ {
+ tree type = targetm.cxx.guard_mask_bit ()
+ ? TREE_TYPE (guard) : char_type_node;
+
+ if (is_atomic_expensive_p (TYPE_MODE (type)))
+ guard = integer_zero_node;
+ else
+ guard = build_atomic_load_type (guard, MEMMODEL_ACQUIRE, type);
+ }
/* Mask off all but the low bit. */
if (targetm.cxx.guard_mask_bit ())
--
1.9.1
next prev parent reply other threads:[~2020-12-05 12:37 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-03 15:08 [PATCH] libgcc: Add a weak stub for __sync_synchronize Bernd Edlinger
2020-11-17 5:43 ` [PING] " Bernd Edlinger
2020-11-17 12:44 ` Richard Earnshaw (lists)
2020-11-17 15:18 ` Bernd Edlinger
2020-11-17 15:41 ` Richard Earnshaw (lists)
2020-11-17 15:51 ` Christophe Lyon
2020-11-17 17:17 ` Bernd Edlinger
2020-11-22 8:05 ` [PATCH] Avoid atomic for guard acquire when that is expensive Bernd Edlinger
2020-11-24 22:10 ` Jason Merrill
2020-12-01 18:28 ` Bernd Edlinger
2020-12-02 18:57 ` Jason Merrill
2020-12-05 12:37 ` Bernd Edlinger [this message]
2020-12-07 15:04 ` Jason Merrill
2020-12-07 16:17 ` Bernd Edlinger
2020-12-08 19:50 ` Jason Merrill
2020-11-30 20:08 ` [PING] " Bernd Edlinger
2020-11-30 20:54 ` Jason Merrill
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=AM6PR03MB5170F6B2C134ABDFAAED5DE2E4F00@AM6PR03MB5170.eurprd03.prod.outlook.com \
--to=bernd.edlinger@hotmail.de \
--cc=Richard.Earnshaw@arm.com \
--cc=christophe.lyon@linaro.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
--cc=nathan@acm.org \
--cc=ramana.radhakrishnan@arm.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).