Viewing file: OpenCLOptions.h (7.42 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
//===--- OpenCLOptions.h ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// Defines the clang::OpenCLOptions class. /// //===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#include "clang/Basic/LangOptions.h" #include "llvm/ADT/StringMap.h"
namespace clang {
class DiagnosticsEngine; class TargetInfo;
namespace { // This enum maps OpenCL version(s) into value. These values are used as // a mask to indicate in which OpenCL version(s) extension is a core or // optional core feature. enum OpenCLVersionID : unsigned int { OCL_C_10 = 0x1, OCL_C_11 = 0x2, OCL_C_12 = 0x4, OCL_C_20 = 0x8, OCL_C_30 = 0x10, OCL_C_ALL = 0x1f, OCL_C_11P = OCL_C_ALL ^ OCL_C_10, // OpenCL C 1.1+ OCL_C_12P = OCL_C_ALL ^ (OCL_C_10 | OCL_C_11), // OpenCL C 1.2+ };
static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) { switch (OpenCLVersion) { default: llvm_unreachable("Unknown OpenCL version code"); case 100: return OCL_C_10; case 110: return OCL_C_11; case 120: return OCL_C_12; case 200: return OCL_C_20; case 300: return OCL_C_30; } }
// Check if OpenCL C version is contained in a given encoded OpenCL C version // mask. static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO, unsigned Mask) { auto CLVer = LO.getOpenCLCompatibleVersion(); OpenCLVersionID Code = encodeOpenCLVersion(CLVer); return Mask & Code; }
} // end anonymous namespace
/// OpenCL supported extensions and optional core features class OpenCLOptions {
public: // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the // __constant address space. // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static // variables inside a function can also be declared in the global // address space. // OpenCL C v3.0 s6.7.1 - Variables at program scope or static or extern // variables inside functions can be declared in global address space if // the __opencl_c_program_scope_global_variables feature is supported // C++ for OpenCL inherits rule from OpenCL C v2.0. bool areProgramScopeVariablesSupported(const LangOptions &Opts) const { return Opts.getOpenCLCompatibleVersion() == 200 || (Opts.getOpenCLCompatibleVersion() == 300 && isSupported("__opencl_c_program_scope_global_variables", Opts)); }
struct OpenCLOptionInfo { // Does this option have pragma. bool WithPragma = false;
// Option starts to be available in this OpenCL version unsigned Avail = 100U;
// Option becomes core feature in this OpenCL versions unsigned Core = 0U;
// Option becomes optional core feature in this OpenCL versions unsigned Opt = 0U;
// Is this option supported bool Supported = false;
// Is this option enabled bool Enabled = false;
OpenCLOptionInfo() = default; OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV, unsigned OptV) : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {}
bool isCore() const { return Core != 0U; }
bool isOptionalCore() const { return Opt != 0U; }
// Is option available in OpenCL version \p LO. bool isAvailableIn(const LangOptions &LO) const { // In C++ mode all extensions should work at least as in v2.0. return LO.getOpenCLCompatibleVersion() >= Avail; }
// Is core option in OpenCL version \p LO. bool isCoreIn(const LangOptions &LO) const { return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Core); }
// Is optional core option in OpenCL version \p LO. bool isOptionalCoreIn(const LangOptions &LO) const { return isAvailableIn(LO) && isOpenCLVersionContainedInMask(LO, Opt); } };
bool isKnown(llvm::StringRef Ext) const;
// For core or optional core feature check that it is supported // by a target, for any other option (extension) check that it is // enabled via pragma bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const;
bool isWithPragma(llvm::StringRef Ext) const;
// Is supported as either an extension or an (optional) core feature for // OpenCL version \p LO. bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const;
// Is supported OpenCL core feature for OpenCL version \p LO. // For supported extension, return false. bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const;
// Is supported optional core OpenCL feature for OpenCL version \p LO. // For supported extension, return false. bool isSupportedOptionalCore(llvm::StringRef Ext, const LangOptions &LO) const;
// Is supported optional core or core OpenCL feature for OpenCL version \p // LO. For supported extension, return false. bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext, const LangOptions &LO) const;
// Is supported OpenCL extension for OpenCL version \p LO. // For supported core or optional core feature, return false. bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const;
// FIXME: Whether extension should accept pragma should not // be reset dynamically. But it currently required when // registering new extensions via pragmas. void acceptsPragma(llvm::StringRef Ext, bool V = true);
void enable(llvm::StringRef Ext, bool V = true);
/// Enable or disable support for OpenCL extensions /// \param Ext name of the extension (not prefixed with '+' or '-') /// \param V value to set for a extension void support(llvm::StringRef Ext, bool V = true);
OpenCLOptions();
// Set supported options based on target settings and language version void addSupport(const llvm::StringMap<bool> &FeaturesMap, const LangOptions &Opts);
// Disable all extensions void disableAll();
friend class ASTWriter; friend class ASTReader;
using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>;
template <typename... Args> static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) { return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO); }
template <typename... Args> static bool isOpenCLOptionAvailableIn(const LangOptions &LO, Args &&... args) { return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO); }
// Diagnose feature dependencies for OpenCL C 3.0. Return false if target // doesn't follow these requirements. static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI, DiagnosticsEngine &Diags);
// Diagnose that features and equivalent extension are set to same values. // Return false if target doesn't follow these requirements. static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI, DiagnosticsEngine &Diags);
private: // Option is enabled via pragma bool isEnabled(llvm::StringRef Ext) const;
OpenCLOptionInfoMap OptMap; };
} // end namespace clang
#endif
|