LLVM 22.0.0git
SPIRVCommandLine.cpp
Go to the documentation of this file.
1//===--- SPIRVCommandLine.cpp ---- Command Line Options ---------*- 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// This file contains definitions of classes and functions needed for
10// processing, parsing, and using CLI options for the SPIR-V backend.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPIRVCommandLine.h"
17#include <algorithm>
18#include <map>
19
20#define DEBUG_TYPE "spirv-commandline"
21
22using namespace llvm;
23
24static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
26 {"SPV_EXT_shader_atomic_float_add",
27 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_add},
28 {"SPV_EXT_shader_atomic_float16_add",
29 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float16_add},
30 {"SPV_EXT_shader_atomic_float_min_max",
31 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_min_max},
32 {"SPV_INTEL_16bit_atomics",
33 SPIRV::Extension::Extension::SPV_INTEL_16bit_atomics},
34 {"SPV_EXT_arithmetic_fence",
35 SPIRV::Extension::Extension::SPV_EXT_arithmetic_fence},
36 {"SPV_EXT_demote_to_helper_invocation",
37 SPIRV::Extension::Extension::SPV_EXT_demote_to_helper_invocation},
38 {"SPV_EXT_descriptor_indexing",
39 SPIRV::Extension::Extension::SPV_EXT_descriptor_indexing},
40 {"SPV_EXT_fragment_fully_covered",
41 SPIRV::Extension::Extension::SPV_EXT_fragment_fully_covered},
42 {"SPV_EXT_fragment_invocation_density",
43 SPIRV::Extension::Extension::SPV_EXT_fragment_invocation_density},
44 {"SPV_EXT_fragment_shader_interlock",
45 SPIRV::Extension::Extension::SPV_EXT_fragment_shader_interlock},
46 {"SPV_EXT_mesh_shader",
47 SPIRV::Extension::Extension::SPV_EXT_mesh_shader},
48 {"SPV_EXT_shader_stencil_export",
49 SPIRV::Extension::Extension::SPV_EXT_shader_stencil_export},
50 {"SPV_EXT_shader_viewport_index_layer",
51 SPIRV::Extension::Extension::SPV_EXT_shader_viewport_index_layer},
52 {"SPV_GOOGLE_hlsl_functionality1",
53 SPIRV::Extension::Extension::SPV_GOOGLE_hlsl_functionality1},
54 {"SPV_GOOGLE_user_type",
55 SPIRV::Extension::Extension::SPV_GOOGLE_user_type},
56 {"SPV_INTEL_arbitrary_precision_integers",
57 SPIRV::Extension::Extension::SPV_INTEL_arbitrary_precision_integers},
58 {"SPV_INTEL_cache_controls",
59 SPIRV::Extension::Extension::SPV_INTEL_cache_controls},
60 {"SPV_INTEL_float_controls2",
61 SPIRV::Extension::Extension::SPV_INTEL_float_controls2},
62 {"SPV_INTEL_global_variable_fpga_decorations",
63 SPIRV::Extension::Extension::
64 SPV_INTEL_global_variable_fpga_decorations},
65 {"SPV_INTEL_global_variable_host_access",
66 SPIRV::Extension::Extension::SPV_INTEL_global_variable_host_access},
67 {"SPV_INTEL_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone},
68 {"SPV_EXT_optnone", SPIRV::Extension::Extension::SPV_EXT_optnone},
69 {"SPV_INTEL_usm_storage_classes",
70 SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes},
71 {"SPV_INTEL_split_barrier",
72 SPIRV::Extension::Extension::SPV_INTEL_split_barrier},
73 {"SPV_INTEL_subgroups",
74 SPIRV::Extension::Extension::SPV_INTEL_subgroups},
75 {"SPV_INTEL_media_block_io",
76 SPIRV::Extension::Extension::SPV_INTEL_media_block_io},
77 {"SPV_INTEL_memory_access_aliasing",
78 SPIRV::Extension::Extension::SPV_INTEL_memory_access_aliasing},
79 {"SPV_INTEL_joint_matrix",
80 SPIRV::Extension::Extension::SPV_INTEL_joint_matrix},
81 {"SPV_KHR_16bit_storage",
82 SPIRV::Extension::Extension::SPV_KHR_16bit_storage},
83 {"SPV_KHR_device_group",
84 SPIRV::Extension::Extension::SPV_KHR_device_group},
85 {"SPV_KHR_fragment_shading_rate",
86 SPIRV::Extension::Extension::SPV_KHR_fragment_shading_rate},
87 {"SPV_KHR_multiview", SPIRV::Extension::Extension::SPV_KHR_multiview},
88 {"SPV_KHR_post_depth_coverage",
89 SPIRV::Extension::Extension::SPV_KHR_post_depth_coverage},
90 {"SPV_KHR_shader_draw_parameters",
91 SPIRV::Extension::Extension::SPV_KHR_shader_draw_parameters},
92 {"SPV_KHR_ray_tracing",
93 SPIRV::Extension::Extension::SPV_KHR_ray_tracing},
94 {"SPV_KHR_uniform_group_instructions",
95 SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions},
96 {"SPV_KHR_no_integer_wrap_decoration",
97 SPIRV::Extension::Extension::SPV_KHR_no_integer_wrap_decoration},
98 {"SPV_KHR_float_controls",
99 SPIRV::Extension::Extension::SPV_KHR_float_controls},
100 {"SPV_KHR_expect_assume",
101 SPIRV::Extension::Extension::SPV_KHR_expect_assume},
102 {"SPV_KHR_bit_instructions",
103 SPIRV::Extension::Extension::SPV_KHR_bit_instructions},
104 {"SPV_KHR_integer_dot_product",
105 SPIRV::Extension::Extension::SPV_KHR_integer_dot_product},
106 {"SPV_KHR_linkonce_odr",
107 SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
108 {"SPV_INTEL_inline_assembly",
109 SPIRV::Extension::Extension::SPV_INTEL_inline_assembly},
110 {"SPV_INTEL_bindless_images",
111 SPIRV::Extension::Extension::SPV_INTEL_bindless_images},
112 {"SPV_INTEL_bfloat16_arithmetic",
113 SPIRV::Extension::Extension::SPV_INTEL_bfloat16_arithmetic},
114 {"SPV_INTEL_bfloat16_conversion",
115 SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
116 {"SPV_KHR_subgroup_rotate",
117 SPIRV::Extension::Extension::SPV_KHR_subgroup_rotate},
118 {"SPV_INTEL_variable_length_array",
119 SPIRV::Extension::Extension::SPV_INTEL_variable_length_array},
120 {"SPV_INTEL_function_pointers",
121 SPIRV::Extension::Extension::SPV_INTEL_function_pointers},
122 {"SPV_KHR_shader_clock",
123 SPIRV::Extension::Extension::SPV_KHR_shader_clock},
124 {"SPV_KHR_cooperative_matrix",
125 SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
126 {"SPV_KHR_non_semantic_info",
127 SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
128 {"SPV_KHR_ray_query", SPIRV::Extension::Extension::SPV_KHR_ray_query},
129 {"SPV_EXT_shader_image_int64",
130 SPIRV::Extension::Extension::SPV_EXT_shader_image_int64},
131 {"SPV_KHR_fragment_shader_barycentric",
132 SPIRV::Extension::Extension::SPV_KHR_fragment_shader_barycentric},
133 {"SPV_KHR_physical_storage_buffer",
134 SPIRV::Extension::Extension::SPV_KHR_physical_storage_buffer},
135 {"SPV_KHR_vulkan_memory_model",
136 SPIRV::Extension::Extension::SPV_KHR_vulkan_memory_model},
137 {"SPV_NV_shader_subgroup_partitioned",
138 SPIRV::Extension::Extension::SPV_NV_shader_subgroup_partitioned},
139 {"SPV_INTEL_long_composites",
140 SPIRV::Extension::Extension::SPV_INTEL_long_composites},
141 {"SPV_INTEL_fp_max_error",
142 SPIRV::Extension::Extension::SPV_INTEL_fp_max_error},
143 {"SPV_INTEL_subgroup_matrix_multiply_accumulate",
144 SPIRV::Extension::Extension::
145 SPV_INTEL_subgroup_matrix_multiply_accumulate},
146 {"SPV_INTEL_ternary_bitwise_function",
147 SPIRV::Extension::Extension::SPV_INTEL_ternary_bitwise_function},
148 {"SPV_INTEL_2d_block_io",
149 SPIRV::Extension::Extension::SPV_INTEL_2d_block_io},
150 {"SPV_INTEL_int4", SPIRV::Extension::Extension::SPV_INTEL_int4},
151 {"SPV_KHR_float_controls2",
152 SPIRV::Extension::Extension::SPV_KHR_float_controls2},
153 {"SPV_INTEL_tensor_float32_conversion",
154 SPIRV::Extension::Extension::SPV_INTEL_tensor_float32_conversion},
155 {"SPV_KHR_bfloat16", SPIRV::Extension::Extension::SPV_KHR_bfloat16},
156 {"SPV_EXT_relaxed_printf_string_address_space",
157 SPIRV::Extension::Extension::
158 SPV_EXT_relaxed_printf_string_address_space},
159 {"SPV_INTEL_predicated_io",
160 SPIRV::Extension::Extension::SPV_INTEL_predicated_io},
161 {"SPV_KHR_maximal_reconvergence",
162 SPIRV::Extension::Extension::SPV_KHR_maximal_reconvergence},
163 {"SPV_INTEL_kernel_attributes",
164 SPIRV::Extension::Extension::SPV_INTEL_kernel_attributes},
165 {"SPV_ALTERA_blocking_pipes",
166 SPIRV::Extension::Extension::SPV_ALTERA_blocking_pipes}};
167
169 StringRef ArgValue,
170 std::set<SPIRV::Extension::Extension> &Vals) {
172 ArgValue.split(Tokens, ",", -1, false);
173 std::sort(Tokens.begin(), Tokens.end());
174
175 std::set<SPIRV::Extension::Extension> EnabledExtensions;
176
177 for (const auto &Token : Tokens) {
178 if (Token == "all") {
179 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
180 EnabledExtensions.insert(ExtensionEnum);
181
182 continue;
183 }
184
185 if (Token.size() == 3 && Token.upper() == "KHR") {
186 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
187 if (StringRef(ExtensionName).starts_with("SPV_KHR_"))
188 EnabledExtensions.insert(ExtensionEnum);
189 continue;
190 }
191
192 if (Token.empty() || (!Token.starts_with("+") && !Token.starts_with("-")))
193 return O.error("Invalid extension list format: " + Token.str());
194
195 StringRef ExtensionName = Token.substr(1);
196 auto NameValuePair = SPIRVExtensionMap.find(ExtensionName);
197
198 if (NameValuePair == SPIRVExtensionMap.end())
199 return O.error("Unknown SPIR-V extension: " + Token.str());
200
201 if (Token.starts_with("+")) {
202 EnabledExtensions.insert(NameValuePair->second);
203 } else if (EnabledExtensions.count(NameValuePair->second)) {
204 if (llvm::is_contained(Tokens, "+" + ExtensionName.str()))
205 return O.error(
206 "Extension cannot be allowed and disallowed at the same time: " +
207 ExtensionName.str());
208
209 EnabledExtensions.erase(NameValuePair->second);
210 }
211 }
212
213 Vals = std::move(EnabledExtensions);
214 return false;
215}
216
218 const std::vector<std::string> &ExtNames,
219 std::set<SPIRV::Extension::Extension> &AllowedExtensions) {
220 for (const auto &Ext : ExtNames) {
221 if (Ext == "all") {
222 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
223 AllowedExtensions.insert(ExtensionEnum);
224 break;
225 }
226 auto It = SPIRVExtensionMap.find(Ext);
227 if (It == SPIRVExtensionMap.end())
228 return Ext;
229 AllowedExtensions.insert(It->second);
230 }
231 return StringRef();
232}
233
234std::set<SPIRV::Extension::Extension>
236 std::set<SPIRV::Extension::Extension> R;
237 SPIRV::Environment::Environment CurrentEnvironment =
238 SPIRV::Environment::Environment::EnvOpenCL;
239 if (TT.getOS() == Triple::Vulkan)
240 CurrentEnvironment = SPIRV::Environment::Environment::EnvVulkan;
241
242 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap) {
244 SPIRV::OperandCategory::OperandCategory::ExtensionOperand,
245 ExtensionEnum);
246
247 if (llvm::is_contained(AllowedEnv, CurrentEnvironment))
248 R.insert(ExtensionEnum);
249 }
250
251 return R;
252}
static const std::map< std::string, SPIRV::Extension::Extension, std::less<> > SPIRVExtensionMap
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:702
std::string str() const
str - Get the contents as an std::string.
Definition StringRef.h:225
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:573
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
This is an optimization pass for GlobalISel generic memory operations.
SmallVector< SPIRV::Environment::Environment, 8 > EnvironmentList
EnvironmentList getSymbolicOperandAllowedEnvironments(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1897
static std::set< SPIRV::Extension::Extension > getValidExtensions(const Triple &TT)
Returns the list of extensions that are valid for a particular target environment (i....
bool parse(cl::Option &O, StringRef ArgName, StringRef ArgValue, std::set< SPIRV::Extension::Extension > &Vals)
Parses SPIR-V extension name from CLI arguments.
static StringRef checkExtensions(const std::vector< std::string > &ExtNames, std::set< SPIRV::Extension::Extension > &AllowedExtensions)
Validates and converts extension names into internal enum values.