xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
1e8d8bef9SDimitry Andric //===--- OpenCLOptions.cpp---------------------------------------*- C++ -*-===//
2e8d8bef9SDimitry Andric //
3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric //
7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric 
9e8d8bef9SDimitry Andric #include "clang/Basic/OpenCLOptions.h"
10fe6060f1SDimitry Andric #include "clang/Basic/Diagnostic.h"
11fe6060f1SDimitry Andric #include "clang/Basic/TargetInfo.h"
12e8d8bef9SDimitry Andric 
13e8d8bef9SDimitry Andric namespace clang {
14e8d8bef9SDimitry Andric 
15*04eeddc0SDimitry Andric const OpenCLOptions::FeatureDepList OpenCLOptions::DependentFeaturesList = {
16*04eeddc0SDimitry Andric     {"__opencl_c_read_write_images", "__opencl_c_images"},
17*04eeddc0SDimitry Andric     {"__opencl_c_3d_image_writes", "__opencl_c_images"},
18*04eeddc0SDimitry Andric     {"__opencl_c_pipes", "__opencl_c_generic_address_space"},
19*04eeddc0SDimitry Andric     {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"},
20*04eeddc0SDimitry Andric     {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}};
21*04eeddc0SDimitry Andric 
22*04eeddc0SDimitry Andric const llvm::StringMap<llvm::StringRef> OpenCLOptions::FeatureExtensionMap = {
23*04eeddc0SDimitry Andric     {"cl_khr_fp64", "__opencl_c_fp64"},
24*04eeddc0SDimitry Andric     {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
25*04eeddc0SDimitry Andric 
26e8d8bef9SDimitry Andric bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
27e8d8bef9SDimitry Andric   return OptMap.find(Ext) != OptMap.end();
28e8d8bef9SDimitry Andric }
29e8d8bef9SDimitry Andric 
30fe6060f1SDimitry Andric bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
31fe6060f1SDimitry Andric                                       const LangOptions &LO) const {
32fe6060f1SDimitry Andric   if (!isKnown(Ext))
33fe6060f1SDimitry Andric     return false;
34fe6060f1SDimitry Andric 
35fe6060f1SDimitry Andric   auto &OptInfo = OptMap.find(Ext)->getValue();
36fe6060f1SDimitry Andric   if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO))
37fe6060f1SDimitry Andric     return isSupported(Ext, LO);
38fe6060f1SDimitry Andric 
39fe6060f1SDimitry Andric   return isEnabled(Ext);
40fe6060f1SDimitry Andric }
41fe6060f1SDimitry Andric 
42e8d8bef9SDimitry Andric bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
43fe6060f1SDimitry Andric   auto I = OptMap.find(Ext);
44fe6060f1SDimitry Andric   return I != OptMap.end() && I->getValue().Enabled;
45fe6060f1SDimitry Andric }
46fe6060f1SDimitry Andric 
47fe6060f1SDimitry Andric bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const {
48e8d8bef9SDimitry Andric   auto E = OptMap.find(Ext);
49fe6060f1SDimitry Andric   return E != OptMap.end() && E->second.WithPragma;
50e8d8bef9SDimitry Andric }
51e8d8bef9SDimitry Andric 
52e8d8bef9SDimitry Andric bool OpenCLOptions::isSupported(llvm::StringRef Ext,
53e8d8bef9SDimitry Andric                                 const LangOptions &LO) const {
54fe6060f1SDimitry Andric   auto I = OptMap.find(Ext);
55fe6060f1SDimitry Andric   return I != OptMap.end() && I->getValue().Supported &&
56fe6060f1SDimitry Andric          I->getValue().isAvailableIn(LO);
57e8d8bef9SDimitry Andric }
58e8d8bef9SDimitry Andric 
59e8d8bef9SDimitry Andric bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
60e8d8bef9SDimitry Andric                                     const LangOptions &LO) const {
61fe6060f1SDimitry Andric   auto I = OptMap.find(Ext);
62fe6060f1SDimitry Andric   return I != OptMap.end() && I->getValue().Supported &&
63fe6060f1SDimitry Andric          I->getValue().isCoreIn(LO);
64e8d8bef9SDimitry Andric }
65e8d8bef9SDimitry Andric 
66e8d8bef9SDimitry Andric bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
67e8d8bef9SDimitry Andric                                             const LangOptions &LO) const {
68fe6060f1SDimitry Andric   auto I = OptMap.find(Ext);
69fe6060f1SDimitry Andric   return I != OptMap.end() && I->getValue().Supported &&
70fe6060f1SDimitry Andric          I->getValue().isOptionalCoreIn(LO);
71e8d8bef9SDimitry Andric }
72e8d8bef9SDimitry Andric 
73e8d8bef9SDimitry Andric bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
74e8d8bef9SDimitry Andric                                                   const LangOptions &LO) const {
75e8d8bef9SDimitry Andric   return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
76e8d8bef9SDimitry Andric }
77e8d8bef9SDimitry Andric 
78e8d8bef9SDimitry Andric bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
79e8d8bef9SDimitry Andric                                          const LangOptions &LO) const {
80fe6060f1SDimitry Andric   auto I = OptMap.find(Ext);
81fe6060f1SDimitry Andric   return I != OptMap.end() && I->getValue().Supported &&
82fe6060f1SDimitry Andric          I->getValue().isAvailableIn(LO) &&
83e8d8bef9SDimitry Andric          !isSupportedCoreOrOptionalCore(Ext, LO);
84e8d8bef9SDimitry Andric }
85e8d8bef9SDimitry Andric 
86e8d8bef9SDimitry Andric void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
87e8d8bef9SDimitry Andric   OptMap[Ext].Enabled = V;
88e8d8bef9SDimitry Andric }
89e8d8bef9SDimitry Andric 
90fe6060f1SDimitry Andric void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) {
91fe6060f1SDimitry Andric   OptMap[Ext].WithPragma = V;
92fe6060f1SDimitry Andric }
93fe6060f1SDimitry Andric 
94e8d8bef9SDimitry Andric void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
95e8d8bef9SDimitry Andric   assert(!Ext.empty() && "Extension is empty.");
96e8d8bef9SDimitry Andric   assert(Ext[0] != '+' && Ext[0] != '-');
97e8d8bef9SDimitry Andric   OptMap[Ext].Supported = V;
98e8d8bef9SDimitry Andric }
99e8d8bef9SDimitry Andric 
100e8d8bef9SDimitry Andric OpenCLOptions::OpenCLOptions() {
101fe6060f1SDimitry Andric #define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
102fe6060f1SDimitry Andric   OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
103e8d8bef9SDimitry Andric #include "clang/Basic/OpenCLExtensions.def"
104e8d8bef9SDimitry Andric }
105e8d8bef9SDimitry Andric 
106e8d8bef9SDimitry Andric void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
107e8d8bef9SDimitry Andric                                const LangOptions &Opts) {
108e8d8bef9SDimitry Andric   for (const auto &F : FeaturesMap) {
109e8d8bef9SDimitry Andric     const auto &Name = F.getKey();
110e8d8bef9SDimitry Andric     if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
111e8d8bef9SDimitry Andric       support(Name);
112e8d8bef9SDimitry Andric   }
113e8d8bef9SDimitry Andric }
114e8d8bef9SDimitry Andric 
115e8d8bef9SDimitry Andric void OpenCLOptions::disableAll() {
116e8d8bef9SDimitry Andric   for (auto &Opt : OptMap)
117e8d8bef9SDimitry Andric     Opt.getValue().Enabled = false;
118e8d8bef9SDimitry Andric }
119e8d8bef9SDimitry Andric 
120fe6060f1SDimitry Andric bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies(
121fe6060f1SDimitry Andric     const TargetInfo &TI, DiagnosticsEngine &Diags) {
122fe6060f1SDimitry Andric   auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
123fe6060f1SDimitry Andric 
124fe6060f1SDimitry Andric   bool IsValid = true;
125*04eeddc0SDimitry Andric   for (auto &FeaturePair : DependentFeaturesList) {
126*04eeddc0SDimitry Andric     auto Feature = FeaturePair.first;
127*04eeddc0SDimitry Andric     auto Dep = FeaturePair.second;
128*04eeddc0SDimitry Andric     if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) &&
129*04eeddc0SDimitry Andric         !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) {
130fe6060f1SDimitry Andric       IsValid = false;
131*04eeddc0SDimitry Andric       Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep;
132*04eeddc0SDimitry Andric     }
133fe6060f1SDimitry Andric   }
134fe6060f1SDimitry Andric   return IsValid;
135fe6060f1SDimitry Andric }
136fe6060f1SDimitry Andric 
137fe6060f1SDimitry Andric bool OpenCLOptions::diagnoseFeatureExtensionDifferences(
138fe6060f1SDimitry Andric     const TargetInfo &TI, DiagnosticsEngine &Diags) {
139fe6060f1SDimitry Andric   auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
140fe6060f1SDimitry Andric 
141fe6060f1SDimitry Andric   bool IsValid = true;
142fe6060f1SDimitry Andric   for (auto &ExtAndFeat : FeatureExtensionMap)
143fe6060f1SDimitry Andric     if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getKey()) !=
144fe6060f1SDimitry Andric         TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getValue())) {
145fe6060f1SDimitry Andric       IsValid = false;
146fe6060f1SDimitry Andric       Diags.Report(diag::err_opencl_extension_and_feature_differs)
147fe6060f1SDimitry Andric           << ExtAndFeat.getKey() << ExtAndFeat.getValue();
148fe6060f1SDimitry Andric     }
149fe6060f1SDimitry Andric   return IsValid;
150e8d8bef9SDimitry Andric }
151e8d8bef9SDimitry Andric 
152e8d8bef9SDimitry Andric } // end namespace clang
153