26#include "llvm/IR/IntrinsicsSPIRV.h"
51 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
52 return MDS->getString() == Name;
62 for (
unsigned I = 1;
I != (*It)->getNumOperands(); ++
I) {
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();
95 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
96 return MDS->getString() == Name;
105 assert(MD &&
"MDNode operand is expected");
108 Constraints = MDS->getString();
115 F.getParent()->getNamedMetadata(
"spv.cloned_funcs"),
F.getFunctionType(),
122 if (MD->getNumOperands() > 0)
124 return MDS->getString();
155 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
156 unsigned StrIndex = i + WordIndex;
158 if (StrIndex < Str.size()) {
159 CharToAdd = Str[StrIndex];
161 Word |= (CharToAdd << (WordIndex * 8));
168 return (Str.size() + 4) & ~3;
173 for (
unsigned i = 0; i < PaddedLen; i += 4) {
181 for (
unsigned i = 0; i < PaddedLen; i += 4) {
188 std::vector<Value *> &Args) {
190 for (
unsigned i = 0; i < PaddedLen; i += 4) {
202 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
203 "Expected G_GLOBAL_VALUE");
204 const GlobalValue *GV = Def->getOperand(1).getGlobal();
211 const auto Bitwidth = Imm.getBitWidth();
214 else if (Bitwidth <= 32) {
215 MIB.
addImm(Imm.getZExtValue());
220 }
else if (Bitwidth <= 64) {
221 uint64_t FullImm = Imm.getZExtValue();
222 uint32_t LowBits = FullImm & 0xffffffff;
223 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
230 unsigned NumWords = (Bitwidth + 31) / 32;
231 for (
unsigned I = 0;
I < NumWords; ++
I) {
232 unsigned LimbIdx =
I / 2;
233 unsigned LimbShift = (
I % 2) * 32;
234 uint32_t Word = (Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
253 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
264 for (
const auto &DecArg : DecArgs)
269 SPIRV::Decoration::Decoration Dec,
271 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
278 SPIRV::Decoration::Decoration Dec,
281 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
288 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
290 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
299 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
302 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
315 if (OpMD->getNumOperands() == 0)
321 "element of the decoration");
331 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
333 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
336 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
339 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
342 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
357 switch (
MI.getOpcode()) {
358 case SPIRV::OpFunction:
359 case SPIRV::OpFunctionParameter:
361 case SPIRV::ASSIGN_TYPE:
368 while (VarPos !=
MBB.end() && VarPos->getOpcode() != SPIRV::OpFunction)
371 while (VarPos !=
MBB.end() && IsPreamble(*VarPos))
378 if (
I ==
MBB->begin())
381 while (
I->isTerminator() ||
I->isDebugValue()) {
382 if (
I ==
MBB->begin())
389SPIRV::StorageClass::StorageClass
393 return SPIRV::StorageClass::Function;
395 return SPIRV::StorageClass::CrossWorkgroup;
397 return SPIRV::StorageClass::UniformConstant;
399 return SPIRV::StorageClass::Workgroup;
401 return SPIRV::StorageClass::Generic;
403 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
404 ? SPIRV::StorageClass::DeviceOnlyINTEL
405 : SPIRV::StorageClass::CrossWorkgroup;
407 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
408 ? SPIRV::StorageClass::HostOnlyINTEL
409 : SPIRV::StorageClass::CrossWorkgroup;
411 return SPIRV::StorageClass::Input;
413 return SPIRV::StorageClass::Output;
415 return SPIRV::StorageClass::CodeSectionINTEL;
417 return SPIRV::StorageClass::Private;
419 return SPIRV::StorageClass::StorageBuffer;
421 return SPIRV::StorageClass::Uniform;
423 return SPIRV::StorageClass::PushConstant;
429SPIRV::MemorySemantics::MemorySemantics
432 case SPIRV::StorageClass::StorageBuffer:
433 case SPIRV::StorageClass::Uniform:
434 return SPIRV::MemorySemantics::UniformMemory;
435 case SPIRV::StorageClass::Workgroup:
436 return SPIRV::MemorySemantics::WorkgroupMemory;
437 case SPIRV::StorageClass::CrossWorkgroup:
438 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
439 case SPIRV::StorageClass::AtomicCounter:
440 return SPIRV::MemorySemantics::AtomicCounterMemory;
441 case SPIRV::StorageClass::Image:
442 return SPIRV::MemorySemantics::ImageMemory;
444 return SPIRV::MemorySemantics::None;
451 return SPIRV::MemorySemantics::Acquire;
453 return SPIRV::MemorySemantics::Release;
455 return SPIRV::MemorySemantics::AcquireRelease;
457 return SPIRV::MemorySemantics::SequentiallyConsistent;
461 return SPIRV::MemorySemantics::None;
473 Ctx.getOrInsertSyncScopeID(
"subgroup");
475 Ctx.getOrInsertSyncScopeID(
"workgroup");
477 Ctx.getOrInsertSyncScopeID(
"device");
480 return SPIRV::Scope::Invocation;
482 return SPIRV::Scope::CrossDevice;
483 else if (Id == SubGroup)
484 return SPIRV::Scope::Subgroup;
485 else if (Id == WorkGroup)
486 return SPIRV::Scope::Workgroup;
487 else if (Id == Device)
488 return SPIRV::Scope::Device;
489 return SPIRV::Scope::CrossDevice;
496 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
500 if (GI->is(Intrinsic::spv_track_constant)) {
504 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
507 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
508 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
517 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
518 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
523 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
524 return MI->getOperand(1).getCImm()->getSExtValue();
529 return GI->is(IntrinsicID);
541 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
542 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
543 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
544 MangledName ==
"reserve_write_pipe" ||
545 MangledName ==
"reserve_read_pipe" ||
546 MangledName ==
"commit_write_pipe" ||
547 MangledName ==
"commit_read_pipe" ||
548 MangledName ==
"work_group_reserve_write_pipe" ||
549 MangledName ==
"work_group_reserve_read_pipe" ||
550 MangledName ==
"work_group_commit_write_pipe" ||
551 MangledName ==
"work_group_commit_read_pipe" ||
552 MangledName ==
"get_pipe_num_packets_ro" ||
553 MangledName ==
"get_pipe_max_packets_ro" ||
554 MangledName ==
"get_pipe_num_packets_wo" ||
555 MangledName ==
"get_pipe_max_packets_wo" ||
556 MangledName ==
"sub_group_reserve_write_pipe" ||
557 MangledName ==
"sub_group_reserve_read_pipe" ||
558 MangledName ==
"sub_group_commit_write_pipe" ||
559 MangledName ==
"sub_group_commit_read_pipe" ||
560 MangledName ==
"to_global" || MangledName ==
"to_local" ||
561 MangledName ==
"to_private";
565 return MangledName ==
"__enqueue_kernel_basic" ||
566 MangledName ==
"__enqueue_kernel_basic_events" ||
567 MangledName ==
"__enqueue_kernel_varargs" ||
568 MangledName ==
"__enqueue_kernel_events_varargs";
572 return MangledName ==
"__get_kernel_work_group_size_impl" ||
573 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
574 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
575 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
579 if (!Name.starts_with(
"__"))
584 Name ==
"__translate_sampler_initializer";
589 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
590 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
591 bool IsMangled = Name.starts_with(
"_Z");
594 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
599 std::string Result = DemangledName;
608 size_t Start, Len = 0;
609 size_t DemangledNameLenStart = 2;
610 if (Name.starts_with(
"_ZN")) {
612 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
614 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
615 return std::string();
616 DemangledNameLenStart = NameSpaceStart + 11;
618 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
619 [[maybe_unused]]
bool Error =
620 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
621 .getAsInteger(10, Len);
622 assert(!
Error &&
"Failed to parse demangled name length");
623 return Name.substr(Start, Len).str();
627 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
628 Name.starts_with(
"spirv."))
650 if (
F.getFnAttribute(
"hlsl.shader").isValid())
657 TypeName.consume_front(
"atomic_");
658 if (TypeName.consume_front(
"void"))
660 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
662 else if (TypeName.consume_front(
"char") ||
663 TypeName.consume_front(
"signed char") ||
664 TypeName.consume_front(
"unsigned char") ||
665 TypeName.consume_front(
"uchar"))
667 else if (TypeName.consume_front(
"short") ||
668 TypeName.consume_front(
"signed short") ||
669 TypeName.consume_front(
"unsigned short") ||
670 TypeName.consume_front(
"ushort"))
672 else if (TypeName.consume_front(
"int") ||
673 TypeName.consume_front(
"signed int") ||
674 TypeName.consume_front(
"unsigned int") ||
675 TypeName.consume_front(
"uint"))
677 else if (TypeName.consume_front(
"long") ||
678 TypeName.consume_front(
"signed long") ||
679 TypeName.consume_front(
"unsigned long") ||
680 TypeName.consume_front(
"ulong"))
682 else if (TypeName.consume_front(
"half") ||
683 TypeName.consume_front(
"_Float16") ||
684 TypeName.consume_front(
"__fp16"))
686 else if (TypeName.consume_front(
"float"))
688 else if (TypeName.consume_front(
"double"))
695SmallPtrSet<BasicBlock *, 0>
696PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
697 std::queue<BasicBlock *> ToVisit;
700 SmallPtrSet<BasicBlock *, 0> Output;
701 while (ToVisit.size() != 0) {
702 BasicBlock *BB = ToVisit.front();
705 if (Output.count(BB) != 0)
719bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
722 if (DT.dominates(BB,
P))
726 if (BlockToOrder.count(
P) == 0)
731 Loop *
L = LI.getLoopFor(
P);
732 if (L ==
nullptr ||
L->contains(BB))
738 assert(
L->getNumBackEdges() <= 1);
744 if (Latch ==
nullptr)
748 if (BlockToOrder.count(Latch) == 0)
756 auto It = BlockToOrder.find(BB);
757 if (It != BlockToOrder.end())
758 return It->second.Rank;
763 if (DT.dominates(BB,
P))
766 auto Iterator = BlockToOrder.end();
767 Loop *L = LI.getLoopFor(
P);
768 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
772 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
773 Iterator = BlockToOrder.find(
P);
778 Iterator = BlockToOrder.find(Latch);
781 assert(Iterator != BlockToOrder.end());
782 result = std::max(result, Iterator->second.Rank + 1);
788size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
792 size_t QueueIndex = 0;
793 while (ToVisit.size() != 0) {
797 if (!CanBeVisited(BB)) {
799 if (QueueIndex >= ToVisit.size())
801 "No valid candidate in the queue. Is the graph reducible?");
808 OrderInfo Info = {Rank, BlockToOrder.
size()};
809 BlockToOrder.try_emplace(BB, Info);
812 if (Queued.count(S) != 0)
826 visit(&*
F.begin(), 0);
828 Order.reserve(
F.size());
829 for (
auto &[BB, Info] : BlockToOrder)
830 Order.emplace_back(BB);
832 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
833 return compare(LHS, RHS);
839 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
840 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
841 if (InfoLHS.Rank != InfoRHS.Rank)
842 return InfoLHS.Rank < InfoRHS.Rank;
843 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
849 assert(BlockToOrder.count(&Start) != 0);
852 auto It = Order.begin();
853 while (It != Order.end() && *It != &Start)
858 assert(It != Order.end());
861 std::optional<size_t> EndRank = std::nullopt;
862 for (; It != Order.end(); ++It) {
863 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
866 if (Reachable.count(*It) == 0) {
871 EndRank = BlockToOrder[*It].Rank;
881 std::vector<BasicBlock *> Order;
882 Order.reserve(
F.size());
887 assert(&*
F.begin() == Order[0]);
890 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
903 F.begin()->getFirstInsertionPt());
913 return TargetToValue.
lookup(BI->getSuccessor());
916 Builder.SetInsertPoint(
T);
922 if (
LHS ==
nullptr ||
RHS ==
nullptr)
924 return Builder.CreateSelect(BI->getCondition(),
LHS,
RHS);
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) {
1011 Args.push_back(Arg2);
1014 return B.CreateIntrinsicWithoutFolding(IntrID, {Types}, Args);
1019 if (Ty->isPtrOrPtrVectorTy())
1024 for (
const Type *ArgTy : RefTy->params())
1037 if (
F->getName().starts_with(
"llvm.spv."))
1044SmallVector<MachineInstr *, 4>
1046 unsigned MinWC,
unsigned ContinuedOpcode,
1051 constexpr unsigned MaxWordCount = UINT16_MAX;
1052 const size_t NumElements = Args.size();
1053 size_t MaxNumElements = MaxWordCount - MinWC;
1054 size_t SPIRVStructNumElements = NumElements;
1056 if (NumElements > MaxNumElements) {
1059 SPIRVStructNumElements = MaxNumElements;
1060 MaxNumElements = MaxWordCount - 1;
1066 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1069 Instructions.push_back(MIB.getInstr());
1071 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1072 I += MaxNumElements) {
1073 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
1074 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1076 Instructions.push_back(MIB.getInstr());
1078 return Instructions;
1081SmallVector<unsigned, 1>
1083 unsigned LC = SPIRV::LoopControl::None;
1087 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
1089 LC |= SPIRV::LoopControl::DontUnroll;
1093 LC |= SPIRV::LoopControl::Unroll;
1099 unsigned Count = CI->getZExtValue();
1101 LC |= SPIRV::LoopControl::PartialCount;
1102 MaskToValueMap.emplace_back(
1103 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1109 for (
auto &[Mask, Val] : MaskToValueMap)
1110 Result.push_back(Val);
1120 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1121 TargetOpcode::G_ADD,
1122 TargetOpcode::G_FADD,
1123 TargetOpcode::G_STRICT_FADD,
1124 TargetOpcode::G_SUB,
1125 TargetOpcode::G_FSUB,
1126 TargetOpcode::G_STRICT_FSUB,
1127 TargetOpcode::G_MUL,
1128 TargetOpcode::G_FMUL,
1129 TargetOpcode::G_STRICT_FMUL,
1130 TargetOpcode::G_SDIV,
1131 TargetOpcode::G_UDIV,
1132 TargetOpcode::G_FDIV,
1133 TargetOpcode::G_STRICT_FDIV,
1134 TargetOpcode::G_SREM,
1135 TargetOpcode::G_UREM,
1136 TargetOpcode::G_FREM,
1137 TargetOpcode::G_STRICT_FREM,
1138 TargetOpcode::G_FNEG,
1139 TargetOpcode::G_CONSTANT,
1140 TargetOpcode::G_FCONSTANT,
1141 TargetOpcode::G_AND,
1143 TargetOpcode::G_XOR,
1144 TargetOpcode::G_SHL,
1145 TargetOpcode::G_ASHR,
1146 TargetOpcode::G_LSHR,
1147 TargetOpcode::G_SELECT,
1148 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1151 return TypeFoldingSupportingOpcs;
1160 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1161 Def->getOpcode() == TargetOpcode::COPY)
1162 ? MRI->
getVRegDef(Def->getOperand(1).getReg())
1174 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1175 Def->getOpcode() == SPIRV::OpConstantI)
1183 if (Def->getOpcode() == SPIRV::OpConstantI)
1184 return Def->getOperand(2).getImm();
1185 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1186 return Def->getOperand(1).getCImm()->getZExtValue();
1199 if (Ty->getStructNumElements() != 2)
1214 if (T_in_struct != SecondElement)
1217 auto *Padding_in_struct =
1219 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1223 TotalSize = ArraySize + 1;
1224 OriginalElementType = ArrayElementType;
1229 if (!Ty->isStructTy())
1233 Type *OriginalElementType =
nullptr;
1243 for (
Type *ElementTy : STy->elements()) {
1245 if (NewElementTy != ElementTy)
1247 NewElementTypes.
push_back(NewElementTy);
1254 if (STy->isLiteral())
1259 NewTy->setBody(NewElementTypes, STy->isPacked());
1265std::optional<SPIRV::LinkageType::LinkageType>
1268 return std::nullopt;
1274 if (SC == SPIRV::StorageClass::Input ||
1275 SC == SPIRV::StorageClass::Output ||
1276 SC == SPIRV::StorageClass::PushConstant)
1277 return std::nullopt;
1279 return SPIRV::LinkageType::Import;
1283 return std::nullopt;
1286 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1287 return SPIRV::LinkageType::LinkOnceODR;
1290 ST.canUseExtension(SPIRV::Extension::SPV_AMD_weak_linkage))
1291 return SPIRV::LinkageType::WeakAMD;
1293 return SPIRV::LinkageType::Export;
1300 "cannot allocate a name for the internal service function");
1302 if (SF->getInstructionCount() > 0)
1304 "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
static ConstantInt * getConstInt(MDNode *MD, unsigned NumOp)
#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)
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.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
bool getVacantFunctionName(Module &M, std::string &Name)
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
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)
static uint32_t convertCharsToWord(const StringRef &Str, unsigned i)
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)
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)
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)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
Type * toTypedPointer(Type *Ty)
DEMANGLE_ABI char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
bool isSpecialOpaqueType(const Type *Ty)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
void setRegClassType(Register Reg, SPIRVTypeInst SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
FunctionAddr VTableAddr Count
static bool isNonMangledOCLBuiltin(StringRef Name)
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)
static bool isPipeOrAddressSpaceCastBI(const StringRef MangledName)
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD, const SPIRVSubtarget &ST)
std::string getStringValueFromReg(Register Reg, MachineRegisterInfo &MRI)
int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
DWARFExpression::Operation Op
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
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(const StringRef &Str)
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
void addStringImm(const StringRef &Str, MCInst &Inst)
static bool isKernelQueryBI(const StringRef MangledName)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
static bool isEnqueueKernelBI(const StringRef MangledName)
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.