/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/OpenCLOptions.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | | #include "clang/Basic/OpenCLOptions.h" |
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 | 911k | bool OpenCLOptions::isKnown(llvm::StringRef Ext) const { |
29 | 911k | return OptMap.find(Ext) != OptMap.end(); |
30 | 911k | } |
31 | | |
32 | | bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext, |
33 | 883k | const LangOptions &LO) const { |
34 | 883k | if (!isKnown(Ext)) |
35 | 0 | return false; |
36 | | |
37 | 883k | auto &OptInfo = OptMap.find(Ext)->getValue(); |
38 | 883k | if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO)) |
39 | 12.5k | return isSupported(Ext, LO); |
40 | | |
41 | 870k | return isEnabled(Ext); |
42 | 883k | } |
43 | | |
44 | 870k | bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const { |
45 | 870k | auto I = OptMap.find(Ext); |
46 | 870k | return I != OptMap.end() && I->getValue().Enabled; |
47 | 870k | } |
48 | | |
49 | 1.62k | bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const { |
50 | 1.62k | auto E = OptMap.find(Ext); |
51 | 1.62k | return E != OptMap.end() && E->second.WithPragma; |
52 | 1.62k | } |
53 | | |
54 | | bool OpenCLOptions::isSupported(llvm::StringRef Ext, |
55 | 86.2k | const LangOptions &LO) const { |
56 | 86.2k | auto I = OptMap.find(Ext); |
57 | 86.2k | return I != OptMap.end() && I->getValue().Supported && |
58 | 86.2k | I->getValue().isAvailableIn(LO)81.9k ; |
59 | 86.2k | } |
60 | | |
61 | | bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext, |
62 | 1.62k | const LangOptions &LO) const { |
63 | 1.62k | auto I = OptMap.find(Ext); |
64 | 1.62k | return I != OptMap.end() && I->getValue().Supported && |
65 | 1.62k | I->getValue().isCoreIn(LO)1.37k ; |
66 | 1.62k | } |
67 | | |
68 | | bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext, |
69 | 1.32k | const LangOptions &LO) const { |
70 | 1.32k | auto I = OptMap.find(Ext); |
71 | 1.32k | return I != OptMap.end() && I->getValue().Supported && |
72 | 1.32k | I->getValue().isOptionalCoreIn(LO)1.07k ; |
73 | 1.32k | } |
74 | | |
75 | | bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext, |
76 | 1.62k | const LangOptions &LO) const { |
77 | 1.62k | return isSupportedCore(Ext, LO) || isSupportedOptionalCore(Ext, LO)1.32k ; |
78 | 1.62k | } |
79 | | |
80 | | bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext, |
81 | 1.36k | const LangOptions &LO) const { |
82 | 1.36k | auto I = OptMap.find(Ext); |
83 | 1.36k | return I != OptMap.end() && I->getValue().Supported && |
84 | 1.36k | I->getValue().isAvailableIn(LO)1.11k && |
85 | 1.36k | !isSupportedCoreOrOptionalCore(Ext, LO)1.11k ; |
86 | 1.36k | } |
87 | | |
88 | 852 | void OpenCLOptions::enable(llvm::StringRef Ext, bool V) { |
89 | 852 | OptMap[Ext].Enabled = V; |
90 | 852 | } |
91 | | |
92 | 16 | void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) { |
93 | 16 | OptMap[Ext].WithPragma = V; |
94 | 16 | } |
95 | | |
96 | 19.6k | void OpenCLOptions::support(llvm::StringRef Ext, bool V) { |
97 | 19.6k | assert(!Ext.empty() && "Extension is empty."); |
98 | 0 | assert(Ext[0] != '+' && Ext[0] != '-'); |
99 | 0 | OptMap[Ext].Supported = V; |
100 | 19.6k | } |
101 | | |
102 | 102k | OpenCLOptions::OpenCLOptions() { |
103 | 102k | #define OPENCL_GENERIC_EXTENSION(Ext, ...) \ |
104 | 4.30M | OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__}); |
105 | 102k | #include "clang/Basic/OpenCLExtensions.def" |
106 | 102k | } |
107 | | |
108 | | void OpenCLOptions::addSupport(const llvm::StringMap<bool> &FeaturesMap, |
109 | 791 | const LangOptions &Opts) { |
110 | 28.2k | for (const auto &F : FeaturesMap) { |
111 | 28.2k | const auto &Name = F.getKey(); |
112 | 28.2k | if (F.getValue() && isKnown(Name)26.5k && OptMap[Name].isAvailableIn(Opts)26.5k ) |
113 | 19.5k | support(Name); |
114 | 28.2k | } |
115 | 791 | } |
116 | | |
117 | 84 | void OpenCLOptions::disableAll() { |
118 | 84 | for (auto &Opt : OptMap) |
119 | 3.54k | Opt.getValue().Enabled = false; |
120 | 84 | } |
121 | | |
122 | | bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies( |
123 | 152 | const TargetInfo &TI, DiagnosticsEngine &Diags) { |
124 | 152 | auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); |
125 | | |
126 | 152 | bool IsValid = true; |
127 | 760 | for (auto &FeaturePair : DependentFeaturesList) { |
128 | 760 | auto Feature = FeaturePair.first; |
129 | 760 | auto Dep = FeaturePair.second; |
130 | 760 | if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) && |
131 | 760 | !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)490 ) { |
132 | 16 | IsValid = false; |
133 | 16 | Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep; |
134 | 16 | } |
135 | 760 | } |
136 | 152 | return IsValid; |
137 | 152 | } |
138 | | |
139 | | bool OpenCLOptions::diagnoseFeatureExtensionDifferences( |
140 | 142 | const TargetInfo &TI, DiagnosticsEngine &Diags) { |
141 | 142 | auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); |
142 | | |
143 | 142 | bool IsValid = true; |
144 | 142 | for (auto &ExtAndFeat : FeatureExtensionMap) |
145 | 284 | if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) != |
146 | 284 | TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) { |
147 | 6 | IsValid = false; |
148 | 6 | Diags.Report(diag::err_opencl_extension_and_feature_differs) |
149 | 6 | << ExtAndFeat.first << ExtAndFeat.second; |
150 | 6 | } |
151 | 142 | return IsValid; |
152 | 142 | } |
153 | | |
154 | | } // end namespace clang |