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 // Option starts to be available in this OpenCL version 69 unsigned Avail; 70 71 // Option becomes core feature in this OpenCL versions 72 unsigned Core; 73 74 // Option becomes optional core feature in this OpenCL versions 75 unsigned Opt; 76 77 // Is this option supported 78 bool Supported = false; 79 80 // Is this option enabled 81 bool Enabled = false; 82 83 OpenCLOptionInfo(unsigned A = 100, unsigned C = 0U, unsigned O = 0U) 84 : Avail(A), Core(C), Opt(O) {} 85 86 bool isCore() const { return Core != 0U; } 87 88 bool isOptionalCore() const { return Opt != 0U; } 89 90 // Is option available in OpenCL version \p LO. 91 bool isAvailableIn(const LangOptions &LO) const { 92 // In C++ mode all extensions should work at least as in v2.0. 93 auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; 94 return CLVer >= Avail; 95 } 96 97 // Is core option in OpenCL version \p LO. 98 bool isCoreIn(const LangOptions &LO) const { 99 return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Core); 100 } 101 102 // Is optional core option in OpenCL version \p LO. 103 bool isOptionalCoreIn(const LangOptions &LO) const { 104 return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Opt); 105 } 106 }; 107 108 bool isKnown(llvm::StringRef Ext) const; 109 110 bool isEnabled(llvm::StringRef Ext) const; 111 112 // Is supported as either an extension or an (optional) core feature for 113 // OpenCL version \p LO. 114 bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const; 115 116 // Is supported OpenCL core feature for OpenCL version \p LO. 117 // For supported extension, return false. 118 bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const; 119 120 // Is supported optional core OpenCL feature for OpenCL version \p LO. 121 // For supported extension, return false. 122 bool isSupportedOptionalCore(llvm::StringRef Ext, 123 const LangOptions &LO) const; 124 125 // Is supported optional core or core OpenCL feature for OpenCL version \p 126 // LO. For supported extension, return false. 127 bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext, 128 const LangOptions &LO) const; 129 130 // Is supported OpenCL extension for OpenCL version \p LO. 131 // For supported core or optional core feature, return false. 132 bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const; 133 134 void enable(llvm::StringRef Ext, bool V = true); 135 136 /// Enable or disable support for OpenCL extensions 137 /// \param Ext name of the extension (not prefixed with '+' or '-') 138 /// \param V value to set for a extension 139 void support(llvm::StringRef Ext, bool V = true); 140 141 OpenCLOptions(); 142 OpenCLOptions(const OpenCLOptions &) = default; 143 144 // Set supported options based on target settings and language version 145 void addSupport(const llvm::StringMap<bool> &FeaturesMap, 146 const LangOptions &Opts); 147 148 // Disable all extensions 149 void disableAll(); 150 151 // Enable supported core and optional core features 152 void enableSupportedCore(const LangOptions &LO); 153 154 friend class ASTWriter; 155 friend class ASTReader; 156 157 using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>; 158 159 private: 160 OpenCLOptionInfoMap OptMap; 161 }; 162 163 } // end namespace clang 164 165 #endif 166