28#include "llvm/IR/IntrinsicsSPIRV.h"
37 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
38 return MDS->getString() == Name;
41 return It == NMD->
op_end() ? nullptr : *It;
63 assert(MD &&
"MDNode operand is expected");
67 assert(CMeta &&
"ConstantAsMetadata operand is expected");
68 int64_t Idx = Const->getSExtValue();
72 RetTy = CMeta->getType();
75 if (Idx >= 0 &&
static_cast<uint64_t>(Idx) < PTys.
size()) {
76 PTys[Idx] = CMeta->getType();
98 assert(MD &&
"MDNode operand is expected");
101 Constraints = MDS->getString();
108 F.getParent()->getNamedMetadata(
"spv.cloned_funcs"),
F.getFunctionType(),
115 if (MD->getNumOperands() > 0)
117 return MDS->getString();
148 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
149 unsigned StrIndex = i + WordIndex;
151 if (StrIndex < Str.size()) {
152 CharToAdd = Str[StrIndex];
154 Word |= (CharToAdd << (WordIndex * 8));
164 for (
unsigned i = 0; i < PaddedLen; i += 4) {
172 for (
unsigned i = 0; i < PaddedLen; i += 4) {
184 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
185 "Expected G_GLOBAL_VALUE");
186 const GlobalValue *GV = Def->getOperand(1).getGlobal();
193 const auto Bitwidth = Imm.getBitWidth();
196 else if (Bitwidth <= 32) {
197 MIB.
addImm(Imm.getZExtValue());
202 }
else if (Bitwidth <= 64) {
203 uint64_t FullImm = Imm.getZExtValue();
211 for (
unsigned I = 0;
I < NumWords; ++
I) {
212 unsigned LimbIdx =
I / 2;
213 unsigned LimbShift = (
I % 2) * 32;
214 uint32_t Word = (Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
233 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
244 for (
const auto &DecArg : DecArgs)
249 SPIRV::Decoration::Decoration Dec,
251 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
258 SPIRV::Decoration::Decoration Dec,
261 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
268 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
270 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
283 if (OpMD->getNumOperands() == 0)
289 "element of the decoration");
299 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
301 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
305 if (Dec ==
static_cast<uint32_t>(SPIRV::Decoration::UniformId)) {
311 "Expect Scope <id> operand of the UniformId decoration");
316 ScopeV->
getZExtValue(), MIRBuilder, SpvTypeInt32,
false);
324 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
327 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
342 switch (
MI.getOpcode()) {
343 case SPIRV::OpFunction:
344 case SPIRV::OpFunctionParameter:
346 case SPIRV::ASSIGN_TYPE:
353 while (VarPos !=
MBB.end() && VarPos->getOpcode() != SPIRV::OpFunction)
356 while (VarPos !=
MBB.end() && IsPreamble(*VarPos))
363 if (
I ==
MBB->begin())
366 while (
I->isTerminator() ||
I->isDebugValue()) {
367 if (
I ==
MBB->begin())
374SPIRV::StorageClass::StorageClass
378 return SPIRV::StorageClass::Function;
380 return SPIRV::StorageClass::CrossWorkgroup;
382 return SPIRV::StorageClass::UniformConstant;
384 return SPIRV::StorageClass::Workgroup;
386 return SPIRV::StorageClass::Generic;
388 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
389 ? SPIRV::StorageClass::DeviceOnlyINTEL
390 : SPIRV::StorageClass::CrossWorkgroup;
392 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
393 ? SPIRV::StorageClass::HostOnlyINTEL
394 : SPIRV::StorageClass::CrossWorkgroup;
396 return SPIRV::StorageClass::Input;
398 return SPIRV::StorageClass::Output;
400 return SPIRV::StorageClass::CodeSectionINTEL;
402 return SPIRV::StorageClass::Private;
404 return SPIRV::StorageClass::StorageBuffer;
406 return SPIRV::StorageClass::Uniform;
408 return SPIRV::StorageClass::PushConstant;
414SPIRV::MemorySemantics::MemorySemantics
417 case SPIRV::StorageClass::StorageBuffer:
418 case SPIRV::StorageClass::Uniform:
419 return SPIRV::MemorySemantics::UniformMemory;
420 case SPIRV::StorageClass::Workgroup:
421 return SPIRV::MemorySemantics::WorkgroupMemory;
422 case SPIRV::StorageClass::CrossWorkgroup:
423 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
424 case SPIRV::StorageClass::AtomicCounter:
425 return SPIRV::MemorySemantics::AtomicCounterMemory;
426 case SPIRV::StorageClass::Image:
427 return SPIRV::MemorySemantics::ImageMemory;
429 return SPIRV::MemorySemantics::None;
436 return SPIRV::MemorySemantics::Acquire;
438 return SPIRV::MemorySemantics::Release;
440 return SPIRV::MemorySemantics::AcquireRelease;
442 return SPIRV::MemorySemantics::SequentiallyConsistent;
446 return SPIRV::MemorySemantics::None;
458 Ctx.getOrInsertSyncScopeID(
"subgroup");
460 Ctx.getOrInsertSyncScopeID(
"workgroup");
462 Ctx.getOrInsertSyncScopeID(
"device");
465 return SPIRV::Scope::Invocation;
467 return SPIRV::Scope::CrossDevice;
468 else if (Id == SubGroup)
469 return SPIRV::Scope::Subgroup;
470 else if (Id == WorkGroup)
471 return SPIRV::Scope::Workgroup;
472 else if (Id == Device)
473 return SPIRV::Scope::Device;
474 return SPIRV::Scope::CrossDevice;
481 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
485 if (GI->is(Intrinsic::spv_track_constant)) {
489 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
492 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
493 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
502 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
503 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
508 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
509 return MI->getOperand(1).getCImm()->getSExtValue();
514 return GI->is(IntrinsicID);
524 if (
N->getNumOperands() <=
I)
532 return MangledName ==
"__enqueue_kernel_basic" ||
533 MangledName ==
"__enqueue_kernel_basic_events" ||
534 MangledName ==
"__enqueue_kernel_varargs" ||
535 MangledName ==
"__enqueue_kernel_events_varargs";
539 return MangledName ==
"__get_kernel_work_group_size_impl" ||
540 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
541 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
542 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
546 if (!Name.starts_with(
"__"))
551 Name ==
"__translate_sampler_initializer";
556 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
557 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
558 bool IsMangled = Name.starts_with(
"_Z");
561 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
566 std::string Result = DemangledName;
575 size_t Start, Len = 0;
576 size_t DemangledNameLenStart = 2;
577 if (Name.starts_with(
"_ZN")) {
579 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
581 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
582 return std::string();
583 DemangledNameLenStart = NameSpaceStart + 11;
585 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
586 bool Error = Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
587 .getAsInteger(10, Len);
589 return std::string();
590 return Name.substr(Start, Len).str();
594 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
595 Name.starts_with(
"spirv."))
617 if (
F.getFnAttribute(
"hlsl.shader").isValid())
624 TypeName.consume_front(
"atomic_");
625 if (TypeName.consume_front(
"void"))
627 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
629 else if (TypeName.consume_front(
"char") ||
630 TypeName.consume_front(
"signed char") ||
631 TypeName.consume_front(
"unsigned char") ||
632 TypeName.consume_front(
"uchar"))
634 else if (TypeName.consume_front(
"short") ||
635 TypeName.consume_front(
"signed short") ||
636 TypeName.consume_front(
"unsigned short") ||
637 TypeName.consume_front(
"ushort"))
639 else if (TypeName.consume_front(
"int") ||
640 TypeName.consume_front(
"signed int") ||
641 TypeName.consume_front(
"unsigned int") ||
642 TypeName.consume_front(
"uint"))
644 else if (TypeName.consume_front(
"long") ||
645 TypeName.consume_front(
"signed long") ||
646 TypeName.consume_front(
"unsigned long") ||
647 TypeName.consume_front(
"ulong"))
649 else if (TypeName.consume_front(
"half") ||
650 TypeName.consume_front(
"_Float16") ||
651 TypeName.consume_front(
"__fp16"))
653 else if (TypeName.consume_front(
"float"))
655 else if (TypeName.consume_front(
"double"))
662SmallPtrSet<BasicBlock *, 0>
663PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
664 std::queue<BasicBlock *> ToVisit;
667 SmallPtrSet<BasicBlock *, 0> Output;
668 while (ToVisit.size() != 0) {
669 BasicBlock *BB = ToVisit.front();
672 if (Output.count(BB) != 0)
686bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
689 if (DT.dominates(BB,
P))
693 if (BlockToOrder.count(
P) == 0)
698 Loop *
L = LI.getLoopFor(
P);
699 if (L ==
nullptr ||
L->contains(BB))
705 assert(
L->getNumBackEdges() <= 1);
711 if (Latch ==
nullptr)
715 if (BlockToOrder.count(Latch) == 0)
723 auto It = BlockToOrder.find(BB);
724 if (It != BlockToOrder.end())
725 return It->second.Rank;
730 if (DT.dominates(BB,
P))
733 auto Iterator = BlockToOrder.end();
734 Loop *L = LI.getLoopFor(
P);
735 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
739 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
740 Iterator = BlockToOrder.find(
P);
745 Iterator = BlockToOrder.find(Latch);
748 assert(Iterator != BlockToOrder.end());
749 result = std::max(result, Iterator->second.Rank + 1);
755size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
759 size_t QueueIndex = 0;
760 while (ToVisit.size() != 0) {
764 if (!CanBeVisited(BB)) {
766 if (QueueIndex >= ToVisit.size())
768 "No valid candidate in the queue. Is the graph reducible?");
775 OrderInfo Info = {Rank, BlockToOrder.
size()};
776 BlockToOrder.try_emplace(BB, Info);
779 if (Queued.count(S) != 0)
793 visit(&*
F.begin(), 0);
795 Order.reserve(
F.size());
796 for (
auto &[BB, Info] : BlockToOrder)
797 Order.emplace_back(BB);
806 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
807 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
808 if (InfoLHS.Rank != InfoRHS.Rank)
809 return InfoLHS.Rank < InfoRHS.Rank;
810 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
816 assert(BlockToOrder.count(&Start) != 0);
819 auto It = Order.begin();
820 while (It != Order.end() && *It != &Start)
825 assert(It != Order.end());
828 std::optional<size_t> EndRank = std::nullopt;
829 for (; It != Order.end(); ++It) {
830 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
833 if (Reachable.count(*It) == 0) {
838 EndRank = BlockToOrder[*It].Rank;
848 std::vector<BasicBlock *> Order;
849 Order.reserve(
F.size());
854 assert(&*
F.begin() == Order[0]);
857 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
870 F.begin()->getFirstInsertionPt());
880 return TargetToValue.
lookup(BI->getSuccessor());
883 Builder.SetInsertPoint(
T);
889 if (
LHS ==
nullptr ||
RHS ==
nullptr)
891 return Builder.CreateSelect(BI->getCondition(),
LHS,
RHS);
900 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
908 constexpr unsigned MaxIters = 1024;
909 for (
unsigned I = 0;
I < MaxIters; ++
I) {
910 std::string OrdName = Name +
Twine(
I).
str();
911 if (!M.getFunction(OrdName)) {
912 Name = std::move(OrdName);
938 SPIRV::AccessQualifier::AccessQualifier AccessQual,
939 bool EmitIR,
bool Force) {
942 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
968 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
978 Args.push_back(Arg2);
981 return B.CreateIntrinsicWithoutFolding(IntrID, {Types}, Args);
986 if (Ty->isPtrOrPtrVectorTy())
991 for (
const Type *ArgTy : RefTy->params())
1004 if (
F->getName().starts_with(
"llvm.spv."))
1011SmallVector<MachineInstr *, 4>
1013 unsigned MinWC,
unsigned ContinuedOpcode,
1018 constexpr unsigned MaxWordCount = UINT16_MAX;
1019 const size_t NumElements = Args.size();
1020 size_t MaxNumElements = MaxWordCount - MinWC;
1021 size_t SPIRVStructNumElements = NumElements;
1023 if (NumElements > MaxNumElements) {
1026 SPIRVStructNumElements = MaxNumElements;
1027 MaxNumElements = MaxWordCount - 1;
1033 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1036 Instructions.push_back(MIB.getInstr());
1038 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1039 I += MaxNumElements) {
1040 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
1041 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1043 Instructions.push_back(MIB.getInstr());
1045 return Instructions;
1048SmallVector<unsigned, 1>
1050 unsigned LC = SPIRV::LoopControl::None;
1054 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
1056 LC |= SPIRV::LoopControl::DontUnroll;
1060 LC |= SPIRV::LoopControl::Unroll;
1066 unsigned Count = CI->getZExtValue();
1068 LC |= SPIRV::LoopControl::PartialCount;
1069 MaskToValueMap.emplace_back(
1070 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1076 for (
auto &[Mask, Val] : MaskToValueMap)
1077 Result.push_back(Val);
1087 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1088 TargetOpcode::G_ADD,
1089 TargetOpcode::G_FADD,
1090 TargetOpcode::G_STRICT_FADD,
1091 TargetOpcode::G_SUB,
1092 TargetOpcode::G_FSUB,
1093 TargetOpcode::G_STRICT_FSUB,
1094 TargetOpcode::G_MUL,
1095 TargetOpcode::G_FMUL,
1096 TargetOpcode::G_STRICT_FMUL,
1097 TargetOpcode::G_SDIV,
1098 TargetOpcode::G_UDIV,
1099 TargetOpcode::G_FDIV,
1100 TargetOpcode::G_STRICT_FDIV,
1101 TargetOpcode::G_SREM,
1102 TargetOpcode::G_UREM,
1103 TargetOpcode::G_FREM,
1104 TargetOpcode::G_STRICT_FREM,
1105 TargetOpcode::G_FNEG,
1106 TargetOpcode::G_CONSTANT,
1107 TargetOpcode::G_FCONSTANT,
1108 TargetOpcode::G_AND,
1110 TargetOpcode::G_XOR,
1111 TargetOpcode::G_SHL,
1112 TargetOpcode::G_ASHR,
1113 TargetOpcode::G_LSHR,
1114 TargetOpcode::G_SELECT,
1115 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1118 return TypeFoldingSupportingOpcs;
1127 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1128 Def->getOpcode() == TargetOpcode::COPY)
1129 ? MRI->
getVRegDef(Def->getOperand(1).getReg())
1141 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1142 Def->getOpcode() == SPIRV::OpConstantI)
1150 if (Def->getOpcode() == SPIRV::OpConstantI)
1151 return Def->getOperand(2).getImm();
1152 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1153 return Def->getOperand(1).getCImm()->getZExtValue();
1166 if (Ty->getStructNumElements() != 2)
1181 if (T_in_struct != SecondElement)
1184 auto *Padding_in_struct =
1186 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1190 TotalSize = ArraySize + 1;
1191 OriginalElementType = ArrayElementType;
1196 if (!Ty->isStructTy())
1200 Type *OriginalElementType =
nullptr;
1210 for (
Type *ElementTy : STy->elements()) {
1212 if (NewElementTy != ElementTy)
1214 NewElementTypes.
push_back(NewElementTy);
1221 if (STy->isLiteral())
1226 NewTy->setBody(NewElementTypes, STy->isPacked());
1232std::optional<SPIRV::LinkageType::LinkageType>
1235 return std::nullopt;
1241 if (SC == SPIRV::StorageClass::Input ||
1242 SC == SPIRV::StorageClass::Output ||
1243 SC == SPIRV::StorageClass::PushConstant)
1244 return std::nullopt;
1246 return SPIRV::LinkageType::Import;
1250 return std::nullopt;
1253 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1254 return SPIRV::LinkageType::LinkOnceODR;
1257 ST.canUseExtension(SPIRV::Extension::SPV_AMD_weak_linkage))
1258 return SPIRV::LinkageType::WeakAMD;
1260 return SPIRV::LinkageType::Export;
1267 "cannot allocate a name for the internal service function");
1269 if (SF->getInstructionCount() > 0)
1271 "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
SPIRVTypeInst getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
LLT getRegType(SPIRVTypeInst SpvType) const
SPIRVTypeInst getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVTypeInst SpvType, bool EmitIR, bool ZeroAsNull=true)
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
unsigned getNumOperands() 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.
static MDNode * findNamedMDOperand(NamedMDNode *NMD, StringRef Name)
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)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
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.