Implement C11 _Atomic

Uros Bizjak ubizjak@gmail.com
Thu Nov 7 17:16:00 GMT 2013


On Wed, Nov 6, 2013 at 12:21 AM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> This patch, relative to trunk and based on work done on the C11-atomic
> branch, adds support for C11 _Atomic.  It is intended to include all
> the required language support.
>
> It does not include the <stdatomic.h> header; there's a version on the
> branch, but it needs further review against the standard and test
> coverage adding to the testsuite before I can propose it for mainline.
>
> Support for atomic types having bigger alignment than the
> corresponding non-atomic types is limited: it includes the code to
> increase the alignment of types whose size is exactly 1, 2, 4, 8 or 16
> to that of the corresponding integer type [*], but not anything for
> target-specific alignment increases.  There's code for target-specific
> alignment on the branch (and I intend to merge trunk back to the
> branch once this patch is on trunk, so it's easy to tell what the
> changes still left on the branch are), should any target maintainers
> wish to have such alignment.  Note however that ideally libstdc++
> atomics would be ABI-compatible with C atomics, requiring them to get
> the same alignment; the branch has an "atomic" attribute for that
> purpose, but I think further work on the C++ front-end changes would
> be needed for them to be ready for mainline.
>
> [*] The c-common.c code to resolve size-generic atomic built-in
> functions to size-specific ones assumes that types are naturally
> aligned (and so resolves to calls to the size-specific functions that
> require natural alignment) without checking it.  If users should be
> able to use the size-generic functions on types with lesser alignment,
> e.g. _Complex double (8-byte rather than 16-byte aligned), rather than
> just on their _Atomic variants, this is of course a bug in the code
> resolving those built-in functions.  (The libatomic functions properly
> check for alignment at runtime.)  But it seems reasonable enough
> anyway to make _Atomic _Complex double 16-byte aligned.
>
> Full use of _Atomic requires linking with libatomic, if you're doing
> any atomic operations that aren't fully expanded inline; arguably
> libatomic should be linked in by default with --as-needed (given that
> previously ordinary C code didn't require the user to link any
> libraries explicitly unless they directly called library functions),
> but that's independent of this patch.  Correct handling of atomic
> compound assignment for floating-point types also requires built-in
> support for floating-point environment manipulation operations roughly
> equivalent to feholdexcept, feclearexcept and feupdateenv (built-ins
> are used to avoid introducing libm dependencies, which generic C code
> not actually calling libm library functions shouldn't require); this
> patch includes such support for x86 [*], and I expect other
> architectures to be simpler.  If you don't have a libatomic port, the
> execution tests for _Atomic simply won't be run; if you have libatomic
> but not the floating-point support, the tests will be run but
> c11-atomic-exec-5.c will fail (assuming the library features are
> present for that test to run at all - it also requires pthreads).
>
> [*] This could be optimized if desired by passing the types in
> question to the target hook so it can generate code for only one of
> x87 and SSE in most cases, much like an optimization present in glibc
> when it internally does feholdexcept / fesetenv / feupdateenv
> sequences.
>
> _Atomic support is currently disabled for Objective-C and OpenMP.  For
> both (but mainly OpenMP), the relevant parser code needs checking to
> determine where convert_lvalue_to_rvalue calls need inserting to
> ensure that accesses to atomic variables involve atomic loads.  For
> Objective-C, there are also various special cases of compound
> assignment that need special handling for atomics just as standard C
> compound assignment is handled differently for atomics, as well as
> some TYPE_MAIN_VARIANT calls to check for correctness for atomics; see
> the comment on the relevant sorry () call for details.  OpenMP should
> also have TYPE_MAIN_VARIANT uses checked as well as a use of
> TYPE_QUALS_NO_ADDR_SPACE for a diagnostic in
> c_parser_omp_declare_reduction (where the diagnostic refers to a
> particular list of qualifiers).
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
> commit (the various non-front-end pieces)?
>
> gcc:
> 2013-11-05  Andrew MacLeod  <amacleod@redhat.com>
>             Joseph Myers  <joseph@codesourcery.com>
>
>         * tree-core.h (enum cv_qualifier): Add TYPE_QUAL_ATOMIC.
>         (enum tree_index): Add TI_ATOMICQI_TYPE, TI_ATOMICHI_TYPE,
>         TI_ATOMICSI_TYPE, TI_ATOMICDI_TYPE and TI_ATOMICTI_TYPE.
>         (struct tree_base): Add atomic_flag field.
>         * tree.h (TYPE_ATOMIC): New accessor macro.
>         (TYPE_QUALS, TYPE_QUALS_NO_ADDR_SPACE): Add TYPE_QUAL_ATOMIC.
>         (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC): New macro.
>         (atomicQI_type_node, atomicHI_type_node, atomicSI_type_node)
>         (atomicDI_type_node, atomicTI_type_node): New macros for type
>         nodes.
>         * tree.c (set_type_quals): Set TYPE_ATOMIC.
>         (find_atomic_core_type): New function.
>         (build_qualified_type): Adjust alignment for qualified types.
>         (build_atomic_base): New function
>         (build_common_tree_nodes): Build atomicQI_type_node,
>         atomicHI_type_node, atomicSI_type_node, atomicDI_type_node and
>         atomicTI_type_node.
>         * print-tree.c (print_node): Print atomic qualifier.
>         * tree-pretty-print.c (dump_generic_node): Print atomic type
>         attribute.
>         * target.def (atomic_assign_expand_fenv): New hook.
>         * doc/tm.texi.in (TARGET_ATOMIC_ASSIGN_EXPAND_FENV): New @hook.
>         * doc/tm.texi: Regenerate.
>         * targhooks.c (default_atomic_assign_expand_fenv): New function.
>         * targhooks.h (default_atomic_assign_expand_fenv): Declare.
>         * sync-builtins.def (__atomic_feraiseexcept): New built-in
>         function.
>         * config/i386/i386-builtin-types.def (VOID_FTYPE_PUSHORT): New
>         function type.
>         * config/i386/i386.c (enum ix86_builtins): Add
>         IX86_BUILTIN_FNSTENV, IX86_BUILTIN_FLDENV, IX86_BUILTIN_FNSTSW and
>         IX86_BUILTIN_FNCLEX.
>         (bdesc_special_args): Add __builtin_ia32_fnstenv,
>         __builtin_ia32_fldenv, __builtin_ia32_fnstsw and
>         __builtin_ia32_fnclex.
>         (ix86_expand_builtin): Handle the new built-in functions.
>         (ix86_atomic_assign_expand_fenv): New function.
>         (TARGET_ATOMIC_ASSIGN_EXPAND_FENV): New macro.
>         * config/i386/i386.md (UNSPECV_FNSTENV, UNSPECV_FLDENV)
>         (UNSPECV_FNSTSW, UNSPECV_FNCLEX): New unspecs.
>         (fnstenv, fldenv, fnstsw, fnclex): New insns.

The x86 part of the patch is OK.

Uros.



More information about the Gcc-patches mailing list