Coverage Report

Created: 2019-07-24 05:18

/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