[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:
Anton Zabaznov 2021-04-22 19:53:59 +03:00
parent 9a66d33452
commit f0efc00751
12 changed files with 101 additions and 37 deletions

View File

@ -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;
}

View File

@ -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">;

View File

@ -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<

View File

@ -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;

View File

@ -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.

View File

@ -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"
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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.

View File

@ -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__");

View File

@ -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

View File

@ -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