26#include "llvm/IR/IntrinsicsSPIRV.h"
38 for (
unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
39 unsigned StrIndex = i + WordIndex;
41 if (StrIndex < Str.size()) {
42 CharToAdd = Str[StrIndex];
44 Word |= (CharToAdd << (WordIndex * 8));
51 return (Str.size() + 4) & ~3;
56 for (
unsigned i = 0; i < PaddedLen; i += 4) {
64 for (
unsigned i = 0; i < PaddedLen; i += 4) {
71 std::vector<Value *> &Args) {
73 for (
unsigned i = 0; i < PaddedLen; i += 4) {
85 assert(Def && Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
86 "Expected G_GLOBAL_VALUE");
87 const GlobalValue *GV = Def->getOperand(1).getGlobal();
94 const auto Bitwidth = Imm.getBitWidth();
97 else if (Bitwidth <= 32) {
98 MIB.
addImm(Imm.getZExtValue());
103 }
else if (Bitwidth <= 64) {
104 uint64_t FullImm = Imm.getZExtValue();
105 uint32_t LowBits = FullImm & 0xffffffff;
106 uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
125 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(SPIRV::OpName))
132 const std::vector<uint32_t> &DecArgs,
136 for (
const auto &DecArg : DecArgs)
141 SPIRV::Decoration::Decoration Dec,
142 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
143 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
150 SPIRV::Decoration::Decoration Dec,
151 const std::vector<uint32_t> &DecArgs,
StringRef StrImm) {
153 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpDecorate))
160 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
161 const std::vector<uint32_t> &DecArgs,
163 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpMemberDecorate)
172 SPIRV::Decoration::Decoration Dec,
uint32_t Member,
173 const std::vector<uint32_t> &DecArgs,
176 auto MIB =
BuildMI(
MBB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpMemberDecorate))
189 if (OpMD->getNumOperands() == 0)
195 "element of the decoration");
205 static_cast<uint32_t>(SPIRV::Decoration::NoContraction) ||
207 static_cast<uint32_t>(SPIRV::Decoration::FPFastMathMode)) {
210 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpDecorate)
213 for (
unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
216 MIB.addImm(
static_cast<uint32_t>(OpV->getZExtValue()));
230 bool IsHeader =
false;
232 for (; It !=
E && It !=
I; ++It) {
233 Opcode = It->getOpcode();
234 if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
236 }
else if (IsHeader &&
237 !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
247 if (
I ==
MBB->begin())
250 while (
I->isTerminator() ||
I->isDebugValue()) {
251 if (
I ==
MBB->begin())
258SPIRV::StorageClass::StorageClass
262 return SPIRV::StorageClass::Function;
264 return SPIRV::StorageClass::CrossWorkgroup;
266 return SPIRV::StorageClass::UniformConstant;
268 return SPIRV::StorageClass::Workgroup;
270 return SPIRV::StorageClass::Generic;
272 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
273 ? SPIRV::StorageClass::DeviceOnlyINTEL
274 : SPIRV::StorageClass::CrossWorkgroup;
276 return STI.
canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
277 ? SPIRV::StorageClass::HostOnlyINTEL
278 : SPIRV::StorageClass::CrossWorkgroup;
280 return SPIRV::StorageClass::Input;
282 return SPIRV::StorageClass::Output;
284 return SPIRV::StorageClass::CodeSectionINTEL;
286 return SPIRV::StorageClass::Private;
288 return SPIRV::StorageClass::StorageBuffer;
290 return SPIRV::StorageClass::Uniform;
296SPIRV::MemorySemantics::MemorySemantics
299 case SPIRV::StorageClass::StorageBuffer:
300 case SPIRV::StorageClass::Uniform:
301 return SPIRV::MemorySemantics::UniformMemory;
302 case SPIRV::StorageClass::Workgroup:
303 return SPIRV::MemorySemantics::WorkgroupMemory;
304 case SPIRV::StorageClass::CrossWorkgroup:
305 return SPIRV::MemorySemantics::CrossWorkgroupMemory;
306 case SPIRV::StorageClass::AtomicCounter:
307 return SPIRV::MemorySemantics::AtomicCounterMemory;
308 case SPIRV::StorageClass::Image:
309 return SPIRV::MemorySemantics::ImageMemory;
311 return SPIRV::MemorySemantics::None;
318 return SPIRV::MemorySemantics::Acquire;
320 return SPIRV::MemorySemantics::Release;
322 return SPIRV::MemorySemantics::AcquireRelease;
324 return SPIRV::MemorySemantics::SequentiallyConsistent;
328 return SPIRV::MemorySemantics::None;
340 Ctx.getOrInsertSyncScopeID(
"subgroup");
342 Ctx.getOrInsertSyncScopeID(
"workgroup");
344 Ctx.getOrInsertSyncScopeID(
"device");
347 return SPIRV::Scope::Invocation;
349 return SPIRV::Scope::CrossDevice;
350 else if (Id == SubGroup)
351 return SPIRV::Scope::Subgroup;
352 else if (Id == WorkGroup)
353 return SPIRV::Scope::Workgroup;
354 else if (Id == Device)
355 return SPIRV::Scope::Device;
356 return SPIRV::Scope::CrossDevice;
363 MI->getOpcode() == SPIRV::G_TRUNC ||
MI->getOpcode() == SPIRV::G_ZEXT
364 ?
MRI->getVRegDef(
MI->getOperand(1).getReg())
367 if (GI->is(Intrinsic::spv_track_constant)) {
369 return MRI->getVRegDef(ConstReg);
371 }
else if (ConstInstr->
getOpcode() == SPIRV::ASSIGN_TYPE) {
373 return MRI->getVRegDef(ConstReg);
374 }
else if (ConstInstr->
getOpcode() == TargetOpcode::G_CONSTANT ||
375 ConstInstr->
getOpcode() == TargetOpcode::G_FCONSTANT) {
379 return MRI->getVRegDef(ConstReg);
384 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
385 return MI->getOperand(1).getCImm()->getValue().getZExtValue();
390 assert(
MI &&
MI->getOpcode() == TargetOpcode::G_CONSTANT);
391 return MI->getOperand(1).getCImm()->getSExtValue();
396 return GI->is(IntrinsicID);
408 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
409 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
410 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
411 MangledName ==
"reserve_write_pipe" ||
412 MangledName ==
"reserve_read_pipe" ||
413 MangledName ==
"commit_write_pipe" ||
414 MangledName ==
"commit_read_pipe" ||
415 MangledName ==
"work_group_reserve_write_pipe" ||
416 MangledName ==
"work_group_reserve_read_pipe" ||
417 MangledName ==
"work_group_commit_write_pipe" ||
418 MangledName ==
"work_group_commit_read_pipe" ||
419 MangledName ==
"get_pipe_num_packets_ro" ||
420 MangledName ==
"get_pipe_max_packets_ro" ||
421 MangledName ==
"get_pipe_num_packets_wo" ||
422 MangledName ==
"get_pipe_max_packets_wo" ||
423 MangledName ==
"sub_group_reserve_write_pipe" ||
424 MangledName ==
"sub_group_reserve_read_pipe" ||
425 MangledName ==
"sub_group_commit_write_pipe" ||
426 MangledName ==
"sub_group_commit_read_pipe" ||
427 MangledName ==
"to_global" || MangledName ==
"to_local" ||
428 MangledName ==
"to_private";
432 return MangledName ==
"__enqueue_kernel_basic" ||
433 MangledName ==
"__enqueue_kernel_basic_events" ||
434 MangledName ==
"__enqueue_kernel_varargs" ||
435 MangledName ==
"__enqueue_kernel_events_varargs";
439 return MangledName ==
"__get_kernel_work_group_size_impl" ||
440 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
441 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
442 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
446 if (!Name.starts_with(
"__"))
451 Name ==
"__translate_sampler_initializer";
456 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
457 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
458 bool IsMangled = Name.starts_with(
"_Z");
461 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
466 std::string Result = DemangledName;
475 size_t Start, Len = 0;
476 size_t DemangledNameLenStart = 2;
477 if (Name.starts_with(
"_ZN")) {
479 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
481 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
482 return std::string();
483 DemangledNameLenStart = NameSpaceStart + 11;
485 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
486 [[maybe_unused]]
bool Error =
487 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
488 .getAsInteger(10, Len);
489 assert(!
Error &&
"Failed to parse demangled name length");
490 return Name.substr(Start, Len).str();
494 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
495 Name.starts_with(
"spirv."))
517 if (
F.getFnAttribute(
"hlsl.shader").isValid())
524 TypeName.consume_front(
"atomic_");
525 if (TypeName.consume_front(
"void"))
527 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
529 else if (TypeName.consume_front(
"char") ||
530 TypeName.consume_front(
"signed char") ||
531 TypeName.consume_front(
"unsigned char") ||
532 TypeName.consume_front(
"uchar"))
534 else if (TypeName.consume_front(
"short") ||
535 TypeName.consume_front(
"signed short") ||
536 TypeName.consume_front(
"unsigned short") ||
537 TypeName.consume_front(
"ushort"))
539 else if (TypeName.consume_front(
"int") ||
540 TypeName.consume_front(
"signed int") ||
541 TypeName.consume_front(
"unsigned int") ||
542 TypeName.consume_front(
"uint"))
544 else if (TypeName.consume_front(
"long") ||
545 TypeName.consume_front(
"signed long") ||
546 TypeName.consume_front(
"unsigned long") ||
547 TypeName.consume_front(
"ulong"))
549 else if (TypeName.consume_front(
"half") ||
550 TypeName.consume_front(
"_Float16") ||
551 TypeName.consume_front(
"__fp16"))
553 else if (TypeName.consume_front(
"float"))
555 else if (TypeName.consume_front(
"double"))
562std::unordered_set<BasicBlock *>
563PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
564 std::queue<BasicBlock *> ToVisit;
567 std::unordered_set<BasicBlock *> Output;
568 while (ToVisit.size() != 0) {
569 BasicBlock *BB = ToVisit.front();
572 if (Output.count(BB) != 0)
586bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
589 if (DT.dominates(BB,
P))
593 if (BlockToOrder.count(
P) == 0)
598 Loop *
L = LI.getLoopFor(
P);
599 if (L ==
nullptr ||
L->contains(BB))
605 assert(
L->getNumBackEdges() <= 1);
611 if (Latch ==
nullptr)
615 if (BlockToOrder.count(Latch) == 0)
623 auto It = BlockToOrder.find(BB);
624 if (It != BlockToOrder.end())
625 return It->second.Rank;
630 if (DT.dominates(BB,
P))
633 auto Iterator = BlockToOrder.end();
634 Loop *L = LI.getLoopFor(
P);
635 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
639 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
640 Iterator = BlockToOrder.find(
P);
645 Iterator = BlockToOrder.find(Latch);
648 assert(Iterator != BlockToOrder.end());
649 result = std::max(result, Iterator->second.Rank + 1);
655size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
659 size_t QueueIndex = 0;
660 while (ToVisit.size() != 0) {
664 if (!CanBeVisited(BB)) {
666 if (QueueIndex >= ToVisit.size())
668 "No valid candidate in the queue. Is the graph reducible?");
675 OrderInfo
Info = {Rank, BlockToOrder.size()};
676 BlockToOrder.emplace(BB,
Info);
679 if (Queued.count(S) != 0)
693 visit(&*
F.begin(), 0);
695 Order.reserve(
F.size());
696 for (
auto &[BB,
Info] : BlockToOrder)
697 Order.emplace_back(BB);
699 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
700 return compare(LHS, RHS);
706 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
707 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
708 if (InfoLHS.Rank != InfoRHS.Rank)
709 return InfoLHS.Rank < InfoRHS.Rank;
710 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
715 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
716 assert(BlockToOrder.count(&Start) != 0);
719 auto It = Order.begin();
720 while (It != Order.end() && *It != &Start)
725 assert(It != Order.end());
728 std::optional<size_t> EndRank = std::nullopt;
729 for (; It != Order.end(); ++It) {
730 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
733 if (Reachable.count(*It) == 0) {
738 EndRank = BlockToOrder[*It].Rank;
748 std::vector<BasicBlock *> Order;
749 Order.reserve(
F.size());
754 assert(&*
F.begin() == Order[0]);
757 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
769 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
777 constexpr unsigned MaxIters = 1024;
778 for (
unsigned I = 0;
I < MaxIters; ++
I) {
779 std::string OrdName = Name +
Twine(
I).
str();
780 if (!M.getFunction(OrdName)) {
781 Name = std::move(OrdName);
794 if (!
MRI->getRegClassOrNull(
Reg) || Force) {
805 SPIRV::AccessQualifier::AccessQualifier AccessQual,
806 bool EmitIR,
bool Force) {
809 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
835 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
845 Args.push_back(Arg2);
848 return B.CreateIntrinsic(IntrID, {Types}, Args);
853 if (Ty->isPtrOrPtrVectorTy())
858 for (
const Type *ArgTy : RefTy->params())
871 if (
F->getName().starts_with(
"llvm.spv."))
878SmallVector<MachineInstr *, 4>
880 unsigned MinWC,
unsigned ContinuedOpcode,
885 constexpr unsigned MaxWordCount = UINT16_MAX;
886 const size_t NumElements = Args.size();
887 size_t MaxNumElements = MaxWordCount - MinWC;
888 size_t SPIRVStructNumElements = NumElements;
890 if (NumElements > MaxNumElements) {
893 SPIRVStructNumElements = MaxNumElements;
894 MaxNumElements = MaxWordCount - 1;
900 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
903 Instructions.push_back(MIB.getInstr());
905 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
906 I += MaxNumElements) {
907 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
908 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
910 Instructions.push_back(MIB.getInstr());
916 unsigned LC = SPIRV::LoopControl::None;
920 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
922 LC |= SPIRV::LoopControl::DontUnroll;
926 LC |= SPIRV::LoopControl::Unroll;
928 std::optional<int>
Count =
931 LC |= SPIRV::LoopControl::PartialCount;
932 MaskToValueMap.emplace_back(
933 std::make_pair(SPIRV::LoopControl::PartialCount, *
Count));
937 for (
auto &[Mask, Val] : MaskToValueMap)
938 Result.push_back(Val);
944 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
946 TargetOpcode::G_FADD,
947 TargetOpcode::G_STRICT_FADD,
949 TargetOpcode::G_FSUB,
950 TargetOpcode::G_STRICT_FSUB,
952 TargetOpcode::G_FMUL,
953 TargetOpcode::G_STRICT_FMUL,
954 TargetOpcode::G_SDIV,
955 TargetOpcode::G_UDIV,
956 TargetOpcode::G_FDIV,
957 TargetOpcode::G_STRICT_FDIV,
958 TargetOpcode::G_SREM,
959 TargetOpcode::G_UREM,
960 TargetOpcode::G_FREM,
961 TargetOpcode::G_STRICT_FREM,
962 TargetOpcode::G_FNEG,
963 TargetOpcode::G_CONSTANT,
964 TargetOpcode::G_FCONSTANT,
969 TargetOpcode::G_ASHR,
970 TargetOpcode::G_LSHR,
971 TargetOpcode::G_SELECT,
972 TargetOpcode::G_EXTRACT_VECTOR_ELT,
975 return TypeFoldingSupportingOpcs;
984 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
985 Def->getOpcode() == TargetOpcode::COPY)
986 ?
MRI->getVRegDef(Def->getOperand(1).getReg())
998 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
999 Def->getOpcode() == SPIRV::OpConstantI)
1007 if (Def->getOpcode() == SPIRV::OpConstantI)
1008 return Def->getOperand(2).getImm();
1009 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1010 return Def->getOperand(1).getCImm()->getZExtValue();
1026 while (VarPos != BB.
end() && VarPos->getOpcode() != SPIRV::OpFunction) {
1033 while (VarPos != BB.
end() &&
1034 VarPos->getOpcode() == SPIRV::OpFunctionParameter) {
1039 return VarPos != BB.
end() && VarPos->getOpcode() == SPIRV::OpLabel ? ++VarPos
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
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.
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
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.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
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.
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
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 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)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Value * getOperand(unsigned i) const
LLVM Value Representation.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ BasicBlock
Various leaf nodes.
@ 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)
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)
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 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)
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)