This revision was not accepted when it landed; it landed in state "Needs
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe123cd674c02: [OpenCL] Refactor of targets OpenCL option
settings (authored by azabaznov).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92277/new/
https://reviews.llvm.org/D92277
Files:
clang/include/clang/Basic/OpenCLExtensions.def
clang/include/clang/Basic/OpenCLOptions.h
clang/include/clang/Basic/TargetInfo.h
clang/include/clang/Basic/TargetOptions.h
clang/lib/Basic/CMakeLists.txt
clang/lib/Basic/OpenCLOptions.cpp
clang/lib/Basic/Targets.cpp
clang/lib/Basic/Targets/AMDGPU.h
clang/lib/Basic/Targets/NVPTX.h
clang/lib/Basic/Targets/SPIR.h
clang/lib/Basic/Targets/X86.h
clang/lib/Frontend/InitPreprocessor.cpp
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/Misc/nvptx.languageOptsOpenCL.cl
clang/test/Misc/r600.languageOptsOpenCL.cl
Index: clang/test/Misc/r600.languageOptsOpenCL.cl
===================================================================
--- clang/test/Misc/r600.languageOptsOpenCL.cl
+++ clang/test/Misc/r600.languageOptsOpenCL.cl
@@ -2,27 +2,21 @@
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple r600-unknown-unknown -target-cpu cayman
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple r600-unknown-unknown -target-cpu cayman
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple r600-unknown-unknown -target-cpu cayman
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple r600-unknown-unknown -target-cpu cayman
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cayman
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cayman
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cayman
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cayman
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple r600-unknown-unknown -target-cpu cypress
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple r600-unknown-unknown -target-cpu cypress
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple r600-unknown-unknown -target-cpu cypress
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple r600-unknown-unknown -target-cpu cypress
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cypress
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cypress
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cypress
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu cypress
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple r600-unknown-unknown -target-cpu turks
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple r600-unknown-unknown -target-cpu turks
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple r600-unknown-unknown -target-cpu turks
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple r600-unknown-unknown -target-cpu turks
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu turks
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu turks
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu turks
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple r600-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -target-cpu turks
// Extensions in all versions
#ifndef cl_clang_storage_class_specifiers
Index: clang/test/Misc/nvptx.languageOptsOpenCL.cl
===================================================================
--- clang/test/Misc/nvptx.languageOptsOpenCL.cl
+++ clang/test/Misc/nvptx.languageOptsOpenCL.cl
@@ -2,19 +2,15 @@
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple nvptx-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple nvptx-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple nvptx-unknown-unknown
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple nvptx-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple nvptx-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple nvptx-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple nvptx-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple nvptx-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple nvptx64-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple nvptx64-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple nvptx64-unknown-unknown
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple nvptx64-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple nvptx64-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple nvptx64-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple nvptx64-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
-// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple nvptx64-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// Extensions in all versions
#ifndef cl_clang_storage_class_specifiers
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -3978,6 +3978,7 @@
Record.push_back(V.Enabled ? 1 : 0);
Record.push_back(V.Avail);
Record.push_back(V.Core);
+ Record.push_back(V.Opt);
}
Stream.EmitRecord(OPENCL_EXTENSIONS, Record);
}
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -3609,11 +3609,12 @@
case OPENCL_EXTENSIONS:
for (unsigned I = 0, E = Record.size(); I != E; ) {
auto Name = ReadString(Record, I);
- auto &Opt = OpenCLExtensions.OptMap[Name];
- Opt.Supported = Record[I++] != 0;
- Opt.Enabled = Record[I++] != 0;
- Opt.Avail = Record[I++];
- Opt.Core = Record[I++];
+ auto &OptInfo = OpenCLExtensions.OptMap[Name];
+ OptInfo.Supported = Record[I++] != 0;
+ OptInfo.Enabled = Record[I++] != 0;
+ OptInfo.Avail = Record[I++];
+ OptInfo.Core = Record[I++];
+ OptInfo.Opt = Record[I++];
}
break;
@@ -7868,7 +7869,7 @@
NewOverrides.applyOverrides(SemaObj->getLangOpts());
}
- SemaObj->OpenCLFeatures.copy(OpenCLExtensions);
+ SemaObj->OpenCLFeatures = OpenCLExtensions;
SemaObj->OpenCLTypeExtMap = OpenCLTypeExtMap;
SemaObj->OpenCLDeclExtMap = OpenCLDeclExtMap;
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -297,7 +297,7 @@
// core features.
if (getLangOpts().OpenCL) {
getOpenCLOptions().addSupport(
- Context.getTargetInfo().getSupportedOpenCLOpts());
+ Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts());
getOpenCLOptions().enableSupportedCore(getLangOpts());
addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
addImplicitTypedef("event_t", Context.OCLEventTy);
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -790,7 +790,7 @@
PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
else if (Opt.isSupportedExtension(Name, getLangOpts()))
Opt.enable(Name, State == Enable);
- else if (Opt.isSupportedCore(Name, getLangOpts()))
+ else if (Opt.isSupportedCoreOrOptionalCore(Name, getLangOpts()))
PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
else
PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -1120,10 +1120,7 @@
// OpenCL definitions.
if (LangOpts.OpenCL) {
-#define OPENCLEXT(Ext) \
- if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \
- Builder.defineMacro(#Ext);
-#include "clang/Basic/OpenCLExtensions.def"
+ TI.getOpenCLFeatureDefines(LangOpts, Builder);
if (TI.getTriple().isSPIR())
Builder.defineMacro("__IMAGE_SUPPORT__");
Index: clang/lib/Basic/Targets/X86.h
===================================================================
--- clang/lib/Basic/Targets/X86.h
+++ clang/lib/Basic/Targets/X86.h
@@ -359,9 +359,7 @@
bool hasSjLjLowering() const override { return true; }
- void setSupportedOpenCLOpts() override {
- getSupportedOpenCLOpts().supportAll();
- }
+ void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
uint64_t getPointerWidthV(unsigned AddrSpace) const override {
if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
Index: clang/lib/Basic/Targets/SPIR.h
===================================================================
--- clang/lib/Basic/Targets/SPIR.h
+++ clang/lib/Basic/Targets/SPIR.h
@@ -100,7 +100,7 @@
void setSupportedOpenCLOpts() override {
// Assume all OpenCL extensions and optional core features are supported
// for SPIR since it is a generic target.
- getSupportedOpenCLOpts().supportAll();
+ supportAllOpenCLOpts();
}
bool hasExtIntType() const override { return true; }
Index: clang/lib/Basic/Targets/NVPTX.h
===================================================================
--- clang/lib/Basic/Targets/NVPTX.h
+++ clang/lib/Basic/Targets/NVPTX.h
@@ -127,16 +127,16 @@
void setSupportedOpenCLOpts() override {
auto &Opts = getSupportedOpenCLOpts();
- Opts.support("cl_clang_storage_class_specifiers");
- Opts.support("__cl_clang_function_pointers");
- Opts.support("__cl_clang_variadic_functions");
-
- Opts.support("cl_khr_fp64");
- Opts.support("cl_khr_byte_addressable_store");
- Opts.support("cl_khr_global_int32_base_atomics");
- Opts.support("cl_khr_global_int32_extended_atomics");
- Opts.support("cl_khr_local_int32_base_atomics");
- Opts.support("cl_khr_local_int32_extended_atomics");
+ Opts["cl_clang_storage_class_specifiers"] = true;
+ Opts["__cl_clang_function_pointers"] = true;
+ Opts["__cl_clang_variadic_functions"] = true;
+
+ Opts["cl_khr_fp64"] = true;
+ Opts["cl_khr_byte_addressable_store"] = true;
+ Opts["cl_khr_global_int32_base_atomics"] = true;
+ Opts["cl_khr_global_int32_extended_atomics"] = true;
+ Opts["cl_khr_local_int32_base_atomics"] = true;
+ Opts["cl_khr_local_int32_extended_atomics"] = true;
}
/// \returns If a target requires an address within a target specific address
Index: clang/lib/Basic/Targets/AMDGPU.h
===================================================================
--- clang/lib/Basic/Targets/AMDGPU.h
+++ clang/lib/Basic/Targets/AMDGPU.h
@@ -284,33 +284,32 @@
void setSupportedOpenCLOpts() override {
auto &Opts = getSupportedOpenCLOpts();
- Opts.support("cl_clang_storage_class_specifiers");
- Opts.support("__cl_clang_function_pointers");
- Opts.support("__cl_clang_variadic_functions");
+ Opts["cl_clang_storage_class_specifiers"] = true;
+ Opts["__cl_clang_variadic_functions"] = true;
+ Opts["__cl_clang_function_pointers"] = true;
bool IsAMDGCN = isAMDGCN(getTriple());
- if (hasFP64())
- Opts.support("cl_khr_fp64");
+ Opts["cl_khr_fp64"] = hasFP64();
if (IsAMDGCN || GPUKind >= llvm::AMDGPU::GK_CEDAR) {
- Opts.support("cl_khr_byte_addressable_store");
- Opts.support("cl_khr_global_int32_base_atomics");
- Opts.support("cl_khr_global_int32_extended_atomics");
- Opts.support("cl_khr_local_int32_base_atomics");
- Opts.support("cl_khr_local_int32_extended_atomics");
+ Opts["cl_khr_byte_addressable_store"] = true;
+ Opts["cl_khr_global_int32_base_atomics"] = true;
+ Opts["cl_khr_global_int32_extended_atomics"] = true;
+ Opts["cl_khr_local_int32_base_atomics"] = true;
+ Opts["cl_khr_local_int32_extended_atomics"] = true;
}
if (IsAMDGCN) {
- Opts.support("cl_khr_fp16");
- Opts.support("cl_khr_int64_base_atomics");
- Opts.support("cl_khr_int64_extended_atomics");
- Opts.support("cl_khr_mipmap_image");
- Opts.support("cl_khr_mipmap_image_writes");
- Opts.support("cl_khr_subgroups");
- Opts.support("cl_khr_3d_image_writes");
- Opts.support("cl_amd_media_ops");
- Opts.support("cl_amd_media_ops2");
+ Opts["cl_khr_fp16"] = true;
+ Opts["cl_khr_int64_base_atomics"] = true;
+ Opts["cl_khr_int64_extended_atomics"] = true;
+ Opts["cl_khr_mipmap_image"] = true;
+ Opts["cl_khr_mipmap_image_writes"] = true;
+ Opts["cl_khr_subgroups"] = true;
+ Opts["cl_khr_3d_image_writes"] = true;
+ Opts["cl_amd_media_ops"] = true;
+ Opts["cl_amd_media_ops2"] = true;
}
}
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -705,7 +705,7 @@
return nullptr;
Target->setSupportedOpenCLOpts();
- Target->setOpenCLExtensionOpts();
+ Target->setCommandLineOpenCLOpts();
Target->setMaxAtomicWidth();
if (!Target->validateTarget(Diags))
@@ -715,3 +715,29 @@
return Target.release();
}
+
+/// getOpenCLFeatureDefines - Define OpenCL macros based on target settings
+/// and language version
+void TargetInfo::getOpenCLFeatureDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+
+ 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(AvailVer, CoreVersions,
+ OptionalVersions)
+ .isAvailableIn(Opts))
+ Builder.defineMacro(Name);
+ };
+#define OPENCL_GENERIC_EXTENSION(Ext, Avail, Core, Opt) \
+ defineOpenCLExtMacro(#Ext, Avail, Core, Opt);
+#include "clang/Basic/OpenCLExtensions.def"
+
+ // 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
+}
Index: clang/lib/Basic/OpenCLOptions.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/OpenCLOptions.cpp
@@ -0,0 +1,106 @@
+//===--- OpenCLOptions.cpp---------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/OpenCLOptions.h"
+
+namespace clang {
+
+bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
+ return OptMap.find(Ext) != OptMap.end();
+}
+
+bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
+ auto E = OptMap.find(Ext);
+ return E != OptMap.end() && E->second.Enabled;
+}
+
+bool OpenCLOptions::isSupported(llvm::StringRef Ext,
+ const LangOptions &LO) const {
+ auto E = OptMap.find(Ext);
+ if (E == OptMap.end()) {
+ return false;
+ }
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.isAvailableIn(LO);
+}
+
+bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
+ const LangOptions &LO) const {
+ auto E = OptMap.find(Ext);
+ if (E == OptMap.end()) {
+ return false;
+ }
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.isCoreIn(LO);
+}
+
+bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
+ const LangOptions &LO) const {
+ auto E = OptMap.find(Ext);
+ if (E == OptMap.end()) {
+ return false;
+ }
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.isOptionalCoreIn(LO);
+}
+
+bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
+ const LangOptions &LO) const {
+ return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
+}
+
+bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
+ const LangOptions &LO) const {
+ auto E = OptMap.find(Ext);
+ if (E == OptMap.end()) {
+ return false;
+ }
+ auto I = OptMap.find(Ext)->getValue();
+ return I.Supported && I.isAvailableIn(LO) &&
+ !isSupportedCoreOrOptionalCore(Ext, LO);
+}
+
+void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
+ OptMap[Ext].Enabled = V;
+}
+
+void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
+ assert(!Ext.empty() && "Extension is empty.");
+ assert(Ext[0] != '+' && Ext[0] != '-');
+ OptMap[Ext].Supported = V;
+}
+
+OpenCLOptions::OpenCLOptions() {
+#define OPENCL_GENERIC_EXTENSION(Ext, AvailVer, CoreVer, OptVer) \
+ OptMap[#Ext].Avail = AvailVer; \
+ OptMap[#Ext].Core = CoreVer; \
+ OptMap[#Ext].Opt = OptVer;
+#include "clang/Basic/OpenCLExtensions.def"
+}
+
+void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
+ const LangOptions &Opts) {
+ for (const auto &F : FeaturesMap) {
+ const auto &Name = F.getKey();
+ if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
+ support(Name);
+ }
+}
+
+void OpenCLOptions::disableAll() {
+ for (auto &Opt : OptMap)
+ Opt.getValue().Enabled = false;
+}
+
+void OpenCLOptions::enableSupportedCore(const LangOptions &LO) {
+ for (auto &Opt : OptMap)
+ if (isSupportedCoreOrOptionalCore(Opt.getKey(), LO))
+ Opt.getValue().Enabled = true;
+}
+
+} // end namespace clang
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -56,6 +56,7 @@
LangStandards.cpp
Module.cpp
ObjCRuntime.cpp
+ OpenCLOptions.cpp
OpenMPKinds.cpp
OperatorPrecedence.cpp
SanitizerBlacklist.cpp
Index: clang/include/clang/Basic/TargetOptions.h
===================================================================
--- clang/include/clang/Basic/TargetOptions.h
+++ clang/include/clang/Basic/TargetOptions.h
@@ -62,7 +62,7 @@
llvm::StringMap<bool> FeatureMap;
/// Supported OpenCL extensions and optional core features.
- OpenCLOptions SupportedOpenCLOptions;
+ llvm::StringMap<bool> OpenCLFeaturesMap;
/// The list of OpenCL extensions to enable or disable, as written on
/// the command line.
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -1438,21 +1438,39 @@
/// Set supported OpenCL extensions and optional core features.
virtual void setSupportedOpenCLOpts() {}
+ virtual void supportAllOpenCLOpts(bool V = true) {
+#define OPENCLEXTNAME(Ext) getTargetOpts().OpenCLFeaturesMap[#Ext] = V;
+#include "clang/Basic/OpenCLExtensions.def"
+ }
+
/// Set supported OpenCL extensions as written on command line
- virtual void setOpenCLExtensionOpts() {
+ virtual void setCommandLineOpenCLOpts() {
for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
- getTargetOpts().SupportedOpenCLOptions.support(Ext);
+ bool IsPrefixed = (Ext[0] == '+' || Ext[0] == '-');
+ std::string Name = IsPrefixed ? Ext.substr(1) : Ext;
+ bool V = IsPrefixed ? Ext[0] == '+' : true;
+
+ if (Name == "all") {
+ supportAllOpenCLOpts(V);
+ continue;
+ }
+
+ getTargetOpts().OpenCLFeaturesMap[Name] = V;
}
}
+ /// 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.
- OpenCLOptions &getSupportedOpenCLOpts() {
- return getTargetOpts().SupportedOpenCLOptions;
+ llvm::StringMap<bool> &getSupportedOpenCLOpts() {
+ return getTargetOpts().OpenCLFeaturesMap;
}
/// Get const supported OpenCL extensions and optional core features.
- const OpenCLOptions &getSupportedOpenCLOpts() const {
- return getTargetOpts().SupportedOpenCLOptions;
+ const llvm::StringMap<bool> &getSupportedOpenCLOpts() const {
+ return getTargetOpts().OpenCLFeaturesMap;
}
/// Get address space for OpenCL type.
Index: clang/include/clang/Basic/OpenCLOptions.h
===================================================================
--- clang/include/clang/Basic/OpenCLOptions.h
+++ clang/include/clang/Basic/OpenCLOptions.h
@@ -19,155 +19,145 @@
namespace clang {
+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;
+ }
+}
+
+// Simple helper to check if OpenCL C version is contained in a given encoded
+// OpenCL C version mask
+static inline bool isOpenCLVersionIsContainedInMask(const LangOptions &LO,
+ unsigned Mask) {
+ auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
+ OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
+ return Mask & Code;
+}
+} // end anonymous namespace
+
/// OpenCL supported extensions and optional core features
class OpenCLOptions {
- struct Info {
- bool Supported; // Is this option supported
- bool Enabled; // Is this option enabled
- unsigned Avail; // Option starts to be available in this OpenCL version
- unsigned Core; // Option becomes (optional) core feature in this OpenCL
- // version
- Info(bool S = false, bool E = false, unsigned A = 100, unsigned C = ~0U)
- :Supported(S), Enabled(E), Avail(A), Core(C){}
- };
- llvm::StringMap<Info> OptMap;
public:
- /// Check if \c Ext is a recognized OpenCL extension.
- ///
- /// \param Ext - Extension to look up.
- /// \returns \c true if \c Ext is known, \c false otherwise.
- bool isKnown(llvm::StringRef Ext) const {
- return OptMap.find(Ext) != OptMap.end();
- }
+ struct OpenCLOptionInfo {
+ // Option starts to be available in this OpenCL version
+ unsigned Avail;
- /// Check if \c Ext is an enabled OpenCL extension.
- ///
- /// \param Ext - Extension to look up.
- /// \returns \c true if \c Ext is known and enabled, \c false otherwise.
- bool isEnabled(llvm::StringRef Ext) const {
- auto E = OptMap.find(Ext);
- return E != OptMap.end() && E->second.Enabled;
- }
+ // Option becomes core feature in this OpenCL versions
+ unsigned Core;
+
+ // Option becomes optional core feature in this OpenCL versions
+ unsigned Opt;
+
+ // Is this option supported
+ bool Supported = false;
- /// Check if \c Ext is supported as either an extension or an (optional) core
- /// feature for the given OpenCL version.
- ///
- /// \param Ext - Extension to look up.
- /// \param LO - \c LangOptions specifying the OpenCL version.
- /// \returns \c true if \c Ext is known and supported, \c false otherwise.
- bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const {
- auto E = OptMap.find(Ext);
- if (E == OptMap.end()) {
- return false;
+ // Is this option enabled
+ bool Enabled = false;
+
+ OpenCLOptionInfo(unsigned A = 100, unsigned C = 0U, unsigned O = 0U)
+ : Avail(A), Core(C), Opt(O) {}
+
+ 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.
+ auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
+ return CLVer >= Avail;
}
- // In C++ mode all extensions should work at least as in v2.0.
- auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
- auto I = E->getValue();
- return I.Supported && I.Avail <= CLVer;
- }
- /// Check if \c Ext is supported as an (optional) OpenCL core features for
- /// the given OpenCL version.
- ///
- /// \param Ext - Extension to look up.
- /// \param LO - \c LangOptions specifying the OpenCL version.
- /// \returns \c true if \c Ext is known and supported, \c false otherwise.
- bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const {
- auto E = OptMap.find(Ext);
- if (E == OptMap.end()) {
- return false;
+ // Is core option in OpenCL version \p LO.
+ bool isCoreIn(const LangOptions &LO) const {
+ return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Core);
}
- // In C++ mode all extensions should work at least as in v2.0.
- auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
- auto I = E->getValue();
- return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core;
- }
- /// Check if \c Ext is a supported OpenCL extension for the given OpenCL
- /// version.
- ///
- /// \param Ext - Extension to look up.
- /// \param LO - \c LangOptions specifying the OpenCL version.
- /// \returns \c true if \c Ext is known and supported, \c false otherwise.
- bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const {
- auto E = OptMap.find(Ext);
- if (E == OptMap.end()) {
- return false;
+ // Is optional core option in OpenCL version \p LO.
+ bool isOptionalCoreIn(const LangOptions &LO) const {
+ return isAvailableIn(LO) && isOpenCLVersionIsContainedInMask(LO, Opt);
}
- // In C++ mode all extensions should work at least as in v2.0.
- auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
- auto I = E->getValue();
- return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core);
- }
+ };
- void enable(llvm::StringRef Ext, bool V = true) {
- OptMap[Ext].Enabled = V;
- }
+ bool isKnown(llvm::StringRef Ext) const;
- /// Enable or disable support for OpenCL extensions
- /// \param Ext name of the extension optionally prefixed with
- /// '+' or '-'
- /// \param V used when \p Ext is not prefixed by '+' or '-'
- void support(llvm::StringRef Ext, bool V = true) {
- assert(!Ext.empty() && "Extension is empty.");
-
- switch (Ext[0]) {
- case '+':
- V = true;
- Ext = Ext.drop_front();
- break;
- case '-':
- V = false;
- Ext = Ext.drop_front();
- break;
- }
+ bool isEnabled(llvm::StringRef Ext) const;
- if (Ext.equals("all")) {
- supportAll(V);
- return;
- }
- OptMap[Ext].Supported = V;
- }
+ // 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;
- OpenCLOptions(){
-#define OPENCLEXT_INTERNAL(Ext, AvailVer, CoreVer) \
- OptMap[#Ext].Avail = AvailVer; \
- OptMap[#Ext].Core = CoreVer;
-#include "clang/Basic/OpenCLExtensions.def"
- }
+ // Is supported OpenCL core feature for OpenCL version \p LO.
+ // For supported extension, return false.
+ bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const;
- void addSupport(const OpenCLOptions &Opts) {
- for (auto &I:Opts.OptMap)
- if (I.second.Supported)
- OptMap[I.getKey()].Supported = true;
- }
+ // 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;
- void copy(const OpenCLOptions &Opts) {
- OptMap = Opts.OptMap;
- }
+ // 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;
- // Turn on or off support of all options.
- void supportAll(bool On = true) {
- for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
- E = OptMap.end(); I != E; ++I)
- I->second.Supported = On;
- }
+ // 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;
- void disableAll() {
- for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
- E = OptMap.end(); I != E; ++I)
- I->second.Enabled = false;
- }
+ void enable(llvm::StringRef Ext, bool V = true);
- void enableSupportedCore(LangOptions LO) {
- for (llvm::StringMap<Info>::iterator I = OptMap.begin(), E = OptMap.end();
- I != E; ++I)
- if (isSupportedCore(I->getKey(), LO))
- I->second.Enabled = 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();
+ OpenCLOptions(const OpenCLOptions &) = default;
+
+ // 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();
+
+ // Enable supported core and optional core features
+ void enableSupportedCore(const LangOptions &LO);
friend class ASTWriter;
friend class ASTReader;
+
+ using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>;
+
+private:
+ OpenCLOptionInfoMap OptMap;
};
} // end namespace clang
Index: clang/include/clang/Basic/OpenCLExtensions.def
===================================================================
--- clang/include/clang/Basic/OpenCLExtensions.def
+++ clang/include/clang/Basic/OpenCLExtensions.def
@@ -10,19 +10,25 @@
//
//===----------------------------------------------------------------------===//
-// Macro OPENCLEXT or OPENCLEXT_INTERNAL can be defined to enumerate the
+// Macro OPENCLEXTNAME or OPENCL_GENERIC_EXTENSION can be defined to enumerate all
// OpenCL extensions listed in this file.
//
-// If the extensions are to be enumerated without the supported OpenCL version,
-// define OPENCLEXT(ext) where ext is the name of the extension.
-//
-// If the extensions are to be enumerated with supported OpenCL version,
-// define OPENCLEXT_INTERNAL(ext, avail, core) where
+// If extensions are to be enumerated with information about whether
+// an extension is core or optional core and minimum OpenCL version
+// when an extension becomes available,
+// define OPENCL_GENERIC_EXTENSION(ext, avail, core, opt) where
// ext - name of the extension or optional core feature.
// avail - minimum OpenCL version supporting it.
-// core - minimum OpenCL version when the extension becomes optional core
-// feature or core feature. ~0U indicates not a core feature or an
-// optional core feature.
+// core - OpenCL versions mask when the extension becomes core feature.
+// 0U indicates not a core feature.
+// opt - OpenCL versions mask when the extension becomes optional core
+// feature. 0U indicates not a optional core feature.
+//
+// If extensions are to be enumerated without any information,
+// define OPENCLEXTNAME(ext) where ext is the name of the extension.
+//
+// Difference between optional core feature and core feature is that the
+// later is unconditionally supported in specific OpenCL version.
//
// As per The OpenCL Extension Specification, Section 1.2, in this file, an
// extension is defined if and only it either:
@@ -32,63 +38,72 @@
// For such an extension, a preprocessor #define that matches the extension
// name must be created and a #pragma is required if and only if the
// compilation flow is impacted, e.g. due to a difference of syntax or
-// semantics in the language compared to the core standard.
+// semantics in the language compared to the core standard. #pragma directive
+// has no effect for optional core and core features.
-#ifndef OPENCLEXT_INTERNAL
-#ifndef OPENCLEXT
-#pragma error "macro OPENCLEXT or OPENCLEXT_INTERNAL is required"
+#ifndef OPENCL_GENERIC_EXTENSION
+#ifndef OPENCLEXTNAME
+#pragma error "macro OPENCLEXTNAME or OPENCL_GENERIC_EXTENSION is required"
#else
-#define OPENCLEXT_INTERNAL(ext, ...) OPENCLEXT(ext)
-#endif // OPENCLEXT
-#endif // OPENCLEXT_INTERNAL
+#define OPENCL_GENERIC_EXTENSION(ext, ...) OPENCLEXTNAME(ext)
+#endif // OPENCLEXTNAME
+#endif // OPENCL_GENERIC_EXTENSION
+
+// Declaration helpers
+#define OPENCL_EXTENSION(ext, avail) OPENCL_GENERIC_EXTENSION(ext, avail, 0U, 0U)
+#define OPENCL_COREFEATURE(ext, avail, core) OPENCL_GENERIC_EXTENSION(ext, avail, core, 0U)
+#define OPENCL_OPTIONALCOREFEATURE(ext, avail, opt) OPENCL_GENERIC_EXTENSION(ext, avail, 0U, opt)
// OpenCL 1.0.
-OPENCLEXT_INTERNAL(cl_khr_3d_image_writes, 100, 200)
-OPENCLEXT_INTERNAL(cl_khr_byte_addressable_store, 100, 110)
-OPENCLEXT_INTERNAL(cl_khr_fp16, 100, ~0U)
-OPENCLEXT_INTERNAL(cl_khr_fp64, 100, 120)
-OPENCLEXT_INTERNAL(cl_khr_global_int32_base_atomics, 100, 110)
-OPENCLEXT_INTERNAL(cl_khr_global_int32_extended_atomics, 100, 110)
-OPENCLEXT_INTERNAL(cl_khr_local_int32_base_atomics, 100, 110)
-OPENCLEXT_INTERNAL(cl_khr_local_int32_extended_atomics, 100, 110)
-OPENCLEXT_INTERNAL(cl_khr_int64_base_atomics, 100, ~0U)
-OPENCLEXT_INTERNAL(cl_khr_int64_extended_atomics, 100, ~0U)
+OPENCL_COREFEATURE(cl_khr_byte_addressable_store, 100, OCL_C_11P)
+OPENCL_COREFEATURE(cl_khr_global_int32_base_atomics, 100, OCL_C_11P)
+OPENCL_COREFEATURE(cl_khr_global_int32_extended_atomics, 100, OCL_C_11P)
+OPENCL_COREFEATURE(cl_khr_local_int32_base_atomics, 100, OCL_C_11P)
+OPENCL_COREFEATURE(cl_khr_local_int32_extended_atomics, 100, OCL_C_11P)
+OPENCL_OPTIONALCOREFEATURE(cl_khr_fp64, 100, OCL_C_12P)
+OPENCL_EXTENSION(cl_khr_fp16, 100)
+OPENCL_EXTENSION(cl_khr_int64_base_atomics, 100)
+OPENCL_EXTENSION(cl_khr_int64_extended_atomics, 100)
+OPENCL_GENERIC_EXTENSION(cl_khr_3d_image_writes, 100, OCL_C_20, OCL_C_30)
// EMBEDDED_PROFILE
-OPENCLEXT_INTERNAL(cles_khr_int64, 110, ~0U)
+OPENCL_EXTENSION(cles_khr_int64, 110)
// OpenCL 1.2.
-OPENCLEXT_INTERNAL(cl_khr_depth_images, 120, ~0U)
-OPENCLEXT_INTERNAL(cl_khr_gl_msaa_sharing, 120, ~0U)
+OPENCL_EXTENSION(cl_khr_depth_images, 120)
+OPENCL_EXTENSION(cl_khr_gl_msaa_sharing, 120)
// OpenCL 2.0.
-OPENCLEXT_INTERNAL(cl_khr_mipmap_image, 200, ~0U)
-OPENCLEXT_INTERNAL(cl_khr_mipmap_image_writes, 200, ~0U)
-OPENCLEXT_INTERNAL(cl_khr_srgb_image_writes, 200, ~0U)
-OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U)
+OPENCL_EXTENSION(cl_khr_mipmap_image, 200)
+OPENCL_EXTENSION(cl_khr_mipmap_image_writes, 200)
+OPENCL_EXTENSION(cl_khr_srgb_image_writes, 200)
+OPENCL_EXTENSION(cl_khr_subgroups, 200)
// Clang Extensions.
-OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U)
-OPENCLEXT_INTERNAL(__cl_clang_function_pointers, 100, ~0U)
-OPENCLEXT_INTERNAL(__cl_clang_variadic_functions, 100, ~0U)
+OPENCL_EXTENSION(cl_clang_storage_class_specifiers, 100)
+OPENCL_EXTENSION(__cl_clang_function_pointers, 100)
+OPENCL_EXTENSION(__cl_clang_variadic_functions, 100)
// AMD OpenCL extensions
-OPENCLEXT_INTERNAL(cl_amd_media_ops, 100, ~0U)
-OPENCLEXT_INTERNAL(cl_amd_media_ops2, 100, ~0U)
+OPENCL_EXTENSION(cl_amd_media_ops, 100)
+OPENCL_EXTENSION(cl_amd_media_ops2, 100)
// ARM OpenCL extensions
-OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_int8, 120, ~0U)
-OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_accumulate_int8, 120, ~0U)
-OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_accumulate_int16, 120, ~0U)
-OPENCLEXT_INTERNAL(cl_arm_integer_dot_product_accumulate_saturate_int8, 120, ~0U)
+OPENCL_EXTENSION(cl_arm_integer_dot_product_int8, 120)
+OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int8, 120)
+OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int16, 120)
+OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_saturate_int8, 120)
// Intel OpenCL extensions
-OPENCLEXT_INTERNAL(cl_intel_subgroups, 120, ~0U)
-OPENCLEXT_INTERNAL(cl_intel_subgroups_short, 120, ~0U)
-OPENCLEXT_INTERNAL(cl_intel_device_side_avc_motion_estimation, 120, ~0U)
+OPENCL_EXTENSION(cl_intel_subgroups, 120)
+OPENCL_EXTENSION(cl_intel_subgroups_short, 120)
+OPENCL_EXTENSION(cl_intel_device_side_avc_motion_estimation, 120)
+
-#undef OPENCLEXT_INTERNAL
+#undef OPENCL_OPTIONALCOREFEATURE
+#undef OPENCL_COREFEATURE
+#undef OPENCL_GENERIC_EXTENSION
-#ifdef OPENCLEXT
-#undef OPENCLEXT
+#ifdef OPENCLEXTNAME
+#undef OPENCLEXTNAME
#endif
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits