26#include "llvm/IR/IntrinsicsSPIRV.h"
38 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
39 unsigned StrIndex = i + WordIndex;
41 if (StrIndex < Str.size()) {
42 CharToAdd = Str[StrIndex];
44 Word |= (CharToAdd << (WordIndex * 8));
51 return (Str.size() + 4) & ~3;
56 for (
unsigned i = 0; i < PaddedLen; i += 4) {
64 for (
unsigned i = 0; i < PaddedLen; i += 4) {
71 std::vector<Value *> &Args) {
73 for (
unsigned i = 0; i < PaddedLen; i += 4) {
85 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
86 "Expected G_GLOBAL_VALUE");
87 const GlobalValue *GV = Def->getOperand(1).getGlobal();
94 const auto Bitwidth = Imm.getBitWidth();
97 else if (Bitwidth <= 32) {
98 MIB.
addImm(Imm.getZExtValue());
103 }
else if (Bitwidth <= 64) {
104 uint64_t FullImm = Imm.getZExtValue();
105 uint32_t LowBits = FullImm & 0xffffffff;
106 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
125 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
132 const std::vector<uint32_t> &DecArgs,
136 for (
const auto &DecArg : DecArgs)
141 SPIRV::Decoration::Decoration Dec,
142 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
143 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
150 SPIRV::Decoration::Decoration Dec,
151 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
153 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
160 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
161 const std::vector<uint32_t> &DecArgs,
163 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
172 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
173 const std::vector<uint32_t> &DecArgs,
176 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
186 auto *OpMD = dyn_cast<MDNode>(GVarMD->
getOperand(
I));
189 if (OpMD->getNumOperands() == 0)
192 mdconst::dyn_extract<ConstantInt>(OpMD->getOperand(0));
195 "element of the decoration");
196 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
199 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
201 mdconst::dyn_extract<ConstantInt>(OpMD->getOperand(OpI)))
203 else if (
MDString *OpV = dyn_cast<MDString>(OpMD->getOperand(OpI)))
216 bool IsHeader =
false;
218 for (; It !=
E && It !=
I; ++It) {
219 Opcode = It->getOpcode();
220 if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
222 }
else if (IsHeader &&
223 !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
236 while (
I->isTerminator() ||
I->isDebugValue()) {
244SPIRV::StorageClass::StorageClass
248 return SPIRV::StorageClass::Function;
250 return SPIRV::StorageClass::CrossWorkgroup;
252 return SPIRV::StorageClass::UniformConstant;
254 return SPIRV::StorageClass::Workgroup;
256 return SPIRV::StorageClass::Generic;
258 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
259 ? SPIRV::StorageClass::DeviceOnlyINTEL
260 : SPIRV::StorageClass::CrossWorkgroup;
262 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
263 ? SPIRV::StorageClass::HostOnlyINTEL
264 : SPIRV::StorageClass::CrossWorkgroup;
266 return SPIRV::StorageClass::Input;
268 return SPIRV::StorageClass::Output;
270 return SPIRV::StorageClass::CodeSectionINTEL;
272 return SPIRV::StorageClass::Private;
274 return SPIRV::StorageClass::StorageBuffer;
276 return SPIRV::StorageClass::Uniform;
282SPIRV::MemorySemantics::MemorySemantics
285 case SPIRV::StorageClass::StorageBuffer:
286 case SPIRV::StorageClass::Uniform:
287 return SPIRV::MemorySemantics::UniformMemory;
288 case SPIRV::StorageClass::Workgroup:
289 return SPIRV::MemorySemantics::WorkgroupMemory;
290 case SPIRV::StorageClass::CrossWorkgroup:
291 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
292 case SPIRV::StorageClass::AtomicCounter:
293 return SPIRV::MemorySemantics::AtomicCounterMemory;
294 case SPIRV::StorageClass::Image:
295 return SPIRV::MemorySemantics::ImageMemory;
297 return SPIRV::MemorySemantics::None;
304 return SPIRV::MemorySemantics::Acquire;
306 return SPIRV::MemorySemantics::Release;
308 return SPIRV::MemorySemantics::AcquireRelease;
310 return SPIRV::MemorySemantics::SequentiallyConsistent;
314 return SPIRV::MemorySemantics::None;
333 return SPIRV::Scope::Invocation;
335 return SPIRV::Scope::CrossDevice;
336 else if (Id == SubGroup)
337 return SPIRV::Scope::Subgroup;
338 else if (Id == WorkGroup)
339 return SPIRV::Scope::Workgroup;
340 else if (Id == Device)
341 return SPIRV::Scope::Device;
342 return SPIRV::Scope::CrossDevice;
349 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
350 ?
MRI->getVRegDef(
MI->getOperand(1).getReg())
352 if (
auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
353 if (GI->is(Intrinsic::spv_track_constant)) {
355 return MRI->getVRegDef(ConstReg);
357 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
359 return MRI->getVRegDef(ConstReg);
360 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
361 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
365 return MRI->getVRegDef(ConstReg);
370 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
371 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
375 if (
const auto *GI = dyn_cast<GIntrinsic>(&
MI))
376 return GI->is(IntrinsicID);
381 Type *ElementTy = cast<ValueAsMetadata>(
N->getOperand(
I))->getType();
388 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
389 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
390 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
391 MangledName ==
"reserve_write_pipe" ||
392 MangledName ==
"reserve_read_pipe" ||
393 MangledName ==
"commit_write_pipe" ||
394 MangledName ==
"commit_read_pipe" ||
395 MangledName ==
"work_group_reserve_write_pipe" ||
396 MangledName ==
"work_group_reserve_read_pipe" ||
397 MangledName ==
"work_group_commit_write_pipe" ||
398 MangledName ==
"work_group_commit_read_pipe" ||
399 MangledName ==
"get_pipe_num_packets_ro" ||
400 MangledName ==
"get_pipe_max_packets_ro" ||
401 MangledName ==
"get_pipe_num_packets_wo" ||
402 MangledName ==
"get_pipe_max_packets_wo" ||
403 MangledName ==
"sub_group_reserve_write_pipe" ||
404 MangledName ==
"sub_group_reserve_read_pipe" ||
405 MangledName ==
"sub_group_commit_write_pipe" ||
406 MangledName ==
"sub_group_commit_read_pipe" ||
407 MangledName ==
"to_global" || MangledName ==
"to_local" ||
408 MangledName ==
"to_private";
412 return MangledName ==
"__enqueue_kernel_basic" ||
413 MangledName ==
"__enqueue_kernel_basic_events" ||
414 MangledName ==
"__enqueue_kernel_varargs" ||
415 MangledName ==
"__enqueue_kernel_events_varargs";
419 return MangledName ==
"__get_kernel_work_group_size_impl" ||
420 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
421 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
422 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
426 if (!
Name.starts_with(
"__"))
431 Name ==
"__translate_sampler_initializer";
436 bool IsNonMangledSPIRV =
Name.starts_with(
"__spirv_");
437 bool IsNonMangledHLSL =
Name.starts_with(
"__hlsl_");
438 bool IsMangled =
Name.starts_with(
"_Z");
441 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
446 std::string Result = DemangledName;
455 size_t Start, Len = 0;
456 size_t DemangledNameLenStart = 2;
457 if (
Name.starts_with(
"_ZN")) {
459 size_t NameSpaceStart =
Name.find_first_not_of(
"rVKRO", 3);
461 if (
Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
462 return std::string();
463 DemangledNameLenStart = NameSpaceStart + 11;
465 Start =
Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
466 [[maybe_unused]]
bool Error =
467 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
468 .getAsInteger(10, Len);
469 assert(!
Error &&
"Failed to parse demangled name length");
470 return Name.substr(Start, Len).str();
474 if (
Name.starts_with(
"opencl.") ||
Name.starts_with(
"ocl_") ||
475 Name.starts_with(
"spirv."))
481 if (
const TargetExtType *ExtTy = dyn_cast<TargetExtType>(Ty))
497 if (
F.getFnAttribute(
"hlsl.shader").isValid())
504 TypeName.consume_front(
"atomic_");
505 if (TypeName.consume_front(
"void"))
507 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
509 else if (TypeName.consume_front(
"char") ||
510 TypeName.consume_front(
"signed char") ||
511 TypeName.consume_front(
"unsigned char") ||
512 TypeName.consume_front(
"uchar"))
514 else if (TypeName.consume_front(
"short") ||
515 TypeName.consume_front(
"signed short") ||
516 TypeName.consume_front(
"unsigned short") ||
517 TypeName.consume_front(
"ushort"))
519 else if (TypeName.consume_front(
"int") ||
520 TypeName.consume_front(
"signed int") ||
521 TypeName.consume_front(
"unsigned int") ||
522 TypeName.consume_front(
"uint"))
524 else if (TypeName.consume_front(
"long") ||
525 TypeName.consume_front(
"signed long") ||
526 TypeName.consume_front(
"unsigned long") ||
527 TypeName.consume_front(
"ulong"))
529 else if (TypeName.consume_front(
"half") ||
530 TypeName.consume_front(
"_Float16") ||
531 TypeName.consume_front(
"__fp16"))
533 else if (TypeName.consume_front(
"float"))
535 else if (TypeName.consume_front(
"double"))
542std::unordered_set<BasicBlock *>
543PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
544 std::queue<BasicBlock *> ToVisit;
547 std::unordered_set<BasicBlock *> Output;
548 while (ToVisit.size() != 0) {
549 BasicBlock *BB = ToVisit.front();
552 if (Output.count(BB) != 0)
566bool PartialOrderingVisitor::CanBeVisited(BasicBlock *BB)
const {
573 if (BlockToOrder.count(
P) == 0)
579 if (L ==
nullptr ||
L->contains(BB))
585 assert(
L->getNumBackEdges() <= 1);
591 if (Latch ==
nullptr)
595 if (BlockToOrder.count(Latch) == 0)
603 auto It = BlockToOrder.find(BB);
604 if (It != BlockToOrder.end())
605 return It->second.Rank;
613 auto Iterator = BlockToOrder.end();
615 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
619 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
620 Iterator = BlockToOrder.find(
P);
625 Iterator = BlockToOrder.find(Latch);
628 assert(Iterator != BlockToOrder.end());
629 result = std::max(result, Iterator->second.Rank + 1);
635size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
639 size_t QueueIndex = 0;
640 while (ToVisit.size() != 0) {
644 if (!CanBeVisited(BB)) {
646 if (QueueIndex >= ToVisit.size())
648 "No valid candidate in the queue. Is the graph reducible?");
655 OrderInfo
Info = {Rank, BlockToOrder.size()};
656 BlockToOrder.emplace(BB,
Info);
659 if (Queued.count(S) != 0)
673 visit(&*
F.begin(), 0);
675 Order.reserve(
F.size());
676 for (
auto &[BB,
Info] : BlockToOrder)
677 Order.emplace_back(BB);
679 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
680 return compare(LHS, RHS);
686 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
687 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
688 if (InfoLHS.Rank != InfoRHS.Rank)
689 return InfoLHS.Rank < InfoRHS.Rank;
690 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
695 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
696 assert(BlockToOrder.count(&Start) != 0);
699 auto It = Order.begin();
700 while (It != Order.end() && *It != &Start)
705 assert(It != Order.end());
708 std::optional<size_t> EndRank = std::nullopt;
709 for (; It != Order.end(); ++It) {
710 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
713 if (Reachable.count(*It) == 0) {
718 EndRank = BlockToOrder[*It].Rank;
728 std::vector<BasicBlock *> Order;
729 Order.reserve(
F.size());
734 assert(&*
F.begin() == Order[0]);
737 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
749 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
757 constexpr unsigned MaxIters = 1024;
758 for (
unsigned I = 0;
I < MaxIters; ++
I) {
760 if (!M.getFunction(OrdName)) {
761 Name = std::move(OrdName);
774 if (!
MRI->getRegClassOrNull(
Reg) || Force) {
785 SPIRV::AccessQualifier::AccessQualifier AccessQual,
786 bool EmitIR,
bool Force) {
789 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
815 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
825 Args.push_back(Arg2);
828 return B.CreateIntrinsic(IntrID, {Types}, Args);
835 if (
const FunctionType *RefTy = dyn_cast<FunctionType>(Ty)) {
838 for (
const Type *ArgTy : RefTy->params())
843 if (
const ArrayType *RefTy = dyn_cast<ArrayType>(Ty))
849 if (
const auto *
II = dyn_cast<IntrinsicInst>(Arg))
851 if (
F->getName().starts_with(
"llvm.spv."))
858SmallVector<MachineInstr *, 4>
860 unsigned MinWC,
unsigned ContinuedOpcode,
865 constexpr unsigned MaxWordCount = UINT16_MAX;
866 const size_t NumElements = Args.size();
867 size_t MaxNumElements = MaxWordCount - MinWC;
868 size_t SPIRVStructNumElements = NumElements;
870 if (NumElements > MaxNumElements) {
873 SPIRVStructNumElements = MaxNumElements;
874 MaxNumElements = MaxWordCount - 1;
880 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
883 Instructions.push_back(MIB.getInstr());
885 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
886 I += MaxNumElements) {
887 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
888 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
890 Instructions.push_back(MIB.getInstr());
896 unsigned LC = SPIRV::LoopControl::None;
900 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
902 LC |= SPIRV::LoopControl::DontUnroll;
906 LC |= SPIRV::LoopControl::Unroll;
908 std::optional<int> Count =
910 if (Count && Count != 1) {
911 LC |= SPIRV::LoopControl::PartialCount;
912 MaskToValueMap.emplace_back(
913 std::make_pair(SPIRV::LoopControl::PartialCount, *Count));
917 for (
auto &[Mask, Val] : MaskToValueMap)
918 Result.push_back(Val);
924 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
926 TargetOpcode::G_FADD,
927 TargetOpcode::G_STRICT_FADD,
929 TargetOpcode::G_FSUB,
930 TargetOpcode::G_STRICT_FSUB,
932 TargetOpcode::G_FMUL,
933 TargetOpcode::G_STRICT_FMUL,
934 TargetOpcode::G_SDIV,
935 TargetOpcode::G_UDIV,
936 TargetOpcode::G_FDIV,
937 TargetOpcode::G_STRICT_FDIV,
938 TargetOpcode::G_SREM,
939 TargetOpcode::G_UREM,
940 TargetOpcode::G_FREM,
941 TargetOpcode::G_STRICT_FREM,
942 TargetOpcode::G_FNEG,
943 TargetOpcode::G_CONSTANT,
944 TargetOpcode::G_FCONSTANT,
949 TargetOpcode::G_ASHR,
950 TargetOpcode::G_LSHR,
951 TargetOpcode::G_SELECT,
952 TargetOpcode::G_EXTRACT_VECTOR_ELT,
955 return TypeFoldingSupportingOpcs;
964 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
965 Def->getOpcode() == TargetOpcode::COPY)
966 ?
MRI->getVRegDef(Def->getOperand(1).getReg())
978 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
979 Def->getOpcode() == SPIRV::OpConstantI)
987 if (Def->getOpcode() == SPIRV::OpConstantI)
988 return Def->getOperand(2).getImm();
989 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
990 return Def->getOperand(1).getCImm()->getZExtValue();
1006 while (VarPos != BB.
end() && VarPos->getOpcode() != SPIRV::OpFunction) {
1013 while (VarPos != BB.
end() &&
1014 VarPos->getOpcode() == SPIRV::OpFunctionParameter) {
1019 return VarPos != BB.
end() && VarPos->getOpcode() == SPIRV::OpLabel ? ++VarPos
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
uint64_t IntrinsicInst * II
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
LLVM Basic Block Representation.
const Instruction & front() const
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
This class represents a function call, abstracting a target machine's calling convention.
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
StringRef getAsCString() const
If this array is isCString(), then this method returns the array (without the trailing null byte) as ...
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This class represents an Operation in the Expression.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
Lightweight error class with error context and mandatory checking.
Class to represent function types.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This is an important class for using LLVM in a threaded context.
LLVM_ABI SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
static MCOperand createImm(int64_t Val)
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
LLVM_ABI iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
MachineInstrBundleIterator< MachineInstr > iterator
const MachineBasicBlock & front() const
Helper class to build MachineInstr.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
MachineRegisterInfo * getMRI()
Getter for MRI.
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.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void setAsmPrinterFlag(uint8_t Flag)
Set a flag for the AsmPrinter.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
size_t GetNodeRank(BasicBlock *BB) const
void partialOrderVisit(BasicBlock &Start, std::function< bool(BasicBlock *)> Op)
bool compare(const BasicBlock *LHS, const BasicBlock *RHS) const
PartialOrderingVisitor(Function &F)
Wrapper class representing virtual and physical registers.
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
LLT getRegType(SPIRVType *SpvType) const
bool canUseExtension(SPIRV::Extension::Extension E) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Value * getOperand(unsigned i) const
LLVM Value Representation.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ BasicBlock
Various leaf nodes.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
@ System
Synchronized with respect to all concurrently executing threads.
This is an optimization pass for GlobalISel generic memory operations.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
bool getVacantFunctionName(Module &M, std::string &Name)
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
LLVM_ABI bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name)
Returns true if Name is applied to TheLoop and enabled.
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
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)
bool isTypeFoldingSupported(unsigned Opcode)
static uint32_t convertCharsToWord(const StringRef &Str, unsigned i)
MachineInstr * getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI)
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
auto successors(const MachineBasicBlock *BB)
CallInst * buildIntrWithMD(Intrinsic::ID IntrID, ArrayRef< Type * > Types, Value *Arg, Value *Arg2, ArrayRef< Constant * > Imms, IRBuilder<> &B)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
unsigned getArrayComponentCount(const MachineRegisterInfo *MRI, const MachineInstr *ResType)
bool sortBlocks(Function &F)
SmallVector< unsigned, 1 > getSpirvLoopControlOperandsFromLoopMetadata(Loop *L)
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
SmallVector< MachineInstr *, 4 > createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode, unsigned MinWC, unsigned ContinuedOpcode, ArrayRef< Register > Args, Register ReturnRegister, Register TypeID)
SPIRV::MemorySemantics::MemorySemantics getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC)
MachineBasicBlock::iterator getFirstValidInstructionInsertPoint(MachineBasicBlock &BB)
bool isNestedPointer(const Type *Ty)
MetadataAsValue * buildMD(Value *Arg)
std::string getOclOrSpirvBuiltinDemangledName(StringRef Name)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I)
Register createVirtualRegister(SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Type * toTypedPointer(Type *Ty)
DEMANGLE_ABI char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
bool isSpecialOpaqueType(const Type *Ty)
void setRegClassType(Register Reg, SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
static bool isNonMangledOCLBuiltin(StringRef Name)
MachineInstr * passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI)
bool isEntryPoint(const Function &F)
const std::set< unsigned > & getTypeFoldingSupportedOpcodes()
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
LLVM_ABI std::optional< int > getOptionalIntLoopAttribute(const Loop *TheLoop, StringRef Name)
Find named metadata for a loop with an integer value.
AtomicOrdering
Atomic ordering for LLVM's memory model.
SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id)
static bool isPipeOrAddressSpaceCastBI(const StringRef MangledName)
std::string getStringValueFromReg(Register Reg, MachineRegisterInfo &MRI)
int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
bool hasBuiltinTypePrefix(StringRef Name)
Type * getMDOperandAsType(const MDNode *N, unsigned I)
auto predecessors(const MachineBasicBlock *BB)
static size_t getPaddedLen(const StringRef &Str)
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
void addStringImm(const StringRef &Str, MCInst &Inst)
static bool isKernelQueryBI(const StringRef MangledName)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)
static bool isEnqueueKernelBI(const StringRef MangledName)
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)