28#include "llvm/IR/IntrinsicsSPIRV.h"
46 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
47 return MDS->getString() == Name;
57 for (
unsigned I = 1;
I != (*It)->getNumOperands(); ++
I) {
59 assert(MD &&
"MDNode operand is expected");
63 assert(CMeta &&
"ConstantAsMetadata operand is expected");
64 int64_t Idx = Const->getSExtValue();
68 RetTy = CMeta->getType();
71 if (Idx >= 0 &&
static_cast<uint64_t>(Idx) < PTys.
size()) {
72 PTys[Idx] = CMeta->getType();
90 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
91 return MDS->getString() == Name;
100 assert(MD &&
"MDNode operand is expected");
103 Constraints = MDS->getString();
110 F.getParent()->getNamedMetadata(
"spv.cloned_funcs"),
F.getFunctionType(),
117 if (MD->getNumOperands() > 0)
119 return MDS->getString();
150 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
151 unsigned StrIndex = i + WordIndex;
153 if (StrIndex < Str.size()) {
154 CharToAdd = Str[StrIndex];
156 Word |= (CharToAdd << (WordIndex * 8));
166 for (
unsigned i = 0; i < PaddedLen; i += 4) {
174 for (
unsigned i = 0; i < PaddedLen; i += 4) {
186 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
187 "Expected G_GLOBAL_VALUE");
188 const GlobalValue *GV = Def->getOperand(1).getGlobal();
195 const auto Bitwidth = Imm.getBitWidth();
198 else if (Bitwidth <= 32) {
199 MIB.
addImm(Imm.getZExtValue());
204 }
else if (Bitwidth <= 64) {
205 uint64_t FullImm = Imm.getZExtValue();
213 for (
unsigned I = 0;
I < NumWords; ++
I) {
214 unsigned LimbIdx =
I / 2;
215 unsigned LimbShift = (
I % 2) * 32;
216 uint32_t Word = (Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
235 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
246 for (
const auto &DecArg : DecArgs)
251 SPIRV::Decoration::Decoration Dec,
253 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
260 SPIRV::Decoration::Decoration Dec,
263 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
270 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
272 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
285 if (OpMD->getNumOperands() == 0)
291 "element of the decoration");
301 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
303 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
306 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
309 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
312 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
327 switch (
MI.getOpcode()) {
328 case SPIRV::OpFunction:
329 case SPIRV::OpFunctionParameter:
331 case SPIRV::ASSIGN_TYPE:
338 while (VarPos !=
MBB.end() && VarPos->getOpcode() != SPIRV::OpFunction)
341 while (VarPos !=
MBB.end() && IsPreamble(*VarPos))
348 if (
I ==
MBB->begin())
351 while (
I->isTerminator() ||
I->isDebugValue()) {
352 if (
I ==
MBB->begin())
359SPIRV::StorageClass::StorageClass
363 return SPIRV::StorageClass::Function;
365 return SPIRV::StorageClass::CrossWorkgroup;
367 return SPIRV::StorageClass::UniformConstant;
369 return SPIRV::StorageClass::Workgroup;
371 return SPIRV::StorageClass::Generic;
373 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
374 ? SPIRV::StorageClass::DeviceOnlyINTEL
375 : SPIRV::StorageClass::CrossWorkgroup;
377 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
378 ? SPIRV::StorageClass::HostOnlyINTEL
379 : SPIRV::StorageClass::CrossWorkgroup;
381 return SPIRV::StorageClass::Input;
383 return SPIRV::StorageClass::Output;
385 return SPIRV::StorageClass::CodeSectionINTEL;
387 return SPIRV::StorageClass::Private;
389 return SPIRV::StorageClass::StorageBuffer;
391 return SPIRV::StorageClass::Uniform;
393 return SPIRV::StorageClass::PushConstant;
399SPIRV::MemorySemantics::MemorySemantics
402 case SPIRV::StorageClass::StorageBuffer:
403 case SPIRV::StorageClass::Uniform:
404 return SPIRV::MemorySemantics::UniformMemory;
405 case SPIRV::StorageClass::Workgroup:
406 return SPIRV::MemorySemantics::WorkgroupMemory;
407 case SPIRV::StorageClass::CrossWorkgroup:
408 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
409 case SPIRV::StorageClass::AtomicCounter:
410 return SPIRV::MemorySemantics::AtomicCounterMemory;
411 case SPIRV::StorageClass::Image:
412 return SPIRV::MemorySemantics::ImageMemory;
414 return SPIRV::MemorySemantics::None;
421 return SPIRV::MemorySemantics::Acquire;
423 return SPIRV::MemorySemantics::Release;
425 return SPIRV::MemorySemantics::AcquireRelease;
427 return SPIRV::MemorySemantics::SequentiallyConsistent;
431 return SPIRV::MemorySemantics::None;
443 Ctx.getOrInsertSyncScopeID(
"subgroup");
445 Ctx.getOrInsertSyncScopeID(
"workgroup");
447 Ctx.getOrInsertSyncScopeID(
"device");
450 return SPIRV::Scope::Invocation;
452 return SPIRV::Scope::CrossDevice;
453 else if (Id == SubGroup)
454 return SPIRV::Scope::Subgroup;
455 else if (Id == WorkGroup)
456 return SPIRV::Scope::Workgroup;
457 else if (Id == Device)
458 return SPIRV::Scope::Device;
459 return SPIRV::Scope::CrossDevice;
466 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
470 if (GI->is(Intrinsic::spv_track_constant)) {
474 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
477 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
478 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
487 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
488 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
493 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
494 return MI->getOperand(1).getCImm()->getSExtValue();
499 return GI->is(IntrinsicID);
509 if (
N->getNumOperands() <=
I)
517 return MangledName ==
"__enqueue_kernel_basic" ||
518 MangledName ==
"__enqueue_kernel_basic_events" ||
519 MangledName ==
"__enqueue_kernel_varargs" ||
520 MangledName ==
"__enqueue_kernel_events_varargs";
524 return MangledName ==
"__get_kernel_work_group_size_impl" ||
525 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
526 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
527 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
531 if (!Name.starts_with(
"__"))
536 Name ==
"__translate_sampler_initializer";
541 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
542 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
543 bool IsMangled = Name.starts_with(
"_Z");
546 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
551 std::string Result = DemangledName;
560 size_t Start, Len = 0;
561 size_t DemangledNameLenStart = 2;
562 if (Name.starts_with(
"_ZN")) {
564 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
566 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
567 return std::string();
568 DemangledNameLenStart = NameSpaceStart + 11;
570 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
571 bool Error = Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
572 .getAsInteger(10, Len);
574 return std::string();
575 return Name.substr(Start, Len).str();
579 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
580 Name.starts_with(
"spirv."))
602 if (
F.getFnAttribute(
"hlsl.shader").isValid())
609 TypeName.consume_front(
"atomic_");
610 if (TypeName.consume_front(
"void"))
612 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
614 else if (TypeName.consume_front(
"char") ||
615 TypeName.consume_front(
"signed char") ||
616 TypeName.consume_front(
"unsigned char") ||
617 TypeName.consume_front(
"uchar"))
619 else if (TypeName.consume_front(
"short") ||
620 TypeName.consume_front(
"signed short") ||
621 TypeName.consume_front(
"unsigned short") ||
622 TypeName.consume_front(
"ushort"))
624 else if (TypeName.consume_front(
"int") ||
625 TypeName.consume_front(
"signed int") ||
626 TypeName.consume_front(
"unsigned int") ||
627 TypeName.consume_front(
"uint"))
629 else if (TypeName.consume_front(
"long") ||
630 TypeName.consume_front(
"signed long") ||
631 TypeName.consume_front(
"unsigned long") ||
632 TypeName.consume_front(
"ulong"))
634 else if (TypeName.consume_front(
"half") ||
635 TypeName.consume_front(
"_Float16") ||
636 TypeName.consume_front(
"__fp16"))
638 else if (TypeName.consume_front(
"float"))
640 else if (TypeName.consume_front(
"double"))
647SmallPtrSet<BasicBlock *, 0>
648PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
649 std::queue<BasicBlock *> ToVisit;
652 SmallPtrSet<BasicBlock *, 0> Output;
653 while (ToVisit.size() != 0) {
654 BasicBlock *BB = ToVisit.front();
657 if (Output.count(BB) != 0)
671bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
674 if (DT.dominates(BB,
P))
678 if (BlockToOrder.count(
P) == 0)
683 Loop *
L = LI.getLoopFor(
P);
684 if (L ==
nullptr ||
L->contains(BB))
690 assert(
L->getNumBackEdges() <= 1);
696 if (Latch ==
nullptr)
700 if (BlockToOrder.count(Latch) == 0)
708 auto It = BlockToOrder.find(BB);
709 if (It != BlockToOrder.end())
710 return It->second.Rank;
715 if (DT.dominates(BB,
P))
718 auto Iterator = BlockToOrder.end();
719 Loop *L = LI.getLoopFor(
P);
720 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
724 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
725 Iterator = BlockToOrder.find(
P);
730 Iterator = BlockToOrder.find(Latch);
733 assert(Iterator != BlockToOrder.end());
734 result = std::max(result, Iterator->second.Rank + 1);
740size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
744 size_t QueueIndex = 0;
745 while (ToVisit.size() != 0) {
749 if (!CanBeVisited(BB)) {
751 if (QueueIndex >= ToVisit.size())
753 "No valid candidate in the queue. Is the graph reducible?");
760 OrderInfo Info = {Rank, BlockToOrder.
size()};
761 BlockToOrder.try_emplace(BB, Info);
764 if (Queued.count(S) != 0)
778 visit(&*
F.begin(), 0);
780 Order.reserve(
F.size());
781 for (
auto &[BB, Info] : BlockToOrder)
782 Order.emplace_back(BB);
791 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
792 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
793 if (InfoLHS.Rank != InfoRHS.Rank)
794 return InfoLHS.Rank < InfoRHS.Rank;
795 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
801 assert(BlockToOrder.count(&Start) != 0);
804 auto It = Order.begin();
805 while (It != Order.end() && *It != &Start)
810 assert(It != Order.end());
813 std::optional<size_t> EndRank = std::nullopt;
814 for (; It != Order.end(); ++It) {
815 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
818 if (Reachable.count(*It) == 0) {
823 EndRank = BlockToOrder[*It].Rank;
833 std::vector<BasicBlock *> Order;
834 Order.reserve(
F.size());
839 assert(&*
F.begin() == Order[0]);
842 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
855 F.begin()->getFirstInsertionPt());
865 return TargetToValue.
lookup(BI->getSuccessor());
868 Builder.SetInsertPoint(
T);
874 if (
LHS ==
nullptr ||
RHS ==
nullptr)
876 return Builder.CreateSelect(BI->getCondition(),
LHS,
RHS);
885 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
893 constexpr unsigned MaxIters = 1024;
894 for (
unsigned I = 0;
I < MaxIters; ++
I) {
895 std::string OrdName = Name +
Twine(
I).
str();
896 if (!M.getFunction(OrdName)) {
897 Name = std::move(OrdName);
923 SPIRV::AccessQualifier::AccessQualifier AccessQual,
924 bool EmitIR,
bool Force) {
927 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
953 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
963 Args.push_back(Arg2);
966 return B.CreateIntrinsicWithoutFolding(IntrID, {Types}, Args);
971 if (Ty->isPtrOrPtrVectorTy())
976 for (
const Type *ArgTy : RefTy->params())
989 if (
F->getName().starts_with(
"llvm.spv."))
996SmallVector<MachineInstr *, 4>
998 unsigned MinWC,
unsigned ContinuedOpcode,
1003 constexpr unsigned MaxWordCount = UINT16_MAX;
1004 const size_t NumElements = Args.size();
1005 size_t MaxNumElements = MaxWordCount - MinWC;
1006 size_t SPIRVStructNumElements = NumElements;
1008 if (NumElements > MaxNumElements) {
1011 SPIRVStructNumElements = MaxNumElements;
1012 MaxNumElements = MaxWordCount - 1;
1018 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1021 Instructions.push_back(MIB.getInstr());
1023 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1024 I += MaxNumElements) {
1025 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
1026 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1028 Instructions.push_back(MIB.getInstr());
1030 return Instructions;
1033SmallVector<unsigned, 1>
1035 unsigned LC = SPIRV::LoopControl::None;
1039 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
1041 LC |= SPIRV::LoopControl::DontUnroll;
1045 LC |= SPIRV::LoopControl::Unroll;
1051 unsigned Count = CI->getZExtValue();
1053 LC |= SPIRV::LoopControl::PartialCount;
1054 MaskToValueMap.emplace_back(
1055 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1061 for (
auto &[Mask, Val] : MaskToValueMap)
1062 Result.push_back(Val);
1072 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1073 TargetOpcode::G_ADD,
1074 TargetOpcode::G_FADD,
1075 TargetOpcode::G_STRICT_FADD,
1076 TargetOpcode::G_SUB,
1077 TargetOpcode::G_FSUB,
1078 TargetOpcode::G_STRICT_FSUB,
1079 TargetOpcode::G_MUL,
1080 TargetOpcode::G_FMUL,
1081 TargetOpcode::G_STRICT_FMUL,
1082 TargetOpcode::G_SDIV,
1083 TargetOpcode::G_UDIV,
1084 TargetOpcode::G_FDIV,
1085 TargetOpcode::G_STRICT_FDIV,
1086 TargetOpcode::G_SREM,
1087 TargetOpcode::G_UREM,
1088 TargetOpcode::G_FREM,
1089 TargetOpcode::G_STRICT_FREM,
1090 TargetOpcode::G_FNEG,
1091 TargetOpcode::G_CONSTANT,
1092 TargetOpcode::G_FCONSTANT,
1093 TargetOpcode::G_AND,
1095 TargetOpcode::G_XOR,
1096 TargetOpcode::G_SHL,
1097 TargetOpcode::G_ASHR,
1098 TargetOpcode::G_LSHR,
1099 TargetOpcode::G_SELECT,
1100 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1103 return TypeFoldingSupportingOpcs;
1112 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1113 Def->getOpcode() == TargetOpcode::COPY)
1114 ? MRI->
getVRegDef(Def->getOperand(1).getReg())
1126 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1127 Def->getOpcode() == SPIRV::OpConstantI)
1135 if (Def->getOpcode() == SPIRV::OpConstantI)
1136 return Def->getOperand(2).getImm();
1137 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1138 return Def->getOperand(1).getCImm()->getZExtValue();
1151 if (Ty->getStructNumElements() != 2)
1166 if (T_in_struct != SecondElement)
1169 auto *Padding_in_struct =
1171 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1175 TotalSize = ArraySize + 1;
1176 OriginalElementType = ArrayElementType;
1181 if (!Ty->isStructTy())
1185 Type *OriginalElementType =
nullptr;
1195 for (
Type *ElementTy : STy->elements()) {
1197 if (NewElementTy != ElementTy)
1199 NewElementTypes.
push_back(NewElementTy);
1206 if (STy->isLiteral())
1211 NewTy->setBody(NewElementTypes, STy->isPacked());
1217std::optional<SPIRV::LinkageType::LinkageType>
1220 return std::nullopt;
1226 if (SC == SPIRV::StorageClass::Input ||
1227 SC == SPIRV::StorageClass::Output ||
1228 SC == SPIRV::StorageClass::PushConstant)
1229 return std::nullopt;
1231 return SPIRV::LinkageType::Import;
1235 return std::nullopt;
1238 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1239 return SPIRV::LinkageType::LinkOnceODR;
1242 ST.canUseExtension(SPIRV::Extension::SPV_AMD_weak_linkage))
1243 return SPIRV::LinkageType::WeakAMD;
1245 return SPIRV::LinkageType::Export;
1252 "cannot allocate a name for the internal service function");
1254 if (SF->getInstructionCount() > 0)
1256 "Unexpected combination of global variables and function pointers");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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
#define SPIRV_BACKEND_SERVICE_FUN_NAME
Class for arbitrary precision integers.
an instruction to allocate memory on the stack
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
LLVM_ABI void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
const Instruction & front() const
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
FunctionType * getFunctionType() const
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, bytes 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...
A parsed version of the target data layout string in and methods for querying it.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
Lightweight error class with error context and mandatory checking.
Class to represent function types.
ArrayRef< Type * > params() const
Type * getReturnType() const
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const Function & getFunction() const
bool hasLocalLinkage() const
bool hasHiddenVisibility() const
bool isDeclarationForLinker() const
bool hasWeakLinkage() const
bool hasLinkOnceODRLinkage() const
@ PrivateLinkage
Like Internal, but omit from symbol table.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
constexpr bool isValid() const
This is an important class for using LLVM in a threaded context.
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.
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 & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void setAsmPrinterFlag(AsmPrinterFlagTy 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,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
A Module instance is used to store all the information related to an LLVM module.
NamedMDNode * getNamedMetadata(StringRef Name) const
Return the first NamedMDNode in the module with the specified name.
iterator_range< op_iterator > operands()
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(SPIRVTypeInst Type, Register VReg, const MachineFunction &MF)
const TargetRegisterClass * getRegClass(SPIRVTypeInst SpvType) const
LLT getRegType(SPIRVTypeInst SpvType) const
SPIRVTypeInst getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
bool canUseExtension(SPIRV::Extension::Extension E) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
constexpr bool empty() const
Check if the string is empty.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
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 IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI Type * getStructElementType(unsigned N) const
bool isArrayTy() const
True if this is an instance of ArrayType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Type * getArrayElementType() const
LLVM_ABI unsigned getStructNumElements() const
LLVM_ABI uint64_t getArrayNumElements() const
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isStructTy() const
True if this is an instance of StructType.
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(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.
static StringRef extractAsmConstraintsFromMetadata(NamedMDNode *NMD, StringRef Constraints, StringRef Name)
bool isPipeOrAddressSpaceCastBuiltin(StringRef Name)
Returns true if Name is a pipe or address-space-cast OpenCL builtin.
FunctionType * getOriginalFunctionType(const Function &F)
static std::optional< StringRef > getMutatedCallsiteKey(const CallBase &CB)
static FunctionType * extractFunctionTypeFromMetadata(NamedMDNode *NMD, FunctionType *FTy, StringRef Name)
StringRef getOriginalAsmConstraints(const CallBase &CB)
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
@ System
Synchronized with respect to all concurrently executing threads.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
This is an optimization pass for GlobalISel generic memory operations.
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
void addStringImm(StringRef Str, MCInst &Inst)
MachineBasicBlock::iterator getOpVariableMBBIt(MachineFunction &MF)
int64_t getIConstValSext(Register ConstReg, const MachineRegisterInfo *MRI)
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.
bool isTypeFoldingSupported(unsigned Opcode)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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)
bool matchPeeledArrayPattern(const StructType *Ty, Type *&OriginalElementType, uint64_t &TotalSize)
Register createVirtualRegister(SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
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)
AllocaInst * createVariable(Function &F, Type *Type)
static bool getVacantFunctionName(Module &M, std::string &Name)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
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)
bool isNestedPointer(const Type *Ty)
Function * getOrCreateBackendServiceFunction(Module &M)
MetadataAsValue * buildMD(Value *Arg)
std::string getOclOrSpirvBuiltinDemangledName(StringRef Name)
void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder)
static void finishBuildOpDecorate(MachineInstrBuilder &MIB, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
SmallVector< unsigned, 1 > getSpirvLoopControlOperandsFromLoopMetadata(MDNode *LoopMD)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
static uint32_t convertCharsToWord(StringRef Str, unsigned i)
void sort(IteratorTy Start, IteratorTy End)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
Type * toTypedPointer(Type *Ty)
ConstantInt * getMDOperandAsConstInt(const MDNode *N, unsigned I)
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,...
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
bool isSpecialOpaqueType(const Type *Ty)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
void setRegClassType(Register Reg, SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
static bool isNonMangledOCLBuiltin(StringRef Name)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
MachineInstr * passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
std::optional< SPIRV::LinkageType::LinkageType > getSpirvLinkageTypeFor(const SPIRVSubtarget &ST, const GlobalValue &GV)
bool isEntryPoint(const Function &F)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
const std::set< unsigned > & getTypeFoldingSupportedOpcodes()
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
AtomicOrdering
Atomic ordering for LLVM's memory model.
SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id)
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
static bool isEnqueueKernelBI(StringRef MangledName)
static bool isKernelQueryBI(StringRef MangledName)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD, const SPIRVSubtarget &ST)
std::string getStringValueFromReg(Register Reg, MachineRegisterInfo &MRI)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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)
Value * createExitVariable(BasicBlock *BB, const DenseMap< BasicBlock *, ConstantInt * > &TargetToValue)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool hasBuiltinTypePrefix(StringRef Name)
Type * getMDOperandAsType(const MDNode *N, unsigned I)
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
auto predecessors(const MachineBasicBlock *BB)
static size_t getPaddedLen(StringRef Str)
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
Type * reconstitutePeeledArrayType(Type *Ty)
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)
LLVM_ABI MDNode * findOptionMDForLoopID(MDNode *LoopID, StringRef Name)
Find and return the loop attribute node for the attribute Name in LoopID.