/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/include/clang/Basic/SyncScope.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- SyncScope.h - Atomic synchronization scopes ------------*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// |
10 | | /// \file |
11 | | /// \brief Provides definitions for the atomic synchronization scopes. |
12 | | /// |
13 | | //===----------------------------------------------------------------------===// |
14 | | |
15 | | #ifndef LLVM_CLANG_BASIC_SYNCSCOPE_H |
16 | | #define LLVM_CLANG_BASIC_SYNCSCOPE_H |
17 | | |
18 | | #include "clang/Basic/LangOptions.h" |
19 | | #include "llvm/ADT/ArrayRef.h" |
20 | | #include "llvm/ADT/StringRef.h" |
21 | | #include <memory> |
22 | | |
23 | | namespace clang { |
24 | | |
25 | | /// \brief Defines synch scope values used internally by clang. |
26 | | /// |
27 | | /// The enum values start from 0 and are contiguous. They are mainly used for |
28 | | /// enumerating all supported synch scope values and mapping them to LLVM |
29 | | /// synch scopes. Their numerical values may be different from the corresponding |
30 | | /// synch scope enums used in source languages. |
31 | | /// |
32 | | /// In atomic builtin and expressions, language-specific synch scope enums are |
33 | | /// used. Currently only OpenCL memory scope enums are supported and assumed |
34 | | /// to be used by all languages. However, in the future, other languages may |
35 | | /// define their own set of synch scope enums. The language-specific synch scope |
36 | | /// values are represented by class AtomicScopeModel and its derived classes. |
37 | | /// |
38 | | /// To add a new enum value: |
39 | | /// Add the enum value to enum class SyncScope. |
40 | | /// Update enum value Last if necessary. |
41 | | /// Update getAsString. |
42 | | /// |
43 | | enum class SyncScope { |
44 | | OpenCLWorkGroup, |
45 | | OpenCLDevice, |
46 | | OpenCLAllSVMDevices, |
47 | | OpenCLSubGroup, |
48 | | Last = OpenCLSubGroup |
49 | | }; |
50 | | |
51 | 32 | inline llvm::StringRef getAsString(SyncScope S) { |
52 | 32 | switch (S) { |
53 | 8 | case SyncScope::OpenCLWorkGroup: |
54 | 8 | return "opencl_workgroup"; |
55 | 8 | case SyncScope::OpenCLDevice: |
56 | 8 | return "opencl_device"; |
57 | 8 | case SyncScope::OpenCLAllSVMDevices: |
58 | 8 | return "opencl_allsvmdevices"; |
59 | 8 | case SyncScope::OpenCLSubGroup: |
60 | 8 | return "opencl_subgroup"; |
61 | 32 | } |
62 | 0 | llvm_unreachable0 ("Invalid synch scope"); |
63 | 32 | } |
64 | | |
65 | | /// \brief Defines the kind of atomic scope models. |
66 | | enum class AtomicScopeModelKind { None, OpenCL }; |
67 | | |
68 | | /// \brief Defines the interface for synch scope model. |
69 | | class AtomicScopeModel { |
70 | | public: |
71 | 384 | virtual ~AtomicScopeModel() {} |
72 | | /// \brief Maps language specific synch scope values to internal |
73 | | /// SyncScope enum. |
74 | | virtual SyncScope map(unsigned S) const = 0; |
75 | | |
76 | | /// \brief Check if the compile-time constant synch scope value |
77 | | /// is valid. |
78 | | virtual bool isValid(unsigned S) const = 0; |
79 | | |
80 | | /// \brief Get all possible synch scope values that might be |
81 | | /// encountered at runtime for the current language. |
82 | | virtual ArrayRef<unsigned> getRuntimeValues() const = 0; |
83 | | |
84 | | /// \brief If atomic builtin function is called with invalid |
85 | | /// synch scope value at runtime, it will fall back to a valid |
86 | | /// synch scope value returned by this function. |
87 | | virtual unsigned getFallBackValue() const = 0; |
88 | | |
89 | | /// \brief Create an atomic scope model by AtomicScopeModelKind. |
90 | | /// \return an empty std::unique_ptr for AtomicScopeModelKind::None. |
91 | | static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K); |
92 | | }; |
93 | | |
94 | | /// \brief Defines the synch scope model for OpenCL. |
95 | | class AtomicScopeOpenCLModel : public AtomicScopeModel { |
96 | | public: |
97 | | /// The enum values match the pre-defined macros |
98 | | /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_* |
99 | | /// enums in opencl-c.h. |
100 | | enum ID { |
101 | | WorkGroup = 1, |
102 | | Device = 2, |
103 | | AllSVMDevices = 3, |
104 | | SubGroup = 4, |
105 | | Last = SubGroup |
106 | | }; |
107 | | |
108 | 384 | AtomicScopeOpenCLModel() {} |
109 | | |
110 | 114 | SyncScope map(unsigned S) const override { |
111 | 114 | switch (static_cast<ID>(S)) { |
112 | 60 | case WorkGroup: |
113 | 60 | return SyncScope::OpenCLWorkGroup; |
114 | 18 | case Device: |
115 | 18 | return SyncScope::OpenCLDevice; |
116 | 18 | case AllSVMDevices: |
117 | 18 | return SyncScope::OpenCLAllSVMDevices; |
118 | 18 | case SubGroup: |
119 | 18 | return SyncScope::OpenCLSubGroup; |
120 | 114 | } |
121 | 0 | llvm_unreachable0 ("Invalid language synch scope value"); |
122 | 114 | } |
123 | | |
124 | 241 | bool isValid(unsigned S) const override { |
125 | 241 | return S >= static_cast<unsigned>(WorkGroup) && |
126 | 239 | S <= static_cast<unsigned>(Last); |
127 | 241 | } |
128 | | |
129 | 8 | ArrayRef<unsigned> getRuntimeValues() const override { |
130 | 8 | static_assert(Last == SubGroup, "Does not include all synch scopes"); |
131 | 8 | static const unsigned Scopes[] = { |
132 | 8 | static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device), |
133 | 8 | static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)}; |
134 | 8 | return llvm::makeArrayRef(Scopes); |
135 | 8 | } |
136 | | |
137 | 8 | unsigned getFallBackValue() const override { |
138 | 8 | return static_cast<unsigned>(AllSVMDevices); |
139 | 8 | } |
140 | | }; |
141 | | |
142 | | inline std::unique_ptr<AtomicScopeModel> |
143 | 8.08k | AtomicScopeModel::create(AtomicScopeModelKind K) { |
144 | 8.08k | switch (K) { |
145 | 7.70k | case AtomicScopeModelKind::None: |
146 | 7.70k | return std::unique_ptr<AtomicScopeModel>{}; |
147 | 384 | case AtomicScopeModelKind::OpenCL: |
148 | 384 | return llvm::make_unique<AtomicScopeOpenCLModel>(); |
149 | 8.08k | } |
150 | 0 | llvm_unreachable0 ("Invalid atomic scope model kind"); |
151 | | } |
152 | | } |
153 | | |
154 | | #endif |