1 //===--- SPIRVCommandLine.cpp ---- Command Line Options ---------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains definitions of classes and functions needed for
10 // processing, parsing, and using CLI options for the SPIR-V backend.
12 //===----------------------------------------------------------------------===//
14 #include "SPIRVCommandLine.h"
15 #include "llvm/ADT/StringRef.h"
19 #define DEBUG_TYPE "spirv-commandline"
23 static const std::map
<std::string
, SPIRV::Extension::Extension
>
25 {"SPV_EXT_shader_atomic_float_add",
26 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_add
},
27 {"SPV_EXT_shader_atomic_float16_add",
28 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float16_add
},
29 {"SPV_EXT_shader_atomic_float_min_max",
30 SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_min_max
},
31 {"SPV_INTEL_arbitrary_precision_integers",
32 SPIRV::Extension::Extension::SPV_INTEL_arbitrary_precision_integers
},
33 {"SPV_INTEL_cache_controls",
34 SPIRV::Extension::Extension::SPV_INTEL_cache_controls
},
35 {"SPV_INTEL_global_variable_fpga_decorations",
36 SPIRV::Extension::Extension::
37 SPV_INTEL_global_variable_fpga_decorations
},
38 {"SPV_INTEL_global_variable_host_access",
39 SPIRV::Extension::Extension::SPV_INTEL_global_variable_host_access
},
40 {"SPV_INTEL_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone
},
41 {"SPV_INTEL_usm_storage_classes",
42 SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes
},
43 {"SPV_INTEL_subgroups",
44 SPIRV::Extension::Extension::SPV_INTEL_subgroups
},
45 {"SPV_KHR_uniform_group_instructions",
46 SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions
},
47 {"SPV_KHR_no_integer_wrap_decoration",
48 SPIRV::Extension::Extension::SPV_KHR_no_integer_wrap_decoration
},
49 {"SPV_KHR_float_controls",
50 SPIRV::Extension::Extension::SPV_KHR_float_controls
},
51 {"SPV_KHR_expect_assume",
52 SPIRV::Extension::Extension::SPV_KHR_expect_assume
},
53 {"SPV_KHR_bit_instructions",
54 SPIRV::Extension::Extension::SPV_KHR_bit_instructions
},
55 {"SPV_KHR_linkonce_odr",
56 SPIRV::Extension::Extension::SPV_KHR_linkonce_odr
},
57 {"SPV_INTEL_inline_assembly",
58 SPIRV::Extension::Extension::SPV_INTEL_inline_assembly
},
59 {"SPV_INTEL_bfloat16_conversion",
60 SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion
},
61 {"SPV_KHR_subgroup_rotate",
62 SPIRV::Extension::Extension::SPV_KHR_subgroup_rotate
},
63 {"SPV_INTEL_variable_length_array",
64 SPIRV::Extension::Extension::SPV_INTEL_variable_length_array
},
65 {"SPV_INTEL_function_pointers",
66 SPIRV::Extension::Extension::SPV_INTEL_function_pointers
},
67 {"SPV_KHR_shader_clock",
68 SPIRV::Extension::Extension::SPV_KHR_shader_clock
},
69 {"SPV_KHR_cooperative_matrix",
70 SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix
},
73 bool SPIRVExtensionsParser::parse(cl::Option
&O
, llvm::StringRef ArgName
,
74 llvm::StringRef ArgValue
,
75 std::set
<SPIRV::Extension::Extension
> &Vals
) {
76 llvm::SmallVector
<llvm::StringRef
, 10> Tokens
;
77 ArgValue
.split(Tokens
, ",", -1, false);
78 std::sort(Tokens
.begin(), Tokens
.end());
80 std::set
<SPIRV::Extension::Extension
> EnabledExtensions
;
82 for (const auto &Token
: Tokens
) {
84 for (const auto &[ExtensionName
, ExtensionEnum
] : SPIRVExtensionMap
)
85 EnabledExtensions
.insert(ExtensionEnum
);
90 if (Token
.empty() || (!Token
.starts_with("+") && !Token
.starts_with("-")))
91 return O
.error("Invalid extension list format: " + Token
.str());
93 llvm::StringRef ExtensionName
= Token
.substr(1);
94 auto NameValuePair
= SPIRVExtensionMap
.find(ExtensionName
.str());
96 if (NameValuePair
== SPIRVExtensionMap
.end())
97 return O
.error("Unknown SPIR-V extension: " + Token
.str());
99 if (Token
.starts_with("+")) {
100 EnabledExtensions
.insert(NameValuePair
->second
);
101 } else if (EnabledExtensions
.count(NameValuePair
->second
)) {
102 if (std::find(Tokens
.begin(), Tokens
.end(), "+" + ExtensionName
.str()) !=
105 "Extension cannot be allowed and disallowed at the same time: " +
106 ExtensionName
.str());
108 EnabledExtensions
.erase(NameValuePair
->second
);
112 Vals
= std::move(EnabledExtensions
);