summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorJF Bastien <jfb@google.com>2016-04-17 21:00:57 +0000
committerJF Bastien <jfb@google.com>2016-04-17 21:00:57 +0000
commit6ef3aa2b7eccddb11c22db3f00173d17306a5135 (patch)
tree5beb943d65a88eaf2132bf1530e8a2626200efc5 /llvm/include
parentcdbecda42af8a2f2d7e71915079af81c54746790 (diff)
downloadbcm5719-llvm-6ef3aa2b7eccddb11c22db3f00173d17306a5135.tar.gz
bcm5719-llvm-6ef3aa2b7eccddb11c22db3f00173d17306a5135.zip
NFC: unify clang / LLVM atomic ordering
Summary: This makes the C11 / C++11 *ABI* atomic ordering accessible from LLVM, as discussed in http://reviews.llvm.org/D18200#inline-151433 Reviewers: jyknight, reames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D18875 llvm-svn: 266573
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/IR/Instructions.h81
-rw-r--r--llvm/include/llvm/Support/AtomicOrdering.h151
2 files changed, 152 insertions, 80 deletions
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 7ff7900ad51..19ea3464a10 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -25,6 +25,7 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/ErrorHandling.h"
#include <iterator>
@@ -36,91 +37,11 @@ class ConstantRange;
class DataLayout;
class LLVMContext;
-/// C++ defines ordering as a lattice. LLVM supplements this with NotAtomic and
-/// Unordered, which are both below the C++ orders. See docs/Atomics.rst for
-/// details.
-///
-/// 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;
-
-/// String used by LLVM IR to represent atomic ordering.
-static inline const char *toIRString(AtomicOrdering ao) {
- static const char *names[8] = {"not_atomic", "unordered", "monotonic",
- "consume", "acquire", "release",
- "acq_rel", "seq_cst"};
- return names[(size_t)ao];
-}
-
-/// Returns true if ao is stronger than other as defined by the AtomicOrdering
-/// lattice, which is based on C++'s definition.
-static inline bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other) {
- static const bool lookup[8][8] = {
- // NA UN RX CO AC RE AR SC
- /* NotAtomic */ {0, 0, 0, 0, 0, 0, 0, 0},
- /* Unordered */ {1, 0, 0, 0, 0, 0, 0, 0},
- /* relaxed */ {1, 1, 0, 0, 0, 0, 0, 0},
- /* consume */ {1, 1, 1, 0, 0, 0, 0, 0},
- /* acquire */ {1, 1, 1, 1, 0, 0, 0, 0},
- /* release */ {1, 1, 1, 0, 0, 0, 0, 0},
- /* acq_rel */ {1, 1, 1, 1, 1, 1, 0, 0},
- /* seq_cst */ {1, 1, 1, 1, 1, 1, 1, 0},
- };
- return lookup[(size_t)ao][(size_t)other];
-}
-
-static inline bool isAtLeastOrStrongerThan(AtomicOrdering ao,
- AtomicOrdering other) {
- static const bool lookup[8][8] = {
- // NA UN RX CO AC RE AR SC
- /* NotAtomic */ {1, 0, 0, 0, 0, 0, 0, 0},
- /* Unordered */ {1, 1, 0, 0, 0, 0, 0, 0},
- /* relaxed */ {1, 1, 1, 0, 0, 0, 0, 0},
- /* consume */ {1, 1, 1, 1, 0, 0, 0, 0},
- /* acquire */ {1, 1, 1, 1, 1, 0, 0, 0},
- /* release */ {1, 1, 1, 0, 0, 1, 0, 0},
- /* acq_rel */ {1, 1, 1, 1, 1, 1, 1, 0},
- /* seq_cst */ {1, 1, 1, 1, 1, 1, 1, 1},
- };
- return lookup[(size_t)ao][(size_t)other];
-}
-
-static inline bool isStrongerThanUnordered(AtomicOrdering Ord) {
- return isStrongerThan(Ord, AtomicOrdering::Unordered);
-}
-
-static inline bool isStrongerThanMonotonic(AtomicOrdering Ord) {
- return isStrongerThan(Ord, AtomicOrdering::Monotonic);
-}
-
-static inline bool isAcquireOrStronger(AtomicOrdering Ord) {
- return isAtLeastOrStrongerThan(Ord, AtomicOrdering::Acquire);
-}
-
-static inline bool isReleaseOrStronger(AtomicOrdering Ord) {
- return isAtLeastOrStrongerThan(Ord, AtomicOrdering::Release);
-}
-
enum SynchronizationScope {
SingleThread = 0,
CrossThread = 1
};
-
//===----------------------------------------------------------------------===//
// AllocaInst Class
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Support/AtomicOrdering.h b/llvm/include/llvm/Support/AtomicOrdering.h
new file mode 100644
index 00000000000..e0b828affa7
--- /dev/null
+++ b/llvm/include/llvm/Support/AtomicOrdering.h
@@ -0,0 +1,151 @@
+//===-- llvm/Support/AtomicOrdering.h ---Atomic Ordering---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief 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
+
+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> static 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> static inline bool isValidAtomicOrdering(Int I) {
+ return (Int)AtomicOrdering::NotAtomic <= I &&
+ I <= (Int)AtomicOrdering::SequentiallyConsistent;
+}
+
+/// String used by LLVM IR to represent atomic ordering.
+static inline const char *toIRString(AtomicOrdering ao) {
+ static const char *names[8] = {"not_atomic", "unordered", "monotonic",
+ "consume", "acquire", "release",
+ "acq_rel", "seq_cst"};
+ return names[(size_t)ao];
+}
+
+/// Returns true if ao is stronger than other as defined by the AtomicOrdering
+/// lattice, which is based on C++'s definition.
+static inline bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other) {
+ static const bool lookup[8][8] = {
+ // NA UN RX CO AC RE AR SC
+ /* NotAtomic */ {0, 0, 0, 0, 0, 0, 0, 0},
+ /* Unordered */ {1, 0, 0, 0, 0, 0, 0, 0},
+ /* relaxed */ {1, 1, 0, 0, 0, 0, 0, 0},
+ /* consume */ {1, 1, 1, 0, 0, 0, 0, 0},
+ /* acquire */ {1, 1, 1, 1, 0, 0, 0, 0},
+ /* release */ {1, 1, 1, 0, 0, 0, 0, 0},
+ /* acq_rel */ {1, 1, 1, 1, 1, 1, 0, 0},
+ /* seq_cst */ {1, 1, 1, 1, 1, 1, 1, 0},
+ };
+ return lookup[(size_t)ao][(size_t)other];
+}
+
+static inline bool isAtLeastOrStrongerThan(AtomicOrdering ao,
+ AtomicOrdering other) {
+ static const bool lookup[8][8] = {
+ // NA UN RX CO AC RE AR SC
+ /* NotAtomic */ {1, 0, 0, 0, 0, 0, 0, 0},
+ /* Unordered */ {1, 1, 0, 0, 0, 0, 0, 0},
+ /* relaxed */ {1, 1, 1, 0, 0, 0, 0, 0},
+ /* consume */ {1, 1, 1, 1, 0, 0, 0, 0},
+ /* acquire */ {1, 1, 1, 1, 1, 0, 0, 0},
+ /* release */ {1, 1, 1, 0, 0, 1, 0, 0},
+ /* acq_rel */ {1, 1, 1, 1, 1, 1, 1, 0},
+ /* seq_cst */ {1, 1, 1, 1, 1, 1, 1, 1},
+ };
+ return lookup[(size_t)ao][(size_t)other];
+}
+
+static inline bool isStrongerThanUnordered(AtomicOrdering ao) {
+ return isStrongerThan(ao, AtomicOrdering::Unordered);
+}
+
+static inline bool isStrongerThanMonotonic(AtomicOrdering ao) {
+ return isStrongerThan(ao, AtomicOrdering::Monotonic);
+}
+
+static inline bool isAcquireOrStronger(AtomicOrdering ao) {
+ return isAtLeastOrStrongerThan(ao, AtomicOrdering::Acquire);
+}
+
+static inline bool isReleaseOrStronger(AtomicOrdering ao) {
+ return isAtLeastOrStrongerThan(ao, AtomicOrdering::Release);
+}
+
+static 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[(size_t)ao];
+}
+
+} // End namespace llvm
+
+#endif
OpenPOWER on IntegriCloud