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(),
139 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
140 unsigned StrIndex = i + WordIndex;
142 if (StrIndex < Str.size()) {
143 CharToAdd = Str[StrIndex];
145 Word |= (CharToAdd << (WordIndex * 8));
152 return (Str.size() + 4) & ~3;
157 for (
unsigned i = 0; i < PaddedLen; i += 4) {
165 for (
unsigned i = 0; i < PaddedLen; i += 4) {
172 std::vector<Value *> &Args) {
174 for (
unsigned i = 0; i < PaddedLen; i += 4) {
186 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
187 "Expected G_GLOBAL_VALUE");
188 const GlobalValue *GV = Def->getOperand(1).getGlobal();
195 const auto Bitwidth = Imm.getBitWidth();
198 else if (Bitwidth <= 32) {
199 MIB.
addImm(Imm.getZExtValue());
204 }
else if (Bitwidth <= 64) {
205 uint64_t FullImm = Imm.getZExtValue();
206 uint32_t LowBits = FullImm & 0xffffffff;
207 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
214 unsigned NumWords = (Bitwidth + 31) / 32;
215 for (
unsigned I = 0;
I < NumWords; ++
I) {
216 unsigned LimbIdx =
I / 2;
217 unsigned LimbShift = (
I % 2) * 32;
218 uint32_t Word = (Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
237 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
244 const std::vector<uint32_t> &DecArgs,
248 for (
const auto &DecArg : DecArgs)
253 SPIRV::Decoration::Decoration Dec,
254 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
255 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
262 SPIRV::Decoration::Decoration Dec,
263 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
265 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
272 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
273 const std::vector<uint32_t> &DecArgs,
275 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
284 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
285 const std::vector<uint32_t> &DecArgs,
288 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
301 if (OpMD->getNumOperands() == 0)
307 "element of the decoration");
317 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
319 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
322 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
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::AtomicCounter:
426 return SPIRV::MemorySemantics::AtomicCounterMemory;
427 case SPIRV::StorageClass::Image:
428 return SPIRV::MemorySemantics::ImageMemory;
430 return SPIRV::MemorySemantics::None;
437 return SPIRV::MemorySemantics::Acquire;
439 return SPIRV::MemorySemantics::Release;
441 return SPIRV::MemorySemantics::AcquireRelease;
443 return SPIRV::MemorySemantics::SequentiallyConsistent;
447 return SPIRV::MemorySemantics::None;
459 Ctx.getOrInsertSyncScopeID(
"subgroup");
461 Ctx.getOrInsertSyncScopeID(
"workgroup");
463 Ctx.getOrInsertSyncScopeID(
"device");
466 return SPIRV::Scope::Invocation;
468 return SPIRV::Scope::CrossDevice;
469 else if (Id == SubGroup)
470 return SPIRV::Scope::Subgroup;
471 else if (Id == WorkGroup)
472 return SPIRV::Scope::Workgroup;
473 else if (Id == Device)
474 return SPIRV::Scope::Device;
475 return SPIRV::Scope::CrossDevice;
482 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
486 if (GI->is(Intrinsic::spv_track_constant)) {
490 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
493 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
494 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
503 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
504 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
509 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
510 return MI->getOperand(1).getCImm()->getSExtValue();
515 return GI->is(IntrinsicID);
527 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
528 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
529 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
530 MangledName ==
"reserve_write_pipe" ||
531 MangledName ==
"reserve_read_pipe" ||
532 MangledName ==
"commit_write_pipe" ||
533 MangledName ==
"commit_read_pipe" ||
534 MangledName ==
"work_group_reserve_write_pipe" ||
535 MangledName ==
"work_group_reserve_read_pipe" ||
536 MangledName ==
"work_group_commit_write_pipe" ||
537 MangledName ==
"work_group_commit_read_pipe" ||
538 MangledName ==
"get_pipe_num_packets_ro" ||
539 MangledName ==
"get_pipe_max_packets_ro" ||
540 MangledName ==
"get_pipe_num_packets_wo" ||
541 MangledName ==
"get_pipe_max_packets_wo" ||
542 MangledName ==
"sub_group_reserve_write_pipe" ||
543 MangledName ==
"sub_group_reserve_read_pipe" ||
544 MangledName ==
"sub_group_commit_write_pipe" ||
545 MangledName ==
"sub_group_commit_read_pipe" ||
546 MangledName ==
"to_global" || MangledName ==
"to_local" ||
547 MangledName ==
"to_private";
551 return MangledName ==
"__enqueue_kernel_basic" ||
552 MangledName ==
"__enqueue_kernel_basic_events" ||
553 MangledName ==
"__enqueue_kernel_varargs" ||
554 MangledName ==
"__enqueue_kernel_events_varargs";
558 return MangledName ==
"__get_kernel_work_group_size_impl" ||
559 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
560 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
561 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
565 if (!Name.starts_with(
"__"))
570 Name ==
"__translate_sampler_initializer";
575 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
576 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
577 bool IsMangled = Name.starts_with(
"_Z");
580 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
585 std::string Result = DemangledName;
594 size_t Start, Len = 0;
595 size_t DemangledNameLenStart = 2;
596 if (Name.starts_with(
"_ZN")) {
598 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
600 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
601 return std::string();
602 DemangledNameLenStart = NameSpaceStart + 11;
604 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
605 [[maybe_unused]]
bool Error =
606 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
607 .getAsInteger(10, Len);
608 assert(!
Error &&
"Failed to parse demangled name length");
609 return Name.substr(Start, Len).str();
613 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
614 Name.starts_with(
"spirv."))
636 if (
F.getFnAttribute(
"hlsl.shader").isValid())
643 TypeName.consume_front(
"atomic_");
644 if (TypeName.consume_front(
"void"))
646 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
648 else if (TypeName.consume_front(
"char") ||
649 TypeName.consume_front(
"signed char") ||
650 TypeName.consume_front(
"unsigned char") ||
651 TypeName.consume_front(
"uchar"))
653 else if (TypeName.consume_front(
"short") ||
654 TypeName.consume_front(
"signed short") ||
655 TypeName.consume_front(
"unsigned short") ||
656 TypeName.consume_front(
"ushort"))
658 else if (TypeName.consume_front(
"int") ||
659 TypeName.consume_front(
"signed int") ||
660 TypeName.consume_front(
"unsigned int") ||
661 TypeName.consume_front(
"uint"))
663 else if (TypeName.consume_front(
"long") ||
664 TypeName.consume_front(
"signed long") ||
665 TypeName.consume_front(
"unsigned long") ||
666 TypeName.consume_front(
"ulong"))
668 else if (TypeName.consume_front(
"half") ||
669 TypeName.consume_front(
"_Float16") ||
670 TypeName.consume_front(
"__fp16"))
672 else if (TypeName.consume_front(
"float"))
674 else if (TypeName.consume_front(
"double"))
681std::unordered_set<BasicBlock *>
682PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
683 std::queue<BasicBlock *> ToVisit;
686 std::unordered_set<BasicBlock *> Output;
687 while (ToVisit.size() != 0) {
688 BasicBlock *BB = ToVisit.front();
691 if (Output.count(BB) != 0)
705bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
708 if (DT.dominates(BB,
P))
712 if (BlockToOrder.count(
P) == 0)
717 Loop *
L = LI.getLoopFor(
P);
718 if (L ==
nullptr ||
L->contains(BB))
724 assert(
L->getNumBackEdges() <= 1);
730 if (Latch ==
nullptr)
734 if (BlockToOrder.count(Latch) == 0)
742 auto It = BlockToOrder.find(BB);
743 if (It != BlockToOrder.end())
744 return It->second.Rank;
749 if (DT.dominates(BB,
P))
752 auto Iterator = BlockToOrder.end();
753 Loop *L = LI.getLoopFor(
P);
754 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
758 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
759 Iterator = BlockToOrder.find(
P);
764 Iterator = BlockToOrder.find(Latch);
767 assert(Iterator != BlockToOrder.end());
768 result = std::max(result, Iterator->second.Rank + 1);
774size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
778 size_t QueueIndex = 0;
779 while (ToVisit.size() != 0) {
783 if (!CanBeVisited(BB)) {
785 if (QueueIndex >= ToVisit.size())
787 "No valid candidate in the queue. Is the graph reducible?");
794 OrderInfo Info = {Rank, BlockToOrder.size()};
795 BlockToOrder.emplace(BB, Info);
798 if (Queued.count(S) != 0)
812 visit(&*
F.begin(), 0);
814 Order.reserve(
F.size());
815 for (
auto &[BB, Info] : BlockToOrder)
816 Order.emplace_back(BB);
818 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
819 return compare(LHS, RHS);
825 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
826 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
827 if (InfoLHS.Rank != InfoRHS.Rank)
828 return InfoLHS.Rank < InfoRHS.Rank;
829 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
834 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
835 assert(BlockToOrder.count(&Start) != 0);
838 auto It = Order.begin();
839 while (It != Order.end() && *It != &Start)
844 assert(It != Order.end());
847 std::optional<size_t> EndRank = std::nullopt;
848 for (; It != Order.end(); ++It) {
849 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
852 if (Reachable.count(*It) == 0) {
857 EndRank = BlockToOrder[*It].Rank;
867 std::vector<BasicBlock *> Order;
868 Order.reserve(
F.size());
873 assert(&*
F.begin() == Order[0]);
876 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
888 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
896 constexpr unsigned MaxIters = 1024;
897 for (
unsigned I = 0;
I < MaxIters; ++
I) {
898 std::string OrdName = Name +
Twine(
I).
str();
899 if (!M.getFunction(OrdName)) {
900 Name = std::move(OrdName);
926 SPIRV::AccessQualifier::AccessQualifier AccessQual,
927 bool EmitIR,
bool Force) {
930 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
956 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
966 Args.push_back(Arg2);
969 return B.CreateIntrinsic(IntrID, {Types}, Args);
974 if (Ty->isPtrOrPtrVectorTy())
979 for (
const Type *ArgTy : RefTy->params())
992 if (
F->getName().starts_with(
"llvm.spv."))
999SmallVector<MachineInstr *, 4>
1001 unsigned MinWC,
unsigned ContinuedOpcode,
1006 constexpr unsigned MaxWordCount = UINT16_MAX;
1007 const size_t NumElements = Args.size();
1008 size_t MaxNumElements = MaxWordCount - MinWC;
1009 size_t SPIRVStructNumElements = NumElements;
1011 if (NumElements > MaxNumElements) {
1014 SPIRVStructNumElements = MaxNumElements;
1015 MaxNumElements = MaxWordCount - 1;
1021 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1024 Instructions.push_back(MIB.getInstr());
1026 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1027 I += MaxNumElements) {
1028 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
1029 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1031 Instructions.push_back(MIB.getInstr());
1033 return Instructions;
1036SmallVector<unsigned, 1>
1038 unsigned LC = SPIRV::LoopControl::None;
1042 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
1044 LC |= SPIRV::LoopControl::DontUnroll;
1048 LC |= SPIRV::LoopControl::Unroll;
1054 unsigned Count = CI->getZExtValue();
1056 LC |= SPIRV::LoopControl::PartialCount;
1057 MaskToValueMap.emplace_back(
1058 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1064 for (
auto &[Mask, Val] : MaskToValueMap)
1065 Result.push_back(Val);
1075 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1076 TargetOpcode::G_ADD,
1077 TargetOpcode::G_FADD,
1078 TargetOpcode::G_STRICT_FADD,
1079 TargetOpcode::G_SUB,
1080 TargetOpcode::G_FSUB,
1081 TargetOpcode::G_STRICT_FSUB,
1082 TargetOpcode::G_MUL,
1083 TargetOpcode::G_FMUL,
1084 TargetOpcode::G_STRICT_FMUL,
1085 TargetOpcode::G_SDIV,
1086 TargetOpcode::G_UDIV,
1087 TargetOpcode::G_FDIV,
1088 TargetOpcode::G_STRICT_FDIV,
1089 TargetOpcode::G_SREM,
1090 TargetOpcode::G_UREM,
1091 TargetOpcode::G_FREM,
1092 TargetOpcode::G_STRICT_FREM,
1093 TargetOpcode::G_FNEG,
1094 TargetOpcode::G_CONSTANT,
1095 TargetOpcode::G_FCONSTANT,
1096 TargetOpcode::G_AND,
1098 TargetOpcode::G_XOR,
1099 TargetOpcode::G_SHL,
1100 TargetOpcode::G_ASHR,
1101 TargetOpcode::G_LSHR,
1102 TargetOpcode::G_SELECT,
1103 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1106 return TypeFoldingSupportingOpcs;
1115 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1116 Def->getOpcode() == TargetOpcode::COPY)
1117 ? MRI->
getVRegDef(Def->getOperand(1).getReg())
1129 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1130 Def->getOpcode() == SPIRV::OpConstantI)
1138 if (Def->getOpcode() == SPIRV::OpConstantI)
1139 return Def->getOperand(2).getImm();
1140 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1141 return Def->getOperand(1).getCImm()->getZExtValue();
1154 if (Ty->getStructNumElements() != 2)
1169 if (T_in_struct != SecondElement)
1172 auto *Padding_in_struct =
1174 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1178 TotalSize = ArraySize + 1;
1179 OriginalElementType = ArrayElementType;
1184 if (!Ty->isStructTy())
1188 Type *OriginalElementType =
nullptr;
1198 for (
Type *ElementTy : STy->elements()) {
1200 if (NewElementTy != ElementTy)
1202 NewElementTypes.
push_back(NewElementTy);
1209 if (STy->isLiteral())
1214 NewTy->setBody(NewElementTypes, STy->isPacked());
1220std::optional<SPIRV::LinkageType::LinkageType>
1223 return std::nullopt;
1229 if (SC == SPIRV::StorageClass::Input ||
1230 SC == SPIRV::StorageClass::Output ||
1231 SC == SPIRV::StorageClass::PushConstant)
1232 return std::nullopt;
1234 return SPIRV::LinkageType::Import;
1238 return std::nullopt;
1241 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1242 return SPIRV::LinkageType::LinkOnceODR;
1245 ST.canUseExtension(SPIRV::Extension::SPV_AMD_weak_linkage))
1246 return SPIRV::LinkageType::WeakAMD;
1248 return SPIRV::LinkageType::Export;
1255 "cannot allocate a name for the internal service function");
1257 if (SF->getInstructionCount() > 0)
1259 "Unexpected combination of global variables and function pointers");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
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
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...
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...
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
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.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
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 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.
static void finishBuildOpDecorate(MachineInstrBuilder &MIB, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
bool isTypeFoldingSupported(unsigned Opcode)
static uint32_t convertCharsToWord(const StringRef &Str, unsigned i)
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)
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)
SmallVector< unsigned, 1 > getSpirvLoopControlOperandsFromLoopMetadata(MDNode *LoopMD)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
void buildOpMemberDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, uint32_t Member, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Type * toTypedPointer(Type *Ty)
DEMANGLE_ABI char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
bool isSpecialOpaqueType(const Type *Ty)
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)
std::optional< SPIRV::LinkageType::LinkageType > getSpirvLinkageTypeFor(const SPIRVSubtarget &ST, const GlobalValue &GV)
bool isEntryPoint(const Function &F)
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)
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)
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.