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 return GI->is(IntrinsicID);
402 return MangledName ==
"write_pipe_2" || MangledName ==
"read_pipe_2" ||
403 MangledName ==
"write_pipe_2_bl" || MangledName ==
"read_pipe_2_bl" ||
404 MangledName ==
"write_pipe_4" || MangledName ==
"read_pipe_4" ||
405 MangledName ==
"reserve_write_pipe" ||
406 MangledName ==
"reserve_read_pipe" ||
407 MangledName ==
"commit_write_pipe" ||
408 MangledName ==
"commit_read_pipe" ||
409 MangledName ==
"work_group_reserve_write_pipe" ||
410 MangledName ==
"work_group_reserve_read_pipe" ||
411 MangledName ==
"work_group_commit_write_pipe" ||
412 MangledName ==
"work_group_commit_read_pipe" ||
413 MangledName ==
"get_pipe_num_packets_ro" ||
414 MangledName ==
"get_pipe_max_packets_ro" ||
415 MangledName ==
"get_pipe_num_packets_wo" ||
416 MangledName ==
"get_pipe_max_packets_wo" ||
417 MangledName ==
"sub_group_reserve_write_pipe" ||
418 MangledName ==
"sub_group_reserve_read_pipe" ||
419 MangledName ==
"sub_group_commit_write_pipe" ||
420 MangledName ==
"sub_group_commit_read_pipe" ||
421 MangledName ==
"to_global" || MangledName ==
"to_local" ||
422 MangledName ==
"to_private";
426 return MangledName ==
"__enqueue_kernel_basic" ||
427 MangledName ==
"__enqueue_kernel_basic_events" ||
428 MangledName ==
"__enqueue_kernel_varargs" ||
429 MangledName ==
"__enqueue_kernel_events_varargs";
433 return MangledName ==
"__get_kernel_work_group_size_impl" ||
434 MangledName ==
"__get_kernel_sub_group_count_for_ndrange_impl" ||
435 MangledName ==
"__get_kernel_max_sub_group_size_for_ndrange_impl" ||
436 MangledName ==
"__get_kernel_preferred_work_group_size_multiple_impl";
440 if (!Name.starts_with(
"__"))
445 Name ==
"__translate_sampler_initializer";
450 bool IsNonMangledSPIRV = Name.starts_with(
"__spirv_");
451 bool IsNonMangledHLSL = Name.starts_with(
"__hlsl_");
452 bool IsMangled = Name.starts_with(
"_Z");
455 if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
460 std::string Result = DemangledName;
469 size_t Start, Len = 0;
470 size_t DemangledNameLenStart = 2;
471 if (Name.starts_with(
"_ZN")) {
473 size_t NameSpaceStart = Name.find_first_not_of(
"rVKRO", 3);
475 if (Name.substr(NameSpaceStart, 11) !=
"2cl7__spirv")
476 return std::string();
477 DemangledNameLenStart = NameSpaceStart + 11;
479 Start = Name.find_first_not_of(
"0123456789", DemangledNameLenStart);
480 [[maybe_unused]]
bool Error =
481 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
482 .getAsInteger(10, Len);
483 assert(!
Error &&
"Failed to parse demangled name length");
484 return Name.substr(Start, Len).str();
488 if (Name.starts_with(
"opencl.") || Name.starts_with(
"ocl_") ||
489 Name.starts_with(
"spirv."))
511 if (
F.getFnAttribute(
"hlsl.shader").isValid())
518 TypeName.consume_front(
"atomic_");
519 if (TypeName.consume_front(
"void"))
521 else if (TypeName.consume_front(
"bool") || TypeName.consume_front(
"_Bool"))
523 else if (TypeName.consume_front(
"char") ||
524 TypeName.consume_front(
"signed char") ||
525 TypeName.consume_front(
"unsigned char") ||
526 TypeName.consume_front(
"uchar"))
528 else if (TypeName.consume_front(
"short") ||
529 TypeName.consume_front(
"signed short") ||
530 TypeName.consume_front(
"unsigned short") ||
531 TypeName.consume_front(
"ushort"))
533 else if (TypeName.consume_front(
"int") ||
534 TypeName.consume_front(
"signed int") ||
535 TypeName.consume_front(
"unsigned int") ||
536 TypeName.consume_front(
"uint"))
538 else if (TypeName.consume_front(
"long") ||
539 TypeName.consume_front(
"signed long") ||
540 TypeName.consume_front(
"unsigned long") ||
541 TypeName.consume_front(
"ulong"))
543 else if (TypeName.consume_front(
"half") ||
544 TypeName.consume_front(
"_Float16") ||
545 TypeName.consume_front(
"__fp16"))
547 else if (TypeName.consume_front(
"float"))
549 else if (TypeName.consume_front(
"double"))
556std::unordered_set<BasicBlock *>
557PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
558 std::queue<BasicBlock *> ToVisit;
561 std::unordered_set<BasicBlock *> Output;
562 while (ToVisit.size() != 0) {
563 BasicBlock *BB = ToVisit.front();
566 if (Output.count(BB) != 0)
580bool PartialOrderingVisitor::CanBeVisited(
BasicBlock *BB)
const {
583 if (DT.dominates(BB,
P))
587 if (BlockToOrder.count(
P) == 0)
592 Loop *
L = LI.getLoopFor(
P);
593 if (L ==
nullptr ||
L->contains(BB))
599 assert(
L->getNumBackEdges() <= 1);
605 if (Latch ==
nullptr)
609 if (BlockToOrder.count(Latch) == 0)
617 auto It = BlockToOrder.find(BB);
618 if (It != BlockToOrder.end())
619 return It->second.Rank;
624 if (DT.dominates(BB,
P))
627 auto Iterator = BlockToOrder.end();
628 Loop *L = LI.getLoopFor(
P);
629 BasicBlock *Latch = L ? L->getLoopLatch() :
nullptr;
633 if (L ==
nullptr || L->contains(BB) || Latch ==
nullptr) {
634 Iterator = BlockToOrder.find(
P);
639 Iterator = BlockToOrder.find(Latch);
642 assert(Iterator != BlockToOrder.end());
643 result = std::max(result, Iterator->second.Rank + 1);
649size_t PartialOrderingVisitor::visit(
BasicBlock *BB,
size_t Unused) {
653 size_t QueueIndex = 0;
654 while (ToVisit.size() != 0) {
658 if (!CanBeVisited(BB)) {
660 if (QueueIndex >= ToVisit.size())
662 "No valid candidate in the queue. Is the graph reducible?");
669 OrderInfo
Info = {Rank, BlockToOrder.size()};
670 BlockToOrder.emplace(BB,
Info);
673 if (Queued.count(S) != 0)
687 visit(&*
F.begin(), 0);
689 Order.reserve(
F.size());
690 for (
auto &[BB,
Info] : BlockToOrder)
691 Order.emplace_back(BB);
693 std::sort(Order.begin(), Order.end(), [&](
const auto &
LHS,
const auto &
RHS) {
694 return compare(LHS, RHS);
700 const OrderInfo &InfoLHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
LHS));
701 const OrderInfo &InfoRHS = BlockToOrder.at(
const_cast<BasicBlock *
>(
RHS));
702 if (InfoLHS.Rank != InfoRHS.Rank)
703 return InfoLHS.Rank < InfoRHS.Rank;
704 return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
709 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
710 assert(BlockToOrder.count(&Start) != 0);
713 auto It = Order.begin();
714 while (It != Order.end() && *It != &Start)
719 assert(It != Order.end());
722 std::optional<size_t> EndRank = std::nullopt;
723 for (; It != Order.end(); ++It) {
724 if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
727 if (Reachable.count(*It) == 0) {
732 EndRank = BlockToOrder[*It].Rank;
742 std::vector<BasicBlock *> Order;
743 Order.reserve(
F.size());
748 assert(&*
F.begin() == Order[0]);
751 if (BB != LastBlock && &*LastBlock->
getNextNode() != BB) {
763 if (MaybeDef && MaybeDef->
getOpcode() == SPIRV::ASSIGN_TYPE)
771 constexpr unsigned MaxIters = 1024;
772 for (
unsigned I = 0;
I < MaxIters; ++
I) {
773 std::string OrdName = Name +
Twine(
I).
str();
774 if (!M.getFunction(OrdName)) {
775 Name = std::move(OrdName);
788 if (!
MRI->getRegClassOrNull(
Reg) || Force) {
799 SPIRV::AccessQualifier::AccessQualifier AccessQual,
800 bool EmitIR,
bool Force) {
803 GR, MIRBuilder.
getMRI(), MIRBuilder.
getMF(), Force);
829 SPIRV::AccessQualifier::AccessQualifier AccessQual,
bool EmitIR) {
839 Args.push_back(Arg2);
842 return B.CreateIntrinsic(IntrID, {Types}, Args);
847 if (Ty->isPtrOrPtrVectorTy())
852 for (
const Type *ArgTy : RefTy->params())
865 if (
F->getName().starts_with(
"llvm.spv."))
872SmallVector<MachineInstr *, 4>
874 unsigned MinWC,
unsigned ContinuedOpcode,
879 constexpr unsigned MaxWordCount = UINT16_MAX;
880 const size_t NumElements = Args.size();
881 size_t MaxNumElements = MaxWordCount - MinWC;
882 size_t SPIRVStructNumElements = NumElements;
884 if (NumElements > MaxNumElements) {
887 SPIRVStructNumElements = MaxNumElements;
888 MaxNumElements = MaxWordCount - 1;
894 for (
size_t I = 0;
I < SPIRVStructNumElements; ++
I)
897 Instructions.push_back(MIB.getInstr());
899 for (
size_t I = SPIRVStructNumElements;
I < NumElements;
900 I += MaxNumElements) {
901 auto MIB = MIRBuilder.
buildInstr(ContinuedOpcode);
902 for (
size_t J =
I; J < std::min(
I + MaxNumElements, NumElements); ++J)
904 Instructions.push_back(MIB.getInstr());
910 unsigned LC = SPIRV::LoopControl::None;
914 std::vector<std::pair<unsigned, unsigned>> MaskToValueMap;
916 LC |= SPIRV::LoopControl::DontUnroll;
920 LC |= SPIRV::LoopControl::Unroll;
922 std::optional<int>
Count =
925 LC |= SPIRV::LoopControl::PartialCount;
926 MaskToValueMap.emplace_back(
927 std::make_pair(SPIRV::LoopControl::PartialCount, *
Count));
931 for (
auto &[Mask, Val] : MaskToValueMap)
932 Result.push_back(Val);
938 static const std::set<unsigned> TypeFoldingSupportingOpcs = {
940 TargetOpcode::G_FADD,
941 TargetOpcode::G_STRICT_FADD,
943 TargetOpcode::G_FSUB,
944 TargetOpcode::G_STRICT_FSUB,
946 TargetOpcode::G_FMUL,
947 TargetOpcode::G_STRICT_FMUL,
948 TargetOpcode::G_SDIV,
949 TargetOpcode::G_UDIV,
950 TargetOpcode::G_FDIV,
951 TargetOpcode::G_STRICT_FDIV,
952 TargetOpcode::G_SREM,
953 TargetOpcode::G_UREM,
954 TargetOpcode::G_FREM,
955 TargetOpcode::G_STRICT_FREM,
956 TargetOpcode::G_FNEG,
957 TargetOpcode::G_CONSTANT,
958 TargetOpcode::G_FCONSTANT,
963 TargetOpcode::G_ASHR,
964 TargetOpcode::G_LSHR,
965 TargetOpcode::G_SELECT,
966 TargetOpcode::G_EXTRACT_VECTOR_ELT,
969 return TypeFoldingSupportingOpcs;
978 return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
979 Def->getOpcode() == TargetOpcode::COPY)
980 ?
MRI->getVRegDef(Def->getOperand(1).getReg())
992 if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
993 Def->getOpcode() == SPIRV::OpConstantI)
1001 if (Def->getOpcode() == SPIRV::OpConstantI)
1002 return Def->getOperand(2).getImm();
1003 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1004 return Def->getOperand(1).getCImm()->getZExtValue();
1020 while (VarPos != BB.
end() && VarPos->getOpcode() != SPIRV::OpFunction) {
1027 while (VarPos != BB.
end() &&
1028 VarPos->getOpcode() == SPIRV::OpFunctionParameter) {
1033 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.
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)