28#include "llvm/IR/IntrinsicsSPIRV.h"
38 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
39 return MDS->getString() == Name;
42 return It == NMD->
op_end() ? nullptr : *It;
64 assert(MD &&
"MDNode operand is expected");
68 assert(CMeta &&
"ConstantAsMetadata operand is expected");
69 int64_t Idx = Const->getSExtValue();
73 RetTy = CMeta->getType();
76 if (Idx >= 0 &&
static_cast<uint64_t>(Idx) < PTys.
size()) {
77 PTys[Idx] = CMeta->getType();
99 assert(MD &&
"MDNode operand is expected");
102 Constraints = MDS->getString();
109 F.getParent()->getNamedMetadata(
"spv.cloned_funcs"),
F.getFunctionType(),
116 if (MD->getNumOperands() > 0)
118 return MDS->getString();
149 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
150 unsigned StrIndex = i + WordIndex;
152 if (StrIndex < Str.size()) {
153 CharToAdd = Str[StrIndex];
155 Word |= (CharToAdd << (WordIndex * 8));
165 for (
unsigned i = 0; i < PaddedLen; i += 4) {
173 for (
unsigned i = 0; i < PaddedLen; i += 4) {
185 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
186 "Expected G_GLOBAL_VALUE");
187 const GlobalValue *GV = Def->getOperand(1).getGlobal();
194 const auto Bitwidth =
Imm.getBitWidth();
197 else if (Bitwidth <= 32) {
203 }
else if (Bitwidth <= 64) {
212 for (
unsigned I = 0;
I < NumWords; ++
I) {
213 unsigned LimbIdx =
I / 2;
214 unsigned LimbShift = (
I % 2) * 32;
215 uint32_t Word = (
Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
234 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
245 for (
const auto &DecArg : DecArgs)
250 SPIRV::Decoration::Decoration Dec,
252 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
259 SPIRV::Decoration::Decoration Dec,
262 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
269 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
271 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
284 if (OpMD->getNumOperands() == 0)
290 "element of the decoration");
300 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
302 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
306 if (Dec ==
static_cast<uint32_t>(SPIRV::Decoration::UniformId)) {
312 "Expect Scope <id> operand of the UniformId decoration");
317 ScopeV->
getZExtValue(), MIRBuilder, SpvTypeInt32,
false);
325 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
328 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
343 switch (
MI.getOpcode()) {
344 case SPIRV::OpFunction:
345 case SPIRV::OpFunctionParameter:
347 case SPIRV::ASSIGN_TYPE:
354 while (VarPos !=
MBB.end() && VarPos->getOpcode() != SPIRV::OpFunction)
357 while (VarPos !=
MBB.end() && IsPreamble(*VarPos))
364 if (
I ==
MBB->begin())
367 while (
I->isTerminator() ||
I->isDebugValue()) {
368 if (
I ==
MBB->begin())
375SPIRV::StorageClass::StorageClass
379 return SPIRV::StorageClass::Function;
381 return SPIRV::StorageClass::CrossWorkgroup;
383 return SPIRV::StorageClass::UniformConstant;
385 return SPIRV::StorageClass::Workgroup;
387 return SPIRV::StorageClass::Generic;
389 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
390 ? SPIRV::StorageClass::DeviceOnlyINTEL
391 : SPIRV::StorageClass::CrossWorkgroup;
393 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
394 ? SPIRV::StorageClass::HostOnlyINTEL
395 : SPIRV::StorageClass::CrossWorkgroup;
397 return SPIRV::StorageClass::Input;
399 return SPIRV::StorageClass::Output;
401 return SPIRV::StorageClass::CodeSectionINTEL;
403 return SPIRV::StorageClass::Private;
405 return SPIRV::StorageClass::StorageBuffer;
407 return SPIRV::StorageClass::Uniform;
409 return SPIRV::StorageClass::PushConstant;
415SPIRV::MemorySemantics::MemorySemantics
418 case SPIRV::StorageClass::StorageBuffer:
419 case SPIRV::StorageClass::Uniform:
420 return SPIRV::MemorySemantics::UniformMemory;
421 case SPIRV::StorageClass::Workgroup:
422 return SPIRV::MemorySemantics::WorkgroupMemory;
423 case SPIRV::StorageClass::CrossWorkgroup:
424 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
425 case SPIRV::StorageClass::Generic:
426 return SPIRV::MemorySemantics::MemorySemantics(
427 SPIRV::MemorySemantics::WorkgroupMemory |
428 SPIRV::MemorySemantics::CrossWorkgroupMemory);
429 case SPIRV::StorageClass::AtomicCounter:
430 return SPIRV::MemorySemantics::AtomicCounterMemory;
431 case SPIRV::StorageClass::Image:
432 return SPIRV::MemorySemantics::ImageMemory;
434 return SPIRV::MemorySemantics::None;
441 return SPIRV::MemorySemantics::Acquire;
443 return SPIRV::MemorySemantics::Release;
445 return SPIRV::MemorySemantics::AcquireRelease;
447 return SPIRV::MemorySemantics::SequentiallyConsistent;
451 return SPIRV::MemorySemantics::None;
458 bool DropStorageClass =
460 OrderSem ==
static_cast<uint32_t>(SPIRV::MemorySemantics::None);
461 return OrderSem | (DropStorageClass ? 0 : StorageClassSem);
479 return SPIRV::Scope::Invocation;
481 return SPIRV::Scope::CrossDevice;
482 else if (Id == SubGroup)
483 return SPIRV::Scope::Subgroup;
484 else if (Id == WorkGroup)
485 return SPIRV::Scope::Workgroup;
487 return SPIRV::Scope::Device;
488 return SPIRV::Scope::CrossDevice;
495 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
499 if (GI->is(Intrinsic::spv_track_constant)) {
503 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
506 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
507 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
516 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
517 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
522 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
523 return MI->getOperand(1).getCImm()->getSExtValue();
528 return GI->is(IntrinsicID);
538 if (
N->getNumOperands() <=
I)
546 return MangledName ==
"__enqueue_kernel_basic" ||
547 MangledName ==
"__enqueue_kernel_basic_events" ||
548 MangledName ==
"__enqueue_kernel_varargs" ||
549 MangledName ==
"__enqueue_kernel_events_varargs";
553 return MangledName ==
"__get_kernel_work_group_size_impl" ||
554 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
555 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
556 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
560 if (!Name.starts_with(
"__"))
565 Name ==
"__translate_sampler_initializer";
570 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
571 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
572 bool IsMangled = Name.starts_with(
"_Z");
575 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
580 std::string Result = DemangledName;
589 size_t Start, Len = 0;
590 size_t DemangledNameLenStart = 2;
591 if (Name.starts_with(
"_ZN")) {
593 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
595 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
596 return std::string();
597 DemangledNameLenStart = NameSpaceStart + 11;
599 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
600 bool Error = Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
601 .getAsInteger(10, Len);
603 return std::string();
604 return Name.substr(Start, Len).str();
608 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
609 Name.starts_with(
"spirv."))
631 if (
F.getFnAttribute(
"hlsl.shader").isValid())
638 TypeName.consume_front(
"atomic_");
639 if (TypeName.consume_front(
"void"))
641 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
643 else if (TypeName.consume_front(
"char") ||
644 TypeName.consume_front(
"signed char") ||
645 TypeName.consume_front(
"unsigned char") ||
646 TypeName.consume_front(
"uchar"))
648 else if (TypeName.consume_front(
"short") ||
649 TypeName.consume_front(
"signed short") ||
650 TypeName.consume_front(
"unsigned short") ||
651 TypeName.consume_front(
"ushort"))
653 else if (TypeName.consume_front(
"int") ||
654 TypeName.consume_front(
"signed int") ||
655 TypeName.consume_front(
"unsigned int") ||
656 TypeName.consume_front(
"uint"))
658 else if (TypeName.consume_front(
"long") ||
659 TypeName.consume_front(
"signed long") ||
660 TypeName.consume_front(
"unsigned long") ||
661 TypeName.consume_front(
"ulong"))
663 else if (TypeName.consume_front(
"half") ||
664 TypeName.consume_front(
"_Float16") ||
665 TypeName.consume_front(
"__fp16"))
667 else if (TypeName.consume_front(
"float"))
669 else if (TypeName.consume_front(
"double"))
676SmallPtrSet<BasicBlock *, 0>
677PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
678 std::queue<BasicBlock *> ToVisit;
681 SmallPtrSet<BasicBlock *, 0> Output;
682 while (ToVisit.size() != 0) {
683 BasicBlock *BB = ToVisit.front();
686 if (Output.count(BB) != 0)
700bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
703 if (DT.dominates(BB,
P))
707 if (BlockToOrder.count(
P) == 0)
712 Loop *
L = LI.getLoopFor(
P);
713 if (L ==
nullptr ||
L->contains(BB))
719 assert(
L->getNumBackEdges() <= 1);
725 if (Latch ==
nullptr)
729 if (BlockToOrder.count(Latch) == 0)
737 auto It = BlockToOrder.find(BB);
738 if (It != BlockToOrder.end())
739 return It->second.Rank;
744 if (DT.dominates(BB,
P))
747 auto Iterator = BlockToOrder.end();
748 Loop *L = LI.getLoopFor(
P);
749 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
753 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
754 Iterator = BlockToOrder.find(
P);
759 Iterator = BlockToOrder.find(Latch);
762 assert(Iterator != BlockToOrder.end());
763 result = std::max(result, Iterator->second.Rank + 1);
769size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
773 size_t QueueIndex = 0;
774 while (ToVisit.size() != 0) {
778 if (!CanBeVisited(BB)) {
780 if (QueueIndex >= ToVisit.size())
782 "No valid candidate in the queue. Is the graph reducible?");
789 OrderInfo Info = {Rank, BlockToOrder.
size()};
790 BlockToOrder.try_emplace(BB, Info);
793 if (Queued.count(S) != 0)
807 visit(&*
F.begin(), 0);
809 Order.reserve(
F.size());
810 for (
auto &[BB, Info] : BlockToOrder)
811 Order.emplace_back(BB);
820 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
821 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
822 if (InfoLHS.Rank != InfoRHS.Rank)
823 return InfoLHS.Rank < InfoRHS.Rank;
824 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
830 assert(BlockToOrder.count(&Start) != 0);
833 auto It = Order.begin();
834 while (It != Order.end() && *It != &Start)
839 assert(It != Order.end());
842 std::optional<size_t> EndRank = std::nullopt;
843 for (; It != Order.end(); ++It) {
844 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
847 if (Reachable.count(*It) == 0) {
852 EndRank = BlockToOrder[*It].Rank;
862 std::vector<BasicBlock *> Order;
863 Order.reserve(
F.size());
868 assert(&*
F.begin() == Order[0]);
871 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
884 F.begin()->getFirstInsertionPt());
894 return TargetToValue.
lookup(BI->getSuccessor());
897 Builder.SetInsertPoint(
T);
903 if (
LHS ==
nullptr ||
RHS ==
nullptr)
905 return Builder.CreateSelect(BI->getCondition(),
LHS,
RHS);
909 Value *Condition =
SI->getCondition();
912 for (
const auto &Case :
SI->cases()) {
913 Value *CaseValue = TargetToValue.
lookup(Case.getCaseSuccessor());
915 if (CaseValue ==
nullptr)
918 if (Result ==
nullptr) {
922 Value *Cmp = Builder.CreateICmpEQ(Condition, Case.getCaseValue());
923 Result = Builder.CreateSelect(Cmp, CaseValue, Result);
933 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
941 constexpr unsigned MaxIters = 1024;
942 for (
unsigned I = 0;
I < MaxIters; ++
I) {
943 std::string OrdName = Name +
Twine(
I).
str();
944 if (!M.getFunction(OrdName)) {
945 Name = std::move(OrdName);
971 SPIRV::AccessQualifier::AccessQualifier AccessQual,
972 bool EmitIR,
bool Force) {
975 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
1001 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
1008 return SPVTy->
getOpcode() == SPIRV::OpTypeVector ||
1009 SPVTy->
getOpcode() == SPIRV::OpTypeVectorIdEXT;
1016 Args.push_back(Arg2);
1019 return B.CreateIntrinsicWithoutFolding(IntrID, {Types}, Args);
1024 if (Ty->isPtrOrPtrVectorTy())
1029 for (
const Type *ArgTy : RefTy->params())
1042 if (
F->getName().starts_with(
"llvm.spv."))
1049SmallVector<MachineInstr *, 4>
1051 unsigned MinWC,
unsigned ContinuedOpcode,
1056 constexpr unsigned MaxWordCount = UINT16_MAX;
1057 const size_t NumElements = Args.size();
1058 size_t MaxNumElements = MaxWordCount - MinWC;
1059 size_t SPIRVStructNumElements = NumElements;
1061 if (NumElements > MaxNumElements) {
1064 SPIRVStructNumElements = MaxNumElements;
1065 MaxNumElements = MaxWordCount - 1;
1071 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1074 Instructions.push_back(MIB.getInstr());
1076 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1077 I += MaxNumElements) {
1078 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
1079 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1081 Instructions.push_back(MIB.getInstr());
1083 return Instructions;
1086SmallVector<unsigned, 1>
1088 unsigned LC = SPIRV::LoopControl::None;
1092 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
1094 LC |= SPIRV::LoopControl::DontUnroll;
1098 LC |= SPIRV::LoopControl::Unroll;
1104 unsigned Count = CI->getZExtValue();
1106 LC |= SPIRV::LoopControl::PartialCount;
1107 MaskToValueMap.emplace_back(
1108 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1114 for (
auto &[Mask, Val] : MaskToValueMap)
1115 Result.push_back(Val);
1125 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1126 TargetOpcode::G_ADD,
1127 TargetOpcode::G_FADD,
1128 TargetOpcode::G_STRICT_FADD,
1129 TargetOpcode::G_SUB,
1130 TargetOpcode::G_FSUB,
1131 TargetOpcode::G_STRICT_FSUB,
1132 TargetOpcode::G_MUL,
1133 TargetOpcode::G_FMUL,
1134 TargetOpcode::G_STRICT_FMUL,
1135 TargetOpcode::G_SDIV,
1136 TargetOpcode::G_UDIV,
1137 TargetOpcode::G_FDIV,
1138 TargetOpcode::G_STRICT_FDIV,
1139 TargetOpcode::G_SREM,
1140 TargetOpcode::G_UREM,
1141 TargetOpcode::G_FREM,
1142 TargetOpcode::G_STRICT_FREM,
1143 TargetOpcode::G_FNEG,
1144 TargetOpcode::G_CONSTANT,
1145 TargetOpcode::G_FCONSTANT,
1146 TargetOpcode::G_AND,
1148 TargetOpcode::G_XOR,
1149 TargetOpcode::G_SHL,
1150 TargetOpcode::G_ASHR,
1151 TargetOpcode::G_LSHR,
1152 TargetOpcode::G_SELECT,
1153 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1156 return TypeFoldingSupportingOpcs;
1165 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1166 Def->getOpcode() == TargetOpcode::COPY)
1167 ? MRI->
getVRegDef(Def->getOperand(1).getReg())
1179 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1180 Def->getOpcode() == SPIRV::OpConstantI)
1188 if (Def->getOpcode() == SPIRV::OpConstantI)
1189 return Def->getOperand(2).getImm();
1190 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1191 return Def->getOperand(1).getCImm()->getZExtValue();
1204 if (Ty->getStructNumElements() != 2)
1219 if (T_in_struct != SecondElement)
1222 auto *Padding_in_struct =
1224 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1228 TotalSize = ArraySize + 1;
1229 OriginalElementType = ArrayElementType;
1234 if (!Ty->isStructTy())
1238 Type *OriginalElementType =
nullptr;
1248 for (
Type *ElementTy : STy->elements()) {
1250 if (NewElementTy != ElementTy)
1252 NewElementTypes.
push_back(NewElementTy);
1259 if (STy->isLiteral()) {
1264 STy->getName(), STy->isPacked());
1269std::optional<SPIRV::LinkageType::LinkageType>
1272 return std::nullopt;
1278 if (SC == SPIRV::StorageClass::Input ||
1279 SC == SPIRV::StorageClass::Output ||
1280 SC == SPIRV::StorageClass::PushConstant)
1281 return std::nullopt;
1284 if (ST.isShader() && (SC == SPIRV::StorageClass::Workgroup ||
1285 SC == SPIRV::StorageClass::Private))
1286 return std::nullopt;
1288 return SPIRV::LinkageType::Import;
1292 return std::nullopt;
1295 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1296 return SPIRV::LinkageType::LinkOnceODR;
1299 ST.canUseExtension(SPIRV::Extension::SPV_AMD_weak_linkage))
1300 return SPIRV::LinkageType::WeakAMD;
1302 return SPIRV::LinkageType::Export;
1309 "cannot allocate a name for the internal service function");
1311 if (SF->getInstructionCount() > 0)
1313 "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 LLVM_READONLY 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.
Triple - Helper class for working with autoconf configuration names.
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.
AtomicScope
Target-neutral memory synchronization scopes.
bool isTypeFoldingSupported(unsigned Opcode)
uint32_t getMemSemanticsWithStorageClass(const Triple &TT, uint32_t OrderSem, uint32_t StorageClassSem)
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)
SPIRV::Scope::Scope getMemScope(const Triple &TT, LLVMContext &Ctx, SyncScope::ID Id)
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 isVectorType(SPIRVTypeInst SPVTy)
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.
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.
std::optional< StringRef > getAtomicScopeIRString(const Triple &T, AtomicScope S, bool IsSingleAddressSpace=false)
Returns the LLVM IR syncscope string that T uses to spell S.
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.