22#include "llvm/IR/IntrinsicsSPIRV.h"
32 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
33 unsigned StrIndex = i + WordIndex;
34 uint8_t CharToAdd = 0;
35 if (StrIndex < Str.size()) {
36 CharToAdd = Str[StrIndex];
38 Word |= (CharToAdd << (WordIndex * 8));
45 const size_t Len = Str.size() + 1;
46 return (Len % 4 == 0) ? Len : Len + (4 - (Len % 4));
51 for (
unsigned i = 0; i < PaddedLen; i += 4) {
59 for (
unsigned i = 0; i < PaddedLen; i += 4) {
66 std::vector<Value *> &Args) {
68 for (
unsigned i = 0; i < PaddedLen; i += 4) {
79 const auto Bitwidth = Imm.getBitWidth();
82 else if (Bitwidth <= 32) {
83 MIB.
addImm(Imm.getZExtValue());
85 }
else if (Bitwidth <= 64) {
86 uint64_t FullImm = Imm.getZExtValue();
87 uint32_t LowBits = FullImm & 0xffffffff;
88 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
104 const std::vector<uint32_t> &DecArgs,
108 for (
const auto &DecArg : DecArgs)
113 SPIRV::Decoration::Decoration Dec,
114 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
115 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
122 SPIRV::Decoration::Decoration Dec,
123 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
125 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
135 case SPIRV::StorageClass::Function:
137 case SPIRV::StorageClass::CrossWorkgroup:
139 case SPIRV::StorageClass::UniformConstant:
141 case SPIRV::StorageClass::Workgroup:
143 case SPIRV::StorageClass::Generic:
145 case SPIRV::StorageClass::Input:
152SPIRV::StorageClass::StorageClass
156 return SPIRV::StorageClass::Function;
158 return SPIRV::StorageClass::CrossWorkgroup;
160 return SPIRV::StorageClass::UniformConstant;
162 return SPIRV::StorageClass::Workgroup;
164 return SPIRV::StorageClass::Generic;
166 return SPIRV::StorageClass::Input;
172SPIRV::MemorySemantics::MemorySemantics
175 case SPIRV::StorageClass::StorageBuffer:
176 case SPIRV::StorageClass::Uniform:
177 return SPIRV::MemorySemantics::UniformMemory;
178 case SPIRV::StorageClass::Workgroup:
179 return SPIRV::MemorySemantics::WorkgroupMemory;
180 case SPIRV::StorageClass::CrossWorkgroup:
181 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
182 case SPIRV::StorageClass::AtomicCounter:
183 return SPIRV::MemorySemantics::AtomicCounterMemory;
184 case SPIRV::StorageClass::Image:
185 return SPIRV::MemorySemantics::ImageMemory;
187 return SPIRV::MemorySemantics::None;
194 return SPIRV::MemorySemantics::Acquire;
196 return SPIRV::MemorySemantics::Release;
198 return SPIRV::MemorySemantics::AcquireRelease;
200 return SPIRV::MemorySemantics::SequentiallyConsistent;
204 return SPIRV::MemorySemantics::None;
212 if (ConstInstr->
getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS &&
215 ConstInstr =
MRI->getVRegDef(ConstReg);
216 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
218 ConstInstr =
MRI->getVRegDef(ConstReg);
225 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
226 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
230 return MI.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS &&
231 MI.getIntrinsicID() == IntrinsicID;
235 return cast<ValueAsMetadata>(
N->getOperand(
I))->getType();
241 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
242 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
243 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
244 MangledName ==
"reserve_write_pipe" ||
245 MangledName ==
"reserve_read_pipe" ||
246 MangledName ==
"commit_write_pipe" ||
247 MangledName ==
"commit_read_pipe" ||
248 MangledName ==
"work_group_reserve_write_pipe" ||
249 MangledName ==
"work_group_reserve_read_pipe" ||
250 MangledName ==
"work_group_commit_write_pipe" ||
251 MangledName ==
"work_group_commit_read_pipe" ||
252 MangledName ==
"get_pipe_num_packets_ro" ||
253 MangledName ==
"get_pipe_max_packets_ro" ||
254 MangledName ==
"get_pipe_num_packets_wo" ||
255 MangledName ==
"get_pipe_max_packets_wo" ||
256 MangledName ==
"sub_group_reserve_write_pipe" ||
257 MangledName ==
"sub_group_reserve_read_pipe" ||
258 MangledName ==
"sub_group_commit_write_pipe" ||
259 MangledName ==
"sub_group_commit_read_pipe" ||
260 MangledName ==
"to_global" || MangledName ==
"to_local" ||
261 MangledName ==
"to_private";
265 return MangledName ==
"__enqueue_kernel_basic" ||
266 MangledName ==
"__enqueue_kernel_basic_events" ||
267 MangledName ==
"__enqueue_kernel_varargs" ||
268 MangledName ==
"__enqueue_kernel_events_varargs";
272 return MangledName ==
"__get_kernel_work_group_size_impl" ||
273 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
274 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
275 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
279 if (!
Name.startswith(
"__"))
284 Name ==
"__translate_sampler_initializer";
289 bool IsNonMangledSPIRV =
Name.startswith(
"__spirv_");
290 bool IsMangled =
Name.startswith(
"_Z");
292 if (!IsNonMangledOCL && !IsNonMangledSPIRV && !IsMangled)
293 return std::string();
297 std::string Result = DemangledName;
302 if (IsNonMangledOCL || IsNonMangledSPIRV)
309 size_t Start, Len = 0;
310 size_t DemangledNameLenStart = 2;
311 if (
Name.startswith(
"_ZN")) {
313 size_t NameSpaceStart =
Name.find_first_not_of(
"rVKRO", 3);
315 if (
Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
316 return std::string();
317 DemangledNameLenStart = NameSpaceStart + 11;
319 Start =
Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
320 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
321 .getAsInteger(10, Len);
322 return Name.substr(Start, Len).str();
326 auto PType = dyn_cast<PointerType>(Ty);
327 if (!PType || PType->isOpaque())
333 if (
Name.starts_with(
"opencl.") ||
Name.starts_with(
"spirv."))
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
static MCOperand createImm(int64_t Val)
Helper class to build MachineInstr.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
unsigned getIntrinsicID() const
Returns the Intrinsic::ID for this instruction.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Class to represent struct types.
bool hasName() const
Return true if this is a named struct that has a non-empty name.
StringRef getName() const
Return the name for this struct type if it has an identity.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
Type * getNonOpaquePointerElementType() const
Only use this method in code that is not reachable with opaque pointers, or part of deprecated method...
#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.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC)
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static void finishBuildOpDecorate(MachineInstrBuilder &MIB, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
static uint32_t convertCharsToWord(const StringRef &Str, unsigned i)
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
SPIRV::MemorySemantics::MemorySemantics getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC)
std::string getOclOrSpirvBuiltinDemangledName(StringRef Name)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace)
bool isSpecialOpaqueType(const Type *Ty)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool isSpvIntrinsic(MachineInstr &MI, Intrinsic::ID IntrinsicID)
static bool isNonMangledOCLBuiltin(StringRef Name)
AtomicOrdering
Atomic ordering for LLVM's memory model.
static bool isPipeOrAddressSpaceCastBI(const StringRef MangledName)
const Type * getTypedPtrEltType(const Type *Ty)
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
Type * getMDOperandAsType(const MDNode *N, unsigned I)
char * itaniumDemangle(std::string_view mangled_name)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
static bool hasBuiltinTypePrefix(StringRef Name)
static size_t getPaddedLen(const StringRef &Str)
void addStringImm(const StringRef &Str, MCInst &Inst)
static bool isKernelQueryBI(const StringRef MangledName)
static bool isEnqueueKernelBI(const StringRef MangledName)
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)