29#define DEBUG_TYPE "spirv-module-analysis"
33 cl::desc(
"Dump MIR with SPIR-V dependencies info"),
48 if (MdNode && OpIndex < MdNode->getNumOperands()) {
49 const auto &Op = MdNode->getOperand(
OpIndex);
50 return mdconst::extract<ConstantInt>(Op)->getZExtValue();
56getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
61 unsigned TargetVer =
ST.getSPIRVVersion();
62 bool MinVerOK = !ReqMinVer || !TargetVer || TargetVer >= ReqMinVer;
63 bool MaxVerOK = !ReqMaxVer || !TargetVer || TargetVer <= ReqMaxVer;
66 if (ReqCaps.
empty()) {
67 if (ReqExts.
empty()) {
68 if (MinVerOK && MaxVerOK)
69 return {
true, {}, {}, ReqMinVer, ReqMaxVer};
70 return {
false, {}, {}, 0, 0};
72 }
else if (MinVerOK && MaxVerOK) {
73 for (
auto Cap : ReqCaps) {
75 return {
true, {Cap}, {}, ReqMinVer, ReqMaxVer};
81 if (
llvm::all_of(ReqExts, [&ST](
const SPIRV::Extension::Extension &Ext) {
82 return ST.canUseExtension(Ext);
84 return {
true, {}, ReqExts, 0, 0};
86 return {
false, {}, {}, 0, 0};
89void SPIRVModuleAnalysis::setBaseInfo(
const Module &M) {
102 if (
auto MemModel =
M.getNamedMetadata(
"spirv.MemoryModel")) {
103 auto MemMD = MemModel->getOperand(0);
104 MAI.
Addr =
static_cast<SPIRV::AddressingModel::AddressingModel
>(
105 getMetadataUInt(MemMD, 0));
107 static_cast<SPIRV::MemoryModel::MemoryModel
>(getMetadataUInt(MemMD, 1));
109 MAI.
Mem = SPIRV::MemoryModel::OpenCL;
110 unsigned PtrSize =
ST->getPointerSize();
111 MAI.
Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
112 : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
113 : SPIRV::AddressingModel::Logical;
117 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
118 MAI.
SrcLang = SPIRV::SourceLanguage::OpenCL_C;
121 assert(VerNode->getNumOperands() > 0 &&
"Invalid SPIR");
122 auto VersionMD = VerNode->getOperand(0);
123 unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
124 unsigned MinorNum = getMetadataUInt(VersionMD, 1);
125 unsigned RevNum = getMetadataUInt(VersionMD, 2);
132 if (
auto ExtNode =
M.getNamedMetadata(
"opencl.used.extensions")) {
133 for (
unsigned I = 0,
E = ExtNode->getNumOperands();
I !=
E; ++
I) {
152 MAI.
ExtInstSetMap[
static_cast<unsigned>(SPIRV::InstructionSet::OpenCL_std)] =
160 bool DoInsert =
true) {
163 assert(
MI &&
"There should be an instruction that defines the register");
169void SPIRVModuleAnalysis::collectGlobalEntities(
170 const std::vector<SPIRV::DTSortableEntry *> &DepsGraph,
173 bool UsePreOrder =
false) {
175 for (
const auto *
E : DepsGraph) {
179 RecHoistUtil = [MSType, UsePreOrder, &Visited, &Pred,
181 if (Visited.count(
E) || !Pred(
E))
190 for (
auto *S :
E->getDeps())
201 collectDefInstr(Reg, MF, &
MAI, MSType, IsFirst);
208 for (
auto *S :
E->getDeps())
219void SPIRVModuleAnalysis::processDefInstrs(
const Module &M) {
220 std::vector<SPIRV::DTSortableEntry *> DepsGraph;
224 collectGlobalEntities(
228 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
235 if (
MI.getOpcode() == SPIRV::OpExtension) {
237 auto Ext = SPIRV::Extension::Extension(
MI.getOperand(0).getImm());
240 }
else if (
MI.getOpcode() == SPIRV::OpCapability) {
241 auto Cap = SPIRV::Capability::Capability(
MI.getOperand(0).getImm());
249 collectGlobalEntities(
260 unsigned StartOpIndex = 0) {
261 for (
const auto *
B : MAI.
MS[MSType]) {
262 const unsigned NumAOps =
A.getNumOperands();
263 if (NumAOps !=
B->getNumOperands() ||
A.getNumDefs() !=
B->getNumDefs())
265 bool AllOpsMatch =
true;
266 for (
unsigned i = StartOpIndex; i < NumAOps && AllOpsMatch; ++i) {
267 if (
A.getOperand(i).isReg() &&
B->getOperand(i).isReg()) {
268 Register RegA =
A.getOperand(i).getReg();
269 Register RegB =
B->getOperand(i).getReg();
273 AllOpsMatch =
A.getOperand(i).isIdenticalTo(
B->getOperand(i));
288 if (
MI.getOpcode() == SPIRV::OpDecorate) {
290 auto Dec =
MI.getOperand(1).getImm();
291 if (Dec ==
static_cast<unsigned>(SPIRV::Decoration::LinkageAttributes)) {
292 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
293 if (Lnk ==
static_cast<unsigned>(SPIRV::LinkageType::Import)) {
301 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
315 bool Append =
true) {
317 if (findSameInstrInMS(
MI, MSType, MAI))
328void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
329 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
330 if ((*F).isDeclaration())
338 const unsigned OpCode =
MI.getOpcode();
339 if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
341 }
else if (OpCode == SPIRV::OpEntryPoint) {
345 collectFuncNames(
MI, &*
F);
350 }
else if (OpCode == SPIRV::OpFunction) {
351 collectFuncNames(
MI, &*
F);
352 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
362void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
363 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
364 if ((*F).isDeclaration())
379 if (
MI.getOpcode() != SPIRV::OpExtInst)
381 auto Set =
MI.getOperand(2).getImm();
395 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
403 if (
MI.getOpcode() == SPIRV::OpSwitch) {
405 SwitchRegs.
insert(
MI.getOperand(0).getReg());
407 if (
MI.getOpcode() == SPIRV::OpISubS &&
408 SwitchRegs.
contains(
MI.getOperand(2).getReg())) {
409 SwitchRegs.
insert(
MI.getOperand(0).getReg());
412 if ((
MI.getOpcode() != SPIRV::OpIEqual &&
413 MI.getOpcode() != SPIRV::OpULessThanEqual) ||
414 !
MI.getOperand(2).isReg() ||
415 !SwitchRegs.
contains(
MI.getOperand(2).getReg()))
432 SPIRV::OperandCategory::OperandCategory Category,
uint32_t i,
434 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
437void SPIRV::RequirementHandler::pruneCapabilities(
439 for (
const auto &Cap : ToPrune) {
441 auto FoundIndex = std::find(MinimalCaps.begin(), MinimalCaps.end(), Cap);
442 if (FoundIndex != MinimalCaps.end())
443 MinimalCaps.erase(FoundIndex);
446 pruneCapabilities(ImplicitDecls);
451 for (
const auto &Cap : ToAdd) {
452 bool IsNewlyInserted = AllCaps.insert(Cap).second;
453 if (!IsNewlyInserted)
457 pruneCapabilities(ImplicitDecls);
458 MinimalCaps.push_back(Cap);
467 if (Req.
Cap.has_value())
468 addCapabilities({Req.
Cap.value()});
470 addExtensions(Req.
Exts);
473 if (MaxVersion && Req.
MinVer > MaxVersion) {
475 <<
" and <= " << MaxVersion <<
"\n");
479 if (MinVersion == 0 || Req.
MinVer > MinVersion)
484 if (MinVersion && Req.
MaxVer < MinVersion) {
486 <<
" and >= " << MinVersion <<
"\n");
490 if (MaxVersion == 0 || Req.
MaxVer < MaxVersion)
498 bool IsSatisfiable =
true;
499 auto TargetVer =
ST.getSPIRVVersion();
501 if (MaxVersion && TargetVer && MaxVersion < TargetVer) {
503 dbgs() <<
"Target SPIR-V version too high for required features\n"
504 <<
"Required max version: " << MaxVersion <<
" target version "
505 << TargetVer <<
"\n");
506 IsSatisfiable =
false;
509 if (MinVersion && TargetVer && MinVersion > TargetVer) {
510 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
511 <<
"Required min version: " << MinVersion
512 <<
" target version " << TargetVer <<
"\n");
513 IsSatisfiable =
false;
516 if (MinVersion && MaxVersion && MinVersion > MaxVersion) {
519 <<
"Version is too low for some features and too high for others.\n"
520 <<
"Required SPIR-V min version: " << MinVersion
521 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
522 IsSatisfiable =
false;
525 for (
auto Cap : MinimalCaps) {
526 if (AvailableCaps.contains(Cap))
530 OperandCategory::CapabilityOperand, Cap)
532 IsSatisfiable =
false;
535 for (
auto Ext : AllExtensions) {
536 if (
ST.canUseExtension(Ext))
540 OperandCategory::ExtensionOperand, Ext)
542 IsSatisfiable =
false;
551 for (
const auto Cap : ToAdd)
552 if (AvailableCaps.insert(Cap).second)
554 SPIRV::OperandCategory::CapabilityOperand, Cap));
559void RequirementHandler::initAvailableCapabilities(
const SPIRVSubtarget &ST) {
561 if (!
ST.isOpenCLEnv())
564 addAvailableCaps({Capability::Addresses, Capability::Float16Buffer,
565 Capability::Int16, Capability::Int8, Capability::Kernel,
566 Capability::Linkage, Capability::Vector16,
567 Capability::Groups, Capability::GenericPointer,
568 Capability::Shader});
569 if (
ST.hasOpenCLFullProfile())
570 addAvailableCaps({Capability::Int64, Capability::Int64Atomics});
571 if (
ST.hasOpenCLImageSupport()) {
572 addAvailableCaps({Capability::ImageBasic, Capability::LiteralSampler,
573 Capability::Image1D, Capability::SampledBuffer,
574 Capability::ImageBuffer});
575 if (
ST.isAtLeastOpenCLVer(20))
576 addAvailableCaps({Capability::ImageReadWrite});
578 if (
ST.isAtLeastSPIRVVer(11) &&
ST.isAtLeastOpenCLVer(22))
579 addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage});
580 if (
ST.isAtLeastSPIRVVer(13))
581 addAvailableCaps({Capability::GroupNonUniform,
582 Capability::GroupNonUniformVote,
583 Capability::GroupNonUniformArithmetic,
584 Capability::GroupNonUniformBallot,
585 Capability::GroupNonUniformClustered,
586 Capability::GroupNonUniformShuffle,
587 Capability::GroupNonUniformShuffleRelative});
588 if (
ST.isAtLeastSPIRVVer(14))
589 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
590 Capability::SignedZeroInfNanPreserve,
591 Capability::RoundingModeRTE,
592 Capability::RoundingModeRTZ});
594 addAvailableCaps({Capability::Float16, Capability::Float64});
603static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
606 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
607 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
609 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
611 if (Dec == SPIRV::Decoration::BuiltIn) {
612 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
613 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
615 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
623 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
626 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
627 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
631 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
632 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
633 bool NoSampler =
MI.getOperand(6).getImm() == 2;
636 switch (
MI.getOperand(2).getImm()) {
637 case SPIRV::Dim::DIM_1D:
639 : SPIRV::Capability::Sampled1D);
641 case SPIRV::Dim::DIM_2D:
642 if (IsMultisampled && NoSampler)
645 case SPIRV::Dim::DIM_Cube:
649 : SPIRV::Capability::SampledCubeArray);
651 case SPIRV::Dim::DIM_Rect:
653 : SPIRV::Capability::SampledRect);
655 case SPIRV::Dim::DIM_Buffer:
657 : SPIRV::Capability::SampledBuffer);
659 case SPIRV::Dim::DIM_SubpassData:
666 if (
MI.getNumOperands() > 8 &&
667 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
676 switch (
MI.getOpcode()) {
677 case SPIRV::OpMemoryModel: {
678 int64_t
Addr =
MI.getOperand(0).getImm();
681 int64_t Mem =
MI.getOperand(1).getImm();
686 case SPIRV::OpEntryPoint: {
687 int64_t
Exe =
MI.getOperand(0).getImm();
692 case SPIRV::OpExecutionMode:
693 case SPIRV::OpExecutionModeId: {
694 int64_t
Exe =
MI.getOperand(1).getImm();
699 case SPIRV::OpTypeMatrix:
702 case SPIRV::OpTypeInt: {
703 unsigned BitWidth =
MI.getOperand(1).getImm();
712 case SPIRV::OpTypeFloat: {
713 unsigned BitWidth =
MI.getOperand(1).getImm();
720 case SPIRV::OpTypeVector: {
721 unsigned NumComponents =
MI.getOperand(2).getImm();
722 if (NumComponents == 8 || NumComponents == 16)
726 case SPIRV::OpTypePointer: {
727 auto SC =
MI.getOperand(1).getImm();
734 if (TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
739 case SPIRV::OpBitReverse:
740 case SPIRV::OpTypeRuntimeArray:
743 case SPIRV::OpTypeOpaque:
744 case SPIRV::OpTypeEvent:
747 case SPIRV::OpTypePipe:
748 case SPIRV::OpTypeReserveId:
751 case SPIRV::OpTypeDeviceEvent:
752 case SPIRV::OpTypeQueue:
753 case SPIRV::OpBuildNDRange:
756 case SPIRV::OpDecorate:
757 case SPIRV::OpDecorateId:
758 case SPIRV::OpDecorateString:
759 addOpDecorateReqs(
MI, 1, Reqs, ST);
761 case SPIRV::OpMemberDecorate:
762 case SPIRV::OpMemberDecorateString:
763 addOpDecorateReqs(
MI, 2, Reqs, ST);
765 case SPIRV::OpInBoundsPtrAccessChain:
768 case SPIRV::OpConstantSampler:
771 case SPIRV::OpTypeImage:
772 addOpTypeImageReqs(
MI, Reqs, ST);
774 case SPIRV::OpTypeSampler:
777 case SPIRV::OpTypeForwardPointer:
781 case SPIRV::OpAtomicFlagTestAndSet:
782 case SPIRV::OpAtomicLoad:
783 case SPIRV::OpAtomicStore:
784 case SPIRV::OpAtomicExchange:
785 case SPIRV::OpAtomicCompareExchange:
786 case SPIRV::OpAtomicIIncrement:
787 case SPIRV::OpAtomicIDecrement:
788 case SPIRV::OpAtomicIAdd:
789 case SPIRV::OpAtomicISub:
790 case SPIRV::OpAtomicUMin:
791 case SPIRV::OpAtomicUMax:
792 case SPIRV::OpAtomicSMin:
793 case SPIRV::OpAtomicSMax:
794 case SPIRV::OpAtomicAnd:
795 case SPIRV::OpAtomicOr:
796 case SPIRV::OpAtomicXor: {
799 if (
MI.getOpcode() == SPIRV::OpAtomicStore) {
801 InstrPtr =
MRI.getVRegDef(
MI.getOperand(3).getReg());
802 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
807 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
814 case SPIRV::OpGroupNonUniformIAdd:
815 case SPIRV::OpGroupNonUniformFAdd:
816 case SPIRV::OpGroupNonUniformIMul:
817 case SPIRV::OpGroupNonUniformFMul:
818 case SPIRV::OpGroupNonUniformSMin:
819 case SPIRV::OpGroupNonUniformUMin:
820 case SPIRV::OpGroupNonUniformFMin:
821 case SPIRV::OpGroupNonUniformSMax:
822 case SPIRV::OpGroupNonUniformUMax:
823 case SPIRV::OpGroupNonUniformFMax:
824 case SPIRV::OpGroupNonUniformBitwiseAnd:
825 case SPIRV::OpGroupNonUniformBitwiseOr:
826 case SPIRV::OpGroupNonUniformBitwiseXor:
827 case SPIRV::OpGroupNonUniformLogicalAnd:
828 case SPIRV::OpGroupNonUniformLogicalOr:
829 case SPIRV::OpGroupNonUniformLogicalXor: {
831 int64_t GroupOp =
MI.getOperand(3).getImm();
833 case SPIRV::GroupOperation::Reduce:
834 case SPIRV::GroupOperation::InclusiveScan:
835 case SPIRV::GroupOperation::ExclusiveScan:
837 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
838 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
840 case SPIRV::GroupOperation::ClusteredReduce:
841 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
843 case SPIRV::GroupOperation::PartitionedReduceNV:
844 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
845 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
846 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
851 case SPIRV::OpGroupNonUniformShuffle:
852 case SPIRV::OpGroupNonUniformShuffleXor:
853 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
855 case SPIRV::OpGroupNonUniformShuffleUp:
856 case SPIRV::OpGroupNonUniformShuffleDown:
857 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
859 case SPIRV::OpGroupAll:
860 case SPIRV::OpGroupAny:
861 case SPIRV::OpGroupBroadcast:
862 case SPIRV::OpGroupIAdd:
863 case SPIRV::OpGroupFAdd:
864 case SPIRV::OpGroupFMin:
865 case SPIRV::OpGroupUMin:
866 case SPIRV::OpGroupSMin:
867 case SPIRV::OpGroupFMax:
868 case SPIRV::OpGroupUMax:
869 case SPIRV::OpGroupSMax:
872 case SPIRV::OpGroupNonUniformElect:
875 case SPIRV::OpGroupNonUniformAll:
876 case SPIRV::OpGroupNonUniformAny:
877 case SPIRV::OpGroupNonUniformAllEqual:
880 case SPIRV::OpGroupNonUniformBroadcast:
881 case SPIRV::OpGroupNonUniformBroadcastFirst:
882 case SPIRV::OpGroupNonUniformBallot:
883 case SPIRV::OpGroupNonUniformInverseBallot:
884 case SPIRV::OpGroupNonUniformBallotBitExtract:
885 case SPIRV::OpGroupNonUniformBallotBitCount:
886 case SPIRV::OpGroupNonUniformBallotFindLSB:
887 case SPIRV::OpGroupNonUniformBallotFindMSB:
888 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
898 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
904 addInstrRequirements(
MI, MAI.
Reqs, ST);
907 auto Node =
M.getNamedMetadata(
"spirv.ExecutionMode");
909 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
910 MDNode *MDN = cast<MDNode>(
Node->getOperand(i));
912 if (
auto *CMeta = dyn_cast<ConstantAsMetadata>(MDOp)) {
915 auto EM =
Const->getZExtValue();
917 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
922 for (
auto FI =
M.begin(),
E =
M.end(); FI !=
E; ++FI) {
924 if (
F.isDeclaration())
926 if (
F.getMetadata(
"reqd_work_group_size"))
928 SPIRV::OperandCategory::ExecutionModeOperand,
929 SPIRV::ExecutionMode::LocalSize, ST);
930 if (
F.getMetadata(
"work_group_size_hint"))
932 SPIRV::OperandCategory::ExecutionModeOperand,
933 SPIRV::ExecutionMode::LocalSizeHint, ST);
934 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
936 SPIRV::OperandCategory::ExecutionModeOperand,
937 SPIRV::ExecutionMode::SubgroupSize, ST);
938 if (
F.getMetadata(
"vec_type_hint"))
940 SPIRV::OperandCategory::ExecutionModeOperand,
941 SPIRV::ExecutionMode::VecTypeHint, ST);
946 unsigned Flags = SPIRV::FPFastMathMode::None;
948 Flags |= SPIRV::FPFastMathMode::NotNaN;
950 Flags |= SPIRV::FPFastMathMode::NotInf;
952 Flags |= SPIRV::FPFastMathMode::NSZ;
954 Flags |= SPIRV::FPFastMathMode::AllowRecip;
956 Flags |= SPIRV::FPFastMathMode::Fast;
964 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
965 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
968 SPIRV::Decoration::NoSignedWrap, {});
971 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
972 SPIRV::Decoration::NoUnsignedWrap, ST,
976 SPIRV::Decoration::NoUnsignedWrap, {});
978 if (!
TII.canUseFastMathFlags(
I))
980 unsigned FMFlags = getFastMathFlags(
I);
981 if (FMFlags == SPIRV::FPFastMathMode::None)
983 Register DstReg =
I.getOperand(0).getReg();
991 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
995 for (
auto &
MBB : *MF)
997 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs);
1011 ST =
TM.getSubtargetImpl();
1012 GR = ST->getSPIRVGlobalRegistry();
1013 TII = ST->getInstrInfo();
1015 MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
1019 addDecorations(M, *
TII, MMI, *ST, MAI);
1021 collectReqs(M, MAI, MMI, *ST);
1027 processDefInstrs(M);
1030 numberRegistersGlobally(M);
1033 processOtherInstrs(M);
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > SPVDumpDeps("spv-dump-deps", cl::desc("Dump MIR with SPIR-V dependencies info"), cl::Optional, cl::init(false))
unsigned unsigned DefaultVal
static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Target-Independent Code Generator Pass Configuration Options pass.
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
Implements a dense probed hash-table based set.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
Tracking metadata reference owned by Metadata.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
This class contains meta information specific to a module.
MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A Module instance is used to store all the information related to an LLVM module.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
void buildDepsGraph(std::vector< SPIRV::DTSortableEntry * > &Graph, MachineModuleInfo *MMI=nullptr)
bool isConstantInstr(const MachineInstr &MI) const
bool isDecorationInstr(const MachineInstr &MI) const
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
std::pair< typename Base::iterator, bool > insert(StringRef key)
Target-Independent Code Generator Pass Configuration Options.
Target - Wrapper for Target specific information.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
@ C
The default llvm calling convention, compatible with C.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
ExtensionList getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
CapabilityList getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
void initializeSPIRVModuleAnalysisPass(PassRegistry &)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
uint32_t getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
constexpr unsigned BitWidth
uint32_t getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
static struct SPIRV::ModuleAnalysisInfo MAI
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Register getRegisterAlias(const MachineFunction *MF, Register Reg)
SmallVector< MachineInstr *, 4 > GlobalVarList
DenseMap< const Function *, Register > FuncMap
DenseSet< MachineBasicBlock * > MBBsToSkip
void setRegisterAlias(const MachineFunction *MF, Register Reg, Register AliasReg)
bool hasRegisterAlias(const MachineFunction *MF, Register Reg)
RegisterAliasMapTy RegisterAliasTable
bool getSkipEmission(const MachineInstr *MI)
MemoryModel::MemoryModel Mem
InstrList MS[NUM_MODULE_SECTIONS]
AddressingModel::AddressingModel Addr
void setSkipEmission(MachineInstr *MI)
SourceLanguage::SourceLanguage SrcLang
DenseSet< MachineInstr * > InstrsToDelete
DenseMap< unsigned, Register > ExtInstSetMap
void addCapabilities(const CapabilityList &ToAdd)
bool isCapabilityAvailable(Capability::Capability Cap) const
void checkSatisfiable(const SPIRVSubtarget &ST) const
void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category, uint32_t i, const SPIRVSubtarget &ST)
void addExtension(Extension::Extension ToAdd)
void initAvailableCapabilities(const SPIRVSubtarget &ST)
void addCapability(Capability::Capability ToAdd)
void addAvailableCaps(const CapabilityList &ToAdd)
void addRequirements(const Requirements &Req)
const std::optional< Capability::Capability > Cap