Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===-- llvm/Support/AtomicOrdering.h ---Atomic Ordering---------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// Atomic ordering constants.
11
///
12
/// These values are used by LLVM to represent atomic ordering for C++11's
13
/// memory model and more, as detailed in docs/Atomics.rst.
14
///
15
//===----------------------------------------------------------------------===//
16
 
17
#ifndef LLVM_SUPPORT_ATOMICORDERING_H
18
#define LLVM_SUPPORT_ATOMICORDERING_H
19
 
20
#include <cstddef>
21
 
22
namespace llvm {
23
 
24
/// Atomic ordering for C11 / C++11's memory models.
25
///
26
/// These values cannot change because they are shared with standard library
27
/// implementations as well as with other compilers.
28
enum class AtomicOrderingCABI {
29
  relaxed = 0,
30
  consume = 1,
31
  acquire = 2,
32
  release = 3,
33
  acq_rel = 4,
34
  seq_cst = 5,
35
};
36
 
37
bool operator<(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
38
bool operator>(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
39
bool operator<=(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
40
bool operator>=(AtomicOrderingCABI, AtomicOrderingCABI) = delete;
41
 
42
// Validate an integral value which isn't known to fit within the enum's range
43
// is a valid AtomicOrderingCABI.
44
template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) {
45
  return (Int)AtomicOrderingCABI::relaxed <= I &&
46
         I <= (Int)AtomicOrderingCABI::seq_cst;
47
}
48
 
49
/// Atomic ordering for LLVM's memory model.
50
///
51
/// C++ defines ordering as a lattice. LLVM supplements this with NotAtomic and
52
/// Unordered, which are both below the C++ orders.
53
///
54
/// not_atomic-->unordered-->relaxed-->release--------------->acq_rel-->seq_cst
55
///                                   \-->consume-->acquire--/
56
enum class AtomicOrdering : unsigned {
57
  NotAtomic = 0,
58
  Unordered = 1,
59
  Monotonic = 2, // Equivalent to C++'s relaxed.
60
  // Consume = 3,  // Not specified yet.
61
  Acquire = 4,
62
  Release = 5,
63
  AcquireRelease = 6,
64
  SequentiallyConsistent = 7,
65
  LAST = SequentiallyConsistent
66
};
67
 
68
bool operator<(AtomicOrdering, AtomicOrdering) = delete;
69
bool operator>(AtomicOrdering, AtomicOrdering) = delete;
70
bool operator<=(AtomicOrdering, AtomicOrdering) = delete;
71
bool operator>=(AtomicOrdering, AtomicOrdering) = delete;
72
 
73
// Validate an integral value which isn't known to fit within the enum's range
74
// is a valid AtomicOrdering.
75
template <typename Int> inline bool isValidAtomicOrdering(Int I) {
76
  return static_cast<Int>(AtomicOrdering::NotAtomic) <= I &&
77
         I <= static_cast<Int>(AtomicOrdering::SequentiallyConsistent);
78
}
79
 
80
/// String used by LLVM IR to represent atomic ordering.
81
inline const char *toIRString(AtomicOrdering ao) {
82
  static const char *names[8] = {"not_atomic", "unordered", "monotonic",
83
                                 "consume",    "acquire",   "release",
84
                                 "acq_rel",    "seq_cst"};
85
  return names[static_cast<size_t>(ao)];
86
}
87
 
88
/// Returns true if ao is stronger than other as defined by the AtomicOrdering
89
/// lattice, which is based on C++'s definition.
90
inline bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
91
  static const bool lookup[8][8] = {
92
      //               NA     UN     RX     CO     AC     RE     AR     SC
93
      /* NotAtomic */ {false, false, false, false, false, false, false, false},
94
      /* Unordered */ { true, false, false, false, false, false, false, false},
95
      /* relaxed   */ { true,  true, false, false, false, false, false, false},
96
      /* consume   */ { true,  true,  true, false, false, false, false, false},
97
      /* acquire   */ { true,  true,  true,  true, false, false, false, false},
98
      /* release   */ { true,  true,  true, false, false, false, false, false},
99
      /* acq_rel   */ { true,  true,  true,  true,  true,  true, false, false},
100
      /* seq_cst   */ { true,  true,  true,  true,  true,  true,  true, false},
101
  };
102
  return lookup[static_cast<size_t>(AO)][static_cast<size_t>(Other)];
103
}
104
 
105
inline bool isAtLeastOrStrongerThan(AtomicOrdering AO, AtomicOrdering Other) {
106
  static const bool lookup[8][8] = {
107
      //               NA     UN     RX     CO     AC     RE     AR     SC
108
      /* NotAtomic */ { true, false, false, false, false, false, false, false},
109
      /* Unordered */ { true,  true, false, false, false, false, false, false},
110
      /* relaxed   */ { true,  true,  true, false, false, false, false, false},
111
      /* consume   */ { true,  true,  true,  true, false, false, false, false},
112
      /* acquire   */ { true,  true,  true,  true,  true, false, false, false},
113
      /* release   */ { true,  true,  true, false, false,  true, false, false},
114
      /* acq_rel   */ { true,  true,  true,  true,  true,  true,  true, false},
115
      /* seq_cst   */ { true,  true,  true,  true,  true,  true,  true,  true},
116
  };
117
  return lookup[static_cast<size_t>(AO)][static_cast<size_t>(Other)];
118
}
119
 
120
inline bool isStrongerThanUnordered(AtomicOrdering AO) {
121
  return isStrongerThan(AO, AtomicOrdering::Unordered);
122
}
123
 
124
inline bool isStrongerThanMonotonic(AtomicOrdering AO) {
125
  return isStrongerThan(AO, AtomicOrdering::Monotonic);
126
}
127
 
128
inline bool isAcquireOrStronger(AtomicOrdering AO) {
129
  return isAtLeastOrStrongerThan(AO, AtomicOrdering::Acquire);
130
}
131
 
132
inline bool isReleaseOrStronger(AtomicOrdering AO) {
133
  return isAtLeastOrStrongerThan(AO, AtomicOrdering::Release);
134
}
135
 
136
/// Return a single atomic ordering that is at least as strong as both the \p AO
137
/// and \p Other orderings for an atomic operation.
138
inline AtomicOrdering getMergedAtomicOrdering(AtomicOrdering AO,
139
                                              AtomicOrdering Other) {
140
  if ((AO == AtomicOrdering::Acquire && Other == AtomicOrdering::Release) ||
141
      (AO == AtomicOrdering::Release && Other == AtomicOrdering::Acquire))
142
    return AtomicOrdering::AcquireRelease;
143
  return isStrongerThan(AO, Other) ? AO : Other;
144
}
145
 
146
inline AtomicOrderingCABI toCABI(AtomicOrdering AO) {
147
  static const AtomicOrderingCABI lookup[8] = {
148
      /* NotAtomic */ AtomicOrderingCABI::relaxed,
149
      /* Unordered */ AtomicOrderingCABI::relaxed,
150
      /* relaxed   */ AtomicOrderingCABI::relaxed,
151
      /* consume   */ AtomicOrderingCABI::consume,
152
      /* acquire   */ AtomicOrderingCABI::acquire,
153
      /* release   */ AtomicOrderingCABI::release,
154
      /* acq_rel   */ AtomicOrderingCABI::acq_rel,
155
      /* seq_cst   */ AtomicOrderingCABI::seq_cst,
156
  };
157
  return lookup[static_cast<size_t>(AO)];
158
}
159
 
160
} // end namespace llvm
161
 
162
#endif // LLVM_SUPPORT_ATOMICORDERING_H