1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_BASIC_SYNCSCOPE_H |
15 | #define LLVM_CLANG_BASIC_SYNCSCOPE_H |
16 | |
17 | #include "clang/Basic/LangOptions.h" |
18 | #include "llvm/ADT/ArrayRef.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include <memory> |
21 | |
22 | namespace clang { |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | enum class SyncScope { |
43 | OpenCLWorkGroup, |
44 | OpenCLDevice, |
45 | OpenCLAllSVMDevices, |
46 | OpenCLSubGroup, |
47 | Last = OpenCLSubGroup |
48 | }; |
49 | |
50 | inline llvm::StringRef getAsString(SyncScope S) { |
51 | switch (S) { |
52 | case SyncScope::OpenCLWorkGroup: |
53 | return "opencl_workgroup"; |
54 | case SyncScope::OpenCLDevice: |
55 | return "opencl_device"; |
56 | case SyncScope::OpenCLAllSVMDevices: |
57 | return "opencl_allsvmdevices"; |
58 | case SyncScope::OpenCLSubGroup: |
59 | return "opencl_subgroup"; |
60 | } |
61 | llvm_unreachable("Invalid synch scope"); |
62 | } |
63 | |
64 | |
65 | enum class AtomicScopeModelKind { None, OpenCL }; |
66 | |
67 | |
68 | class AtomicScopeModel { |
69 | public: |
70 | virtual ~AtomicScopeModel() {} |
71 | |
72 | |
73 | virtual SyncScope map(unsigned S) const = 0; |
74 | |
75 | |
76 | |
77 | virtual bool isValid(unsigned S) const = 0; |
78 | |
79 | |
80 | |
81 | virtual ArrayRef<unsigned> getRuntimeValues() const = 0; |
82 | |
83 | |
84 | |
85 | |
86 | virtual unsigned getFallBackValue() const = 0; |
87 | |
88 | |
89 | |
90 | static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K); |
91 | }; |
92 | |
93 | |
94 | class AtomicScopeOpenCLModel : public AtomicScopeModel { |
95 | public: |
96 | |
97 | |
98 | |
99 | enum ID { |
100 | WorkGroup = 1, |
101 | Device = 2, |
102 | AllSVMDevices = 3, |
103 | SubGroup = 4, |
104 | Last = SubGroup |
105 | }; |
106 | |
107 | AtomicScopeOpenCLModel() {} |
108 | |
109 | SyncScope map(unsigned S) const override { |
110 | switch (static_cast<ID>(S)) { |
111 | case WorkGroup: |
112 | return SyncScope::OpenCLWorkGroup; |
113 | case Device: |
114 | return SyncScope::OpenCLDevice; |
115 | case AllSVMDevices: |
116 | return SyncScope::OpenCLAllSVMDevices; |
117 | case SubGroup: |
118 | return SyncScope::OpenCLSubGroup; |
119 | } |
120 | llvm_unreachable("Invalid language synch scope value"); |
121 | } |
122 | |
123 | bool isValid(unsigned S) const override { |
124 | return S >= static_cast<unsigned>(WorkGroup) && |
125 | S <= static_cast<unsigned>(Last); |
126 | } |
127 | |
128 | ArrayRef<unsigned> getRuntimeValues() const override { |
129 | static_assert(Last == SubGroup, "Does not include all synch scopes"); |
130 | static const unsigned Scopes[] = { |
131 | static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device), |
132 | static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)}; |
133 | return llvm::makeArrayRef(Scopes); |
134 | } |
135 | |
136 | unsigned getFallBackValue() const override { |
137 | return static_cast<unsigned>(AllSVMDevices); |
138 | } |
139 | }; |
140 | |
141 | inline std::unique_ptr<AtomicScopeModel> |
142 | AtomicScopeModel::create(AtomicScopeModelKind K) { |
143 | switch (K) { |
144 | case AtomicScopeModelKind::None: |
145 | return std::unique_ptr<AtomicScopeModel>{}; |
146 | case AtomicScopeModelKind::OpenCL: |
147 | return llvm::make_unique<AtomicScopeOpenCLModel>(); |
148 | } |
149 | llvm_unreachable("Invalid atomic scope model kind"); |
150 | } |
151 | } |
152 | |
153 | #endif |
154 | |