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();
90 if (auto *MDS = dyn_cast_or_null<MDString>(N->getOperand(0)))
91 return MDS->getString() == Name;
100 assert(MD &&
"MDNode operand is expected");
103 Constraints = MDS->getString();
110 F.getParent()->getNamedMetadata(
"spv.cloned_funcs"),
F.getFunctionType(),
134 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
135 unsigned StrIndex = i + WordIndex;
137 if (StrIndex < Str.size()) {
138 CharToAdd = Str[StrIndex];
140 Word |= (CharToAdd << (WordIndex * 8));
147 return (Str.size() + 4) & ~3;
152 for (
unsigned i = 0; i < PaddedLen; i += 4) {
160 for (
unsigned i = 0; i < PaddedLen; i += 4) {
167 std::vector<Value *> &Args) {
169 for (
unsigned i = 0; i < PaddedLen; i += 4) {
181 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
182 "Expected G_GLOBAL_VALUE");
183 const GlobalValue *GV = Def->getOperand(1).getGlobal();
190 const auto Bitwidth = Imm.getBitWidth();
193 else if (Bitwidth <= 32) {
194 MIB.
addImm(Imm.getZExtValue());
199 }
else if (Bitwidth <= 64) {
200 uint64_t FullImm = Imm.getZExtValue();
201 uint32_t LowBits = FullImm & 0xffffffff;
202 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
209 unsigned NumWords = (Bitwidth + 31) / 32;
210 for (
unsigned I = 0;
I < NumWords; ++
I) {
211 unsigned LimbIdx =
I / 2;
212 unsigned LimbShift = (
I % 2) * 32;
213 uint32_t Word = (Imm.getRawData()[LimbIdx] >> LimbShift) & 0xffffffff;
232 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
239 const std::vector<uint32_t> &DecArgs,
243 for (
const auto &DecArg : DecArgs)
248 SPIRV::Decoration::Decoration Dec,
249 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
250 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
257 SPIRV::Decoration::Decoration Dec,
258 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
260 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
267 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
268 const std::vector<uint32_t> &DecArgs,
270 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
279 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
280 const std::vector<uint32_t> &DecArgs,
283 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
296 if (OpMD->getNumOperands() == 0)
302 "element of the decoration");
312 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
314 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
317 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
320 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
323 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
338 switch (
MI.getOpcode()) {
339 case SPIRV::OpFunction:
340 case SPIRV::OpFunctionParameter:
342 case SPIRV::ASSIGN_TYPE:
349 while (VarPos !=
MBB.end() && VarPos->getOpcode() != SPIRV::OpFunction)
352 while (VarPos !=
MBB.end() && IsPreamble(*VarPos))
359 if (
I ==
MBB->begin())
362 while (
I->isTerminator() ||
I->isDebugValue()) {
363 if (
I ==
MBB->begin())
370SPIRV::StorageClass::StorageClass
374 return SPIRV::StorageClass::Function;
376 return SPIRV::StorageClass::CrossWorkgroup;
378 return SPIRV::StorageClass::UniformConstant;
380 return SPIRV::StorageClass::Workgroup;
382 return SPIRV::StorageClass::Generic;
384 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
385 ? SPIRV::StorageClass::DeviceOnlyINTEL
386 : SPIRV::StorageClass::CrossWorkgroup;
388 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
389 ? SPIRV::StorageClass::HostOnlyINTEL
390 : SPIRV::StorageClass::CrossWorkgroup;
392 return SPIRV::StorageClass::Input;
394 return SPIRV::StorageClass::Output;
396 return SPIRV::StorageClass::CodeSectionINTEL;
398 return SPIRV::StorageClass::Private;
400 return SPIRV::StorageClass::StorageBuffer;
402 return SPIRV::StorageClass::Uniform;
404 return SPIRV::StorageClass::PushConstant;
410SPIRV::MemorySemantics::MemorySemantics
413 case SPIRV::StorageClass::StorageBuffer:
414 case SPIRV::StorageClass::Uniform:
415 return SPIRV::MemorySemantics::UniformMemory;
416 case SPIRV::StorageClass::Workgroup:
417 return SPIRV::MemorySemantics::WorkgroupMemory;
418 case SPIRV::StorageClass::CrossWorkgroup:
419 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
420 case SPIRV::StorageClass::AtomicCounter:
421 return SPIRV::MemorySemantics::AtomicCounterMemory;
422 case SPIRV::StorageClass::Image:
423 return SPIRV::MemorySemantics::ImageMemory;
425 return SPIRV::MemorySemantics::None;
432 return SPIRV::MemorySemantics::Acquire;
434 return SPIRV::MemorySemantics::Release;
436 return SPIRV::MemorySemantics::AcquireRelease;
438 return SPIRV::MemorySemantics::SequentiallyConsistent;
442 return SPIRV::MemorySemantics::None;
454 Ctx.getOrInsertSyncScopeID(
"subgroup");
456 Ctx.getOrInsertSyncScopeID(
"workgroup");
458 Ctx.getOrInsertSyncScopeID(
"device");
461 return SPIRV::Scope::Invocation;
463 return SPIRV::Scope::CrossDevice;
464 else if (Id == SubGroup)
465 return SPIRV::Scope::Subgroup;
466 else if (Id == WorkGroup)
467 return SPIRV::Scope::Workgroup;
468 else if (Id == Device)
469 return SPIRV::Scope::Device;
470 return SPIRV::Scope::CrossDevice;
477 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
481 if (GI->is(Intrinsic::spv_track_constant)) {
485 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
488 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
489 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
498 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
499 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
504 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
505 return MI->getOperand(1).getCImm()->getSExtValue();
510 return GI->is(IntrinsicID);
522 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
523 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
524 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
525 MangledName ==
"reserve_write_pipe" ||
526 MangledName ==
"reserve_read_pipe" ||
527 MangledName ==
"commit_write_pipe" ||
528 MangledName ==
"commit_read_pipe" ||
529 MangledName ==
"work_group_reserve_write_pipe" ||
530 MangledName ==
"work_group_reserve_read_pipe" ||
531 MangledName ==
"work_group_commit_write_pipe" ||
532 MangledName ==
"work_group_commit_read_pipe" ||
533 MangledName ==
"get_pipe_num_packets_ro" ||
534 MangledName ==
"get_pipe_max_packets_ro" ||
535 MangledName ==
"get_pipe_num_packets_wo" ||
536 MangledName ==
"get_pipe_max_packets_wo" ||
537 MangledName ==
"sub_group_reserve_write_pipe" ||
538 MangledName ==
"sub_group_reserve_read_pipe" ||
539 MangledName ==
"sub_group_commit_write_pipe" ||
540 MangledName ==
"sub_group_commit_read_pipe" ||
541 MangledName ==
"to_global" || MangledName ==
"to_local" ||
542 MangledName ==
"to_private";
546 return MangledName ==
"__enqueue_kernel_basic" ||
547 MangledName ==
"__enqueue_kernel_basic_events" ||
548 MangledName ==
"__enqueue_kernel_varargs" ||
549 MangledName ==
"__enqueue_kernel_events_varargs";
553 return MangledName ==
"__get_kernel_work_group_size_impl" ||
554 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
555 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
556 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
560 if (!Name.starts_with(
"__"))
565 Name ==
"__translate_sampler_initializer";
570 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
571 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
572 bool IsMangled = Name.starts_with(
"_Z");
575 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
580 std::string Result = DemangledName;
589 size_t Start, Len = 0;
590 size_t DemangledNameLenStart = 2;
591 if (Name.starts_with(
"_ZN")) {
593 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
595 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
596 return std::string();
597 DemangledNameLenStart = NameSpaceStart + 11;
599 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
600 [[maybe_unused]]
bool Error =
601 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
602 .getAsInteger(10, Len);
603 assert(!
Error &&
"Failed to parse demangled name length");
604 return Name.substr(Start, Len).str();
608 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
609 Name.starts_with(
"spirv."))
631 if (
F.getFnAttribute(
"hlsl.shader").isValid())
638 TypeName.consume_front(
"atomic_");
639 if (TypeName.consume_front(
"void"))
641 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
643 else if (TypeName.consume_front(
"char") ||
644 TypeName.consume_front(
"signed char") ||
645 TypeName.consume_front(
"unsigned char") ||
646 TypeName.consume_front(
"uchar"))
648 else if (TypeName.consume_front(
"short") ||
649 TypeName.consume_front(
"signed short") ||
650 TypeName.consume_front(
"unsigned short") ||
651 TypeName.consume_front(
"ushort"))
653 else if (TypeName.consume_front(
"int") ||
654 TypeName.consume_front(
"signed int") ||
655 TypeName.consume_front(
"unsigned int") ||
656 TypeName.consume_front(
"uint"))
658 else if (TypeName.consume_front(
"long") ||
659 TypeName.consume_front(
"signed long") ||
660 TypeName.consume_front(
"unsigned long") ||
661 TypeName.consume_front(
"ulong"))
663 else if (TypeName.consume_front(
"half") ||
664 TypeName.consume_front(
"_Float16") ||
665 TypeName.consume_front(
"__fp16"))
667 else if (TypeName.consume_front(
"float"))
669 else if (TypeName.consume_front(
"double"))
676std::unordered_set<BasicBlock *>
677PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
678 std::queue<BasicBlock *> ToVisit;
681 std::unordered_set<BasicBlock *> Output;
682 while (ToVisit.size() != 0) {
683 BasicBlock *BB = ToVisit.front();
686 if (Output.count(BB) != 0)
700bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
703 if (DT.dominates(BB,
P))
707 if (BlockToOrder.count(
P) == 0)
712 Loop *
L = LI.getLoopFor(
P);
713 if (L ==
nullptr ||
L->contains(BB))
719 assert(
L->getNumBackEdges() <= 1);
725 if (Latch ==
nullptr)
729 if (BlockToOrder.count(Latch) == 0)
737 auto It = BlockToOrder.find(BB);
738 if (It != BlockToOrder.end())
739 return It->second.Rank;
744 if (DT.dominates(BB,
P))
747 auto Iterator = BlockToOrder.end();
748 Loop *L = LI.getLoopFor(
P);
749 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
753 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
754 Iterator = BlockToOrder.find(
P);
759 Iterator = BlockToOrder.find(Latch);
762 assert(Iterator != BlockToOrder.end());
763 result = std::max(result, Iterator->second.Rank + 1);
769size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
773 size_t QueueIndex = 0;
774 while (ToVisit.size() != 0) {
778 if (!CanBeVisited(BB)) {
780 if (QueueIndex >= ToVisit.size())
782 "No valid candidate in the queue. Is the graph reducible?");
789 OrderInfo Info = {Rank, BlockToOrder.size()};
790 BlockToOrder.emplace(BB, Info);
793 if (Queued.count(S) != 0)
807 visit(&*
F.begin(), 0);
809 Order.reserve(
F.size());
810 for (
auto &[BB, Info] : BlockToOrder)
811 Order.emplace_back(BB);
813 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
814 return compare(LHS, RHS);
820 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
821 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
822 if (InfoLHS.Rank != InfoRHS.Rank)
823 return InfoLHS.Rank < InfoRHS.Rank;
824 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
829 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
830 assert(BlockToOrder.count(&Start) != 0);
833 auto It = Order.begin();
834 while (It != Order.end() && *It != &Start)
839 assert(It != Order.end());
842 std::optional<size_t> EndRank = std::nullopt;
843 for (; It != Order.end(); ++It) {
844 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
847 if (Reachable.count(*It) == 0) {
852 EndRank = BlockToOrder[*It].Rank;
862 std::vector<BasicBlock *> Order;
863 Order.reserve(
F.size());
868 assert(&*
F.begin() == Order[0]);
871 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
883 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
891 constexpr unsigned MaxIters = 1024;
892 for (
unsigned I = 0;
I < MaxIters; ++
I) {
893 std::string OrdName = Name +
Twine(
I).
str();
894 if (!M.getFunction(OrdName)) {
895 Name = std::move(OrdName);
921 SPIRV::AccessQualifier::AccessQualifier AccessQual,
922 bool EmitIR,
bool Force) {
925 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
951 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
961 Args.push_back(Arg2);
964 return B.CreateIntrinsic(IntrID, {Types}, Args);
969 if (Ty->isPtrOrPtrVectorTy())
974 for (
const Type *ArgTy : RefTy->params())
987 if (
F->getName().starts_with(
"llvm.spv."))
994SmallVector<MachineInstr *, 4>
996 unsigned MinWC,
unsigned ContinuedOpcode,
1001 constexpr unsigned MaxWordCount = UINT16_MAX;
1002 const size_t NumElements = Args.size();
1003 size_t MaxNumElements = MaxWordCount - MinWC;
1004 size_t SPIRVStructNumElements = NumElements;
1006 if (NumElements > MaxNumElements) {
1009 SPIRVStructNumElements = MaxNumElements;
1010 MaxNumElements = MaxWordCount - 1;
1016 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
1019 Instructions.push_back(MIB.getInstr());
1021 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
1022 I += MaxNumElements) {
1023 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
1024 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
1026 Instructions.push_back(MIB.getInstr());
1028 return Instructions;
1033 unsigned LC = SPIRV::LoopControl::None;
1037 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
1039 LC |= SPIRV::LoopControl::DontUnroll;
1043 LC |= SPIRV::LoopControl::Unroll;
1049 unsigned Count = CI->getZExtValue();
1051 LC |= SPIRV::LoopControl::PartialCount;
1052 MaskToValueMap.emplace_back(
1053 std::make_pair(SPIRV::LoopControl::PartialCount,
Count));
1059 for (
auto &[Mask, Val] : MaskToValueMap)
1060 Result.push_back(Val);
1070 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1071 TargetOpcode::G_ADD,
1072 TargetOpcode::G_FADD,
1073 TargetOpcode::G_STRICT_FADD,
1074 TargetOpcode::G_SUB,
1075 TargetOpcode::G_FSUB,
1076 TargetOpcode::G_STRICT_FSUB,
1077 TargetOpcode::G_MUL,
1078 TargetOpcode::G_FMUL,
1079 TargetOpcode::G_STRICT_FMUL,
1080 TargetOpcode::G_SDIV,
1081 TargetOpcode::G_UDIV,
1082 TargetOpcode::G_FDIV,
1083 TargetOpcode::G_STRICT_FDIV,
1084 TargetOpcode::G_SREM,
1085 TargetOpcode::G_UREM,
1086 TargetOpcode::G_FREM,
1087 TargetOpcode::G_STRICT_FREM,
1088 TargetOpcode::G_FNEG,
1089 TargetOpcode::G_CONSTANT,
1090 TargetOpcode::G_FCONSTANT,
1091 TargetOpcode::G_AND,
1093 TargetOpcode::G_XOR,
1094 TargetOpcode::G_SHL,
1095 TargetOpcode::G_ASHR,
1096 TargetOpcode::G_LSHR,
1097 TargetOpcode::G_SELECT,
1098 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1101 return TypeFoldingSupportingOpcs;
1110 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1111 Def->getOpcode() == TargetOpcode::COPY)
1112 ? MRI->
getVRegDef(Def->getOperand(1).getReg())
1124 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1125 Def->getOpcode() == SPIRV::OpConstantI)
1133 if (Def->getOpcode() == SPIRV::OpConstantI)
1134 return Def->getOperand(2).getImm();
1135 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1136 return Def->getOperand(1).getCImm()->getZExtValue();
1149 if (Ty->getStructNumElements() != 2)
1164 if (T_in_struct != SecondElement)
1167 auto *Padding_in_struct =
1169 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1173 TotalSize = ArraySize + 1;
1174 OriginalElementType = ArrayElementType;
1179 if (!Ty->isStructTy())
1183 Type *OriginalElementType =
nullptr;
1193 for (
Type *ElementTy : STy->elements()) {
1195 if (NewElementTy != ElementTy)
1197 NewElementTypes.
push_back(NewElementTy);
1204 if (STy->isLiteral())
1209 NewTy->setBody(NewElementTypes, STy->isPacked());
1215std::optional<SPIRV::LinkageType::LinkageType>
1218 return std::nullopt;
1224 if (SC == SPIRV::StorageClass::Input ||
1225 SC == SPIRV::StorageClass::Output ||
1226 SC == SPIRV::StorageClass::PushConstant)
1227 return std::nullopt;
1229 return SPIRV::LinkageType::Import;
1233 return std::nullopt;
1236 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1237 return SPIRV::LinkageType::LinkOnceODR;
1240 ST.canUseExtension(SPIRV::Extension::SPV_AMD_weak_linkage))
1241 return SPIRV::LinkageType::Weak;
1243 return SPIRV::LinkageType::Export;
1250 "cannot allocate a name for the internal service function");
1252 if (SF->getInstructionCount() > 0)
1254 "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.
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...
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.
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.
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)
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.