xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===--- SPIRVCommandLine.cpp ---- Command Line Options ---------*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file contains definitions of classes and functions needed for
10*0fca6ea1SDimitry Andric // processing, parsing, and using CLI options for the SPIR-V backend.
11*0fca6ea1SDimitry Andric //
12*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
13*0fca6ea1SDimitry Andric 
14*0fca6ea1SDimitry Andric #include "SPIRVCommandLine.h"
15*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h"
16*0fca6ea1SDimitry Andric #include <algorithm>
17*0fca6ea1SDimitry Andric #include <map>
18*0fca6ea1SDimitry Andric 
19*0fca6ea1SDimitry Andric #define DEBUG_TYPE "spirv-commandline"
20*0fca6ea1SDimitry Andric 
21*0fca6ea1SDimitry Andric using namespace llvm;
22*0fca6ea1SDimitry Andric 
23*0fca6ea1SDimitry Andric static const std::map<std::string, SPIRV::Extension::Extension>
24*0fca6ea1SDimitry Andric     SPIRVExtensionMap = {
25*0fca6ea1SDimitry Andric         {"SPV_EXT_shader_atomic_float_add",
26*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_add},
27*0fca6ea1SDimitry Andric         {"SPV_EXT_shader_atomic_float16_add",
28*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float16_add},
29*0fca6ea1SDimitry Andric         {"SPV_EXT_shader_atomic_float_min_max",
30*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_EXT_shader_atomic_float_min_max},
31*0fca6ea1SDimitry Andric         {"SPV_INTEL_arbitrary_precision_integers",
32*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_arbitrary_precision_integers},
33*0fca6ea1SDimitry Andric         {"SPV_INTEL_cache_controls",
34*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_cache_controls},
35*0fca6ea1SDimitry Andric         {"SPV_INTEL_global_variable_fpga_decorations",
36*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::
37*0fca6ea1SDimitry Andric              SPV_INTEL_global_variable_fpga_decorations},
38*0fca6ea1SDimitry Andric         {"SPV_INTEL_global_variable_host_access",
39*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_global_variable_host_access},
40*0fca6ea1SDimitry Andric         {"SPV_INTEL_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone},
41*0fca6ea1SDimitry Andric         {"SPV_INTEL_usm_storage_classes",
42*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes},
43*0fca6ea1SDimitry Andric         {"SPV_INTEL_subgroups",
44*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_subgroups},
45*0fca6ea1SDimitry Andric         {"SPV_KHR_uniform_group_instructions",
46*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions},
47*0fca6ea1SDimitry Andric         {"SPV_KHR_no_integer_wrap_decoration",
48*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_no_integer_wrap_decoration},
49*0fca6ea1SDimitry Andric         {"SPV_KHR_float_controls",
50*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_float_controls},
51*0fca6ea1SDimitry Andric         {"SPV_KHR_expect_assume",
52*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_expect_assume},
53*0fca6ea1SDimitry Andric         {"SPV_KHR_bit_instructions",
54*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_bit_instructions},
55*0fca6ea1SDimitry Andric         {"SPV_KHR_linkonce_odr",
56*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
57*0fca6ea1SDimitry Andric         {"SPV_INTEL_inline_assembly",
58*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_inline_assembly},
59*0fca6ea1SDimitry Andric         {"SPV_INTEL_bfloat16_conversion",
60*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
61*0fca6ea1SDimitry Andric         {"SPV_KHR_subgroup_rotate",
62*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_subgroup_rotate},
63*0fca6ea1SDimitry Andric         {"SPV_INTEL_variable_length_array",
64*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_variable_length_array},
65*0fca6ea1SDimitry Andric         {"SPV_INTEL_function_pointers",
66*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_INTEL_function_pointers},
67*0fca6ea1SDimitry Andric         {"SPV_KHR_shader_clock",
68*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_shader_clock},
69*0fca6ea1SDimitry Andric         {"SPV_KHR_cooperative_matrix",
70*0fca6ea1SDimitry Andric          SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
71*0fca6ea1SDimitry Andric };
72*0fca6ea1SDimitry Andric 
73*0fca6ea1SDimitry Andric bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
74*0fca6ea1SDimitry Andric                                   llvm::StringRef ArgValue,
75*0fca6ea1SDimitry Andric                                   std::set<SPIRV::Extension::Extension> &Vals) {
76*0fca6ea1SDimitry Andric   llvm::SmallVector<llvm::StringRef, 10> Tokens;
77*0fca6ea1SDimitry Andric   ArgValue.split(Tokens, ",", -1, false);
78*0fca6ea1SDimitry Andric   std::sort(Tokens.begin(), Tokens.end());
79*0fca6ea1SDimitry Andric 
80*0fca6ea1SDimitry Andric   std::set<SPIRV::Extension::Extension> EnabledExtensions;
81*0fca6ea1SDimitry Andric 
82*0fca6ea1SDimitry Andric   for (const auto &Token : Tokens) {
83*0fca6ea1SDimitry Andric     if (Token == "all") {
84*0fca6ea1SDimitry Andric       for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
85*0fca6ea1SDimitry Andric         EnabledExtensions.insert(ExtensionEnum);
86*0fca6ea1SDimitry Andric 
87*0fca6ea1SDimitry Andric       continue;
88*0fca6ea1SDimitry Andric     }
89*0fca6ea1SDimitry Andric 
90*0fca6ea1SDimitry Andric     if (Token.empty() || (!Token.starts_with("+") && !Token.starts_with("-")))
91*0fca6ea1SDimitry Andric       return O.error("Invalid extension list format: " + Token.str());
92*0fca6ea1SDimitry Andric 
93*0fca6ea1SDimitry Andric     llvm::StringRef ExtensionName = Token.substr(1);
94*0fca6ea1SDimitry Andric     auto NameValuePair = SPIRVExtensionMap.find(ExtensionName.str());
95*0fca6ea1SDimitry Andric 
96*0fca6ea1SDimitry Andric     if (NameValuePair == SPIRVExtensionMap.end())
97*0fca6ea1SDimitry Andric       return O.error("Unknown SPIR-V extension: " + Token.str());
98*0fca6ea1SDimitry Andric 
99*0fca6ea1SDimitry Andric     if (Token.starts_with("+")) {
100*0fca6ea1SDimitry Andric       EnabledExtensions.insert(NameValuePair->second);
101*0fca6ea1SDimitry Andric     } else if (EnabledExtensions.count(NameValuePair->second)) {
102*0fca6ea1SDimitry Andric       if (std::find(Tokens.begin(), Tokens.end(), "+" + ExtensionName.str()) !=
103*0fca6ea1SDimitry Andric           Tokens.end())
104*0fca6ea1SDimitry Andric         return O.error(
105*0fca6ea1SDimitry Andric             "Extension cannot be allowed and disallowed at the same time: " +
106*0fca6ea1SDimitry Andric             ExtensionName.str());
107*0fca6ea1SDimitry Andric 
108*0fca6ea1SDimitry Andric       EnabledExtensions.erase(NameValuePair->second);
109*0fca6ea1SDimitry Andric     }
110*0fca6ea1SDimitry Andric   }
111*0fca6ea1SDimitry Andric 
112*0fca6ea1SDimitry Andric   Vals = std::move(EnabledExtensions);
113*0fca6ea1SDimitry Andric   return false;
114*0fca6ea1SDimitry Andric }
115