LLVM 22.0.0git
SPIRVBaseInfo.cpp
Go to the documentation of this file.
1//===-- SPIRVBaseInfo.cpp - Top level SPIRV definitions ---------*- 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 the implementation for helper mnemonic lookup functions,
10// versioning/capabilities/extensions getters for symbolic/named operands used
11// in various SPIR-V instructions.
12//
13//===----------------------------------------------------------------------===//
14
15#include "SPIRVBaseInfo.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/StringRef.h"
18
19namespace llvm {
20namespace SPIRV {
22 OperandCategory::OperandCategory Category;
27};
28
30 OperandCategory::OperandCategory Category;
32 Extension::Extension ReqExtension;
33};
34
36 OperandCategory::OperandCategory Category;
38 Capability::Capability ReqCapability;
39};
40
42 OperandCategory::OperandCategory Category;
44 Environment::Environment AllowedEnvironment;
45};
46
47using namespace OperandCategory;
48using namespace Extension;
49using namespace Environment;
50using namespace Capability;
51using namespace InstructionSet;
52#define GET_SymbolicOperands_DECL
53#define GET_SymbolicOperands_IMPL
54#define GET_ExtensionEntries_DECL
55#define GET_ExtensionEntries_IMPL
56#define GET_CapabilityEntries_DECL
57#define GET_CapabilityEntries_IMPL
58#define GET_EnvironmentEntries_DECL
59#define GET_EnvironmentEntries_IMPL
60#define GET_ExtendedBuiltins_DECL
61#define GET_ExtendedBuiltins_IMPL
62#include "SPIRVGenTables.inc"
63} // namespace SPIRV
64
65std::string
66getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category,
67 int32_t Value) {
69 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
70 // Value that encodes just one enum value.
71 if (Lookup)
72 return Lookup->Mnemonic.str();
73 if (Category != SPIRV::OperandCategory::ImageOperandOperand &&
74 Category != SPIRV::OperandCategory::FPFastMathModeOperand &&
75 Category != SPIRV::OperandCategory::SelectionControlOperand &&
76 Category != SPIRV::OperandCategory::LoopControlOperand &&
77 Category != SPIRV::OperandCategory::FunctionControlOperand &&
78 Category != SPIRV::OperandCategory::MemorySemanticsOperand &&
79 Category != SPIRV::OperandCategory::MemoryOperandOperand &&
80 Category != SPIRV::OperandCategory::KernelProfilingInfoOperand &&
81 Category != SPIRV::OperandCategory::SpecConstantOpOperandsOperand)
82 return "UNKNOWN";
83 // Value that encodes many enum values (one bit per enum value).
84 std::string Name;
85 std::string Separator;
86 const SPIRV::SymbolicOperand *EnumValueInCategory =
87 SPIRV::lookupSymbolicOperandByCategory(Category);
88
89 auto TableEnd = ArrayRef(SPIRV::SymbolicOperands).end();
90 while (EnumValueInCategory && EnumValueInCategory->Category == Category) {
91 if ((EnumValueInCategory->Value != 0) &&
92 (Value & EnumValueInCategory->Value)) {
93 Name += Separator + EnumValueInCategory->Mnemonic.str();
94 Separator = "|";
95 }
96 if (++EnumValueInCategory == TableEnd)
97 break;
98 }
99
100 return Name;
101}
102
103VersionTuple
104getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category,
105 uint32_t Value) {
107 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
108
109 if (Lookup)
110 return VersionTuple(Lookup->MinVersion / 10, Lookup->MinVersion % 10);
111
112 return VersionTuple(0);
113}
114
115VersionTuple
116getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,
117 uint32_t Value) {
119 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
120
121 if (Lookup)
122 return VersionTuple(Lookup->MaxVersion / 10, Lookup->MaxVersion % 10);
123
124 return VersionTuple();
125}
126
128getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
129 uint32_t Value) {
130 CapabilityList Capabilities;
131 const SPIRV::CapabilityEntry *Capability =
132 SPIRV::lookupCapabilityByCategoryAndValue(Category, Value);
133 auto TableEnd = ArrayRef(SPIRV::CapabilityEntries).end();
134 while (Capability && Capability->Category == Category &&
135 Capability->Value == Value) {
136 Capabilities.push_back(
137 static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability));
138 if (++Capability == TableEnd)
139 break;
140 }
141
142 return Capabilities;
143}
144
146 SPIRV::OperandCategory::OperandCategory Category, uint32_t Value) {
147 EnvironmentList Environments;
148 const SPIRV::EnvironmentEntry *Environment =
149 SPIRV::lookupEnvironmentByCategoryAndValue(Category, Value);
150 auto TableEnd = ArrayRef(SPIRV::EnvironmentEntries).end();
151 while (Environment && Environment->Category == Category &&
152 Environment->Value == Value) {
153 Environments.push_back(static_cast<SPIRV::Environment::Environment>(
154 Environment->AllowedEnvironment));
155 if (++Environment == TableEnd)
156 break;
157 }
158
159 return Environments;
160}
161
163getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension) {
164 const SPIRV::ExtensionEntry *Entry =
165 SPIRV::lookupSymbolicOperandsEnabledByExtension(
166 Extension, SPIRV::OperandCategory::CapabilityOperand);
167
168 CapabilityList Capabilities;
169 auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();
170 while (Entry &&
171 Entry->Category == SPIRV::OperandCategory::CapabilityOperand) {
172 // Some capabilities' codes might go not in order.
173 if (Entry->ReqExtension == Extension)
174 Capabilities.push_back(
175 static_cast<SPIRV::Capability::Capability>(Entry->Value));
176 if (++Entry == TableEnd)
177 break;
178 }
179
180 return Capabilities;
181}
182
184getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
185 uint32_t Value) {
187 SPIRV::lookupExtensionByCategoryAndValue(Category, Value);
188
190 auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();
191 while (Extension && Extension->Category == Category &&
192 Extension->Value == Value) {
193 Extensions.push_back(
194 static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension));
195 if (++Extension == TableEnd)
196 break;
197 }
198
199 return Extensions;
200}
201
202std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) {
204 SPIRV::lookupSymbolicOperandByCategoryAndValue(
205 SPIRV::OperandCategory::BuiltInOperand, BuiltInValue);
206
207 if (Lookup)
208 return "__spirv_BuiltIn" + Lookup->Mnemonic.str();
209 return "UNKNOWN_BUILTIN";
210}
211
213 SPIRV::BuiltIn::BuiltIn &BI) {
214 const std::string Prefix = "__spirv_BuiltIn";
215 if (!Name.starts_with(Prefix))
216 return false;
217
219 SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(
220 SPIRV::OperandCategory::BuiltInOperand,
221 Name.drop_front(Prefix.length()));
222
223 if (!Lookup)
224 return false;
225
226 BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value);
227 return true;
228}
229
230std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) {
231 switch (Set) {
232 case SPIRV::InstructionSet::OpenCL_std:
233 return "OpenCL.std";
234 case SPIRV::InstructionSet::GLSL_std_450:
235 return "GLSL.std.450";
236 case SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100:
237 return "NonSemantic.Shader.DebugInfo.100";
238 case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax:
239 return "SPV_AMD_shader_trinary_minmax";
240 }
241 return "UNKNOWN_EXT_INST_SET";
242}
243
244SPIRV::InstructionSet::InstructionSet
245getExtInstSetFromString(std::string SetName) {
246 for (auto Set :
247 {SPIRV::InstructionSet::GLSL_std_450, SPIRV::InstructionSet::OpenCL_std,
248 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100}) {
249 if (SetName == getExtInstSetName(Set))
250 return Set;
251 }
252 llvm_unreachable("UNKNOWN_EXT_INST_SET");
253}
254
255std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set,
256 uint32_t InstructionNumber) {
258 SPIRV::lookupExtendedBuiltinBySetAndNumber(Set, InstructionNumber);
259
260 if (!Lookup)
261 return "UNKNOWN_EXT_INST";
262
263 return Lookup->Name.str();
264}
265} // namespace llvm
std::string Name
spirv structurize SPIRV
static cl::opt< std::set< SPIRV::Extension::Extension >, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:136
void push_back(const T &Elt)
Definition: SmallVector.h:414
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
LLVM Value Representation.
Definition: Value.h:75
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:30
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
ExtensionList getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set, uint32_t InstructionNumber)
CapabilityList getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set)
bool getSpirvBuiltInIdByName(llvm::StringRef Name, SPIRV::BuiltIn::BuiltIn &BI)
VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
EnvironmentList getSymbolicOperandAllowedEnvironments(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
CapabilityList getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension)
SPIRV::InstructionSet::InstructionSet getExtInstSetFromString(std::string SetName)
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
SmallVector< SPIRV::Extension::Extension, 8 > ExtensionList
VersionTuple getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
SmallVector< SPIRV::Capability::Capability, 8 > CapabilityList
std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue)
Capability::Capability ReqCapability
OperandCategory::OperandCategory Category
Environment::Environment AllowedEnvironment
OperandCategory::OperandCategory Category
Extension::Extension ReqExtension
OperandCategory::OperandCategory Category
OperandCategory::OperandCategory Category