Home | History | Annotate | Line # | Download | only in Basic
      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 // Check if OpenCL C version is contained in a given encoded OpenCL C version
     55 // 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;
     88     OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV,
     89                      unsigned OptV)
     90         : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {}
     91 
     92     bool isCore() const { return Core != 0U; }
     93 
     94     bool isOptionalCore() const { return Opt != 0U; }
     95 
     96     // Is option available in OpenCL version \p LO.
     97     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.
    104     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.
    109     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>
    172   static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) {
    173     return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO);
    174   }
    175 
    176   template <typename... 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