xref: /llvm-project/clang/lib/Basic/OpenCLOptions.cpp (revision ea9d404032be1541e82e965bada82935629a98c8)
1e123cd67SAnton Zabaznov //===--- OpenCLOptions.cpp---------------------------------------*- C++ -*-===//
2e123cd67SAnton Zabaznov //
3e123cd67SAnton Zabaznov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e123cd67SAnton Zabaznov // See https://llvm.org/LICENSE.txt for license information.
5e123cd67SAnton Zabaznov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e123cd67SAnton Zabaznov //
7e123cd67SAnton Zabaznov //===----------------------------------------------------------------------===//
8e123cd67SAnton Zabaznov 
9e123cd67SAnton Zabaznov #include "clang/Basic/OpenCLOptions.h"
10ab76101fSAnton Zabaznov #include "clang/Basic/Diagnostic.h"
11ab76101fSAnton Zabaznov #include "clang/Basic/TargetInfo.h"
12e123cd67SAnton Zabaznov 
13e123cd67SAnton Zabaznov namespace clang {
14e123cd67SAnton Zabaznov 
1514af99d3SBenjamin Kramer // First feature in a pair requires the second one to be supported.
1614af99d3SBenjamin Kramer static const std::pair<StringRef, StringRef> DependentFeaturesList[] = {
17a5de66c4SAnton Zabaznov     {"__opencl_c_read_write_images", "__opencl_c_images"},
18a5de66c4SAnton Zabaznov     {"__opencl_c_3d_image_writes", "__opencl_c_images"},
19a5de66c4SAnton Zabaznov     {"__opencl_c_pipes", "__opencl_c_generic_address_space"},
20a5de66c4SAnton Zabaznov     {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"},
21a5de66c4SAnton Zabaznov     {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}};
22a5de66c4SAnton Zabaznov 
2314af99d3SBenjamin Kramer // Extensions and equivalent feature pairs.
2414af99d3SBenjamin Kramer static const std::pair<StringRef, StringRef> FeatureExtensionMap[] = {
25a5de66c4SAnton Zabaznov     {"cl_khr_fp64", "__opencl_c_fp64"},
26a5de66c4SAnton Zabaznov     {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
27a5de66c4SAnton Zabaznov 
isKnown(llvm::StringRef Ext) const28e123cd67SAnton Zabaznov bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
29*ea9d4040SKazu Hirata   return OptMap.contains(Ext);
30e123cd67SAnton Zabaznov }
31e123cd67SAnton Zabaznov 
isAvailableOption(llvm::StringRef Ext,const LangOptions & LO) const32840643bbSAnton Zabaznov bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
33840643bbSAnton Zabaznov                                       const LangOptions &LO) const {
34840643bbSAnton Zabaznov   if (!isKnown(Ext))
35840643bbSAnton Zabaznov     return false;
36840643bbSAnton Zabaznov 
37840643bbSAnton Zabaznov   auto &OptInfo = OptMap.find(Ext)->getValue();
38840643bbSAnton Zabaznov   if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO))
39840643bbSAnton Zabaznov     return isSupported(Ext, LO);
40840643bbSAnton Zabaznov 
41840643bbSAnton Zabaznov   return isEnabled(Ext);
42840643bbSAnton Zabaznov }
43840643bbSAnton Zabaznov 
isEnabled(llvm::StringRef Ext) const44e123cd67SAnton Zabaznov bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const {
45840643bbSAnton Zabaznov   auto I = OptMap.find(Ext);
46840643bbSAnton Zabaznov   return I != OptMap.end() && I->getValue().Enabled;
47e123cd67SAnton Zabaznov }
48e123cd67SAnton Zabaznov 
isWithPragma(llvm::StringRef Ext) const4925ad188bSAnastasia Stulova bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const {
5025ad188bSAnastasia Stulova   auto E = OptMap.find(Ext);
5125ad188bSAnastasia Stulova   return E != OptMap.end() && E->second.WithPragma;
5225ad188bSAnastasia Stulova }
5325ad188bSAnastasia Stulova 
isSupported(llvm::StringRef Ext,const LangOptions & LO) const54e123cd67SAnton Zabaznov bool OpenCLOptions::isSupported(llvm::StringRef Ext,
55e123cd67SAnton Zabaznov                                 const LangOptions &LO) const {
56840643bbSAnton Zabaznov   auto I = OptMap.find(Ext);
57840643bbSAnton Zabaznov   return I != OptMap.end() && I->getValue().Supported &&
58840643bbSAnton Zabaznov          I->getValue().isAvailableIn(LO);
59e123cd67SAnton Zabaznov }
60e123cd67SAnton Zabaznov 
isSupportedCore(llvm::StringRef Ext,const LangOptions & LO) const61e123cd67SAnton Zabaznov bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext,
62e123cd67SAnton Zabaznov                                     const LangOptions &LO) const {
63840643bbSAnton Zabaznov   auto I = OptMap.find(Ext);
64840643bbSAnton Zabaznov   return I != OptMap.end() && I->getValue().Supported &&
65840643bbSAnton Zabaznov          I->getValue().isCoreIn(LO);
66e123cd67SAnton Zabaznov }
67e123cd67SAnton Zabaznov 
isSupportedOptionalCore(llvm::StringRef Ext,const LangOptions & LO) const68e123cd67SAnton Zabaznov bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext,
69e123cd67SAnton Zabaznov                                             const LangOptions &LO) const {
70840643bbSAnton Zabaznov   auto I = OptMap.find(Ext);
71840643bbSAnton Zabaznov   return I != OptMap.end() && I->getValue().Supported &&
72840643bbSAnton Zabaznov          I->getValue().isOptionalCoreIn(LO);
73e123cd67SAnton Zabaznov }
74e123cd67SAnton Zabaznov 
isSupportedCoreOrOptionalCore(llvm::StringRef Ext,const LangOptions & LO) const75e123cd67SAnton Zabaznov bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext,
76e123cd67SAnton Zabaznov                                                   const LangOptions &LO) const {
77e123cd67SAnton Zabaznov   return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO);
78e123cd67SAnton Zabaznov }
79e123cd67SAnton Zabaznov 
isSupportedExtension(llvm::StringRef Ext,const LangOptions & LO) const80e123cd67SAnton Zabaznov bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext,
81e123cd67SAnton Zabaznov                                          const LangOptions &LO) const {
82840643bbSAnton Zabaznov   auto I = OptMap.find(Ext);
83840643bbSAnton Zabaznov   return I != OptMap.end() && I->getValue().Supported &&
84840643bbSAnton Zabaznov          I->getValue().isAvailableIn(LO) &&
85e123cd67SAnton Zabaznov          !isSupportedCoreOrOptionalCore(Ext, LO);
86e123cd67SAnton Zabaznov }
87e123cd67SAnton Zabaznov 
enable(llvm::StringRef Ext,bool V)88e123cd67SAnton Zabaznov void OpenCLOptions::enable(llvm::StringRef Ext, bool V) {
89e123cd67SAnton Zabaznov   OptMap[Ext].Enabled = V;
90e123cd67SAnton Zabaznov }
91e123cd67SAnton Zabaznov 
acceptsPragma(llvm::StringRef Ext,bool V)9225ad188bSAnastasia Stulova void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) {
9325ad188bSAnastasia Stulova   OptMap[Ext].WithPragma = V;
9425ad188bSAnastasia Stulova }
9525ad188bSAnastasia Stulova 
support(llvm::StringRef Ext,bool V)96e123cd67SAnton Zabaznov void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
97e123cd67SAnton Zabaznov   assert(!Ext.empty() && "Extension is empty.");
98e123cd67SAnton Zabaznov   assert(Ext[0] != '+' && Ext[0] != '-');
99e123cd67SAnton Zabaznov   OptMap[Ext].Supported = V;
100e123cd67SAnton Zabaznov }
101e123cd67SAnton Zabaznov 
OpenCLOptions()102e123cd67SAnton Zabaznov OpenCLOptions::OpenCLOptions() {
103f0efc007SAnton Zabaznov #define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
104f0efc007SAnton Zabaznov   OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
105e123cd67SAnton Zabaznov #include "clang/Basic/OpenCLExtensions.def"
106e123cd67SAnton Zabaznov }
107e123cd67SAnton Zabaznov 
addSupport(const llvm::StringMap<bool> & FeaturesMap,const LangOptions & Opts)108e123cd67SAnton Zabaznov void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap,
109e123cd67SAnton Zabaznov                                const LangOptions &Opts) {
110e123cd67SAnton Zabaznov   for (const auto &F : FeaturesMap) {
111e123cd67SAnton Zabaznov     const auto &Name = F.getKey();
112e123cd67SAnton Zabaznov     if (F.getValue() && isKnown(Name) && OptMap[Name].isAvailableIn(Opts))
113e123cd67SAnton Zabaznov       support(Name);
114e123cd67SAnton Zabaznov   }
115e123cd67SAnton Zabaznov }
116e123cd67SAnton Zabaznov 
disableAll()117e123cd67SAnton Zabaznov void OpenCLOptions::disableAll() {
118e123cd67SAnton Zabaznov   for (auto &Opt : OptMap)
119e123cd67SAnton Zabaznov     Opt.getValue().Enabled = false;
120e123cd67SAnton Zabaznov }
121e123cd67SAnton Zabaznov 
diagnoseUnsupportedFeatureDependencies(const TargetInfo & TI,DiagnosticsEngine & Diags)122ab76101fSAnton Zabaznov bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies(
123ab76101fSAnton Zabaznov     const TargetInfo &TI, DiagnosticsEngine &Diags) {
124ab76101fSAnton Zabaznov   auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
125ab76101fSAnton Zabaznov 
126ab76101fSAnton Zabaznov   bool IsValid = true;
127a5de66c4SAnton Zabaznov   for (auto &FeaturePair : DependentFeaturesList) {
128a5de66c4SAnton Zabaznov     auto Feature = FeaturePair.first;
129a5de66c4SAnton Zabaznov     auto Dep = FeaturePair.second;
130a5de66c4SAnton Zabaznov     if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) &&
131a5de66c4SAnton Zabaznov         !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) {
132ab76101fSAnton Zabaznov       IsValid = false;
133a5de66c4SAnton Zabaznov       Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep;
134a5de66c4SAnton Zabaznov     }
135ab76101fSAnton Zabaznov   }
136ab76101fSAnton Zabaznov   return IsValid;
137ab76101fSAnton Zabaznov }
138ab76101fSAnton Zabaznov 
diagnoseFeatureExtensionDifferences(const TargetInfo & TI,DiagnosticsEngine & Diags)139ab76101fSAnton Zabaznov bool OpenCLOptions::diagnoseFeatureExtensionDifferences(
140ab76101fSAnton Zabaznov     const TargetInfo &TI, DiagnosticsEngine &Diags) {
141ab76101fSAnton Zabaznov   auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
142ab76101fSAnton Zabaznov 
143ab76101fSAnton Zabaznov   bool IsValid = true;
144ab76101fSAnton Zabaznov   for (auto &ExtAndFeat : FeatureExtensionMap)
14514af99d3SBenjamin Kramer     if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) !=
14614af99d3SBenjamin Kramer         TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) {
147ab76101fSAnton Zabaznov       IsValid = false;
148ab76101fSAnton Zabaznov       Diags.Report(diag::err_opencl_extension_and_feature_differs)
14914af99d3SBenjamin Kramer           << ExtAndFeat.first << ExtAndFeat.second;
150ab76101fSAnton Zabaznov     }
151ab76101fSAnton Zabaznov   return IsValid;
152ab76101fSAnton Zabaznov }
153ab76101fSAnton Zabaznov 
154e123cd67SAnton Zabaznov } // end namespace clang
155