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 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 // Simple helper to check if OpenCL C version is contained in a given encoded 55 // OpenCL C version mask 56 static inline bool isOpenCLVersionIsContainedInMask(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 } // end anonymous namespace 63 64 /// OpenCL supported extensions and optional core features 65 class OpenCLOptions { 66 public: 67 struct OpenCLOptionInfo { 68 // Does this option have pragma. 69 bool WithPragma = false; 70 71 // Option starts to be available in this OpenCL version 72 unsigned Avail = 100U; 73 74 // Option becomes core feature in this OpenCL versions 75 unsigned Core = 0U; 76 77 // Option becomes optional core feature in this OpenCL versions 78 unsigned Opt = 0U; 79 80 // Is this option supported 81 bool Supported = false; 82 83 // Is this option enabled 84 bool Enabled = false; 85 86 OpenCLOptionInfo() = default; 87 OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV, 88 unsigned OptV) 89 : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {} 90 91 bool isCore() const { return Core != 0U; } 92 93 bool isOptionalCore() const { return Opt != 0U; } 94 95 // Is option available in OpenCL version \p LO. 96 bool isAvailableIn(const LangOptions &LO) const { 97 // In C++ mode all extensions should work at least as in v2.0. 98 auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; 99 return CLVer >= Avail; 100 } 101 102 // Is core option in OpenCL version \p LO. 103 bool isCoreIn(const LangOptions &LO) const { 104 return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Core); 105 } 106 107 // Is optional core option in OpenCL version \p LO. 108 bool isOptionalCoreIn(const LangOptions &LO) const { 109 return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Opt); 110 } 111 }; 112 113 bool isKnown(llvm::StringRef Ext) const; 114 115 // For core or optional core feature check that it is supported 116 // by a target, for any other option (extension) check that it is 117 // enabled via pragma 118 bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const; 119 120 bool isWithPragma(llvm::StringRef Ext) const; 121 122 // Is supported as either an extension or an (optional) core feature for 123 // OpenCL version \p LO. 124 bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const; 125 126 // Is supported OpenCL core feature for OpenCL version \p LO. 127 // For supported extension, return false. 128 bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const; 129 130 // Is supported optional core OpenCL feature for OpenCL version \p LO. 131 // For supported extension, return false. 132 bool isSupportedOptionalCore(llvm::StringRef Ext, 133 const LangOptions &LO) const; 134 135 // Is supported optional core or core OpenCL feature for OpenCL version \p 136 // LO. For supported extension, return false. 137 bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext, 138 const LangOptions &LO) const; 139 140 // Is supported OpenCL extension for OpenCL version \p LO. 141 // For supported core or optional core feature, return false. 142 bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const; 143 144 // FIXME: Whether extension should accept pragma should not 145 // be reset dynamically. But it currently required when 146 // registering new extensions via pragmas. 147 void acceptsPragma(llvm::StringRef Ext, bool V = true); 148 149 void enable(llvm::StringRef Ext, bool V = true); 150 151 /// Enable or disable support for OpenCL extensions 152 /// \param Ext name of the extension (not prefixed with '+' or '-') 153 /// \param V value to set for a extension 154 void support(llvm::StringRef Ext, bool V = true); 155 156 OpenCLOptions(); 157 OpenCLOptions(const OpenCLOptions &) = default; 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 private: 172 // Option is enabled via pragma 173 bool isEnabled(llvm::StringRef Ext) const; 174 175 OpenCLOptionInfoMap OptMap; 176 }; 177 178 } // end namespace clang 179 180 #endif 181