#ifndef LLVM_SUPPORT_ATOMICORDERING_H
#define LLVM_SUPPORT_ATOMICORDERING_H
#include <cstddef>
namespace llvm {
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;
template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) {
return (Int)AtomicOrderingCABI::relaxed <= I &&
I <= (Int)AtomicOrderingCABI::seq_cst;
}
enum class AtomicOrdering : unsigned {
NotAtomic = 0,
Unordered = 1,
Monotonic = 2, Acquire = 4,
Release = 5,
AcquireRelease = 6,
SequentiallyConsistent = 7,
LAST = SequentiallyConsistent
};
bool operator<(AtomicOrdering, AtomicOrdering) = delete;
bool operator>(AtomicOrdering, AtomicOrdering) = delete;
bool operator<=(AtomicOrdering, AtomicOrdering) = delete;
bool operator>=(AtomicOrdering, AtomicOrdering) = delete;
template <typename Int> inline bool isValidAtomicOrdering(Int I) {
return static_cast<Int>(AtomicOrdering::NotAtomic) <= I &&
I <= static_cast<Int>(AtomicOrdering::SequentiallyConsistent);
}
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)];
}
inline bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
static const bool lookup[8][8] = {
{false, false, false, false, false, false, false, false},
{ true, false, false, false, false, false, false, false},
{ true, true, false, false, false, false, false, false},
{ true, true, true, false, false, false, false, false},
{ true, true, true, true, false, false, false, false},
{ true, true, true, false, false, false, false, false},
{ true, true, true, true, true, true, false, false},
{ 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] = {
{ true, false, false, false, false, false, false, false},
{ true, true, false, false, false, false, false, false},
{ true, true, true, false, false, false, false, false},
{ true, true, true, true, false, false, false, false},
{ true, true, true, true, true, false, false, false},
{ true, true, true, false, false, true, false, false},
{ true, true, true, true, true, true, true, false},
{ 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 AtomicOrdering getMergedAtomicOrdering(AtomicOrdering AO,
AtomicOrdering Other) {
if ((AO == AtomicOrdering::Acquire && Other == AtomicOrdering::Release) ||
(AO == AtomicOrdering::Release && Other == AtomicOrdering::Acquire))
return AtomicOrdering::AcquireRelease;
return isStrongerThan(AO, Other) ? AO : Other;
}
inline AtomicOrderingCABI toCABI(AtomicOrdering AO) {
static const AtomicOrderingCABI lookup[8] = {
AtomicOrderingCABI::relaxed,
AtomicOrderingCABI::relaxed,
AtomicOrderingCABI::relaxed,
AtomicOrderingCABI::consume,
AtomicOrderingCABI::acquire,
AtomicOrderingCABI::release,
AtomicOrderingCABI::acq_rel,
AtomicOrderingCABI::seq_cst,
};
return lookup[static_cast<size_t>(AO)];
}
}
#endif