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;
174 }
else if (Bitwidth <= 128) {
175 uint32_t LowBits = Imm.getRawData()[0] & 0xffffffff;
176 uint32_t MidBits0 = (Imm.getRawData()[0] >> 32) & 0xffffffff;
177 uint32_t MidBits1 = Imm.getRawData()[1] & 0xffffffff;
178 uint32_t HighBits = (Imm.getRawData()[1] >> 32) & 0xffffffff;
197 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
204 const std::vector<uint32_t> &DecArgs,
208 for (
const auto &DecArg : DecArgs)
213 SPIRV::Decoration::Decoration Dec,
214 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
215 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
222 SPIRV::Decoration::Decoration Dec,
223 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
225 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
232 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
233 const std::vector<uint32_t> &DecArgs,
235 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
244 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
245 const std::vector<uint32_t> &DecArgs,
248 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
261 if (OpMD->getNumOperands() == 0)
267 "element of the decoration");
277 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
279 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
282 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
285 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
288 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
302 bool IsHeader =
false;
304 for (; It !=
E && It !=
I; ++It) {
305 Opcode = It->getOpcode();
306 if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
308 }
else if (IsHeader &&
309 !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
319 if (
I ==
MBB->begin())
322 while (
I->isTerminator() ||
I->isDebugValue()) {
323 if (
I ==
MBB->begin())
330SPIRV::StorageClass::StorageClass
334 return SPIRV::StorageClass::Function;
336 return SPIRV::StorageClass::CrossWorkgroup;
338 return SPIRV::StorageClass::UniformConstant;
340 return SPIRV::StorageClass::Workgroup;
342 return SPIRV::StorageClass::Generic;
344 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
345 ? SPIRV::StorageClass::DeviceOnlyINTEL
346 : SPIRV::StorageClass::CrossWorkgroup;
348 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
349 ? SPIRV::StorageClass::HostOnlyINTEL
350 : SPIRV::StorageClass::CrossWorkgroup;
352 return SPIRV::StorageClass::Input;
354 return SPIRV::StorageClass::Output;
356 return SPIRV::StorageClass::CodeSectionINTEL;
358 return SPIRV::StorageClass::Private;
360 return SPIRV::StorageClass::StorageBuffer;
362 return SPIRV::StorageClass::Uniform;
368SPIRV::MemorySemantics::MemorySemantics
371 case SPIRV::StorageClass::StorageBuffer:
372 case SPIRV::StorageClass::Uniform:
373 return SPIRV::MemorySemantics::UniformMemory;
374 case SPIRV::StorageClass::Workgroup:
375 return SPIRV::MemorySemantics::WorkgroupMemory;
376 case SPIRV::StorageClass::CrossWorkgroup:
377 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
378 case SPIRV::StorageClass::AtomicCounter:
379 return SPIRV::MemorySemantics::AtomicCounterMemory;
380 case SPIRV::StorageClass::Image:
381 return SPIRV::MemorySemantics::ImageMemory;
383 return SPIRV::MemorySemantics::None;
390 return SPIRV::MemorySemantics::Acquire;
392 return SPIRV::MemorySemantics::Release;
394 return SPIRV::MemorySemantics::AcquireRelease;
396 return SPIRV::MemorySemantics::SequentiallyConsistent;
400 return SPIRV::MemorySemantics::None;
412 Ctx.getOrInsertSyncScopeID(
"subgroup");
414 Ctx.getOrInsertSyncScopeID(
"workgroup");
416 Ctx.getOrInsertSyncScopeID(
"device");
419 return SPIRV::Scope::Invocation;
421 return SPIRV::Scope::CrossDevice;
422 else if (Id == SubGroup)
423 return SPIRV::Scope::Subgroup;
424 else if (Id == WorkGroup)
425 return SPIRV::Scope::Workgroup;
426 else if (Id == Device)
427 return SPIRV::Scope::Device;
428 return SPIRV::Scope::CrossDevice;
435 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
436 ?
MRI->getVRegDef(
MI->getOperand(1).getReg())
439 if (GI->is(Intrinsic::spv_track_constant)) {
441 return MRI->getVRegDef(ConstReg);
443 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
445 return MRI->getVRegDef(ConstReg);
446 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
447 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
451 return MRI->getVRegDef(ConstReg);
456 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
457 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
462 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
463 return MI->getOperand(1).getCImm()->getSExtValue();
468 return GI->is(IntrinsicID);
480 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
481 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
482 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
483 MangledName ==
"reserve_write_pipe" ||
484 MangledName ==
"reserve_read_pipe" ||
485 MangledName ==
"commit_write_pipe" ||
486 MangledName ==
"commit_read_pipe" ||
487 MangledName ==
"work_group_reserve_write_pipe" ||
488 MangledName ==
"work_group_reserve_read_pipe" ||
489 MangledName ==
"work_group_commit_write_pipe" ||
490 MangledName ==
"work_group_commit_read_pipe" ||
491 MangledName ==
"get_pipe_num_packets_ro" ||
492 MangledName ==
"get_pipe_max_packets_ro" ||
493 MangledName ==
"get_pipe_num_packets_wo" ||
494 MangledName ==
"get_pipe_max_packets_wo" ||
495 MangledName ==
"sub_group_reserve_write_pipe" ||
496 MangledName ==
"sub_group_reserve_read_pipe" ||
497 MangledName ==
"sub_group_commit_write_pipe" ||
498 MangledName ==
"sub_group_commit_read_pipe" ||
499 MangledName ==
"to_global" || MangledName ==
"to_local" ||
500 MangledName ==
"to_private";
504 return MangledName ==
"__enqueue_kernel_basic" ||
505 MangledName ==
"__enqueue_kernel_basic_events" ||
506 MangledName ==
"__enqueue_kernel_varargs" ||
507 MangledName ==
"__enqueue_kernel_events_varargs";
511 return MangledName ==
"__get_kernel_work_group_size_impl" ||
512 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
513 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
514 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
518 if (!Name.starts_with(
"__"))
523 Name ==
"__translate_sampler_initializer";
528 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
529 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
530 bool IsMangled = Name.starts_with(
"_Z");
533 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
538 std::string Result = DemangledName;
547 size_t Start, Len = 0;
548 size_t DemangledNameLenStart = 2;
549 if (Name.starts_with(
"_ZN")) {
551 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
553 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
554 return std::string();
555 DemangledNameLenStart = NameSpaceStart + 11;
557 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
558 [[maybe_unused]]
bool Error =
559 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
560 .getAsInteger(10, Len);
561 assert(!
Error &&
"Failed to parse demangled name length");
562 return Name.substr(Start, Len).str();
566 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
567 Name.starts_with(
"spirv."))
589 if (
F.getFnAttribute(
"hlsl.shader").isValid())
596 TypeName.consume_front(
"atomic_");
597 if (TypeName.consume_front(
"void"))
599 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
601 else if (TypeName.consume_front(
"char") ||
602 TypeName.consume_front(
"signed char") ||
603 TypeName.consume_front(
"unsigned char") ||
604 TypeName.consume_front(
"uchar"))
606 else if (TypeName.consume_front(
"short") ||
607 TypeName.consume_front(
"signed short") ||
608 TypeName.consume_front(
"unsigned short") ||
609 TypeName.consume_front(
"ushort"))
611 else if (TypeName.consume_front(
"int") ||
612 TypeName.consume_front(
"signed int") ||
613 TypeName.consume_front(
"unsigned int") ||
614 TypeName.consume_front(
"uint"))
616 else if (TypeName.consume_front(
"long") ||
617 TypeName.consume_front(
"signed long") ||
618 TypeName.consume_front(
"unsigned long") ||
619 TypeName.consume_front(
"ulong"))
621 else if (TypeName.consume_front(
"half") ||
622 TypeName.consume_front(
"_Float16") ||
623 TypeName.consume_front(
"__fp16"))
625 else if (TypeName.consume_front(
"float"))
627 else if (TypeName.consume_front(
"double"))
634std::unordered_set<BasicBlock *>
635PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
636 std::queue<BasicBlock *> ToVisit;
639 std::unordered_set<BasicBlock *> Output;
640 while (ToVisit.size() != 0) {
641 BasicBlock *BB = ToVisit.front();
644 if (Output.count(BB) != 0)
658bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
661 if (DT.dominates(BB,
P))
665 if (BlockToOrder.count(
P) == 0)
670 Loop *
L = LI.getLoopFor(
P);
671 if (L ==
nullptr ||
L->contains(BB))
677 assert(
L->getNumBackEdges() <= 1);
683 if (Latch ==
nullptr)
687 if (BlockToOrder.count(Latch) == 0)
695 auto It = BlockToOrder.find(BB);
696 if (It != BlockToOrder.end())
697 return It->second.Rank;
702 if (DT.dominates(BB,
P))
705 auto Iterator = BlockToOrder.end();
706 Loop *L = LI.getLoopFor(
P);
707 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
711 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
712 Iterator = BlockToOrder.find(
P);
717 Iterator = BlockToOrder.find(Latch);
720 assert(Iterator != BlockToOrder.end());
721 result = std::max(result, Iterator->second.Rank + 1);
727size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
731 size_t QueueIndex = 0;
732 while (ToVisit.size() != 0) {
736 if (!CanBeVisited(BB)) {
738 if (QueueIndex >= ToVisit.size())
740 "No valid candidate in the queue. Is the graph reducible?");
747 OrderInfo
Info = {Rank, BlockToOrder.size()};
748 BlockToOrder.emplace(BB,
Info);
751 if (Queued.count(S) != 0)
765 visit(&*
F.begin(), 0);
767 Order.reserve(
F.size());
768 for (
auto &[BB,
Info] : BlockToOrder)
769 Order.emplace_back(BB);
771 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
772 return compare(LHS, RHS);
778 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
779 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
780 if (InfoLHS.Rank != InfoRHS.Rank)
781 return InfoLHS.Rank < InfoRHS.Rank;
782 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
787 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
788 assert(BlockToOrder.count(&Start) != 0);
791 auto It = Order.begin();
792 while (It != Order.end() && *It != &Start)
797 assert(It != Order.end());
800 std::optional<size_t> EndRank = std::nullopt;
801 for (; It != Order.end(); ++It) {
802 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
805 if (Reachable.count(*It) == 0) {
810 EndRank = BlockToOrder[*It].Rank;
820 std::vector<BasicBlock *> Order;
821 Order.reserve(
F.size());
826 assert(&*
F.begin() == Order[0]);
829 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
841 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
849 constexpr unsigned MaxIters = 1024;
850 for (
unsigned I = 0;
I < MaxIters; ++
I) {
851 std::string OrdName = Name +
Twine(
I).
str();
852 if (!M.getFunction(OrdName)) {
853 Name = std::move(OrdName);
866 if (!
MRI->getRegClassOrNull(
Reg) || Force) {
877 SPIRV::AccessQualifier::AccessQualifier AccessQual,
878 bool EmitIR,
bool Force) {
881 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
907 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
917 Args.push_back(Arg2);
920 return B.CreateIntrinsic(IntrID, {Types}, Args);
925 if (Ty->isPtrOrPtrVectorTy())
930 for (
const Type *ArgTy : RefTy->params())
943 if (
F->getName().starts_with(
"llvm.spv."))
950SmallVector<MachineInstr *, 4>
952 unsigned MinWC,
unsigned ContinuedOpcode,
957 constexpr unsigned MaxWordCount = UINT16_MAX;
958 const size_t NumElements = Args.size();
959 size_t MaxNumElements = MaxWordCount - MinWC;
960 size_t SPIRVStructNumElements = NumElements;
962 if (NumElements > MaxNumElements) {
965 SPIRVStructNumElements = MaxNumElements;
966 MaxNumElements = MaxWordCount - 1;
972 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
975 Instructions.push_back(MIB.getInstr());
977 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
978 I += MaxNumElements) {
979 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
980 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
982 Instructions.push_back(MIB.getInstr());
988 unsigned LC = SPIRV::LoopControl::None;
992 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
994 LC |= SPIRV::LoopControl::DontUnroll;
998 LC |= SPIRV::LoopControl::Unroll;
1000 std::optional<int>
Count =
1003 LC |= SPIRV::LoopControl::PartialCount;
1004 MaskToValueMap.emplace_back(
1005 std::make_pair(SPIRV::LoopControl::PartialCount, *
Count));
1009 for (
auto &[Mask, Val] : MaskToValueMap)
1010 Result.push_back(Val);
1016 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
1017 TargetOpcode::G_ADD,
1018 TargetOpcode::G_FADD,
1019 TargetOpcode::G_STRICT_FADD,
1020 TargetOpcode::G_SUB,
1021 TargetOpcode::G_FSUB,
1022 TargetOpcode::G_STRICT_FSUB,
1023 TargetOpcode::G_MUL,
1024 TargetOpcode::G_FMUL,
1025 TargetOpcode::G_STRICT_FMUL,
1026 TargetOpcode::G_SDIV,
1027 TargetOpcode::G_UDIV,
1028 TargetOpcode::G_FDIV,
1029 TargetOpcode::G_STRICT_FDIV,
1030 TargetOpcode::G_SREM,
1031 TargetOpcode::G_UREM,
1032 TargetOpcode::G_FREM,
1033 TargetOpcode::G_STRICT_FREM,
1034 TargetOpcode::G_FNEG,
1035 TargetOpcode::G_CONSTANT,
1036 TargetOpcode::G_FCONSTANT,
1037 TargetOpcode::G_AND,
1039 TargetOpcode::G_XOR,
1040 TargetOpcode::G_SHL,
1041 TargetOpcode::G_ASHR,
1042 TargetOpcode::G_LSHR,
1043 TargetOpcode::G_SELECT,
1044 TargetOpcode::G_EXTRACT_VECTOR_ELT,
1047 return TypeFoldingSupportingOpcs;
1056 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
1057 Def->getOpcode() == TargetOpcode::COPY)
1058 ?
MRI->getVRegDef(Def->getOperand(1).getReg())
1070 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
1071 Def->getOpcode() == SPIRV::OpConstantI)
1079 if (Def->getOpcode() == SPIRV::OpConstantI)
1080 return Def->getOperand(2).getImm();
1081 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1082 return Def->getOperand(1).getCImm()->getZExtValue();
1098 while (VarPos != BB.
end() && VarPos->getOpcode() != SPIRV::OpFunction) {
1105 while (VarPos != BB.
end() &&
1106 VarPos->getOpcode() == SPIRV::OpFunctionParameter) {
1111 return VarPos != BB.
end() && VarPos->getOpcode() == SPIRV::OpLabel ? ++VarPos
1118 if (Ty->getStructNumElements() != 2)
1133 if (T_in_struct != SecondElement)
1136 auto *Padding_in_struct =
1138 if (!Padding_in_struct || Padding_in_struct->getName() !=
"spirv.Padding")
1142 TotalSize = ArraySize + 1;
1143 OriginalElementType = ArrayElementType;
1148 if (!Ty->isStructTy())
1152 Type *OriginalElementType =
nullptr;
1162 for (
Type *ElementTy : STy->elements()) {
1164 if (NewElementTy != ElementTy)
1166 NewElementTypes.
push_back(NewElementTy);
1173 if (STy->isLiteral())
1178 NewTy->setBody(NewElementTypes, STy->isPacked());
1184std::optional<SPIRV::LinkageType::LinkageType>
1187 return std::nullopt;
1190 return SPIRV::LinkageType::Import;
1193 ST.canUseExtension(SPIRV::Extension::SPV_KHR_linkonce_odr))
1194 return SPIRV::LinkageType::LinkOnceODR;
1196 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")
Analysis containing CSE Info
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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
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(SPIRVType *Type, Register VReg, const MachineFunction &MF)
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineInstr &I, SPIRV::AccessQualifier::AccessQualifier AQ, bool EmitIR)
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
LLT getRegType(SPIRVType *SpvType) const
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 * > 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)
LLVM_ABI bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name)
Returns true if Name is applied to TheLoop and enabled.
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)
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)
SmallVector< unsigned, 1 > getSpirvLoopControlOperandsFromLoopMetadata(Loop *L)
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)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I)
Register createVirtualRegister(SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
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)
void setRegClassType(Register Reg, SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
FunctionAddr VTableAddr Count
const MachineInstr SPIRVType
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)
LLVM_ABI std::optional< int > getOptionalIntLoopAttribute(const Loop *TheLoop, StringRef Name)
Find named metadata for a loop with an integer value.
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)