[llvm-dev] [cfe-dev] Adding sanity to the Atomics implementation

James Y Knight via llvm-dev llvm-dev at lists.llvm.org
Fri Jan 29 21:06:06 PST 2016

On Thu, Jan 28, 2016 at 5:36 PM, Joerg Sonnenberger via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> On Thu, Jan 28, 2016 at 08:32:31AM -0800, Reid Kleckner via llvm-dev wrote:
> > I think Clang should continue to duplicate this information, the same way
> > we duplicate target datalayout strings. Other than that, sure, we can let
> > LLVM expand IR operations to libcalls. I don't immediately see a problem
> > with that.
> Note that a libcall doesn't necessarily mean using locks.

Yes, and having possibly-lock-free atomics is fine -- __atomic_is_lock_free
has a fallback to a libcall if the compiler doesn't know the answer is
"true", for that exact reason.

> With one

exception, NetBSD provides lock-free CAS on all platforms for natural
> argument sizes. The intersection between platforms with MP support and
> platforms without hardware CAS is SPARCv8. Everything else works fine,
> even the libcall version.

Indeed, with kernel support (magic restartable sequences, or a syscall),
lock-free atomics can be provided for any uniprocessor architecture. So,
linux on ARM provides a memory page you can jump to, which contains a
normal un-atomic instruction sequence on uniprocessor ARMv5s, or actual
ll/sc instructions on ARMv6+. And for the ARMv5 implementation, the kernel
arranges to magically restart the nonatomic sequence from the beginning if
it's interrupted in the middle, thus making it act as if it were atomic. (
https://lwn.net/Articles/314561/ is a nice explanation). I see that NetBSD
has something similar for restartable instruction sequences.

After some further investigation on how this is all supposed to hang
together, I do need to modify my plan slightly. The detail I neglected to
take account of earlier is that some platforms don't just have
*potentially* lock-free
library functions (e.g., depending on the CPU model you detect at runtime),
but rather, can have *guaranteed* lock-free library functions via this
kernel support.

For any target that has kernel-supported lock-free atomics, the LLVM target
should claim those atomic sizes as supported and clang should return true
from __atomic_always_lock_free. By claiming them supported as if they were
supported by native instructions, AtomicExpandPass will let them through
unscathed to ISel.

Then, the change in plan: I actually will preserve the ability to expand to
libcalls from within ISel, for this use-case only. The libcall names for
these routines will only be defined on those CPU+OS combinations which
implement this functionality.

In GCC, the supported-through-kernel atomic ops expand to a __sync_*
libcall, which is provided by the compiler runtime support library libgcc.a
(on the targets in question). It's not *necessary* for GCC to emit a
libcall, an inline syscall would be fine too sometimes, but currently it
always emits a call.

Like my plan for LLVM, GCC only enables these on some architectures (grep
for "init_sync_libfuncs"): Linux OS, on ARM, 68000, Nios2, PA-Risc, and
Super-H chips.

Note that unlike with the __atomic_* library calls, these target-specific
libcalls *are* okay to mix and match with CPU instructions since they must
be guaranteed lock-free. It is also okay to include potentially multiple
copies of the functions into a executable image, since they're stateless,
which is why it's okay for them to live in libgcc.a (not libgcc_s.so).

BTW, regarding NetBSD in particular: it appears as though the
implementation of the __sync_* functions in its libc sometimes use locks,
when the target is built with the generic "atomic_init_testset.c"
implementation, and then runs on a multiprocessor system. I think that
might happen if you compiled your binary for an armv5, but then actually
ran it on a multiprocessor armv6+ system? If I've read that right (which
I'm not at all sure I have), then llvm can't properly depend on NetBSD's
__sync_* functions to be always lock-free, at least at the moment.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160130/f03b221f/attachment.html>

More information about the llvm-dev mailing list