diff options
| author | Stephen Hines <srhines@google.com> | 2019-07-02 16:25:20 -0700 |
|---|---|---|
| committer | Ali B <abittin@gmail.com> | 2019-07-05 19:33:16 +0300 |
| commit | 9afee4e65dc5f9f5eb371683729ff67b8df81d03 (patch) | |
| tree | 4cf241d6c9044f91ee8c06e6920174d06f8de0b6 /clang-r353983e/include/llvm/Support/AtomicOrdering.h | |
| parent | 2f19bd722c4c825320d1511c1ed83161b7f95d51 (diff) | |
clang 9.0.5 (based on r353983e) from build 5696680.
Bug: http://b/135931688
Bug: http://b/136008926
Test: N/A
Change-Id: I922d17410047d2e2df4625615352c588ee71b203
Diffstat (limited to 'clang-r353983e/include/llvm/Support/AtomicOrdering.h')
| -rw-r--r-- | clang-r353983e/include/llvm/Support/AtomicOrdering.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/clang-r353983e/include/llvm/Support/AtomicOrdering.h b/clang-r353983e/include/llvm/Support/AtomicOrdering.h new file mode 100644 index 00000000..763bc3ea --- /dev/null +++ b/clang-r353983e/include/llvm/Support/AtomicOrdering.h @@ -0,0 +1,151 @@ +//===-- llvm/Support/AtomicOrdering.h ---Atomic Ordering---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Atomic ordering constants. +/// +/// These values are used by LLVM to represent atomic ordering for C++11's +/// memory model and more, as detailed in docs/Atomics.rst. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ATOMICORDERING_H +#define LLVM_SUPPORT_ATOMICORDERING_H + +#include <cstddef> + +namespace llvm { + +/// Atomic ordering for C11 / C++11's memody models. +/// +/// These values cannot change because they are shared with standard library +/// implementations as well as with other compilers. +enum class AtomicOrderingCABI { + relaxed = 0, + consume = 1, + acquire = 2, + release = 3, + acq_rel = 4, + seq_cst = 5, +}; + +bool operator<(AtomicOrderingCABI, AtomicOrderingCABI) = delete; +bool operator>(AtomicOrderingCABI, AtomicOrderingCABI) = delete; +bool operator<=(AtomicOrderingCABI, AtomicOrderingCABI) = delete; +bool operator>=(AtomicOrderingCABI, AtomicOrderingCABI) = delete; + +// Validate an integral value which isn't known to fit within the enum's range +// is a valid AtomicOrderingCABI. +template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) { + return (Int)AtomicOrderingCABI::relaxed <= I && + I <= (Int)AtomicOrderingCABI::seq_cst; +} + +/// Atomic ordering for LLVM's memory model. +/// +/// C++ defines ordering as a lattice. LLVM supplements this with NotAtomic and +/// Unordered, which are both below the C++ orders. +/// +/// not_atomic-->unordered-->relaxed-->release--------------->acq_rel-->seq_cst +/// \-->consume-->acquire--/ +enum class AtomicOrdering { + NotAtomic = 0, + Unordered = 1, + Monotonic = 2, // Equivalent to C++'s relaxed. + // Consume = 3, // Not specified yet. + Acquire = 4, + Release = 5, + AcquireRelease = 6, + SequentiallyConsistent = 7 +}; + +bool operator<(AtomicOrdering, AtomicOrdering) = delete; +bool operator>(AtomicOrdering, AtomicOrdering) = delete; +bool operator<=(AtomicOrdering, AtomicOrdering) = delete; +bool operator>=(AtomicOrdering, AtomicOrdering) = delete; + +// Validate an integral value which isn't known to fit within the enum's range +// is a valid AtomicOrdering. +template <typename Int> inline bool isValidAtomicOrdering(Int I) { + return static_cast<Int>(AtomicOrdering::NotAtomic) <= I && + I <= static_cast<Int>(AtomicOrdering::SequentiallyConsistent); +} + +/// String used by LLVM IR to represent atomic ordering. +inline const char *toIRString(AtomicOrdering ao) { + static const char *names[8] = {"not_atomic", "unordered", "monotonic", + "consume", "acquire", "release", + "acq_rel", "seq_cst"}; + return names[static_cast<size_t>(ao)]; +} + +/// Returns true if ao is stronger than other as defined by the AtomicOrdering +/// lattice, which is based on C++'s definition. +inline bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other) { + static const bool lookup[8][8] = { + // NA UN RX CO AC RE AR SC + /* NotAtomic */ {false, false, false, false, false, false, false, false}, + /* Unordered */ { true, false, false, false, false, false, false, false}, + /* relaxed */ { true, true, false, false, false, false, false, false}, + /* consume */ { true, true, true, false, false, false, false, false}, + /* acquire */ { true, true, true, true, false, false, false, false}, + /* release */ { true, true, true, false, false, false, false, false}, + /* acq_rel */ { true, true, true, true, true, true, false, false}, + /* seq_cst */ { true, true, true, true, true, true, true, false}, + }; + return lookup[static_cast<size_t>(ao)][static_cast<size_t>(other)]; +} + +inline bool isAtLeastOrStrongerThan(AtomicOrdering ao, AtomicOrdering other) { + static const bool lookup[8][8] = { + // NA UN RX CO AC RE AR SC + /* NotAtomic */ { true, false, false, false, false, false, false, false}, + /* Unordered */ { true, true, false, false, false, false, false, false}, + /* relaxed */ { true, true, true, false, false, false, false, false}, + /* consume */ { true, true, true, true, false, false, false, false}, + /* acquire */ { true, true, true, true, true, false, false, false}, + /* release */ { true, true, true, false, false, true, false, false}, + /* acq_rel */ { true, true, true, true, true, true, true, false}, + /* seq_cst */ { true, true, true, true, true, true, true, true}, + }; + return lookup[static_cast<size_t>(ao)][static_cast<size_t>(other)]; +} + +inline bool isStrongerThanUnordered(AtomicOrdering ao) { + return isStrongerThan(ao, AtomicOrdering::Unordered); +} + +inline bool isStrongerThanMonotonic(AtomicOrdering ao) { + return isStrongerThan(ao, AtomicOrdering::Monotonic); +} + +inline bool isAcquireOrStronger(AtomicOrdering ao) { + return isAtLeastOrStrongerThan(ao, AtomicOrdering::Acquire); +} + +inline bool isReleaseOrStronger(AtomicOrdering ao) { + return isAtLeastOrStrongerThan(ao, AtomicOrdering::Release); +} + +inline AtomicOrderingCABI toCABI(AtomicOrdering ao) { + static const AtomicOrderingCABI lookup[8] = { + /* NotAtomic */ AtomicOrderingCABI::relaxed, + /* Unordered */ AtomicOrderingCABI::relaxed, + /* relaxed */ AtomicOrderingCABI::relaxed, + /* consume */ AtomicOrderingCABI::consume, + /* acquire */ AtomicOrderingCABI::acquire, + /* release */ AtomicOrderingCABI::release, + /* acq_rel */ AtomicOrderingCABI::acq_rel, + /* seq_cst */ AtomicOrderingCABI::seq_cst, + }; + return lookup[static_cast<size_t>(ao)]; +} + +} // end namespace llvm + +#endif // LLVM_SUPPORT_ATOMICORDERING_H |
