On 9/8/20 8:51 AM, Tom de Vries wrote: > Hi, > > Add nvptx support to libatomic. > > Given that atomic_test_and_set is not implemented for nvptx (PR96964), the > compiler translates __atomic_test_and_set falling back onto the "Failing all > else, assume a single threaded environment and simply perform the operation" > case in expand_atomic_test_and_set, so it doesn't map onto an actual atomic > operation. > > Still, that counts as supported for the configure test of libatomic, so we > end up with HAVE_ATOMIC_TAS_1/2/4/8/16 == 1, and the corresponding > __atomic_test_and_set_1/2/4/8/16 in libatomic all using that non-atomic > implementation. > > Fix this by adding an atomic_test_and_set expansion for nvptx, that uses > libatomics __atomic_test_and_set_1. > > This again makes the configure tests for HAVE_ATOMIC_TAS_1/2/4/8/16 fail, so > instead we use this case in tas_n.c: > ... > /* If this type is smaller than word-sized, fall back to a word-sized > compare-and-swap loop. */ > bool > SIZE(libat_test_and_set) (UTYPE *mptr, int smodel) > ... > which for __atomic_test_and_set_8 uses INVERT_MASK_8. > > Add INVERT_MASK_8 in libatomic_i.h, as well as MASK_8. > > Tested libatomic testsuite on nvptx. > > Non-target bits (sync-builtins.def, libatomic_i.h) OK for trunk? > > Any other comments? > > Thanks, > - Tom > > [libatomic] Add nvptx support > > gcc/ChangeLog: > > PR target/96964 > * config/nvptx/nvptx.md (define_expand "atomic_test_and_set"): New > expansion. > * sync-builtins.def (BUILT_IN_ATOMIC_TEST_AND_SET_1): New builtin. >
I realized after reading the header comment of write_fn_proto_from_insn in nvptx.c that I could drop the sync-builtins.def bit. So, committed without the sync-builtins.def change. Thanks, - Tom > libatomic/ChangeLog: > > PR target/96898 > * configure.tgt: Add nvptx. > * libatomic_i.h (MASK_8, INVERT_MASK_8): New macro definition. > * config/nvptx/host-config.h: New file. > * config/nvptx/lock.c: New file. > > --- > gcc/config/nvptx/nvptx.md | 16 +++++++++++ > gcc/sync-builtins.def | 2 ++ > libatomic/config/nvptx/host-config.h | 56 > ++++++++++++++++++++++++++++++++++++ > libatomic/config/nvptx/lock.c | 56 > ++++++++++++++++++++++++++++++++++++ > libatomic/configure.tgt | 3 ++ > libatomic/libatomic_i.h | 2 ++ > 6 files changed, 135 insertions(+) > > diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md > index 4168190fa42..6178e6a0f77 100644 > --- a/gcc/config/nvptx/nvptx.md > +++ b/gcc/config/nvptx/nvptx.md > @@ -1667,6 +1667,22 @@ > "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;" > [(set_attr "atomic" "true")]) > > +(define_expand "atomic_test_and_set" > + [(match_operand:SI 0 "nvptx_register_operand") ;; bool success output > + (match_operand:QI 1 "memory_operand") ;; memory > + (match_operand:SI 2 "const_int_operand")] ;; model > + "" > +{ > + rtx libfunc; > + rtx addr; > + libfunc = init_one_libfunc ("__atomic_test_and_set_1"); > + addr = convert_memory_address (ptr_mode, XEXP (operands[1], 0)); > + emit_library_call_value (libfunc, operands[0], LCT_NORMAL, SImode, > + addr, ptr_mode, > + operands[2], SImode); > + DONE; > +}) > + > (define_insn "nvptx_barsync" > [(unspec_volatile [(match_operand:SI 0 "nvptx_nonmemory_operand" "Ri") > (match_operand:SI 1 "const_int_operand")] > diff --git a/gcc/sync-builtins.def b/gcc/sync-builtins.def > index 156a13ce0f8..b802257bd1a 100644 > --- a/gcc/sync-builtins.def > +++ b/gcc/sync-builtins.def > @@ -261,6 +261,8 @@ DEF_SYNC_BUILTIN (BUILT_IN_SYNC_SYNCHRONIZE, > "__sync_synchronize", > > DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_TEST_AND_SET, "__atomic_test_and_set", > BT_FN_BOOL_VPTR_INT, ATTR_NOTHROWCALL_LEAF_LIST) > +DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_TEST_AND_SET_1, "__atomic_test_and_set_1", > + BT_FN_BOOL_VPTR_INT, ATTR_NOTHROWCALL_LEAF_LIST) > > DEF_SYNC_BUILTIN (BUILT_IN_ATOMIC_CLEAR, "__atomic_clear", > BT_FN_VOID_VPTR_INT, > ATTR_NOTHROWCALL_LEAF_LIST) > diff --git a/libatomic/config/nvptx/host-config.h > b/libatomic/config/nvptx/host-config.h > new file mode 100644 > index 00000000000..eb9de81f388 > --- /dev/null > +++ b/libatomic/config/nvptx/host-config.h > @@ -0,0 +1,56 @@ > +/* Copyright (C) 2020 Free Software Foundation, Inc. > + > + This file is part of the GNU Atomic Library (libatomic). > + > + Libatomic is free software; you can redistribute it and/or modify it > + under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + Libatomic is distributed in the hope that it will be useful, but WITHOUT > ANY > + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS > + FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + more details. > + > + Under Section 7 of GPL version 3, you are granted additional > + permissions described in the GCC Runtime Library Exception, version > + 3.1, as published by the Free Software Foundation. > + > + You should have received a copy of the GNU General Public License and > + a copy of the GCC Runtime Library Exception along with this program; > + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > + <http://www.gnu.org/licenses/>. */ > + > +/* Copied from libatomic/config/posix/host-config.h. */ > + > +/* Included after all more target-specific host-config.h. */ > + > + > +#ifndef protect_start_end > +# ifdef HAVE_ATTRIBUTE_VISIBILITY > +# pragma GCC visibility push(hidden) > +# endif > + > +void libat_lock_1 (void *ptr); > +void libat_unlock_1 (void *ptr); > + > +static inline UWORD > +protect_start (void *ptr) > +{ > + libat_lock_1 (ptr); > + return 0; > +} > + > +static inline void > +protect_end (void *ptr, UWORD dummy UNUSED) > +{ > + libat_unlock_1 (ptr); > +} > + > +# define protect_start_end 1 > +# ifdef HAVE_ATTRIBUTE_VISIBILITY > +# pragma GCC visibility pop > +# endif > +#endif /* protect_start_end */ > + > +#include_next <host-config.h> > diff --git a/libatomic/config/nvptx/lock.c b/libatomic/config/nvptx/lock.c > new file mode 100644 > index 00000000000..dea85a3e5bd > --- /dev/null > +++ b/libatomic/config/nvptx/lock.c > @@ -0,0 +1,56 @@ > +/* Copyright (C) 2020 Free Software Foundation, Inc. > + > + This file is part of the GNU Atomic Library (libatomic). > + > + Libatomic is free software; you can redistribute it and/or modify it > + under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + Libatomic is distributed in the hope that it will be useful, but WITHOUT > ANY > + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS > + FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + more details. > + > + Under Section 7 of GPL version 3, you are granted additional > + permissions described in the GCC Runtime Library Exception, version > + 3.1, as published by the Free Software Foundation. > + > + You should have received a copy of the GNU General Public License and > + a copy of the GCC Runtime Library Exception along with this program; > + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > + <http://www.gnu.org/licenses/>. */ > + > +/* Functions libat_lock_n/libat_unlock_n based on GOMP_atomic_start/end in > + libgomp/atomic.c. */ > + > +#include "libatomic_i.h" > + > +static int atomic_lock; > + > +void > +libat_lock_n (void *ptr __attribute__((unused)), > + size_t n __attribute__((unused))) > +{ > + while (__sync_lock_test_and_set (&atomic_lock, 1)) > + ; /* Spin. */ > +} > + > +void > +libat_unlock_n (void *ptr __attribute__((unused)), > + size_t n __attribute__((unused))) > +{ > + __sync_lock_release (&atomic_lock); > +} > + > +void > +libat_lock_1 (void *ptr) > +{ > + libat_lock_n (ptr, 1); > +} > + > +void > +libat_unlock_1 (void *ptr) > +{ > + libat_unlock_n (ptr, 1); > +} > diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt > index efb3b1efb68..7834e0a6528 100644 > --- a/libatomic/configure.tgt > +++ b/libatomic/configure.tgt > @@ -174,6 +174,9 @@ case "${target}" in > UNSUPPORTED=1 > ;; > > + nvptx*-*-*) > + ;; > + > *) > # Who are you? > UNSUPPORTED=1 > diff --git a/libatomic/libatomic_i.h b/libatomic/libatomic_i.h > index 081b154e9d7..37de9921024 100644 > --- a/libatomic/libatomic_i.h > +++ b/libatomic/libatomic_i.h > @@ -109,9 +109,11 @@ typedef unsigned UWORD __attribute__((mode(word))); > #define MASK_1 ((UWORD)0xff) > #define MASK_2 ((UWORD)0xffff) > #define MASK_4 ((UWORD)0xffffffff) > +#define MASK_8 ((UWORD)0xffffffffffffffff) > #define INVERT_MASK_1 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 1) * > CHAR_BIT)) > #define INVERT_MASK_2 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 2) * > CHAR_BIT)) > #define INVERT_MASK_4 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 4) * > CHAR_BIT)) > +#define INVERT_MASK_8 ((UWORD)WORDS_BIGENDIAN << ((WORDSIZE - 8) * > CHAR_BIT)) > > /* Most of the files in this library are compiled multiple times with > N defined to be a power of 2 between 1 and 16. The SIZE macro is >