[OpenCL] Introduce new method for validating OpenCL target
Language options are not available when a target is being created, thus, a new method is introduced. Also, some refactoring is done, such as removing OpenCL feature macros setting from TargetInfo. Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D101087
This commit is contained in:
parent
9a66d33452
commit
f0efc00751
|
@ -360,4 +360,8 @@ def note_suggest_disabling_all_checkers : Note<
|
|||
def warn_poison_system_directories : Warning <
|
||||
"include location '%0' is unsafe for cross-compilation">,
|
||||
InGroup<DiagGroup<"poison-system-directories">>, DefaultIgnore;
|
||||
|
||||
def warn_opencl_unsupported_core_feature : Warning<
|
||||
"%0 is a core feature in %select{OpenCL C|C++ for OpenCL}1 version %2 but not supported on this target">,
|
||||
InGroup<OpenCLCoreFeaturesDiagGroup>, DefaultIgnore;
|
||||
}
|
||||
|
|
|
@ -1286,3 +1286,5 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings.
|
|||
def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
|
||||
|
||||
def RTTI : DiagGroup<"rtti">;
|
||||
|
||||
def OpenCLCoreFeaturesDiagGroup : DiagGroup<"pedantic-core-features">;
|
||||
|
|
|
@ -1246,7 +1246,8 @@ def warn_pragma_unknown_extension : Warning<
|
|||
def warn_pragma_unsupported_extension : Warning<
|
||||
"unsupported OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
|
||||
def warn_pragma_extension_is_core : Warning<
|
||||
"OpenCL extension %0 is core feature or supported optional core feature - ignoring">, InGroup<DiagGroup<"pedantic-core-features">>, DefaultIgnore;
|
||||
"OpenCL extension %0 is core feature or supported optional core feature - ignoring">,
|
||||
InGroup<OpenCLCoreFeaturesDiagGroup>, DefaultIgnore;
|
||||
|
||||
// OpenCL errors.
|
||||
def err_opencl_taking_function_address_parser : Error<
|
||||
|
|
|
@ -59,6 +59,7 @@ static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
|
|||
OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
|
||||
return Mask & Code;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// OpenCL supported extensions and optional core features
|
||||
|
@ -167,6 +168,17 @@ public:
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
// Option is enabled via pragma
|
||||
bool isEnabled(llvm::StringRef Ext) const;
|
||||
|
|
|
@ -1234,6 +1234,12 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Check if target has a given feature enabled
|
||||
virtual bool hasFeatureEnabled(const llvm::StringMap<bool> &Features,
|
||||
StringRef Name) const {
|
||||
return Features.lookup(Name);
|
||||
}
|
||||
|
||||
/// Enable or disable a specific target feature;
|
||||
/// the feature name must be valid.
|
||||
virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
|
||||
|
@ -1481,7 +1487,8 @@ public:
|
|||
virtual void setSupportedOpenCLOpts() {}
|
||||
|
||||
virtual void supportAllOpenCLOpts(bool V = true) {
|
||||
#define OPENCLEXTNAME(Ext) getTargetOpts().OpenCLFeaturesMap[#Ext] = V;
|
||||
#define OPENCLEXTNAME(Ext) \
|
||||
setFeatureEnabled(getTargetOpts().OpenCLFeaturesMap, #Ext, V);
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
}
|
||||
|
||||
|
@ -1501,10 +1508,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/// Define OpenCL macros based on target settings and language version
|
||||
void getOpenCLFeatureDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const;
|
||||
|
||||
/// Get supported OpenCL extensions and optional core features.
|
||||
llvm::StringMap<bool> &getSupportedOpenCLOpts() {
|
||||
return getTargetOpts().OpenCLFeaturesMap;
|
||||
|
@ -1544,6 +1547,11 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Check that OpenCL target has valid options setting based on OpenCL
|
||||
/// version.
|
||||
virtual bool validateOpenCLTarget(const LangOptions &Opts,
|
||||
DiagnosticsEngine &Diags) const;
|
||||
|
||||
virtual void setAuxTarget(const TargetInfo *Aux) {}
|
||||
|
||||
/// Whether target allows debuginfo types for decl only variables/functions.
|
||||
|
|
|
@ -85,9 +85,8 @@ void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
|
|||
}
|
||||
|
||||
OpenCLOptions::OpenCLOptions() {
|
||||
#define OPENCL_GENERIC_EXTENSION(Ext, WithPragma, AvailVer, CoreVer, OptVer) \
|
||||
OptMap.insert_or_assign( \
|
||||
#Ext, OpenCLOptionInfo{WithPragma, AvailVer, CoreVer, OptVer});
|
||||
#define OPENCL_GENERIC_EXTENSION(Ext, ...) \
|
||||
OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
}
|
||||
|
||||
|
|
|
@ -726,30 +726,24 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
|
|||
|
||||
return Target.release();
|
||||
}
|
||||
/// validateOpenCLTarget - Check that OpenCL target has valid
|
||||
/// options setting based on OpenCL version.
|
||||
bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
|
||||
DiagnosticsEngine &Diags) const {
|
||||
const llvm::StringMap<bool> &OpenCLFeaturesMap = getSupportedOpenCLOpts();
|
||||
|
||||
/// getOpenCLFeatureDefines - Define OpenCL macros based on target settings
|
||||
/// and language version
|
||||
void TargetInfo::getOpenCLFeatureDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
// FIXME: OpenCL options which affect language semantics/syntax
|
||||
// should be moved into LangOptions, thus macro definitions of
|
||||
// such options is better to be done in clang::InitializePreprocessor.
|
||||
auto defineOpenCLExtMacro = [&](llvm::StringRef Name, unsigned AvailVer,
|
||||
unsigned CoreVersions,
|
||||
unsigned OptionalVersions) {
|
||||
// Check if extension is supported by target and is available in this
|
||||
// OpenCL version
|
||||
auto It = getTargetOpts().OpenCLFeaturesMap.find(Name);
|
||||
if ((It != getTargetOpts().OpenCLFeaturesMap.end()) && It->getValue() &&
|
||||
OpenCLOptions::OpenCLOptionInfo(false, AvailVer, CoreVersions,
|
||||
OptionalVersions)
|
||||
.isAvailableIn(Opts))
|
||||
Builder.defineMacro(Name);
|
||||
auto diagnoseNotSupportedCore = [&](llvm::StringRef Name, auto... OptArgs) {
|
||||
if (OpenCLOptions::isOpenCLOptionCoreIn(Opts, OptArgs...) &&
|
||||
!hasFeatureEnabled(OpenCLFeaturesMap, Name))
|
||||
Diags.Report(diag::warn_opencl_unsupported_core_feature)
|
||||
<< Name << Opts.OpenCLCPlusPlus
|
||||
<< Opts.getOpenCLVersionTuple().getAsString();
|
||||
};
|
||||
#define OPENCL_GENERIC_EXTENSION(Ext, WithPragma, Avail, Core, Opt) \
|
||||
defineOpenCLExtMacro(#Ext, Avail, Core, Opt);
|
||||
#define OPENCL_GENERIC_EXTENSION(Ext, ...) \
|
||||
diagnoseNotSupportedCore(#Ext, __VA_ARGS__);
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
|
||||
// Assume compiling for FULL profile
|
||||
Builder.defineMacro("__opencl_c_int64");
|
||||
// For now assume that OpenCL target is always
|
||||
// valid and just provide necessary diagnostics
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1398,13 +1398,13 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
|
|||
return Size <= 64;
|
||||
case 'z':
|
||||
// XMM0/YMM/ZMM0
|
||||
if (FeatureMap.lookup("avx512f"))
|
||||
if (hasFeatureEnabled(FeatureMap, "avx512f"))
|
||||
// ZMM0 can be used if target supports AVX512F.
|
||||
return Size <= 512U;
|
||||
else if (FeatureMap.lookup("avx"))
|
||||
else if (hasFeatureEnabled(FeatureMap, "avx"))
|
||||
// YMM0 can be used if target supports AVX.
|
||||
return Size <= 256U;
|
||||
else if (FeatureMap.lookup("sse"))
|
||||
else if (hasFeatureEnabled(FeatureMap, "sse"))
|
||||
return Size <= 128U;
|
||||
return false;
|
||||
case 'i':
|
||||
|
@ -1418,10 +1418,10 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
|
|||
break;
|
||||
case 'v':
|
||||
case 'x':
|
||||
if (FeatureMap.lookup("avx512f"))
|
||||
if (hasFeatureEnabled(FeatureMap, "avx512f"))
|
||||
// 512-bit zmm registers can be used if target supports AVX512F.
|
||||
return Size <= 512U;
|
||||
else if (FeatureMap.lookup("avx"))
|
||||
else if (hasFeatureEnabled(FeatureMap, "avx"))
|
||||
// 256-bit ymm registers can be used if target supports AVX.
|
||||
return Size <= 256U;
|
||||
return Size <= 128U;
|
||||
|
|
|
@ -133,6 +133,11 @@ bool CompilerInstance::createTarget() {
|
|||
// FIXME: can we disable FEnvAccess?
|
||||
}
|
||||
|
||||
// We should do it here because target knows nothing about
|
||||
// language options when it's being created.
|
||||
if (getLangOpts().OpenCL)
|
||||
getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics());
|
||||
|
||||
// Inform the target of the language options.
|
||||
// FIXME: We shouldn't need to do this, the target should be immutable once
|
||||
// created. This complexity should be lifted elsewhere.
|
||||
|
|
|
@ -601,6 +601,29 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
|
|||
Builder.defineMacro("__cpp_coroutines", "201703L");
|
||||
}
|
||||
|
||||
/// InitializeOpenCLFeatureTestMacros - Define OpenCL macros based on target
|
||||
/// settings and language version
|
||||
void InitializeOpenCLFeatureTestMacros(const TargetInfo &TI,
|
||||
const LangOptions &Opts,
|
||||
MacroBuilder &Builder) {
|
||||
const llvm::StringMap<bool> &OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
|
||||
// FIXME: OpenCL options which affect language semantics/syntax
|
||||
// should be moved into LangOptions.
|
||||
auto defineOpenCLExtMacro = [&](llvm::StringRef Name, auto... OptArgs) {
|
||||
// Check if extension is supported by target and is available in this
|
||||
// OpenCL version
|
||||
if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Name) &&
|
||||
OpenCLOptions::isOpenCLOptionAvailableIn(Opts, OptArgs...))
|
||||
Builder.defineMacro(Name);
|
||||
};
|
||||
#define OPENCL_GENERIC_EXTENSION(Ext, ...) \
|
||||
defineOpenCLExtMacro(#Ext, __VA_ARGS__);
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
|
||||
// Assume compiling for FULL profile
|
||||
Builder.defineMacro("__opencl_c_int64");
|
||||
}
|
||||
|
||||
static void InitializePredefinedMacros(const TargetInfo &TI,
|
||||
const LangOptions &LangOpts,
|
||||
const FrontendOptions &FEOpts,
|
||||
|
@ -1137,7 +1160,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
|||
|
||||
// OpenCL definitions.
|
||||
if (LangOpts.OpenCL) {
|
||||
TI.getOpenCLFeatureDefines(LangOpts, Builder);
|
||||
InitializeOpenCLFeatureTestMacros(TI, LangOpts, Builder);
|
||||
|
||||
if (TI.getTriple().isSPIR())
|
||||
Builder.defineMacro("__IMAGE_SUPPORT__");
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// RUN: %clang_cc1 -cl-std=CL2.0 -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t
|
||||
// RUN: FileCheck --check-prefixes=CHECK-C < %t %s
|
||||
// RUN: %clang_cc1 -cl-std=CLC++ -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t
|
||||
// RUN: FileCheck --check-prefixes=CHECK-CPP < %t %s
|
||||
|
||||
// CHECK-C: cl_khr_3d_image_writes is a core feature in OpenCL C version 2.0 but not supported on this target
|
||||
// CHECK-CPP: cl_khr_3d_image_writes is a core feature in C++ for OpenCL version 1.0 but not supported on this target
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: %clang_cc1 -cl-std=CL2.0 -triple r600-unknown-unknown -Wpedantic-core-features %s 2> %t
|
||||
// RUN: FileCheck < %t %s
|
||||
|
||||
// CHECK: cl_khr_byte_addressable_store is a core feature in OpenCL C version 2.0 but not supported on this target
|
||||
// CHECK: cl_khr_global_int32_base_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
|
||||
// CHECK: cl_khr_global_int32_extended_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
|
||||
// CHECK: cl_khr_local_int32_base_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
|
||||
// CHECK: cl_khr_local_int32_extended_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
|
||||
// CHECK: cl_khr_3d_image_writes is a core feature in OpenCL C version 2.0 but not supported on this target
|
Loading…
Reference in New Issue