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 assert(Const->getSExtValue() >= -1);
72 if (Const->getSExtValue() == -1)
73 RetTy = CMeta->getType();
75 PTys[Const->getSExtValue()] = CMeta->getType();
84 F.getParent()->getNamedMetadata(
"spv.cloned_funcs"),
F.getFunctionType(),
101 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
102 unsigned StrIndex = i + WordIndex;
104 if (StrIndex < Str.size()) {
105 CharToAdd = Str[StrIndex];
107 Word |= (CharToAdd << (WordIndex * 8));
114 return (Str.size() + 4) & ~3;
119 for (
unsigned i = 0; i < PaddedLen; i += 4) {
127 for (
unsigned i = 0; i < PaddedLen; i += 4) {
134 std::vector<Value *> &Args) {
136 for (
unsigned i = 0; i < PaddedLen; i += 4) {
148 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
149 "Expected G_GLOBAL_VALUE");
150 const GlobalValue *GV = Def->getOperand(1).getGlobal();
157 const auto Bitwidth = Imm.getBitWidth();
160 else if (Bitwidth <= 32) {
161 MIB.
addImm(Imm.getZExtValue());
166 }
else if (Bitwidth <= 64) {
167 uint64_t FullImm = Imm.getZExtValue();
168 uint32_t LowBits = FullImm & 0xffffffff;
169 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
176 unsigned NumWords = (Bitwidth + 31) / 32;
177 for (
unsigned I = 0;
I < NumWords; ++
I) {
178 unsigned LimbIdx =
I / 2;
179 unsigned LimbShift = (
I % 2) * 32;
180 uint32_t Word = (Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
199 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
206 const std::vector<uint32_t> &DecArgs,
210 for (
const auto &DecArg : DecArgs)
215 SPIRV::Decoration::Decoration Dec,
216 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
217 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
224 SPIRV::Decoration::Decoration Dec,
225 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
227 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
234 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
235 const std::vector<uint32_t> &DecArgs,
237 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
246 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
247 const std::vector<uint32_t> &DecArgs,
250 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
263 if (OpMD->getNumOperands() == 0)
269 "element of the decoration");
279 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
281 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
284 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
287 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
290 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
304 bool IsHeader =
false;
306 for (; It !=
E && It !=
I; ++It) {
307 Opcode = It->getOpcode();
308 if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
310 }
else if (IsHeader &&
311 !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
321 if (
I ==
MBB->begin())
324 while (
I->isTerminator() ||
I->isDebugValue()) {
325 if (
I ==
MBB->begin())
332SPIRV::StorageClass::StorageClass
336 return SPIRV::StorageClass::Function;
338 return SPIRV::StorageClass::CrossWorkgroup;
340 return SPIRV::StorageClass::UniformConstant;
342 return SPIRV::StorageClass::Workgroup;
344 return SPIRV::StorageClass::Generic;
346 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
347 ? SPIRV::StorageClass::DeviceOnlyINTEL
348 : SPIRV::StorageClass::CrossWorkgroup;
350 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
351 ? SPIRV::StorageClass::HostOnlyINTEL
352 : SPIRV::StorageClass::CrossWorkgroup;
354 return SPIRV::StorageClass::Input;
356 return SPIRV::StorageClass::Output;
358 return SPIRV::StorageClass::CodeSectionINTEL;
360 return SPIRV::StorageClass::Private;
362 return SPIRV::StorageClass::StorageBuffer;
364 return SPIRV::StorageClass::Uniform;
366 return SPIRV::StorageClass::PushConstant;
372SPIRV::MemorySemantics::MemorySemantics
375 case SPIRV::StorageClass::StorageBuffer:
376 case SPIRV::StorageClass::Uniform:
377 return SPIRV::MemorySemantics::UniformMemory;
378 case SPIRV::StorageClass::Workgroup:
379 return SPIRV::MemorySemantics::WorkgroupMemory;
380 case SPIRV::StorageClass::CrossWorkgroup:
381 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
382 case SPIRV::StorageClass::AtomicCounter:
383 return SPIRV::MemorySemantics::AtomicCounterMemory;
384 case SPIRV::StorageClass::Image:
385 return SPIRV::MemorySemantics::ImageMemory;
387 return SPIRV::MemorySemantics::None;
394 return SPIRV::MemorySemantics::Acquire;
396 return SPIRV::MemorySemantics::Release;
398 return SPIRV::MemorySemantics::AcquireRelease;
400 return SPIRV::MemorySemantics::SequentiallyConsistent;
404 return SPIRV::MemorySemantics::None;
416 Ctx.getOrInsertSyncScopeID(
"subgroup");
418 Ctx.getOrInsertSyncScopeID(
"workgroup");
420 Ctx.getOrInsertSyncScopeID(
"device");
423 return SPIRV::Scope::Invocation;
425 return SPIRV::Scope::CrossDevice;
426 else if (Id == SubGroup)
427 return SPIRV::Scope::Subgroup;
428 else if (Id == WorkGroup)
429 return SPIRV::Scope::Workgroup;
430 else if (Id == Device)
431 return SPIRV::Scope::Device;
432 return SPIRV::Scope::CrossDevice;
439 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
440 ?
MRI->getVRegDef(
MI->getOperand(1).getReg())
443 if (GI->is(Intrinsic::spv_track_constant)) {
445 return MRI->getVRegDef(ConstReg);
447 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
449 return MRI->getVRegDef(ConstReg);
450 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
451 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
455 return MRI->getVRegDef(ConstReg);
460 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
461 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
466 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
467 return MI->getOperand(1).getCImm()->getSExtValue();
472 return GI->is(IntrinsicID);
484 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
485 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
486 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
487 MangledName ==
"reserve_write_pipe" ||
488 MangledName ==
"reserve_read_pipe" ||
489 MangledName ==
"commit_write_pipe" ||
490 MangledName ==
"commit_read_pipe" ||
491 MangledName ==
"work_group_reserve_write_pipe" ||
492 MangledName ==
"work_group_reserve_read_pipe" ||
493 MangledName ==
"work_group_commit_write_pipe" ||
494 MangledName ==
"work_group_commit_read_pipe" ||
495 MangledName ==
"get_pipe_num_packets_ro" ||
496 MangledName ==
"get_pipe_max_packets_ro" ||
497 MangledName ==
"get_pipe_num_packets_wo" ||
498 MangledName ==
"get_pipe_max_packets_wo" ||
499 MangledName ==
"sub_group_reserve_write_pipe" ||
500 MangledName ==
"sub_group_reserve_read_pipe" ||
501 MangledName ==
"sub_group_commit_write_pipe" ||
502 MangledName ==
"sub_group_commit_read_pipe" ||
503 MangledName ==
"to_global" || MangledName ==
"to_local" ||
504 MangledName ==
"to_private";
508 return MangledName ==
"__enqueue_kernel_basic" ||
509 MangledName ==
"__enqueue_kernel_basic_events" ||
510 MangledName ==
"__enqueue_kernel_varargs" ||
511 MangledName ==
"__enqueue_kernel_events_varargs";
515 return MangledName ==
"__get_kernel_work_group_size_impl" ||
516 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
517 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
518 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
522 if (!Name.starts_with(
"__"))
527 Name ==
"__translate_sampler_initializer";
532 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
533 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
534 bool IsMangled = Name.starts_with(
"_Z");
537 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
542 std::string Result = DemangledName;
551 size_t Start, Len = 0;
552 size_t DemangledNameLenStart = 2;
553 if (Name.starts_with(
"_ZN")) {
555 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
557 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
558 return std::string();
559 DemangledNameLenStart = NameSpaceStart + 11;
561 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
562 [[maybe_unused]]
bool Error =
563 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
564 .getAsInteger(10, Len);
565 assert(!
Error &&
"Failed to parse demangled name length");
566 return Name.substr(Start, Len).str();
570 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
571 Name.starts_with(
"spirv."))
593 if (
F.getFnAttribute(
"hlsl.shader").isValid())
600 TypeName.consume_front(
"atomic_");
601 if (TypeName.consume_front(
"void"))
603 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
605 else if (TypeName.consume_front(
"char") ||
606 TypeName.consume_front(
"signed char") ||
607 TypeName.consume_front(
"unsigned char") ||
608 TypeName.consume_front(
"uchar"))
610 else if (TypeName.consume_front(
"short") ||
611 TypeName.consume_front(
"signed short") ||
612 TypeName.consume_front(
"unsigned short") ||
613 TypeName.consume_front(
"ushort"))
615 else if (TypeName.consume_front(
"int") ||
616 TypeName.consume_front(
"signed int") ||
617 TypeName.consume_front(
"unsigned int") ||
618 TypeName.consume_front(
"uint"))
620 else if (TypeName.consume_front(
"long") ||
621 TypeName.consume_front(
"signed long") ||
622 TypeName.consume_front(
"unsigned long") ||
623 TypeName.consume_front(
"ulong"))
625 else if (TypeName.consume_front(
"half") ||
626 TypeName.consume_front(
"_Float16") ||
627 TypeName.consume_front(
"__fp16"))
629 else if (TypeName.consume_front(
"float"))
631 else if (TypeName.consume_front(
"double"))
638std::unordered_set<BasicBlock *>
639PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
640 std::queue<BasicBlock *> ToVisit;
643 std::unordered_set<BasicBlock *> Output;
644 while (ToVisit.size() != 0) {
645 BasicBlock *BB = ToVisit.front();
648 if (Output.count(BB) != 0)
662bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
665 if (DT.dominates(BB,
P))
669 if (BlockToOrder.count(
P) == 0)
674 Loop *
L = LI.getLoopFor(
P);
675 if (L ==
nullptr ||
L->contains(BB))
681 assert(
L->getNumBackEdges() <= 1);
687 if (Latch ==
nullptr)
691 if (BlockToOrder.count(Latch) == 0)
699 auto It = BlockToOrder.find(BB);
700 if (It != BlockToOrder.end())
701 return It->second.Rank;
706 if (DT.dominates(BB,
P))
709 auto Iterator = BlockToOrder.end();
710 Loop *L = LI.getLoopFor(
P);
711 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
715 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
716 Iterator = BlockToOrder.find(
P);
721 Iterator = BlockToOrder.find(Latch);
724 assert(Iterator != BlockToOrder.end());
725 result = std::max(result, Iterator->second.Rank + 1);
731size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
735 size_t QueueIndex = 0;
736 while (ToVisit.size() != 0) {
740 if (!CanBeVisited(BB)) {
742 if (QueueIndex >= ToVisit.size())
744 "No valid candidate in the queue. Is the graph reducible?");
751 OrderInfo Info = {Rank, BlockToOrder.size()};
752 BlockToOrder.emplace(BB, Info);
755 if (Queued.count(S) != 0)
769 visit(&*
F.begin(), 0);
771 Order.reserve(
F.size());
772 for (
auto &[BB, Info] : BlockToOrder)
773 Order.emplace_back(BB);
775 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
776 return compare(LHS, RHS);
782 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
783 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
784 if (InfoLHS.Rank != InfoRHS.Rank)
785 return InfoLHS.Rank < InfoRHS.Rank;
786 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
791 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
792 assert(BlockToOrder.count(&Start) != 0);
795 auto It = Order.begin();
796 while (It != Order.end() && *It != &Start)
801 assert(It != Order.end());
804 std::optional<size_t> EndRank = std::nullopt;
805 for (; It != Order.end(); ++It) {
806 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
809 if (Reachable.count(*It) == 0) {
814 EndRank = BlockToOrder[*It].Rank;
824 std::vector<BasicBlock *> Order;
825 Order.reserve(
F.size());
830 assert(&*
F.begin() == Order[0]);
833 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
845 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
853 constexpr unsigned MaxIters = 1024;
854 for (
unsigned I = 0;
I < MaxIters; ++
I) {
855 std::string OrdName = Name +
Twine(
I).
str();
856 if (!M.getFunction(OrdName)) {
857 Name = std::move(OrdName);
870 if (!
MRI->getRegClassOrNull(
Reg) || Force) {
881 SPIRV::AccessQualifier::AccessQualifier AccessQual,
882 bool EmitIR,
bool Force) {
885 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
911 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
921 Args.push_back(Arg2);
924 return B.CreateIntrinsic(IntrID, {Types}, Args);
929 if (Ty->isPtrOrPtrVectorTy())
934 for (
const Type *ArgTy : RefTy->params())
947 if (
F->getName().starts_with(
"llvm.spv."))
954SmallVector<MachineInstr *, 4>
956 unsigned MinWC,
unsigned ContinuedOpcode,
961 constexpr unsigned MaxWordCount = UINT16_MAX;
962 const size_t NumElements = Args.size();
963 size_t MaxNumElements = MaxWordCount - MinWC;
964 size_t SPIRVStructNumElements = NumElements;
966 if (NumElements > MaxNumElements) {
969 SPIRVStructNumElements = MaxNumElements;
970 MaxNumElements = MaxWordCount - 1;
976 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
979 Instructions.push_back(MIB.getInstr());
981 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
982 I += MaxNumElements) {
983 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
984 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
986 Instructions.push_back(MIB.getInstr());
993 unsigned LC = SPIRV::LoopControl::None;
997 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
999 LC |= SPIRV::LoopControl::DontUnroll;
1003 LC |= SPIRV::LoopControl::Unroll;
1009 unsigned Count = CI->getZExtValue();
1011 LC |= SPIRV::LoopControl::PartialCount;
1012 MaskToValueMap.emplace_back(
1013 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1019 for (
auto &[Mask, Val] : MaskToValueMap)
1020 Result.push_back(Val);
1030 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1031 TargetOpcode::G_ADD,
1032 TargetOpcode::G_FADD,
1033 TargetOpcode::G_STRICT_FADD,
1034 TargetOpcode::G_SUB,
1035 TargetOpcode::G_FSUB,
1036 TargetOpcode::G_STRICT_FSUB,
1037 TargetOpcode::G_MUL,
1038 TargetOpcode::G_FMUL,
1039 TargetOpcode::G_STRICT_FMUL,
1040 TargetOpcode::G_SDIV,
1041 TargetOpcode::G_UDIV,
1042 TargetOpcode::G_FDIV,
1043 TargetOpcode::G_STRICT_FDIV,
1044 TargetOpcode::G_SREM,
1045 TargetOpcode::G_UREM,
1046 TargetOpcode::G_FREM,
1047 TargetOpcode::G_STRICT_FREM,
1048 TargetOpcode::G_FNEG,
1049 TargetOpcode::G_CONSTANT,
1050 TargetOpcode::G_FCONSTANT,
1051 TargetOpcode::G_AND,
1053 TargetOpcode::G_XOR,
1054 TargetOpcode::G_SHL,
1055 TargetOpcode::G_ASHR,
1056 TargetOpcode::G_LSHR,
1057 TargetOpcode::G_SELECT,
1058 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1061 return TypeFoldingSupportingOpcs;
1070 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1071 Def->getOpcode() == TargetOpcode::COPY)
1072 ?
MRI->getVRegDef(Def->getOperand(1).getReg())
1084 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1085 Def->getOpcode() == SPIRV::OpConstantI)
1093 if (Def->getOpcode() == SPIRV::OpConstantI)
1094 return Def->getOperand(2).getImm();
1095 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1096 return Def->getOperand(1).getCImm()->getZExtValue();
1112 while (VarPos != BB.
end() && VarPos->getOpcode() != SPIRV::OpFunction) {
1119 while (VarPos != BB.
end() &&
1120 VarPos->getOpcode() == SPIRV::OpFunctionParameter) {
1125 return VarPos != BB.
end() && VarPos->getOpcode() == SPIRV::OpLabel ? ++VarPos
1132 if (Ty->getStructNumElements() != 2)
1147 if (T_in_struct != SecondElement)
1150 auto *Padding_in_struct =
1152 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1156 TotalSize = ArraySize + 1;
1157 OriginalElementType = ArrayElementType;
1162 if (!Ty->isStructTy())
1166 Type *OriginalElementType =
nullptr;
1176 for (
Type *ElementTy : STy->elements()) {
1178 if (NewElementTy != ElementTy)
1180 NewElementTypes.
push_back(NewElementTy);
1187 if (STy->isLiteral())
1192 NewTy->setBody(NewElementTypes, STy->isPacked());
1198std::optional<SPIRV::LinkageType::LinkageType>
1201 return std::nullopt;
1204 return SPIRV::LinkageType::Import;
1207 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1208 return SPIRV::LinkageType::LinkOnceODR;
1210 return SPIRV::LinkageType::Export;
unsigned const MachineRegisterInfo * MRI
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)
Class for arbitrary precision integers.
ArrayRef - 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...
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 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.
bool hasLocalLinkage() const
bool hasHiddenVisibility() const
bool isDeclarationForLinker() const
bool hasLinkOnceODRLinkage() const
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...
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(uint8_t 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,...
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.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - 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.
FunctionType * getOriginalFunctionType(const Function &F)
static FunctionType * extractFunctionTypeFromMetadata(NamedMDNode *NMD, FunctionType *FTy, StringRef Name)
@ 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)
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)
MachineBasicBlock::iterator getFirstValidInstructionInsertPoint(MachineBasicBlock &BB)
bool isNestedPointer(const Type *Ty)
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)
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I)
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)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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.