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"
15#include "llvm/ADT/StringRef.h"
16#include <algorithm>
17#include <map>
18
19#define DEBUG_TYPE "spirv-commandline"
20
21using namespace llvm;
22
23static const std::map<std::string, SPIRV::Extension::Extension>
24 SPIRVExtensionMap = {
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_optnone", SPIRV::Extension::Extension::SPV_INTEL_optnone},
34 {"SPV_INTEL_usm_storage_classes",
35 SPIRV::Extension::Extension::SPV_INTEL_usm_storage_classes},
36 {"SPV_INTEL_subgroups",
37 SPIRV::Extension::Extension::SPV_INTEL_subgroups},
38 {"SPV_KHR_uniform_group_instructions",
39 SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions},
40 {"SPV_KHR_no_integer_wrap_decoration",
41 SPIRV::Extension::Extension::SPV_KHR_no_integer_wrap_decoration},
42 {"SPV_KHR_float_controls",
43 SPIRV::Extension::Extension::SPV_KHR_float_controls},
44 {"SPV_KHR_expect_assume",
45 SPIRV::Extension::Extension::SPV_KHR_expect_assume},
46 {"SPV_KHR_bit_instructions",
47 SPIRV::Extension::Extension::SPV_KHR_bit_instructions},
48 {"SPV_KHR_linkonce_odr",
49 SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
50 {"SPV_INTEL_bfloat16_conversion",
51 SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
52 {"SPV_KHR_subgroup_rotate",
53 SPIRV::Extension::Extension::SPV_KHR_subgroup_rotate},
54 {"SPV_INTEL_variable_length_array",
55 SPIRV::Extension::Extension::SPV_INTEL_variable_length_array},
56 {"SPV_INTEL_function_pointers",
57 SPIRV::Extension::Extension::SPV_INTEL_function_pointers},
58};
59
60bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
61 llvm::StringRef ArgValue,
62 std::set<SPIRV::Extension::Extension> &Vals) {
63 llvm::SmallVector<llvm::StringRef, 10> Tokens;
64 ArgValue.split(A&: Tokens, Separator: ",", MaxSplit: -1, KeepEmpty: false);
65 std::sort(first: Tokens.begin(), last: Tokens.end());
66
67 std::set<SPIRV::Extension::Extension> EnabledExtensions;
68
69 for (const auto &Token : Tokens) {
70 if (Token == "all") {
71 for (const auto &[ExtensionName, ExtensionEnum] : SPIRVExtensionMap)
72 EnabledExtensions.insert(ExtensionEnum);
73
74 continue;
75 }
76
77 if (Token.empty() || (!Token.starts_with(Prefix: "+") && !Token.starts_with(Prefix: "-")))
78 return O.error(Message: "Invalid extension list format: " + Token.str());
79
80 llvm::StringRef ExtensionName = Token.substr(Start: 1);
81 auto NameValuePair = SPIRVExtensionMap.find(ExtensionName.str());
82
83 if (NameValuePair == SPIRVExtensionMap.end())
84 return O.error(Message: "Unknown SPIR-V extension: " + Token.str());
85
86 if (Token.starts_with(Prefix: "+")) {
87 EnabledExtensions.insert(NameValuePair->second);
88 } else if (EnabledExtensions.count(NameValuePair->second)) {
89 if (std::find(first: Tokens.begin(), last: Tokens.end(), val: "+" + ExtensionName.str()) !=
90 Tokens.end())
91 return O.error(
92 Message: "Extension cannot be allowed and disallowed at the same time: " +
93 ExtensionName.str());
94
95 EnabledExtensions.erase(NameValuePair->second);
96 }
97 }
98
99 Vals = std::move(EnabledExtensions);
100 return false;
101}
102

source code of llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp