Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:50

0001 //===--- OpenCLOptions.h ----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Defines the clang::OpenCLOptions class.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
0015 #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
0016 
0017 #include "clang/Basic/LangOptions.h"
0018 #include "llvm/ADT/StringMap.h"
0019 
0020 namespace clang {
0021 
0022 class DiagnosticsEngine;
0023 class TargetInfo;
0024 
0025 namespace {
0026 // This enum maps OpenCL version(s) into value. These values are used as
0027 // a mask to indicate in which OpenCL version(s) extension is a core or
0028 // optional core feature.
0029 enum OpenCLVersionID : unsigned int {
0030   OCL_C_10 = 0x1,
0031   OCL_C_11 = 0x2,
0032   OCL_C_12 = 0x4,
0033   OCL_C_20 = 0x8,
0034   OCL_C_30 = 0x10,
0035   OCL_C_ALL = 0x1f,
0036   OCL_C_11P = OCL_C_ALL ^ OCL_C_10,              // OpenCL C 1.1+
0037   OCL_C_12P = OCL_C_ALL ^ (OCL_C_10 | OCL_C_11), // OpenCL C 1.2+
0038 };
0039 
0040 static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) {
0041   switch (OpenCLVersion) {
0042   default:
0043     llvm_unreachable("Unknown OpenCL version code");
0044   case 100:
0045     return OCL_C_10;
0046   case 110:
0047     return OCL_C_11;
0048   case 120:
0049     return OCL_C_12;
0050   case 200:
0051     return OCL_C_20;
0052   case 300:
0053     return OCL_C_30;
0054   }
0055 }
0056 
0057 // Check if OpenCL C version is contained in a given encoded OpenCL C version
0058 // mask.
0059 static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
0060                                                   unsigned Mask) {
0061   auto CLVer = LO.getOpenCLCompatibleVersion();
0062   OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
0063   return Mask & Code;
0064 }
0065 
0066 } // end anonymous namespace
0067 
0068 /// OpenCL supported extensions and optional core features
0069 class OpenCLOptions {
0070 
0071 public:
0072   // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the
0073   // __constant address space.
0074   // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static
0075   // variables inside a function can also be declared in the global
0076   // address space.
0077   // OpenCL C v3.0 s6.7.1 - Variables at program scope or static or extern
0078   // variables inside functions can be declared in global address space if
0079   // the __opencl_c_program_scope_global_variables feature is supported
0080   // C++ for OpenCL inherits rule from OpenCL C v2.0.
0081   bool areProgramScopeVariablesSupported(const LangOptions &Opts) const {
0082     return Opts.getOpenCLCompatibleVersion() == 200 ||
0083            (Opts.getOpenCLCompatibleVersion() == 300 &&
0084             isSupported("__opencl_c_program_scope_global_variables", Opts));
0085   }
0086 
0087   struct OpenCLOptionInfo {
0088     // Does this option have pragma.
0089     bool WithPragma = false;
0090 
0091     // Option starts to be available in this OpenCL version
0092     unsigned Avail = 100U;
0093 
0094     // Option becomes core feature in this OpenCL versions
0095     unsigned Core = 0U;
0096 
0097     // Option becomes optional core feature in this OpenCL versions
0098     unsigned Opt = 0U;
0099 
0100     // Is this option supported
0101     bool Supported = false;
0102 
0103     // Is this option enabled
0104     bool Enabled = false;
0105 
0106     OpenCLOptionInfo() = default;
0107     OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV,
0108                      unsigned OptV)
0109         : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {}
0110 
0111     bool isCore() const { return Core != 0U; }
0112 
0113     bool isOptionalCore() const { return Opt != 0U; }
0114 
0115     // Is option available in OpenCL version \p LO.
0116     bool isAvailableIn(const LangOptions &LO) const {
0117       // In C++ mode all extensions should work at least as in v2.0.
0118       return LO.getOpenCLCompatibleVersion() >= Avail;
0119     }
0120 
0121     // Is core option in OpenCL version \p LO.
0122     bool isCoreIn(const LangOptions &LO) const {
0123       return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Core);
0124     }
0125 
0126     // Is optional core option in OpenCL version \p LO.
0127     bool isOptionalCoreIn(const LangOptions &LO) const {
0128       return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Opt);
0129     }
0130   };
0131 
0132   bool isKnown(llvm::StringRef Ext) const;
0133 
0134   // For core or optional core feature check that it is supported
0135   // by a target, for any other option (extension) check that it is
0136   // enabled via pragma
0137   bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const;
0138 
0139   bool isWithPragma(llvm::StringRef Ext) const;
0140 
0141   // Is supported as either an extension or an (optional) core feature for
0142   // OpenCL version \p LO.
0143   bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const;
0144 
0145   // Is supported OpenCL core feature for OpenCL version \p LO.
0146   // For supported extension, return false.
0147   bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const;
0148 
0149   // Is supported optional core OpenCL feature for OpenCL version \p LO.
0150   // For supported extension, return false.
0151   bool isSupportedOptionalCore(llvm::StringRef Ext,
0152                                const LangOptions &LO) const;
0153 
0154   // Is supported optional core or core OpenCL feature for OpenCL version \p
0155   // LO. For supported extension, return false.
0156   bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
0157                                      const LangOptions &LO) const;
0158 
0159   // Is supported OpenCL extension for OpenCL version \p LO.
0160   // For supported core or optional core feature, return false.
0161   bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const;
0162 
0163   // FIXME: Whether extension should accept pragma should not
0164   // be reset dynamically. But it currently required when
0165   // registering new extensions via pragmas.
0166   void acceptsPragma(llvm::StringRef Ext, bool V = true);
0167 
0168   void enable(llvm::StringRef Ext, bool V = true);
0169 
0170   /// Enable or disable support for OpenCL extensions
0171   /// \param Ext name of the extension (not prefixed with '+' or '-')
0172   /// \param V value to set for a extension
0173   void support(llvm::StringRef Ext, bool V = true);
0174 
0175   OpenCLOptions();
0176 
0177   // Set supported options based on target settings and language version
0178   void addSupport(const llvm::StringMap<bool> &FeaturesMap,
0179                   const LangOptions &Opts);
0180 
0181   // Disable all extensions
0182   void disableAll();
0183 
0184   friend class ASTWriter;
0185   friend class ASTReader;
0186 
0187   using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>;
0188 
0189   template <typename... Args>
0190   static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) {
0191     return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO);
0192   }
0193 
0194   template <typename... Args>
0195   static bool isOpenCLOptionAvailableIn(const LangOptions &LO,
0196                                         Args &&... args) {
0197     return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO);
0198   }
0199 
0200   // Diagnose feature dependencies for OpenCL C 3.0. Return false if target
0201   // doesn't follow these requirements.
0202   static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI,
0203                                                      DiagnosticsEngine &Diags);
0204 
0205   // Diagnose that features and equivalent extension are set to same values.
0206   // Return false if target doesn't follow these requirements.
0207   static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI,
0208                                                   DiagnosticsEngine &Diags);
0209 
0210 private:
0211   // Option is enabled via pragma
0212   bool isEnabled(llvm::StringRef Ext) const;
0213 
0214   OpenCLOptionInfoMap OptMap;
0215 };
0216 
0217 } // end namespace clang
0218 
0219 #endif