Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Aug 2013 12:34:13 +0100
From:      David Chisnall <theraven@FreeBSD.org>
To:        Ed Schouten <ed@80386.nl>
Cc:        svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org
Subject:   Re: svn commit: r255092 - in head: lib/libcompiler_rt sys/arm/arm
Message-ID:  <34C4386C-25D8-449C-8E53-5A0597FEEF7A@FreeBSD.org>
In-Reply-To: <CAJOYFBB63WuWXRCTtj4VbN1G3WBaQ9P6uhWwLDqWJxFNwjztug@mail.gmail.com>
References:  <201308310850.r7V8ojQX022383@svn.freebsd.org> <CAJOYFBB63WuWXRCTtj4VbN1G3WBaQ9P6uhWwLDqWJxFNwjztug@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help

On 31 Aug 2013, at 12:30, Ed Schouten <ed@80386.nl> wrote:

> 1. Fix LLVM/Clang.
>=20
> Never ever let LLVM/Clang emit calls to __sync_*. You can easily
> implement the __sync_* interface on top of __atomic_*. What baffles
> me, is that the calls to __sync_* are emitted by LLVM
> (SelectionDAGLegalize::ExpandAtomic), while Clang is responsible for
> emitting the __atomic_* calls (CodeGenFunction::EmitAtomicExpr).
>=20
> All of this should have been pushed down into LLVM in the first place.
> It is currently hard to implement your own programming language on top
> of LLVM that is capable of doing atomic operations the same way
> C11/C++11 does them. You either have to use the __sync_* intrinsics or
> duplicate all the code that emits the libcalls.
>=20
> I've noticed that due to this separation of doing __sync_* in LLVM and
> __atomic_* in Clang, the behaviour of Clang can sometimes be
> incredibly counter-intuitive. For example, both LLVM and Clang need a
> similar piece of code to determine whether hardware atomics are
> available. I've noticed that if this logic is not identical, Clang
> does some really weird things. If you call __atomic_* functions and
> Clang thinks we have hardware atomics, but LLVM thinks we do not, we
> may end up emitting calls to __sync_* instead.
>=20
> Furthermore, the duplication of code between EmitAtomicExpr,
> EmitAtomicStore and EmitAtomicLoad leads to the problem that
> EmitAtomicExpr properly emits power-of-two-sized calls for most
> primitive datatypes, while EmitAtomicStore and EmitAtomicLoad do not.

I completely agree with all of this.  There are lots of things in the =
layering in LLVM that I don't like that place too much target-specific =
knowledge in the front ends. =20

> 2. Fix the consumers.
>=20
> Right now there are only two pieces of code in our tree (libc++ and
> libcxxrt) that emit calls to __sync_* unconditionally. All the other
> code either uses <machine/atomic.h> or <stdatomic.h>. These pieces of
> code could have been ported to use C11 atomics with a similar amount
> of effort.
>=20
> For libcxxrt you could even argue that this should have done in the
> first place, because it already used __atomic_* calls in certain
> source files.
>=20
> Example patch for libcxxrt:
>=20
> http://80386.nl/pub/libcxxrt.txt

libcxxrt, in particular, has the constraint that it must also compile =
with gcc and Path64, so patches of this nature need careful testing.  =
Although this would fix the issue in the tree, a number of ports =
explicitly call the __sync_* builtins, including some that have USE_GCC =
set, so even fixing clang would not address this.

David




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?34C4386C-25D8-449C-8E53-5A0597FEEF7A>