clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
220 lines
7.4 KiB
C++
220 lines
7.4 KiB
C++
//===--- 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
|