clang  19.0.0git
OpenCLOptions.cpp
Go to the documentation of this file.
1 //===--- OpenCLOptions.cpp---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "clang/Basic/Diagnostic.h"
11 #include "clang/Basic/TargetInfo.h"
12 
13 namespace clang {
14 
15 // First feature in a pair requires the second one to be supported.
16 static const std::pair<StringRef, StringRef> DependentFeaturesList[] = {
17  {"__opencl_c_read_write_images", "__opencl_c_images"},
18  {"__opencl_c_3d_image_writes", "__opencl_c_images"},
19  {"__opencl_c_pipes", "__opencl_c_generic_address_space"},
20  {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"},
21  {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}};
22 
23 // Extensions and equivalent feature pairs.
24 static const std::pair<StringRef, StringRef> FeatureExtensionMap[] = {
25  {"cl_khr_fp64", "__opencl_c_fp64"},
26  {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
27 
28 bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
29  return OptMap.contains(Ext);
30 }
31 
32 bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
33  const LangOptions &LO) const {
34  if (!isKnown(Ext))
35  return false;
36 
37  auto &OptInfo = OptMap.find(Ext)->getValue();
38  if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO))
39  return isSupported(Ext, LO);
40 
41  return isEnabled(Ext);
42 }
43 
44 bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
45  auto I = OptMap.find(Ext);
46  return I != OptMap.end() && I->getValue().Enabled;
47 }
48 
49 bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const {
50  auto E = OptMap.find(Ext);
51  return E != OptMap.end() && E->second.WithPragma;
52 }
53 
54 bool OpenCLOptions::isSupported(llvm::StringRef Ext,
55  const LangOptions &LO) const {
56  auto I = OptMap.find(Ext);
57  return I != OptMap.end() && I->getValue().Supported &&
58  I->getValue().isAvailableIn(LO);
59 }
60 
61 bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
62  const LangOptions &LO) const {
63  auto I = OptMap.find(Ext);
64  return I != OptMap.end() && I->getValue().Supported &&
65  I->getValue().isCoreIn(LO);
66 }
67 
68 bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
69  const LangOptions &LO) const {
70  auto I = OptMap.find(Ext);
71  return I != OptMap.end() && I->getValue().Supported &&
72  I->getValue().isOptionalCoreIn(LO);
73 }
74 
76  const LangOptions &LO) const {
77  return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
78 }
79 
80 bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
81  const LangOptions &LO) const {
82  auto I = OptMap.find(Ext);
83  return I != OptMap.end() && I->getValue().Supported &&
84  I->getValue().isAvailableIn(LO) &&
86 }
87 
88 void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
89  OptMap[Ext].Enabled = V;
90 }
91 
92 void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) {
93  OptMap[Ext].WithPragma = V;
94 }
95 
96 void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
97  assert(!Ext.empty() && "Extension is empty.");
98  assert(Ext[0] != '+' && Ext[0] != '-');
99  OptMap[Ext].Supported = V;
100 }
101 
103 #define OPENCL_GENERIC_EXTENSION(Ext, ...) \
104  OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
105 #include "clang/Basic/OpenCLExtensions.def"
106 }
107 
108 void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
109  const LangOptions &Opts) {
110  for (const auto &F : FeaturesMap) {
111  const auto &Name = F.getKey();
112  if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
113  support(Name);
114  }
115 }
116 
118  for (auto &Opt : OptMap)
119  Opt.getValue().Enabled = false;
120 }
121 
123  const TargetInfo &TI, DiagnosticsEngine &Diags) {
124  auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
125 
126  bool IsValid = true;
127  for (auto &FeaturePair : DependentFeaturesList) {
128  auto Feature = FeaturePair.first;
129  auto Dep = FeaturePair.second;
130  if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) &&
131  !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) {
132  IsValid = false;
133  Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep;
134  }
135  }
136  return IsValid;
137 }
138 
140  const TargetInfo &TI, DiagnosticsEngine &Diags) {
141  auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
142 
143  bool IsValid = true;
144  for (auto &ExtAndFeat : FeatureExtensionMap)
145  if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) !=
146  TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) {
147  IsValid = false;
148  Diags.Report(diag::err_opencl_extension_and_feature_differs)
149  << ExtAndFeat.first << ExtAndFeat.second;
150  }
151  return IsValid;
152 }
153 
154 } // end namespace clang
#define V(N, I)
Definition: ASTContext.h:3299
Defines the Diagnostic-related interfaces.
Defines the clang::OpenCLOptions class.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const
static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI, DiagnosticsEngine &Diags)
bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const
void enable(llvm::StringRef Ext, bool V=true)
bool isWithPragma(llvm::StringRef Ext) const
bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const
static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI, DiagnosticsEngine &Diags)
bool isSupportedCoreOrOptionalCore(llvm::StringRef Ext, const LangOptions &LO) const
bool isSupportedOptionalCore(llvm::StringRef Ext, const LangOptions &LO) const
void addSupport(const llvm::StringMap< bool > &FeaturesMap, const LangOptions &Opts)
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
void acceptsPragma(llvm::StringRef Ext, bool V=true)
void support(llvm::StringRef Ext, bool V=true)
Enable or disable support for OpenCL extensions.
bool isKnown(llvm::StringRef Ext) const
Exposes information about the current target.
Definition: TargetInfo.h:218
llvm::StringMap< bool > & getSupportedOpenCLOpts()
Get supported OpenCL extensions and optional core features.
Definition: TargetInfo.h:1750
virtual bool hasFeatureEnabled(const llvm::StringMap< bool > &Features, StringRef Name) const
Check if target has a given feature enabled.
Definition: TargetInfo.h:1379
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
static const std::pair< StringRef, StringRef > FeatureExtensionMap[]
static const std::pair< StringRef, StringRef > DependentFeaturesList[]