LLVM 24.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"
19
20namespace llvm {
21namespace SPIRV {
29
31 OperandCategory::OperandCategory Category;
33 Extension::Extension ReqExtension;
34};
35
37 OperandCategory::OperandCategory Category;
39 Capability::Capability ReqCapability;
40};
41
43 OperandCategory::OperandCategory Category;
45 Environment::Environment AllowedEnvironment;
46};
47
48using namespace OperandCategory;
49using namespace Extension;
50using namespace Environment;
51using namespace Capability;
52using namespace InstructionSet;
53#define GET_SymbolicOperands_DECL
54#define GET_SymbolicOperands_IMPL
55#define GET_ExtensionEntries_DECL
56#define GET_ExtensionEntries_IMPL
57#define GET_CapabilityEntries_DECL
58#define GET_CapabilityEntries_IMPL
59#define GET_EnvironmentEntries_DECL
60#define GET_EnvironmentEntries_IMPL
61#define GET_ExtendedBuiltins_DECL
62#define GET_ExtendedBuiltins_IMPL
63#include "SPIRVGenTables.inc"
64} // namespace SPIRV
65
66std::string
67getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category,
68 int32_t Value) {
70 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
71 // Value that encodes just one enum value.
72 if (Lookup)
73 return SPIRV::getSymbolicOperandStr(Lookup->Mnemonic).str();
74 if (Category != SPIRV::OperandCategory::ImageOperandOperand &&
75 Category != SPIRV::OperandCategory::FPFastMathModeOperand &&
76 Category != SPIRV::OperandCategory::SelectionControlOperand &&
77 Category != SPIRV::OperandCategory::LoopControlOperand &&
78 Category != SPIRV::OperandCategory::FunctionControlOperand &&
79 Category != SPIRV::OperandCategory::MemorySemanticsOperand &&
80 Category != SPIRV::OperandCategory::MemoryOperandOperand &&
81 Category != SPIRV::OperandCategory::KernelProfilingInfoOperand &&
82 Category != SPIRV::OperandCategory::SpecConstantOpOperandsOperand)
83 return "UNKNOWN";
84 // Value that encodes many enum values (one bit per enum value).
85 std::string Name;
86 std::string Separator;
87 const SPIRV::SymbolicOperand *EnumValueInCategory =
88 SPIRV::lookupSymbolicOperandByCategory(Category);
89
90 auto TableEnd = ArrayRef(SPIRV::SymbolicOperands).end();
91 while (EnumValueInCategory && EnumValueInCategory->Category == Category) {
92 if ((EnumValueInCategory->Value != 0) &&
93 (Value & EnumValueInCategory->Value)) {
94 Name += Separator +
95 SPIRV::getSymbolicOperandStr(EnumValueInCategory->Mnemonic).str();
96 Separator = "|";
97 }
98 if (++EnumValueInCategory == TableEnd)
99 break;
100 }
101
102 return Name;
103}
104
105// Versions are encoded as in the SPIR-V header: 0x00MMmm00.
107 return VersionTuple((V >> 16) & 0xff, (V >> 8) & 0xff);
108}
109
110VersionTuple
111getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category,
112 uint32_t Value) {
114 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
115
116 if (Lookup)
117 return decodeVersion(Lookup->MinVersion);
118
119 return VersionTuple(0);
120}
121
122VersionTuple
123getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,
124 uint32_t Value) {
126 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
127
128 if (Lookup)
129 return decodeVersion(Lookup->MaxVersion);
130
131 return VersionTuple();
132}
133
135getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
136 uint32_t Value) {
137 CapabilityList Capabilities;
138 const SPIRV::CapabilityEntry *Capability =
139 SPIRV::lookupCapabilityByCategoryAndValue(Category, Value);
140 auto TableEnd = ArrayRef(SPIRV::CapabilityEntries).end();
141 while (Capability && Capability->Category == Category &&
142 Capability->Value == Value) {
143 Capabilities.push_back(
144 static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability));
145 if (++Capability == TableEnd)
146 break;
147 }
148
149 return Capabilities;
150}
151
153 SPIRV::OperandCategory::OperandCategory Category, uint32_t Value) {
154 EnvironmentList Environments;
155 const SPIRV::EnvironmentEntry *Environment =
156 SPIRV::lookupEnvironmentByCategoryAndValue(Category, Value);
157 auto TableEnd = ArrayRef(SPIRV::EnvironmentEntries).end();
158 while (Environment && Environment->Category == Category &&
159 Environment->Value == Value) {
160 Environments.push_back(static_cast<SPIRV::Environment::Environment>(
161 Environment->AllowedEnvironment));
162 if (++Environment == TableEnd)
163 break;
164 }
165
166 return Environments;
167}
168
170getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension) {
171 const SPIRV::ExtensionEntry *Entry =
172 SPIRV::lookupSymbolicOperandsEnabledByExtension(
173 Extension, SPIRV::OperandCategory::CapabilityOperand);
174
175 CapabilityList Capabilities;
176 auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();
177 while (Entry &&
178 Entry->Category == SPIRV::OperandCategory::CapabilityOperand) {
179 // Some capabilities' codes might go not in order.
180 if (Entry->ReqExtension == Extension)
181 Capabilities.push_back(
182 static_cast<SPIRV::Capability::Capability>(Entry->Value));
183 if (++Entry == TableEnd)
184 break;
185 }
186
187 return Capabilities;
188}
189
191getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
192 uint32_t Value) {
193 const SPIRV::ExtensionEntry *Extension =
194 SPIRV::lookupExtensionByCategoryAndValue(Category, Value);
195
197 auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();
198 while (Extension && Extension->Category == Category &&
199 Extension->Value == Value) {
200 Extensions.push_back(
201 static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension));
202 if (++Extension == TableEnd)
203 break;
204 }
205
206 return Extensions;
207}
208
209std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) {
211 SPIRV::lookupSymbolicOperandByCategoryAndValue(
212 SPIRV::OperandCategory::BuiltInOperand, BuiltInValue);
213
214 if (Lookup)
215 return "__spirv_BuiltIn" +
216 SPIRV::getSymbolicOperandStr(Lookup->Mnemonic).str();
217 return "UNKNOWN_BUILTIN";
218}
219
221 SPIRV::BuiltIn::BuiltIn &BI) {
222 const std::string Prefix = "__spirv_BuiltIn";
223 if (!Name.starts_with(Prefix))
224 return false;
225
227 SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(
228 SPIRV::OperandCategory::BuiltInOperand,
229 Name.drop_front(Prefix.length()));
230
231 if (!Lookup)
232 return false;
233
234 BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value);
235 return true;
236}
237
238std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) {
239 switch (Set) {
240 case SPIRV::InstructionSet::OpenCL_std:
241 return "OpenCL.std";
242 case SPIRV::InstructionSet::GLSL_std_450:
243 return "GLSL.std.450";
244 case SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100:
245 return "NonSemantic.Shader.DebugInfo.100";
246 case SPIRV::InstructionSet::NonSemantic_AuxData:
247 return "NonSemantic.AuxData";
248 case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax:
249 return "SPV_AMD_shader_trinary_minmax";
250 }
251 return "UNKNOWN_EXT_INST_SET";
252}
253
254SPIRV::InstructionSet::InstructionSet
255getExtInstSetFromString(std::string SetName) {
256 for (auto Set :
257 {SPIRV::InstructionSet::GLSL_std_450, SPIRV::InstructionSet::OpenCL_std,
258 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100,
259 SPIRV::InstructionSet::NonSemantic_AuxData}) {
260 if (SetName == getExtInstSetName(Set))
261 return Set;
262 }
263 llvm_unreachable("UNKNOWN_EXT_INST_SET");
264}
265
266std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set,
267 uint32_t InstructionNumber) {
269 SPIRV::lookupExtendedBuiltinBySetAndNumber(Set, InstructionNumber);
270
271 if (!Lookup)
272 return "UNKNOWN_EXT_INST";
273
274 return SPIRV::getExtendedBuiltinStr(Lookup->Name).str();
275}
276} // namespace llvm
static cl::opt< ExtensionSet, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM Value Representation.
Definition Value.h:75
Represents a version number in the form major[.minor[.subminor[.build]]].
#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.
SmallVector< SPIRV::Environment::Environment, 8 > EnvironmentList
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)
SmallVector< SPIRV::Extension::Extension, 8 > ExtensionList
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)
static VersionTuple decodeVersion(uint32_t V)
CapabilityList getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension)
SPIRV::InstructionSet::InstructionSet getExtInstSetFromString(std::string SetName)
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
ArrayRef(const T &OneElt) -> ArrayRef< T >
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
StringTable::Offset Mnemonic