LLVM 24.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"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/Support/Error.h"
20
21#include <string>
22
23#define DEBUG_TYPE "spirv-commandline"
24
25using namespace llvm;
26
28 {"SPV_EXT_shader_atomic_float_add",
29 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_add},
30 {"SPV_EXT_shader_atomic_float16_add",
31 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float16_add},
32 {"SPV_EXT_shader_atomic_float_min_max",
33 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_min_max},
34 {"SPV_INTEL_16bit_atomics",
35 SPIRV::Extension::Extension::SPV_INTEL_16bit_atomics},
36 {"SPV_NV_shader_atomic_fp16_vector",
37 SPIRV::Extension::Extension::SPV_NV_shader_atomic_fp16_vector},
38 {"SPV_EXT_arithmetic_fence",
39 SPIRV::Extension::Extension::SPV_EXT_arithmetic_fence},
40 {"SPV_EXT_demote_to_helper_invocation",
41 SPIRV::Extension::Extension::SPV_EXT_demote_to_helper_invocation},
42 {"SPV_EXT_descriptor_indexing",
43 SPIRV::Extension::Extension::SPV_EXT_descriptor_indexing},
44 {"SPV_EXT_fragment_fully_covered",
45 SPIRV::Extension::Extension::SPV_EXT_fragment_fully_covered},
46 {"SPV_EXT_fragment_invocation_density",
47 SPIRV::Extension::Extension::SPV_EXT_fragment_invocation_density},
48 {"SPV_EXT_fragment_shader_interlock",
49 SPIRV::Extension::Extension::SPV_EXT_fragment_shader_interlock},
50 {"SPV_EXT_mesh_shader", SPIRV::Extension::Extension::SPV_EXT_mesh_shader},
51 {"SPV_EXT_shader_stencil_export",
52 SPIRV::Extension::Extension::SPV_EXT_shader_stencil_export},
53 {"SPV_EXT_shader_viewport_index_layer",
54 SPIRV::Extension::Extension::SPV_EXT_shader_viewport_index_layer},
55 {"SPV_GOOGLE_hlsl_functionality1",
56 SPIRV::Extension::Extension::SPV_GOOGLE_hlsl_functionality1},
57 {"SPV_GOOGLE_user_type", SPIRV::Extension::Extension::SPV_GOOGLE_user_type},
58 {"SPV_ALTERA_arbitrary_precision_integers",
59 SPIRV::Extension::Extension::SPV_ALTERA_arbitrary_precision_integers},
60 {"SPV_ALTERA_arbitrary_precision_floating_point",
61 SPIRV::Extension::Extension::
62 SPV_ALTERA_arbitrary_precision_floating_point},
63 {"SPV_INTEL_cache_controls",
64 SPIRV::Extension::Extension::SPV_INTEL_cache_controls},
65 {"SPV_INTEL_float_controls2",
66 SPIRV::Extension::Extension::SPV_INTEL_float_controls2},
67 {"SPV_INTEL_global_variable_fpga_decorations",
68 SPIRV::Extension::Extension::SPV_INTEL_global_variable_fpga_decorations},
69 {"SPV_INTEL_global_variable_host_access",
70 SPIRV::Extension::Extension::SPV_INTEL_global_variable_host_access},
71 {"SPV_INTEL_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone},
72 {"SPV_EXT_optnone", SPIRV::Extension::Extension::SPV_EXT_optnone},
73 {"SPV_INTEL_usm_storage_classes",
74 SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes},
75 {"SPV_INTEL_split_barrier",
76 SPIRV::Extension::Extension::SPV_INTEL_split_barrier},
77 {"SPV_INTEL_subgroups", SPIRV::Extension::Extension::SPV_INTEL_subgroups},
78 {"SPV_INTEL_media_block_io",
79 SPIRV::Extension::Extension::SPV_INTEL_media_block_io},
80 {"SPV_INTEL_memory_access_aliasing",
81 SPIRV::Extension::Extension::SPV_INTEL_memory_access_aliasing},
82 {"SPV_INTEL_joint_matrix",
83 SPIRV::Extension::Extension::SPV_INTEL_joint_matrix},
84 {"SPV_INTEL_masked_gather_scatter",
85 SPIRV::Extension::Extension::SPV_INTEL_masked_gather_scatter},
86 {"SPV_KHR_16bit_storage",
87 SPIRV::Extension::Extension::SPV_KHR_16bit_storage},
88 {"SPV_KHR_device_group", SPIRV::Extension::Extension::SPV_KHR_device_group},
89 {"SPV_KHR_fragment_shading_rate",
90 SPIRV::Extension::Extension::SPV_KHR_fragment_shading_rate},
91 {"SPV_KHR_multiview", SPIRV::Extension::Extension::SPV_KHR_multiview},
92 {"SPV_KHR_post_depth_coverage",
93 SPIRV::Extension::Extension::SPV_KHR_post_depth_coverage},
94 {"SPV_KHR_shader_draw_parameters",
95 SPIRV::Extension::Extension::SPV_KHR_shader_draw_parameters},
96 {"SPV_KHR_ray_tracing", SPIRV::Extension::Extension::SPV_KHR_ray_tracing},
97 {"SPV_KHR_storage_buffer_storage_class",
98 SPIRV::Extension::Extension::SPV_KHR_storage_buffer_storage_class},
99 {"SPV_KHR_uniform_group_instructions",
100 SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions},
101 {"SPV_KHR_no_integer_wrap_decoration",
102 SPIRV::Extension::Extension::SPV_KHR_no_integer_wrap_decoration},
103 {"SPV_KHR_float_controls",
104 SPIRV::Extension::Extension::SPV_KHR_float_controls},
105 {"SPV_KHR_expect_assume",
106 SPIRV::Extension::Extension::SPV_KHR_expect_assume},
107 {"SPV_KHR_bit_instructions",
108 SPIRV::Extension::Extension::SPV_KHR_bit_instructions},
109 {"SPV_KHR_integer_dot_product",
110 SPIRV::Extension::Extension::SPV_KHR_integer_dot_product},
111 {"SPV_KHR_linkonce_odr", SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
112 {"SPV_KHR_fma", SPIRV::Extension::Extension::SPV_KHR_fma},
113 {"SPV_INTEL_inline_assembly",
114 SPIRV::Extension::Extension::SPV_INTEL_inline_assembly},
115 {"SPV_INTEL_bindless_images",
116 SPIRV::Extension::Extension::SPV_INTEL_bindless_images},
117 {"SPV_INTEL_bfloat16_arithmetic",
118 SPIRV::Extension::Extension::SPV_INTEL_bfloat16_arithmetic},
119 {"SPV_INTEL_bfloat16_conversion",
120 SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
121 {"SPV_KHR_subgroup_rotate",
122 SPIRV::Extension::Extension::SPV_KHR_subgroup_rotate},
123 {"SPV_INTEL_variable_length_array",
124 SPIRV::Extension::Extension::SPV_INTEL_variable_length_array},
125 {"SPV_INTEL_function_pointers",
126 SPIRV::Extension::Extension::SPV_INTEL_function_pointers},
127 {"SPV_KHR_shader_clock", SPIRV::Extension::Extension::SPV_KHR_shader_clock},
128 {"SPV_KHR_cooperative_matrix",
129 SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
130 {"SPV_KHR_non_semantic_info",
131 SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
132 {"SPV_KHR_relaxed_extended_instruction",
133 SPIRV::Extension::Extension::SPV_KHR_relaxed_extended_instruction},
134 {"SPV_KHR_ray_query", SPIRV::Extension::Extension::SPV_KHR_ray_query},
135 {"SPV_EXT_shader_image_int64",
136 SPIRV::Extension::Extension::SPV_EXT_shader_image_int64},
137 {"SPV_KHR_fragment_shader_barycentric",
138 SPIRV::Extension::Extension::SPV_KHR_fragment_shader_barycentric},
139 {"SPV_KHR_physical_storage_buffer",
140 SPIRV::Extension::Extension::SPV_KHR_physical_storage_buffer},
141 {"SPV_KHR_vulkan_memory_model",
142 SPIRV::Extension::Extension::SPV_KHR_vulkan_memory_model},
143 {"SPV_NV_shader_subgroup_partitioned",
144 SPIRV::Extension::Extension::SPV_NV_shader_subgroup_partitioned},
145 {"SPV_EXT_shader_subgroup_partitioned",
146 SPIRV::Extension::Extension::SPV_EXT_shader_subgroup_partitioned},
147 {"SPV_INTEL_long_composites",
148 SPIRV::Extension::Extension::SPV_INTEL_long_composites},
149 {"SPV_INTEL_fp_max_error",
150 SPIRV::Extension::Extension::SPV_INTEL_fp_max_error},
151 {"SPV_INTEL_subgroup_matrix_multiply_accumulate",
152 SPIRV::Extension::Extension::
153 SPV_INTEL_subgroup_matrix_multiply_accumulate},
154 {"SPV_INTEL_ternary_bitwise_function",
155 SPIRV::Extension::Extension::SPV_INTEL_ternary_bitwise_function},
156 {"SPV_INTEL_2d_block_io",
157 SPIRV::Extension::Extension::SPV_INTEL_2d_block_io},
158 {"SPV_INTEL_int4", SPIRV::Extension::Extension::SPV_INTEL_int4},
159 {"SPV_KHR_float_controls2",
160 SPIRV::Extension::Extension::SPV_KHR_float_controls2},
161 {"SPV_INTEL_tensor_float32_conversion",
162 SPIRV::Extension::Extension::SPV_INTEL_tensor_float32_conversion},
163 {"SPV_KHR_bfloat16", SPIRV::Extension::Extension::SPV_KHR_bfloat16},
164 {"SPV_EXT_relaxed_printf_string_address_space",
165 SPIRV::Extension::Extension::SPV_EXT_relaxed_printf_string_address_space},
166 {"SPV_INTEL_predicated_io",
167 SPIRV::Extension::Extension::SPV_INTEL_predicated_io},
168 {"SPV_KHR_maximal_reconvergence",
169 SPIRV::Extension::Extension::SPV_KHR_maximal_reconvergence},
170 {"SPV_INTEL_kernel_attributes",
171 SPIRV::Extension::Extension::SPV_INTEL_kernel_attributes},
172 {"SPV_ALTERA_blocking_pipes",
173 SPIRV::Extension::Extension::SPV_ALTERA_blocking_pipes},
174 {"SPV_ALTERA_arbitrary_precision_fixed_point",
175 SPIRV::Extension::Extension::SPV_ALTERA_arbitrary_precision_fixed_point},
176 {"SPV_EXT_image_raw10_raw12",
177 SPIRV::Extension::Extension::SPV_EXT_image_raw10_raw12},
178 {"SPV_INTEL_unstructured_loop_controls",
179 SPIRV::Extension::Extension::SPV_INTEL_unstructured_loop_controls},
180 {"SPV_AMD_weak_linkage", SPIRV::Extension::Extension::SPV_AMD_weak_linkage},
181 {"SPV_KHR_abort", SPIRV::Extension::Extension::SPV_KHR_abort},
182 {"SPV_KHR_poison_freeze",
183 SPIRV::Extension::Extension::SPV_KHR_poison_freeze},
184 {"SPV_KHR_untyped_pointers",
185 SPIRV::Extension::Extension::SPV_KHR_untyped_pointers},
186 {"SPV_EXT_long_vector", SPIRV::Extension::Extension::SPV_EXT_long_vector},
187 {"SPV_KHR_quad_control", SPIRV::Extension::Extension::SPV_KHR_quad_control},
188 {"SPV_KHR_compute_shader_derivatives",
189 SPIRV::Extension::Extension::SPV_KHR_compute_shader_derivatives},
190 {"SPV_KHR_relaxed_extended_instruction",
191 SPIRV::Extension::Extension::SPV_KHR_relaxed_extended_instruction}};
192
196 ArgValue.split(Tokens, ",", -1, false);
197
198 ExtensionSet EnabledExtensions;
199
200 auto M = partition(Tokens, [](auto &&T) { return T.starts_with('+'); });
201
202 if (std::any_of(M, Tokens.end(), equal_to("all")))
203 for (auto &&El : make_second_range(SPIRVExtensionMap))
204 Enabled.insert(El);
205
206 for (auto &&Token : make_range(Tokens.begin(), M)) {
207 StringRef ExtensionName = Token.substr(1);
208 auto NameValuePair = SPIRVExtensionMap.find(ExtensionName);
209
210 if (NameValuePair == SPIRVExtensionMap.end())
211 return createStringError("Unknown SPIR-V extension: " + Token);
212
213 EnabledExtensions.insert(NameValuePair->second);
214 }
215
216 for (auto &&Token : make_range(M, Tokens.end())) {
217 if (Token == "all")
218 continue;
219
220 if (Token.size() == 3 && Token.upper() == "KHR") {
221 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
222 if (StringRef(ExtensionName).starts_with("SPV_KHR_"))
223 Enabled.insert(ExtensionEnum);
224 continue;
225 }
226
227 if (Token.empty() || (!Token.starts_with("+") && !Token.starts_with("-")))
228 return createStringError("Invalid extension list format: " + Token);
229
230 auto NameValuePair = SPIRVExtensionMap.find(Token.substr(1));
231
232 if (NameValuePair == SPIRVExtensionMap.end())
233 return createStringError("Unknown SPIR-V extension: " + Token);
234 if (EnabledExtensions.count(NameValuePair->second))
235 return createStringError(
236 "Extension cannot be allowed and disallowed at the same time: " +
237 NameValuePair->first());
238 Disabled.insert(NameValuePair->second);
239 Enabled.erase(NameValuePair->second);
240 }
241
242 Enabled.insert(EnabledExtensions.begin(), EnabledExtensions.end());
243
244 return Error::success();
245}
246
249 ExtensionSet &AllowedExtensions) {
250 for (const auto &Ext : ExtNames) {
251 if (Ext == "all") {
252 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
253 AllowedExtensions.insert(ExtensionEnum);
254 return StringRef();
255 }
256 auto It = SPIRVExtensionMap.find(Ext);
257 if (It == SPIRVExtensionMap.end())
258 return Ext;
259 AllowedExtensions.insert(It->second);
260 }
261 return StringRef();
262}
263
266 const ExtensionSet &Disabled) {
267 ExtensionSet R;
268 SPIRV::Environment::Environment CurrentEnvironment =
269 SPIRV::Environment::Environment::EnvOpenCL;
270 if (TT.getOS() == Triple::Vulkan)
271 CurrentEnvironment = SPIRV::Environment::Environment::EnvVulkan;
272
273 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap) {
275 SPIRV::OperandCategory::OperandCategory::ExtensionOperand,
276 ExtensionEnum);
277
278 if (llvm::is_contained(AllowedEnv, CurrentEnvironment) &&
279 !Disabled.contains(ExtensionEnum))
280 R.insert(ExtensionEnum);
281 }
282
283 return R;
284}
This file defines the StringMap class.
#define T
static const StringMap< SPIRV::Extension::Extension > SPIRVExtensionMap
This file contains some templates that are useful if you are working with the STL at all.
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:188
This is an optimization pass for GlobalISel generic memory operations.
SmallVector< SPIRV::Environment::Environment, 8 > EnvironmentList
DenseSet< SPIRV::Extension::Extension > ExtensionSet
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
EnvironmentList getSymbolicOperandAllowedEnvironments(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
auto partition(R &&Range, UnaryPredicate P)
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:2049
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition STLExtras.h:1425
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
Definition DWP.h:31
@ Disabled
Don't do any conversion of .debug_str_offsets tables.
Definition DWP.h:30
static StringRef checkExtensions(ArrayRef< std::string > ExtNames, ExtensionSet &AllowedExtensions)
Validates and converts extension names into internal enum values.
static ExtensionSet getValidExtensions(const Triple &TT, const ExtensionSet &Disabled)
Returns the list of extensions that are valid for a particular target environment (i....
static Error parse(StringRef ArgValue, ExtensionSet &Enabled, ExtensionSet &Disabled)
Parses the value of -spirv-ext into Enabled and Disabled.