LLVM 20.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
41using namespace OperandCategory;
42using namespace Extension;
43using namespace Capability;
44using namespace InstructionSet;
45#define GET_SymbolicOperands_DECL
46#define GET_SymbolicOperands_IMPL
47#define GET_ExtensionEntries_DECL
48#define GET_ExtensionEntries_IMPL
49#define GET_CapabilityEntries_DECL
50#define GET_CapabilityEntries_IMPL
51#define GET_ExtendedBuiltins_DECL
52#define GET_ExtendedBuiltins_IMPL
53#include "SPIRVGenTables.inc"
54} // namespace SPIRV
55
56std::string
57getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category,
58 int32_t Value) {
60 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
61 // Value that encodes just one enum value.
62 if (Lookup)
63 return Lookup->Mnemonic.str();
64 if (Category != SPIRV::OperandCategory::ImageOperandOperand &&
65 Category != SPIRV::OperandCategory::FPFastMathModeOperand &&
66 Category != SPIRV::OperandCategory::SelectionControlOperand &&
67 Category != SPIRV::OperandCategory::LoopControlOperand &&
68 Category != SPIRV::OperandCategory::FunctionControlOperand &&
69 Category != SPIRV::OperandCategory::MemorySemanticsOperand &&
70 Category != SPIRV::OperandCategory::MemoryOperandOperand &&
71 Category != SPIRV::OperandCategory::KernelProfilingInfoOperand)
72 return "UNKNOWN";
73 // Value that encodes many enum values (one bit per enum value).
74 std::string Name;
75 std::string Separator;
76 const SPIRV::SymbolicOperand *EnumValueInCategory =
77 SPIRV::lookupSymbolicOperandByCategory(Category);
78
79 auto TableEnd = ArrayRef(SPIRV::SymbolicOperands).end();
80 while (EnumValueInCategory && EnumValueInCategory->Category == Category) {
81 if ((EnumValueInCategory->Value != 0) &&
82 (Value & EnumValueInCategory->Value)) {
83 Name += Separator + EnumValueInCategory->Mnemonic.str();
84 Separator = "|";
85 }
86 if (++EnumValueInCategory == TableEnd)
87 break;
88 }
89
90 return Name;
91}
92
93VersionTuple
94getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category,
97 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
98
99 if (Lookup)
100 return VersionTuple(Lookup->MinVersion / 10, Lookup->MinVersion % 10);
101
102 return VersionTuple(0);
103}
104
105VersionTuple
106getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category,
107 uint32_t Value) {
109 SPIRV::lookupSymbolicOperandByCategoryAndValue(Category, Value);
110
111 if (Lookup)
112 return VersionTuple(Lookup->MaxVersion / 10, Lookup->MaxVersion % 10);
113
114 return VersionTuple();
115}
116
118getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category,
119 uint32_t Value) {
120 CapabilityList Capabilities;
121 const SPIRV::CapabilityEntry *Capability =
122 SPIRV::lookupCapabilityByCategoryAndValue(Category, Value);
123 auto TableEnd = ArrayRef(SPIRV::CapabilityEntries).end();
124 while (Capability && Capability->Category == Category &&
125 Capability->Value == Value) {
126 Capabilities.push_back(
127 static_cast<SPIRV::Capability::Capability>(Capability->ReqCapability));
128 if (++Capability == TableEnd)
129 break;
130 }
131
132 return Capabilities;
133}
134
136getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension) {
137 const SPIRV::ExtensionEntry *Entry =
138 SPIRV::lookupSymbolicOperandsEnabledByExtension(
139 Extension, SPIRV::OperandCategory::CapabilityOperand);
140
141 CapabilityList Capabilities;
142 auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();
143 while (Entry &&
144 Entry->Category == SPIRV::OperandCategory::CapabilityOperand) {
145 // Some capabilities' codes might go not in order.
146 if (Entry->ReqExtension == Extension)
147 Capabilities.push_back(
148 static_cast<SPIRV::Capability::Capability>(Entry->Value));
149 if (++Entry == TableEnd)
150 break;
151 }
152
153 return Capabilities;
154}
155
157getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category,
158 uint32_t Value) {
160 SPIRV::lookupExtensionByCategoryAndValue(Category, Value);
161
163 auto TableEnd = ArrayRef(SPIRV::ExtensionEntries).end();
164 while (Extension && Extension->Category == Category &&
165 Extension->Value == Value) {
166 Extensions.push_back(
167 static_cast<SPIRV::Extension::Extension>(Extension->ReqExtension));
168 if (++Extension == TableEnd)
169 break;
170 }
171
172 return Extensions;
173}
174
175std::string getLinkStringForBuiltIn(SPIRV::BuiltIn::BuiltIn BuiltInValue) {
177 SPIRV::lookupSymbolicOperandByCategoryAndValue(
178 SPIRV::OperandCategory::BuiltInOperand, BuiltInValue);
179
180 if (Lookup)
181 return "__spirv_BuiltIn" + Lookup->Mnemonic.str();
182 return "UNKNOWN_BUILTIN";
183}
184
186 SPIRV::BuiltIn::BuiltIn &BI) {
187 const std::string Prefix = "__spirv_BuiltIn";
188 if (!Name.starts_with(Prefix))
189 return false;
190
192 SPIRV::lookupSymbolicOperandByCategoryAndMnemonic(
193 SPIRV::OperandCategory::BuiltInOperand,
194 Name.drop_front(Prefix.length()));
195
196 if (!Lookup)
197 return false;
198
199 BI = static_cast<SPIRV::BuiltIn::BuiltIn>(Lookup->Value);
200 return true;
201}
202
203std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set) {
204 switch (Set) {
205 case SPIRV::InstructionSet::OpenCL_std:
206 return "OpenCL.std";
207 case SPIRV::InstructionSet::GLSL_std_450:
208 return "GLSL.std.450";
209 case SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100:
210 return "NonSemantic.Shader.DebugInfo.100";
211 case SPIRV::InstructionSet::SPV_AMD_shader_trinary_minmax:
212 return "SPV_AMD_shader_trinary_minmax";
213 }
214 return "UNKNOWN_EXT_INST_SET";
215}
216
217SPIRV::InstructionSet::InstructionSet
218getExtInstSetFromString(std::string SetName) {
219 for (auto Set :
220 {SPIRV::InstructionSet::GLSL_std_450, SPIRV::InstructionSet::OpenCL_std,
221 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100}) {
222 if (SetName == getExtInstSetName(Set))
223 return Set;
224 }
225 llvm_unreachable("UNKNOWN_EXT_INST_SET");
226}
227
228std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set,
229 uint32_t InstructionNumber) {
231 SPIRV::lookupExtendedBuiltinBySetAndNumber(Set, InstructionNumber);
232
233 if (!Lookup)
234 return "UNKNOWN_EXT_INST";
235
236 return Lookup->Name.str();
237}
238} // 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:157
void push_back(const T &Elt)
Definition: SmallVector.h:413
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
LLVM Value Representation.
Definition: Value.h:74
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
#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)
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
Extension::Extension ReqExtension
OperandCategory::OperandCategory Category
OperandCategory::OperandCategory Category