xref: /netbsd-src/external/apache2/llvm/dist/clang/include/clang/Basic/OpenCLOptions.h (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
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 namespace {
23 // This enum maps OpenCL version(s) into value. These values are used as
24 // a mask to indicate in which OpenCL version(s) extension is a core or
25 // optional core feature.
26 enum OpenCLVersionID : unsigned int {
27   OCL_C_10 = 0x1,
28   OCL_C_11 = 0x2,
29   OCL_C_12 = 0x4,
30   OCL_C_20 = 0x8,
31   OCL_C_30 = 0x10,
32   OCL_C_ALL = 0x1f,
33   OCL_C_11P = OCL_C_ALL ^ OCL_C_10,              // OpenCL C 1.1+
34   OCL_C_12P = OCL_C_ALL ^ (OCL_C_10 | OCL_C_11), // OpenCL C 1.2+
35 };
36 
encodeOpenCLVersion(unsigned OpenCLVersion)37 static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) {
38   switch (OpenCLVersion) {
39   default:
40     llvm_unreachable("Unknown OpenCL version code");
41   case 100:
42     return OCL_C_10;
43   case 110:
44     return OCL_C_11;
45   case 120:
46     return OCL_C_12;
47   case 200:
48     return OCL_C_20;
49   case 300:
50     return OCL_C_30;
51   }
52 }
53 
54 // Check if OpenCL C version is contained in a given encoded OpenCL C version
55 // mask.
isOpenCLVersionContainedInMask(const LangOptions & LO,unsigned Mask)56 static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
57                                                   unsigned Mask) {
58   auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
59   OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
60   return Mask & Code;
61 }
62 
63 } // end anonymous namespace
64 
65 /// OpenCL supported extensions and optional core features
66 class OpenCLOptions {
67 public:
68   struct OpenCLOptionInfo {
69     // Does this option have pragma.
70     bool WithPragma = false;
71 
72     // Option starts to be available in this OpenCL version
73     unsigned Avail = 100U;
74 
75     // Option becomes core feature in this OpenCL versions
76     unsigned Core = 0U;
77 
78     // Option becomes optional core feature in this OpenCL versions
79     unsigned Opt = 0U;
80 
81     // Is this option supported
82     bool Supported = false;
83 
84     // Is this option enabled
85     bool Enabled = false;
86 
87     OpenCLOptionInfo() = default;
OpenCLOptionInfoOpenCLOptionInfo88     OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV,
89                      unsigned OptV)
90         : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {}
91 
isCoreOpenCLOptionInfo92     bool isCore() const { return Core != 0U; }
93 
isOptionalCoreOpenCLOptionInfo94     bool isOptionalCore() const { return Opt != 0U; }
95 
96     // Is option available in OpenCL version \p LO.
isAvailableInOpenCLOptionInfo97     bool isAvailableIn(const LangOptions &LO) const {
98       // In C++ mode all extensions should work at least as in v2.0.
99       auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
100       return CLVer >= Avail;
101     }
102 
103     // Is core option in OpenCL version \p LO.
isCoreInOpenCLOptionInfo104     bool isCoreIn(const LangOptions &LO) const {
105       return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Core);
106     }
107 
108     // Is optional core option in OpenCL version \p LO.
isOptionalCoreInOpenCLOptionInfo109     bool isOptionalCoreIn(const LangOptions &LO) const {
110       return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Opt);
111     }
112   };
113 
114   bool isKnown(llvm::StringRef Ext) const;
115 
116   // For core or optional core feature check that it is supported
117   // by a target, for any other option (extension) check that it is
118   // enabled via pragma
119   bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const;
120 
121   bool isWithPragma(llvm::StringRef Ext) const;
122 
123   // Is supported as either an extension or an (optional) core feature for
124   // OpenCL version \p LO.
125   bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const;
126 
127   // Is supported OpenCL core feature for OpenCL version \p LO.
128   // For supported extension, return false.
129   bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const;
130 
131   // Is supported optional core OpenCL feature for OpenCL version \p LO.
132   // For supported extension, return false.
133   bool isSupportedOptionalCore(llvm::StringRef Ext,
134                                const LangOptions &LO) const;
135 
136   // Is supported optional core or core OpenCL feature for OpenCL version \p
137   // LO. For supported extension, return false.
138   bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
139                                      const LangOptions &LO) const;
140 
141   // Is supported OpenCL extension for OpenCL version \p LO.
142   // For supported core or optional core feature, return false.
143   bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const;
144 
145   // FIXME: Whether extension should accept pragma should not
146   // be reset dynamically. But it currently required when
147   // registering new extensions via pragmas.
148   void acceptsPragma(llvm::StringRef Ext, bool V = true);
149 
150   void enable(llvm::StringRef Ext, bool V = true);
151 
152   /// Enable or disable support for OpenCL extensions
153   /// \param Ext name of the extension (not prefixed with '+' or '-')
154   /// \param V value to set for a extension
155   void support(llvm::StringRef Ext, bool V = true);
156 
157   OpenCLOptions();
158 
159   // Set supported options based on target settings and language version
160   void addSupport(const llvm::StringMap<bool> &FeaturesMap,
161                   const LangOptions &Opts);
162 
163   // Disable all extensions
164   void disableAll();
165 
166   friend class ASTWriter;
167   friend class ASTReader;
168 
169   using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>;
170 
171   template <typename... Args>
isOpenCLOptionCoreIn(const LangOptions & LO,Args &&...args)172   static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) {
173     return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO);
174   }
175 
176   template <typename... Args>
isOpenCLOptionAvailableIn(const LangOptions & LO,Args &&...args)177   static bool isOpenCLOptionAvailableIn(const LangOptions &LO,
178                                         Args &&... args) {
179     return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO);
180   }
181 
182 private:
183   // Option is enabled via pragma
184   bool isEnabled(llvm::StringRef Ext) const;
185 
186   OpenCLOptionInfoMap OptMap;
187 };
188 
189 } // end namespace clang
190 
191 #endif
192