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));
110 MAI.
Mem =
ST->isOpenCLEnv() ? SPIRV::MemoryModel::OpenCL
111 : SPIRV::MemoryModel::GLSL450;
112 if (
MAI.
Mem == SPIRV::MemoryModel::OpenCL) {
113 unsigned PtrSize =
ST->getPointerSize();
114 MAI.
Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
115 : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
116 : SPIRV::AddressingModel::Logical;
119 MAI.
Addr = SPIRV::AddressingModel::Logical;
124 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
125 MAI.
SrcLang = SPIRV::SourceLanguage::OpenCL_C;
128 assert(VerNode->getNumOperands() > 0 &&
"Invalid SPIR");
129 auto VersionMD = VerNode->getOperand(0);
130 unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
131 unsigned MinorNum = getMetadataUInt(VersionMD, 1);
132 unsigned RevNum = getMetadataUInt(VersionMD, 2);
139 if (
auto ExtNode =
M.getNamedMetadata(
"opencl.used.extensions")) {
140 for (
unsigned I = 0,
E = ExtNode->getNumOperands();
I !=
E; ++
I) {
158 if (
ST->isOpenCLEnv()) {
161 SPIRV::InstructionSet::OpenCL_std)] =
170 bool DoInsert =
true) {
173 assert(
MI &&
"There should be an instruction that defines the register");
179void SPIRVModuleAnalysis::collectGlobalEntities(
180 const std::vector<SPIRV::DTSortableEntry *> &DepsGraph,
183 bool UsePreOrder =
false) {
185 for (
const auto *
E : DepsGraph) {
189 RecHoistUtil = [MSType, UsePreOrder, &Visited, &Pred,
191 if (Visited.count(
E) || !Pred(
E))
200 for (
auto *S :
E->getDeps())
211 collectDefInstr(Reg, MF, &
MAI, MSType, IsFirst);
218 for (
auto *S :
E->getDeps())
229void SPIRVModuleAnalysis::processDefInstrs(
const Module &M) {
230 std::vector<SPIRV::DTSortableEntry *> DepsGraph;
234 collectGlobalEntities(
238 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
245 if (
MI.getOpcode() == SPIRV::OpExtension) {
247 auto Ext = SPIRV::Extension::Extension(
MI.getOperand(0).getImm());
250 }
else if (
MI.getOpcode() == SPIRV::OpCapability) {
251 auto Cap = SPIRV::Capability::Capability(
MI.getOperand(0).getImm());
259 collectGlobalEntities(
270 unsigned StartOpIndex = 0) {
271 for (
const auto *
B : MAI.
MS[MSType]) {
272 const unsigned NumAOps =
A.getNumOperands();
273 if (NumAOps !=
B->getNumOperands() ||
A.getNumDefs() !=
B->getNumDefs())
275 bool AllOpsMatch =
true;
276 for (
unsigned i = StartOpIndex; i < NumAOps && AllOpsMatch; ++i) {
277 if (
A.getOperand(i).isReg() &&
B->getOperand(i).isReg()) {
278 Register RegA =
A.getOperand(i).getReg();
279 Register RegB =
B->getOperand(i).getReg();
283 AllOpsMatch =
A.getOperand(i).isIdenticalTo(
B->getOperand(i));
298 if (
MI.getOpcode() == SPIRV::OpDecorate) {
300 auto Dec =
MI.getOperand(1).getImm();
301 if (Dec ==
static_cast<unsigned>(SPIRV::Decoration::LinkageAttributes)) {
302 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
303 if (Lnk ==
static_cast<unsigned>(SPIRV::LinkageType::Import)) {
311 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
325 bool Append =
true) {
327 if (findSameInstrInMS(
MI, MSType, MAI))
338void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
339 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
340 if ((*F).isDeclaration())
348 const unsigned OpCode =
MI.getOpcode();
349 if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
351 }
else if (OpCode == SPIRV::OpEntryPoint) {
355 collectFuncNames(
MI, &*
F);
360 }
else if (OpCode == SPIRV::OpFunction) {
361 collectFuncNames(
MI, &*
F);
362 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
372void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
373 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
374 if ((*F).isDeclaration())
389 if (
MI.getOpcode() != SPIRV::OpExtInst)
391 auto Set =
MI.getOperand(2).getImm();
401 SPIRV::OperandCategory::OperandCategory Category,
uint32_t i,
403 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
406void SPIRV::RequirementHandler::pruneCapabilities(
408 for (
const auto &Cap : ToPrune) {
410 auto FoundIndex = std::find(MinimalCaps.begin(), MinimalCaps.end(), Cap);
411 if (FoundIndex != MinimalCaps.end())
412 MinimalCaps.erase(FoundIndex);
415 pruneCapabilities(ImplicitDecls);
420 for (
const auto &Cap : ToAdd) {
421 bool IsNewlyInserted = AllCaps.insert(Cap).second;
422 if (!IsNewlyInserted)
426 pruneCapabilities(ImplicitDecls);
427 MinimalCaps.push_back(Cap);
436 if (Req.
Cap.has_value())
437 addCapabilities({Req.
Cap.value()});
439 addExtensions(Req.
Exts);
442 if (MaxVersion && Req.
MinVer > MaxVersion) {
444 <<
" and <= " << MaxVersion <<
"\n");
448 if (MinVersion == 0 || Req.
MinVer > MinVersion)
453 if (MinVersion && Req.
MaxVer < MinVersion) {
455 <<
" and >= " << MinVersion <<
"\n");
459 if (MaxVersion == 0 || Req.
MaxVer < MaxVersion)
467 bool IsSatisfiable =
true;
468 auto TargetVer =
ST.getSPIRVVersion();
470 if (MaxVersion && TargetVer && MaxVersion < TargetVer) {
472 dbgs() <<
"Target SPIR-V version too high for required features\n"
473 <<
"Required max version: " << MaxVersion <<
" target version "
474 << TargetVer <<
"\n");
475 IsSatisfiable =
false;
478 if (MinVersion && TargetVer && MinVersion > TargetVer) {
479 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
480 <<
"Required min version: " << MinVersion
481 <<
" target version " << TargetVer <<
"\n");
482 IsSatisfiable =
false;
485 if (MinVersion && MaxVersion && MinVersion > MaxVersion) {
488 <<
"Version is too low for some features and too high for others.\n"
489 <<
"Required SPIR-V min version: " << MinVersion
490 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
491 IsSatisfiable =
false;
494 for (
auto Cap : MinimalCaps) {
495 if (AvailableCaps.contains(Cap))
499 OperandCategory::CapabilityOperand, Cap)
501 IsSatisfiable =
false;
504 for (
auto Ext : AllExtensions) {
505 if (
ST.canUseExtension(Ext))
509 OperandCategory::ExtensionOperand, Ext)
511 IsSatisfiable =
false;
520 for (
const auto Cap : ToAdd)
521 if (AvailableCaps.insert(Cap).second)
523 SPIRV::OperandCategory::CapabilityOperand, Cap));
528void RequirementHandler::initAvailableCapabilities(
const SPIRVSubtarget &ST) {
529 if (
ST.isOpenCLEnv()) {
530 initAvailableCapabilitiesForOpenCL(ST);
534 if (
ST.isVulkanEnv()) {
535 initAvailableCapabilitiesForVulkan(ST);
542void RequirementHandler::initAvailableCapabilitiesForOpenCL(
545 addAvailableCaps({Capability::Addresses, Capability::Float16Buffer,
546 Capability::Int16, Capability::Int8, Capability::Kernel,
547 Capability::Linkage, Capability::Vector16,
548 Capability::Groups, Capability::GenericPointer,
549 Capability::Shader});
550 if (
ST.hasOpenCLFullProfile())
551 addAvailableCaps({Capability::Int64, Capability::Int64Atomics});
552 if (
ST.hasOpenCLImageSupport()) {
553 addAvailableCaps({Capability::ImageBasic, Capability::LiteralSampler,
554 Capability::Image1D, Capability::SampledBuffer,
555 Capability::ImageBuffer});
556 if (
ST.isAtLeastOpenCLVer(20))
557 addAvailableCaps({Capability::ImageReadWrite});
559 if (
ST.isAtLeastSPIRVVer(11) &&
ST.isAtLeastOpenCLVer(22))
560 addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage});
561 if (
ST.isAtLeastSPIRVVer(13))
562 addAvailableCaps({Capability::GroupNonUniform,
563 Capability::GroupNonUniformVote,
564 Capability::GroupNonUniformArithmetic,
565 Capability::GroupNonUniformBallot,
566 Capability::GroupNonUniformClustered,
567 Capability::GroupNonUniformShuffle,
568 Capability::GroupNonUniformShuffleRelative});
569 if (
ST.isAtLeastSPIRVVer(14))
570 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
571 Capability::SignedZeroInfNanPreserve,
572 Capability::RoundingModeRTE,
573 Capability::RoundingModeRTZ});
575 addAvailableCaps({Capability::Float16, Capability::Float64});
578 for (
auto Extension :
ST.getAllAvailableExtensions()) {
581 addAvailableCaps(EnabledCapabilities);
587void RequirementHandler::initAvailableCapabilitiesForVulkan(
589 addAvailableCaps({Capability::Shader, Capability::Linkage});
592 addAvailableCaps({Capability::Int16, Capability::Int64, Capability::Float64});
600static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
603 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
604 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
606 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
608 if (Dec == SPIRV::Decoration::BuiltIn) {
609 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
610 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
612 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
620 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
623 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
624 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
628 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
629 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
630 bool NoSampler =
MI.getOperand(6).getImm() == 2;
633 switch (
MI.getOperand(2).getImm()) {
634 case SPIRV::Dim::DIM_1D:
636 : SPIRV::Capability::Sampled1D);
638 case SPIRV::Dim::DIM_2D:
639 if (IsMultisampled && NoSampler)
642 case SPIRV::Dim::DIM_Cube:
646 : SPIRV::Capability::SampledCubeArray);
648 case SPIRV::Dim::DIM_Rect:
650 : SPIRV::Capability::SampledRect);
652 case SPIRV::Dim::DIM_Buffer:
654 : SPIRV::Capability::SampledBuffer);
656 case SPIRV::Dim::DIM_SubpassData:
663 if (
MI.getNumOperands() > 8 &&
664 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
673 switch (
MI.getOpcode()) {
674 case SPIRV::OpMemoryModel: {
675 int64_t
Addr =
MI.getOperand(0).getImm();
678 int64_t Mem =
MI.getOperand(1).getImm();
683 case SPIRV::OpEntryPoint: {
684 int64_t
Exe =
MI.getOperand(0).getImm();
689 case SPIRV::OpExecutionMode:
690 case SPIRV::OpExecutionModeId: {
691 int64_t
Exe =
MI.getOperand(1).getImm();
696 case SPIRV::OpTypeMatrix:
699 case SPIRV::OpTypeInt: {
700 unsigned BitWidth =
MI.getOperand(1).getImm();
709 case SPIRV::OpTypeFloat: {
710 unsigned BitWidth =
MI.getOperand(1).getImm();
717 case SPIRV::OpTypeVector: {
718 unsigned NumComponents =
MI.getOperand(2).getImm();
719 if (NumComponents == 8 || NumComponents == 16)
723 case SPIRV::OpTypePointer: {
724 auto SC =
MI.getOperand(1).getImm();
731 if (TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
736 case SPIRV::OpBitReverse:
737 case SPIRV::OpTypeRuntimeArray:
740 case SPIRV::OpTypeOpaque:
741 case SPIRV::OpTypeEvent:
744 case SPIRV::OpTypePipe:
745 case SPIRV::OpTypeReserveId:
748 case SPIRV::OpTypeDeviceEvent:
749 case SPIRV::OpTypeQueue:
750 case SPIRV::OpBuildNDRange:
753 case SPIRV::OpDecorate:
754 case SPIRV::OpDecorateId:
755 case SPIRV::OpDecorateString:
756 addOpDecorateReqs(
MI, 1, Reqs, ST);
758 case SPIRV::OpMemberDecorate:
759 case SPIRV::OpMemberDecorateString:
760 addOpDecorateReqs(
MI, 2, Reqs, ST);
762 case SPIRV::OpInBoundsPtrAccessChain:
765 case SPIRV::OpConstantSampler:
768 case SPIRV::OpTypeImage:
769 addOpTypeImageReqs(
MI, Reqs, ST);
771 case SPIRV::OpTypeSampler:
774 case SPIRV::OpTypeForwardPointer:
778 case SPIRV::OpAtomicFlagTestAndSet:
779 case SPIRV::OpAtomicLoad:
780 case SPIRV::OpAtomicStore:
781 case SPIRV::OpAtomicExchange:
782 case SPIRV::OpAtomicCompareExchange:
783 case SPIRV::OpAtomicIIncrement:
784 case SPIRV::OpAtomicIDecrement:
785 case SPIRV::OpAtomicIAdd:
786 case SPIRV::OpAtomicISub:
787 case SPIRV::OpAtomicUMin:
788 case SPIRV::OpAtomicUMax:
789 case SPIRV::OpAtomicSMin:
790 case SPIRV::OpAtomicSMax:
791 case SPIRV::OpAtomicAnd:
792 case SPIRV::OpAtomicOr:
793 case SPIRV::OpAtomicXor: {
796 if (
MI.getOpcode() == SPIRV::OpAtomicStore) {
798 InstrPtr =
MRI.getVRegDef(
MI.getOperand(3).getReg());
799 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
804 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
811 case SPIRV::OpGroupNonUniformIAdd:
812 case SPIRV::OpGroupNonUniformFAdd:
813 case SPIRV::OpGroupNonUniformIMul:
814 case SPIRV::OpGroupNonUniformFMul:
815 case SPIRV::OpGroupNonUniformSMin:
816 case SPIRV::OpGroupNonUniformUMin:
817 case SPIRV::OpGroupNonUniformFMin:
818 case SPIRV::OpGroupNonUniformSMax:
819 case SPIRV::OpGroupNonUniformUMax:
820 case SPIRV::OpGroupNonUniformFMax:
821 case SPIRV::OpGroupNonUniformBitwiseAnd:
822 case SPIRV::OpGroupNonUniformBitwiseOr:
823 case SPIRV::OpGroupNonUniformBitwiseXor:
824 case SPIRV::OpGroupNonUniformLogicalAnd:
825 case SPIRV::OpGroupNonUniformLogicalOr:
826 case SPIRV::OpGroupNonUniformLogicalXor: {
828 int64_t GroupOp =
MI.getOperand(3).getImm();
830 case SPIRV::GroupOperation::Reduce:
831 case SPIRV::GroupOperation::InclusiveScan:
832 case SPIRV::GroupOperation::ExclusiveScan:
834 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
835 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
837 case SPIRV::GroupOperation::ClusteredReduce:
838 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
840 case SPIRV::GroupOperation::PartitionedReduceNV:
841 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
842 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
843 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
848 case SPIRV::OpGroupNonUniformShuffle:
849 case SPIRV::OpGroupNonUniformShuffleXor:
850 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
852 case SPIRV::OpGroupNonUniformShuffleUp:
853 case SPIRV::OpGroupNonUniformShuffleDown:
854 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
856 case SPIRV::OpGroupAll:
857 case SPIRV::OpGroupAny:
858 case SPIRV::OpGroupBroadcast:
859 case SPIRV::OpGroupIAdd:
860 case SPIRV::OpGroupFAdd:
861 case SPIRV::OpGroupFMin:
862 case SPIRV::OpGroupUMin:
863 case SPIRV::OpGroupSMin:
864 case SPIRV::OpGroupFMax:
865 case SPIRV::OpGroupUMax:
866 case SPIRV::OpGroupSMax:
869 case SPIRV::OpGroupNonUniformElect:
872 case SPIRV::OpGroupNonUniformAll:
873 case SPIRV::OpGroupNonUniformAny:
874 case SPIRV::OpGroupNonUniformAllEqual:
877 case SPIRV::OpGroupNonUniformBroadcast:
878 case SPIRV::OpGroupNonUniformBroadcastFirst:
879 case SPIRV::OpGroupNonUniformBallot:
880 case SPIRV::OpGroupNonUniformInverseBallot:
881 case SPIRV::OpGroupNonUniformBallotBitExtract:
882 case SPIRV::OpGroupNonUniformBallotBitCount:
883 case SPIRV::OpGroupNonUniformBallotFindLSB:
884 case SPIRV::OpGroupNonUniformBallotFindMSB:
885 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
895 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
901 addInstrRequirements(
MI, MAI.
Reqs, ST);
904 auto Node =
M.getNamedMetadata(
"spirv.ExecutionMode");
906 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
907 MDNode *MDN = cast<MDNode>(
Node->getOperand(i));
909 if (
auto *CMeta = dyn_cast<ConstantAsMetadata>(MDOp)) {
912 auto EM =
Const->getZExtValue();
914 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
919 for (
auto FI =
M.begin(),
E =
M.end(); FI !=
E; ++FI) {
921 if (
F.isDeclaration())
923 if (
F.getMetadata(
"reqd_work_group_size"))
925 SPIRV::OperandCategory::ExecutionModeOperand,
926 SPIRV::ExecutionMode::LocalSize, ST);
927 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
929 SPIRV::OperandCategory::ExecutionModeOperand,
930 SPIRV::ExecutionMode::LocalSize, ST);
932 if (
F.getMetadata(
"work_group_size_hint"))
934 SPIRV::OperandCategory::ExecutionModeOperand,
935 SPIRV::ExecutionMode::LocalSizeHint, ST);
936 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
938 SPIRV::OperandCategory::ExecutionModeOperand,
939 SPIRV::ExecutionMode::SubgroupSize, ST);
940 if (
F.getMetadata(
"vec_type_hint"))
942 SPIRV::OperandCategory::ExecutionModeOperand,
943 SPIRV::ExecutionMode::VecTypeHint, ST);
945 if (
F.hasOptNone() &&
946 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
955 unsigned Flags = SPIRV::FPFastMathMode::None;
957 Flags |= SPIRV::FPFastMathMode::NotNaN;
959 Flags |= SPIRV::FPFastMathMode::NotInf;
961 Flags |= SPIRV::FPFastMathMode::NSZ;
963 Flags |= SPIRV::FPFastMathMode::AllowRecip;
965 Flags |= SPIRV::FPFastMathMode::Fast;
973 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
974 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
977 SPIRV::Decoration::NoSignedWrap, {});
980 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
981 SPIRV::Decoration::NoUnsignedWrap, ST,
985 SPIRV::Decoration::NoUnsignedWrap, {});
987 if (!
TII.canUseFastMathFlags(
I))
989 unsigned FMFlags = getFastMathFlags(
I);
990 if (FMFlags == SPIRV::FPFastMathMode::None)
992 Register DstReg =
I.getOperand(0).getReg();
1000 for (
auto F =
M.begin(),
E =
M.end();
F !=
E; ++
F) {
1004 for (
auto &
MBB : *MF)
1005 for (
auto &
MI :
MBB)
1006 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs);
1020 ST =
TM.getSubtargetImpl();
1021 GR = ST->getSPIRVGlobalRegistry();
1022 TII = ST->getInstrInfo();
1024 MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
1028 addDecorations(M, *
TII, MMI, *ST, MAI);
1030 collectReqs(M, MAI, MMI, *ST);
1034 processDefInstrs(M);
1037 numberRegistersGlobally(M);
1040 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
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.
This class represents an Operation in the Expression.
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.
constexpr bool isValid() const
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)
@ 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)
CapabilityList getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension)
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
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