/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/AtomicOrdering.h
Line | Count | Source |
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 memody 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 | 2.50k | template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) { |
45 | 2.50k | return (Int)AtomicOrderingCABI::relaxed <= I && |
46 | 2.50k | I <= (Int)AtomicOrderingCABI::seq_cst2.50k ; |
47 | 2.50k | } bool llvm::isValidAtomicOrderingCABI<long long>(long long) Line | Count | Source | 44 | 2.09k | template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) { | 45 | 2.09k | return (Int)AtomicOrderingCABI::relaxed <= I && | 46 | 2.09k | I <= (Int)AtomicOrderingCABI::seq_cst2.09k ; | 47 | 2.09k | } |
bool llvm::isValidAtomicOrderingCABI<unsigned long long>(unsigned long long) Line | Count | Source | 44 | 414 | template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) { | 45 | 414 | return (Int)AtomicOrderingCABI::relaxed <= I && | 46 | 414 | I <= (Int)AtomicOrderingCABI::seq_cst; | 47 | 414 | } |
|
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 { |
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 | | }; |
66 | | |
67 | | bool operator<(AtomicOrdering, AtomicOrdering) = delete; |
68 | | bool operator>(AtomicOrdering, AtomicOrdering) = delete; |
69 | | bool operator<=(AtomicOrdering, AtomicOrdering) = delete; |
70 | | bool operator>=(AtomicOrdering, AtomicOrdering) = delete; |
71 | | |
72 | | // Validate an integral value which isn't known to fit within the enum's range |
73 | | // is a valid AtomicOrdering. |
74 | | template <typename Int> inline bool isValidAtomicOrdering(Int I) { |
75 | | return static_cast<Int>(AtomicOrdering::NotAtomic) <= I && |
76 | | I <= static_cast<Int>(AtomicOrdering::SequentiallyConsistent); |
77 | | } |
78 | | |
79 | | /// String used by LLVM IR to represent atomic ordering. |
80 | 5.68k | inline const char *toIRString(AtomicOrdering ao) { |
81 | 5.68k | static const char *names[8] = {"not_atomic", "unordered", "monotonic", |
82 | 5.68k | "consume", "acquire", "release", |
83 | 5.68k | "acq_rel", "seq_cst"}; |
84 | 5.68k | return names[static_cast<size_t>(ao)]; |
85 | 5.68k | } |
86 | | |
87 | | /// Returns true if ao is stronger than other as defined by the AtomicOrdering |
88 | | /// lattice, which is based on C++'s definition. |
89 | 22.9M | inline bool isStrongerThan(AtomicOrdering ao, AtomicOrdering other) { |
90 | 22.9M | static const bool lookup[8][8] = { |
91 | 22.9M | // NA UN RX CO AC RE AR SC |
92 | 22.9M | /* NotAtomic */ {false, false, false, false, false, false, false, false}, |
93 | 22.9M | /* Unordered */ { true, false, false, false, false, false, false, false}, |
94 | 22.9M | /* relaxed */ { true, true, false, false, false, false, false, false}, |
95 | 22.9M | /* consume */ { true, true, true, false, false, false, false, false}, |
96 | 22.9M | /* acquire */ { true, true, true, true, false, false, false, false}, |
97 | 22.9M | /* release */ { true, true, true, false, false, false, false, false}, |
98 | 22.9M | /* acq_rel */ { true, true, true, true, true, true, false, false}, |
99 | 22.9M | /* seq_cst */ { true, true, true, true, true, true, true, false}, |
100 | 22.9M | }; |
101 | 22.9M | return lookup[static_cast<size_t>(ao)][static_cast<size_t>(other)]; |
102 | 22.9M | } |
103 | | |
104 | 88.5k | inline bool isAtLeastOrStrongerThan(AtomicOrdering ao, AtomicOrdering other) { |
105 | 88.5k | static const bool lookup[8][8] = { |
106 | 88.5k | // NA UN RX CO AC RE AR SC |
107 | 88.5k | /* NotAtomic */ { true, false, false, false, false, false, false, false}, |
108 | 88.5k | /* Unordered */ { true, true, false, false, false, false, false, false}, |
109 | 88.5k | /* relaxed */ { true, true, true, false, false, false, false, false}, |
110 | 88.5k | /* consume */ { true, true, true, true, false, false, false, false}, |
111 | 88.5k | /* acquire */ { true, true, true, true, true, false, false, false}, |
112 | 88.5k | /* release */ { true, true, true, false, false, true, false, false}, |
113 | 88.5k | /* acq_rel */ { true, true, true, true, true, true, true, false}, |
114 | 88.5k | /* seq_cst */ { true, true, true, true, true, true, true, true}, |
115 | 88.5k | }; |
116 | 88.5k | return lookup[static_cast<size_t>(ao)][static_cast<size_t>(other)]; |
117 | 88.5k | } |
118 | | |
119 | 1.41k | inline bool isStrongerThanUnordered(AtomicOrdering ao) { |
120 | 1.41k | return isStrongerThan(ao, AtomicOrdering::Unordered); |
121 | 1.41k | } |
122 | | |
123 | 2.84M | inline bool isStrongerThanMonotonic(AtomicOrdering ao) { |
124 | 2.84M | return isStrongerThan(ao, AtomicOrdering::Monotonic); |
125 | 2.84M | } |
126 | | |
127 | 27.6k | inline bool isAcquireOrStronger(AtomicOrdering ao) { |
128 | 27.6k | return isAtLeastOrStrongerThan(ao, AtomicOrdering::Acquire); |
129 | 27.6k | } |
130 | | |
131 | 44.3k | inline bool isReleaseOrStronger(AtomicOrdering ao) { |
132 | 44.3k | return isAtLeastOrStrongerThan(ao, AtomicOrdering::Release); |
133 | 44.3k | } |
134 | | |
135 | 1.17k | inline AtomicOrderingCABI toCABI(AtomicOrdering ao) { |
136 | 1.17k | static const AtomicOrderingCABI lookup[8] = { |
137 | 1.17k | /* NotAtomic */ AtomicOrderingCABI::relaxed, |
138 | 1.17k | /* Unordered */ AtomicOrderingCABI::relaxed, |
139 | 1.17k | /* relaxed */ AtomicOrderingCABI::relaxed, |
140 | 1.17k | /* consume */ AtomicOrderingCABI::consume, |
141 | 1.17k | /* acquire */ AtomicOrderingCABI::acquire, |
142 | 1.17k | /* release */ AtomicOrderingCABI::release, |
143 | 1.17k | /* acq_rel */ AtomicOrderingCABI::acq_rel, |
144 | 1.17k | /* seq_cst */ AtomicOrderingCABI::seq_cst, |
145 | 1.17k | }; |
146 | 1.17k | return lookup[static_cast<size_t>(ao)]; |
147 | 1.17k | } |
148 | | |
149 | | } // end namespace llvm |
150 | | |
151 | | #endif // LLVM_SUPPORT_ATOMICORDERING_H |