Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===--- OpenCLOptions.h ----------------------------------------*- 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 | /// Defines the clang::OpenCLOptions class. |
||
11 | /// |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H |
||
15 | #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H |
||
16 | |||
17 | #include "clang/Basic/LangOptions.h" |
||
18 | #include "llvm/ADT/StringMap.h" |
||
19 | |||
20 | namespace clang { |
||
21 | |||
22 | class DiagnosticsEngine; |
||
23 | class TargetInfo; |
||
24 | |||
25 | namespace { |
||
26 | // This enum maps OpenCL version(s) into value. These values are used as |
||
27 | // a mask to indicate in which OpenCL version(s) extension is a core or |
||
28 | // optional core feature. |
||
29 | enum OpenCLVersionID : unsigned int { |
||
30 | OCL_C_10 = 0x1, |
||
31 | OCL_C_11 = 0x2, |
||
32 | OCL_C_12 = 0x4, |
||
33 | OCL_C_20 = 0x8, |
||
34 | OCL_C_30 = 0x10, |
||
35 | OCL_C_ALL = 0x1f, |
||
36 | OCL_C_11P = OCL_C_ALL ^ OCL_C_10, // OpenCL C 1.1+ |
||
37 | OCL_C_12P = OCL_C_ALL ^ (OCL_C_10 | OCL_C_11), // OpenCL C 1.2+ |
||
38 | }; |
||
39 | |||
40 | static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) { |
||
41 | switch (OpenCLVersion) { |
||
42 | default: |
||
43 | llvm_unreachable("Unknown OpenCL version code"); |
||
44 | case 100: |
||
45 | return OCL_C_10; |
||
46 | case 110: |
||
47 | return OCL_C_11; |
||
48 | case 120: |
||
49 | return OCL_C_12; |
||
50 | case 200: |
||
51 | return OCL_C_20; |
||
52 | case 300: |
||
53 | return OCL_C_30; |
||
54 | } |
||
55 | } |
||
56 | |||
57 | // Check if OpenCL C version is contained in a given encoded OpenCL C version |
||
58 | // mask. |
||
59 | static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO, |
||
60 | unsigned Mask) { |
||
61 | auto CLVer = LO.getOpenCLCompatibleVersion(); |
||
62 | OpenCLVersionID Code = encodeOpenCLVersion(CLVer); |
||
63 | return Mask & Code; |
||
64 | } |
||
65 | |||
66 | } // end anonymous namespace |
||
67 | |||
68 | /// OpenCL supported extensions and optional core features |
||
69 | class OpenCLOptions { |
||
70 | |||
71 | public: |
||
72 | // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the |
||
73 | // __constant address space. |
||
74 | // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static |
||
75 | // variables inside a function can also be declared in the global |
||
76 | // address space. |
||
77 | // OpenCL C v3.0 s6.7.1 - Variables at program scope or static or extern |
||
78 | // variables inside functions can be declared in global address space if |
||
79 | // the __opencl_c_program_scope_global_variables feature is supported |
||
80 | // C++ for OpenCL inherits rule from OpenCL C v2.0. |
||
81 | bool areProgramScopeVariablesSupported(const LangOptions &Opts) const { |
||
82 | return Opts.getOpenCLCompatibleVersion() == 200 || |
||
83 | (Opts.getOpenCLCompatibleVersion() == 300 && |
||
84 | isSupported("__opencl_c_program_scope_global_variables", Opts)); |
||
85 | } |
||
86 | |||
87 | struct OpenCLOptionInfo { |
||
88 | // Does this option have pragma. |
||
89 | bool WithPragma = false; |
||
90 | |||
91 | // Option starts to be available in this OpenCL version |
||
92 | unsigned Avail = 100U; |
||
93 | |||
94 | // Option becomes core feature in this OpenCL versions |
||
95 | unsigned Core = 0U; |
||
96 | |||
97 | // Option becomes optional core feature in this OpenCL versions |
||
98 | unsigned Opt = 0U; |
||
99 | |||
100 | // Is this option supported |
||
101 | bool Supported = false; |
||
102 | |||
103 | // Is this option enabled |
||
104 | bool Enabled = false; |
||
105 | |||
106 | OpenCLOptionInfo() = default; |
||
107 | OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV, |
||
108 | unsigned OptV) |
||
109 | : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {} |
||
110 | |||
111 | bool isCore() const { return Core != 0U; } |
||
112 | |||
113 | bool isOptionalCore() const { return Opt != 0U; } |
||
114 | |||
115 | // Is option available in OpenCL version \p LO. |
||
116 | bool isAvailableIn(const LangOptions &LO) const { |
||
117 | // In C++ mode all extensions should work at least as in v2.0. |
||
118 | return LO.getOpenCLCompatibleVersion() >= Avail; |
||
119 | } |
||
120 | |||
121 | // Is core option in OpenCL version \p LO. |
||
122 | bool isCoreIn(const LangOptions &LO) const { |
||
123 | return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Core); |
||
124 | } |
||
125 | |||
126 | // Is optional core option in OpenCL version \p LO. |
||
127 | bool isOptionalCoreIn(const LangOptions &LO) const { |
||
128 | return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Opt); |
||
129 | } |
||
130 | }; |
||
131 | |||
132 | bool isKnown(llvm::StringRef Ext) const; |
||
133 | |||
134 | // For core or optional core feature check that it is supported |
||
135 | // by a target, for any other option (extension) check that it is |
||
136 | // enabled via pragma |
||
137 | bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const; |
||
138 | |||
139 | bool isWithPragma(llvm::StringRef Ext) const; |
||
140 | |||
141 | // Is supported as either an extension or an (optional) core feature for |
||
142 | // OpenCL version \p LO. |
||
143 | bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const; |
||
144 | |||
145 | // Is supported OpenCL core feature for OpenCL version \p LO. |
||
146 | // For supported extension, return false. |
||
147 | bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const; |
||
148 | |||
149 | // Is supported optional core OpenCL feature for OpenCL version \p LO. |
||
150 | // For supported extension, return false. |
||
151 | bool isSupportedOptionalCore(llvm::StringRef Ext, |
||
152 | const LangOptions &LO) const; |
||
153 | |||
154 | // Is supported optional core or core OpenCL feature for OpenCL version \p |
||
155 | // LO. For supported extension, return false. |
||
156 | bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext, |
||
157 | const LangOptions &LO) const; |
||
158 | |||
159 | // Is supported OpenCL extension for OpenCL version \p LO. |
||
160 | // For supported core or optional core feature, return false. |
||
161 | bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const; |
||
162 | |||
163 | // FIXME: Whether extension should accept pragma should not |
||
164 | // be reset dynamically. But it currently required when |
||
165 | // registering new extensions via pragmas. |
||
166 | void acceptsPragma(llvm::StringRef Ext, bool V = true); |
||
167 | |||
168 | void enable(llvm::StringRef Ext, bool V = true); |
||
169 | |||
170 | /// Enable or disable support for OpenCL extensions |
||
171 | /// \param Ext name of the extension (not prefixed with '+' or '-') |
||
172 | /// \param V value to set for a extension |
||
173 | void support(llvm::StringRef Ext, bool V = true); |
||
174 | |||
175 | OpenCLOptions(); |
||
176 | |||
177 | // Set supported options based on target settings and language version |
||
178 | void addSupport(const llvm::StringMap<bool> &FeaturesMap, |
||
179 | const LangOptions &Opts); |
||
180 | |||
181 | // Disable all extensions |
||
182 | void disableAll(); |
||
183 | |||
184 | friend class ASTWriter; |
||
185 | friend class ASTReader; |
||
186 | |||
187 | using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>; |
||
188 | |||
189 | template <typename... Args> |
||
190 | static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) { |
||
191 | return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO); |
||
192 | } |
||
193 | |||
194 | template <typename... Args> |
||
195 | static bool isOpenCLOptionAvailableIn(const LangOptions &LO, |
||
196 | Args &&... args) { |
||
197 | return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO); |
||
198 | } |
||
199 | |||
200 | // Diagnose feature dependencies for OpenCL C 3.0. Return false if target |
||
201 | // doesn't follow these requirements. |
||
202 | static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI, |
||
203 | DiagnosticsEngine &Diags); |
||
204 | |||
205 | // Diagnose that features and equivalent extension are set to same values. |
||
206 | // Return false if target doesn't follow these requirements. |
||
207 | static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI, |
||
208 | DiagnosticsEngine &Diags); |
||
209 | |||
210 | private: |
||
211 | // Option is enabled via pragma |
||
212 | bool isEnabled(llvm::StringRef Ext) const; |
||
213 | |||
214 | OpenCLOptionInfoMap OptMap; |
||
215 | }; |
||
216 | |||
217 | } // end namespace clang |
||
218 | |||
219 | #endif |