Lines Matching +full:mi +full:- +full:v
1 //===- SPIRVModuleAnalysis.cpp - analysis of global instrs & regs - C++ -*-===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
31 #define DEBUG_TYPE "spirv-module-analysis"
34 SPVDumpDeps("spv-dump-deps",
35 cl::desc("Dump MIR with SPIR-V dependencies info"),
39 AvoidCapabilities("avoid-spirv-capabilities",
40 cl::desc("SPIR-V capabilities to avoid if there are "
44 "SPIR-V Shader capability")));
66 if (MdNode && OpIndex < MdNode->getNumOperands()) { in getMetadataUInt()
67 const auto &Op = MdNode->getOperand(OpIndex); in getMetadataUInt()
68 return mdconst::extract<ConstantInt>(Op)->getZExtValue(); in getMetadataUInt()
100 // By SPIR-V specification: "If an instruction, enumerant, or other in getSymbolicOperandRequirements()
112 if (i == Sz - 1 || !AvoidCaps.S.contains(Cap)) in getSymbolicOperandRequirements()
146 auto MemMD = MemModel->getOperand(0); in setBaseInfo()
153 MAI.Mem = ST->isOpenCLEnv() ? SPIRV::MemoryModel::OpenCL in setBaseInfo()
156 unsigned PtrSize = ST->getPointerSize(); in setBaseInfo()
169 // Construct version literal in accordance with SPIRV-LLVM-Translator. in setBaseInfo()
171 assert(VerNode->getNumOperands() > 0 && "Invalid SPIR"); in setBaseInfo()
172 auto VersionMD = VerNode->getOperand(0); in setBaseInfo()
182 // run-times with Unknown/0.0 version output. For a reference, LLVM-SPIRV in setBaseInfo()
183 // Translator avoids potential issues with run-times in a similar manner. in setBaseInfo()
184 if (ST->isOpenCLEnv()) { in setBaseInfo()
194 for (unsigned I = 0, E = ExtNode->getNumOperands(); I != E; ++I) { in setBaseInfo()
195 MDNode *MD = ExtNode->getOperand(I); in setBaseInfo()
196 if (!MD || MD->getNumOperands() == 0) in setBaseInfo()
198 for (unsigned J = 0, N = MD->getNumOperands(); J != N; ++J) in setBaseInfo()
199 MAI.SrcExt.insert(cast<MDString>(MD->getOperand(J))->getString()); in setBaseInfo()
212 if (ST->isOpenCLEnv()) { in setBaseInfo()
220 // Collect MI which defines the register in the given machine function.
225 assert(MAI->hasRegisterAlias(MF, Reg) && "Cannot find register alias"); in collectDefInstr()
226 MachineInstr *MI = MF->getRegInfo().getUniqueVRegDef(Reg); in collectDefInstr() local
227 assert(MI && "There should be an instruction that defines the register"); in collectDefInstr()
228 MAI->setSkipEmission(MI); in collectDefInstr()
230 MAI->MS[MSType].push_back(MI); in collectDefInstr()
249 // Traversing deps graph in post-order allows us to get rid of in collectGlobalEntities()
251 // But pre-order is required for correct processing of function in collectGlobalEntities()
254 for (auto *S : E->getDeps()) in collectGlobalEntities()
263 if (!MF->getRegInfo().getUniqueVRegDef(Reg)) in collectGlobalEntities()
267 if (E->getIsGV()) in collectGlobalEntities()
268 MAI.GlobalVarList.push_back(MF->getRegInfo().getUniqueVRegDef(Reg)); in collectGlobalEntities()
272 for (auto *S : E->getDeps()) in collectGlobalEntities()
286 GR->buildDepsGraph(DepsGraph, SPVDumpDeps ? MMI : nullptr); in processDefInstrs()
290 [](const SPIRV::DTSortableEntry *E) { return !E->getIsFunc(); }); in processDefInstrs()
293 MachineFunction *MF = MMI->getMachineFunction(*F); in processDefInstrs()
298 for (MachineInstr &MI : MBB) { in processDefInstrs()
299 if (MI.getOpcode() == SPIRV::OpExtension) { in processDefInstrs()
301 auto Ext = SPIRV::Extension::Extension(MI.getOperand(0).getImm()); in processDefInstrs()
303 MAI.setSkipEmission(&MI); in processDefInstrs()
304 } else if (MI.getOpcode() == SPIRV::OpCapability) { in processDefInstrs()
305 auto Cap = SPIRV::Capability::Capability(MI.getOperand(0).getImm()); in processDefInstrs()
307 MAI.setSkipEmission(&MI); in processDefInstrs()
315 [](const SPIRV::DTSortableEntry *E) { return E->getIsFunc(); }, true); in processDefInstrs()
322 void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI, in collectFuncNames() argument
324 if (MI.getOpcode() == SPIRV::OpDecorate) { in collectFuncNames()
326 auto Dec = MI.getOperand(1).getImm(); in collectFuncNames()
328 auto Lnk = MI.getOperand(MI.getNumOperands() - 1).getImm(); in collectFuncNames()
332 F->getParent()->getFunction(getStringImm(MI, 2)); in collectFuncNames()
333 Register Target = MI.getOperand(0).getReg(); in collectFuncNames()
334 MAI.FuncMap[ImportedFunc] = MAI.getRegisterAlias(MI.getMF(), Target); in collectFuncNames()
337 } else if (MI.getOpcode() == SPIRV::OpFunction) { in collectFuncNames()
339 Register Reg = MI.defs().begin()->getReg(); in collectFuncNames()
340 Register GlobalReg = MAI.getRegisterAlias(MI.getMF(), Reg); in collectFuncNames()
351 for (auto &MI : MAI.MS[SPIRV::MB_TypeConstVars]) in collectFuncPtrs() local
352 if (MI->getOpcode() == SPIRV::OpConstantFunctionPointerINTEL) in collectFuncPtrs()
353 collectFuncPtrs(MI); in collectFuncPtrs()
356 void SPIRVModuleAnalysis::collectFuncPtrs(MachineInstr *MI) { in collectFuncPtrs() argument
357 const MachineOperand *FunUse = &MI->getOperand(2); in collectFuncPtrs()
358 if (const MachineOperand *FunDef = GR->getFunctionDefinitionByUse(FunUse)) { in collectFuncPtrs()
359 const MachineInstr *FunDefMI = FunDef->getParent(); in collectFuncPtrs()
360 assert(FunDefMI->getOpcode() == SPIRV::OpFunction && in collectFuncPtrs()
362 Register FunDefReg = FunDef->getReg(); in collectFuncPtrs()
364 MAI.getRegisterAlias(FunDefMI->getMF(), FunDefReg); in collectFuncPtrs()
367 Register FunPtrReg = FunUse->getReg(); in collectFuncPtrs()
368 MAI.setRegisterAlias(MI->getMF(), FunPtrReg, GlobalFunDefReg); in collectFuncPtrs()
379 static InstrSignature instrToSignature(MachineInstr &MI, in instrToSignature() argument
382 for (unsigned i = 0; i < MI.getNumOperands(); ++i) { in instrToSignature()
383 const MachineOperand &MO = MI.getOperand(i); in instrToSignature()
386 Register RegAlias = MAI.getRegisterAlias(MI.getMF(), MO.getReg()); in instrToSignature()
401 static void collectOtherInstr(MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI, in collectOtherInstr() argument
404 MAI.setSkipEmission(&MI); in collectOtherInstr()
405 InstrSignature MISign = instrToSignature(MI, MAI); in collectOtherInstr()
411 MAI.MS[MSType].push_back(&MI); in collectOtherInstr()
413 MAI.MS[MSType].insert(MAI.MS[MSType].begin(), &MI); in collectOtherInstr()
416 // Some global instructions make reference to function-local ID regs, so cannot
423 MachineFunction *MF = MMI->getMachineFunction(*F); in processOtherInstrs()
426 for (MachineInstr &MI : MBB) { in processOtherInstrs()
427 if (MAI.getSkipEmission(&MI)) in processOtherInstrs()
429 const unsigned OpCode = MI.getOpcode(); in processOtherInstrs()
431 collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS); in processOtherInstrs()
433 collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS); in processOtherInstrs()
434 } else if (TII->isDecorationInstr(MI)) { in processOtherInstrs()
435 collectOtherInstr(MI, MAI, SPIRV::MB_Annotations, IS); in processOtherInstrs()
436 collectFuncNames(MI, &*F); in processOtherInstrs()
437 } else if (TII->isConstantInstr(MI)) { in processOtherInstrs()
440 collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, IS); in processOtherInstrs()
442 collectFuncNames(MI, &*F); in processOtherInstrs()
444 collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, IS, false); in processOtherInstrs()
457 MachineFunction *MF = MMI->getMachineFunction(*F); in numberRegistersGlobally()
460 for (MachineInstr &MI : MBB) { in numberRegistersGlobally()
461 for (MachineOperand &Op : MI.operands()) { in numberRegistersGlobally()
470 if (MI.getOpcode() != SPIRV::OpExtInst) in numberRegistersGlobally()
472 auto Set = MI.getOperand(2).getImm(); in numberRegistersGlobally()
500 if (!IsNewlyInserted) // Don't re-add if it's already been declared. in addCapabilities()
512 report_fatal_error("Adding SPIR-V requirements this target can't satisfy."); in addRequirements()
523 report_fatal_error("Adding SPIR-V requirements that can't be satisfied."); in addRequirements()
534 report_fatal_error("Adding SPIR-V requirements that can't be satisfied."); in addRequirements()
550 dbgs() << "Target SPIR-V version too high for required features\n" in checkSatisfiable()
557 LLVM_DEBUG(dbgs() << "Target SPIR-V version too low for required features\n" in checkSatisfiable()
567 << "Required SPIR-V min version: " << MinVersion in checkSatisfiable()
568 << " required SPIR-V max version " << MaxVersion << "\n"); in checkSatisfiable()
593 report_fatal_error("Unable to meet SPIR-V requirements for this target."); in checkSatisfiable()
624 report_fatal_error("Unimplemented environment for SPIR-V generation."); in initAvailableCapabilities()
629 // Add the min requirements for different OpenCL and SPIR-V versions. in initAvailableCapabilitiesForOpenCL()
687 static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex, in addOpDecorateReqs() argument
690 int64_t DecOp = MI.getOperand(DecIndex).getImm(); in addOpDecorateReqs()
696 int64_t BuiltInOp = MI.getOperand(DecIndex + 1).getImm(); in addOpDecorateReqs()
701 int64_t LinkageOp = MI.getOperand(MI.getNumOperands() - 1).getImm(); in addOpDecorateReqs()
719 static void addOpTypeImageReqs(const MachineInstr &MI, in addOpTypeImageReqs() argument
722 assert(MI.getNumOperands() >= 8 && "Insufficient operands for OpTypeImage"); in addOpTypeImageReqs()
725 int64_t ImgFormatOp = MI.getOperand(7).getImm(); in addOpTypeImageReqs()
730 bool IsArrayed = MI.getOperand(4).getImm() == 1; in addOpTypeImageReqs()
731 bool IsMultisampled = MI.getOperand(5).getImm() == 1; in addOpTypeImageReqs()
732 bool NoSampler = MI.getOperand(6).getImm() == 2; in addOpTypeImageReqs()
734 assert(MI.getOperand(2).isImm()); in addOpTypeImageReqs()
735 switch (MI.getOperand(2).getImm()) { in addOpTypeImageReqs()
765 if (MI.getNumOperands() > 8 && in addOpTypeImageReqs()
766 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite) in addOpTypeImageReqs()
774 "The atomic float instruction requires the following SPIR-V " \
776 static void AddAtomicFloatRequirements(const MachineInstr &MI, in AddAtomicFloatRequirements() argument
779 assert(MI.getOperand(1).isReg() && in AddAtomicFloatRequirements()
781 Register TypeReg = MI.getOperand(1).getReg(); in AddAtomicFloatRequirements()
782 SPIRVType *TypeDef = MI.getMF()->getRegInfo().getVRegDef(TypeReg); in AddAtomicFloatRequirements()
783 if (TypeDef->getOpcode() != SPIRV::OpTypeFloat) in AddAtomicFloatRequirements()
785 "floating-point type scalar"); in AddAtomicFloatRequirements()
787 unsigned BitWidth = TypeDef->getOperand(1).getImm(); in AddAtomicFloatRequirements()
788 unsigned Op = MI.getOpcode(); in AddAtomicFloatRequirements()
809 "Unexpected floating-point type width in atomic float instruction"); in AddAtomicFloatRequirements()
828 "Unexpected floating-point type width in atomic float instruction"); in AddAtomicFloatRequirements()
833 void addInstrRequirements(const MachineInstr &MI, in addInstrRequirements() argument
836 switch (MI.getOpcode()) { in addInstrRequirements()
838 int64_t Addr = MI.getOperand(0).getImm(); in addInstrRequirements()
841 int64_t Mem = MI.getOperand(1).getImm(); in addInstrRequirements()
847 int64_t Exe = MI.getOperand(0).getImm(); in addInstrRequirements()
854 int64_t Exe = MI.getOperand(1).getImm(); in addInstrRequirements()
863 unsigned BitWidth = MI.getOperand(1).getImm(); in addInstrRequirements()
873 unsigned BitWidth = MI.getOperand(1).getImm(); in addInstrRequirements()
881 unsigned NumComponents = MI.getOperand(2).getImm(); in addInstrRequirements()
887 auto SC = MI.getOperand(1).getImm(); in addInstrRequirements()
894 assert(MI.getOperand(2).isReg()); in addInstrRequirements()
895 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); in addInstrRequirements()
896 SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(2).getReg()); in addInstrRequirements()
897 if (TypeDef->getOpcode() == SPIRV::OpTypeFloat && in addInstrRequirements()
898 TypeDef->getOperand(1).getImm() == 16) in addInstrRequirements()
932 addOpDecorateReqs(MI, 1, Reqs, ST); in addInstrRequirements()
936 addOpDecorateReqs(MI, 2, Reqs, ST); in addInstrRequirements()
945 addOpTypeImageReqs(MI, Reqs, ST); in addInstrRequirements()
970 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); in addInstrRequirements()
971 const MachineInstr *InstrPtr = &MI; in addInstrRequirements()
972 if (MI.getOpcode() == SPIRV::OpAtomicStore) { in addInstrRequirements()
973 assert(MI.getOperand(3).isReg()); in addInstrRequirements()
974 InstrPtr = MRI.getVRegDef(MI.getOperand(3).getReg()); in addInstrRequirements()
977 assert(InstrPtr->getOperand(1).isReg() && "Unexpected operand in atomic"); in addInstrRequirements()
978 Register TypeReg = InstrPtr->getOperand(1).getReg(); in addInstrRequirements()
980 if (TypeDef->getOpcode() == SPIRV::OpTypeInt) { in addInstrRequirements()
981 unsigned BitWidth = TypeDef->getOperand(1).getImm(); in addInstrRequirements()
1003 assert(MI.getOperand(3).isImm()); in addInstrRequirements()
1004 int64_t GroupOp = MI.getOperand(3).getImm(); in addInstrRequirements()
1109 "following SPIR-V extension: SPV_KHR_subgroup_rotate", in addInstrRequirements()
1132 "following SPIR-V extension: SPV_KHR_shader_clock", in addInstrRequirements()
1146 AddAtomicFloatRequirements(MI, Reqs, ST); in addInstrRequirements()
1175 "following SPIR-V extension: SPV_KHR_cooperative_matrix", in addInstrRequirements()
1195 MachineFunction *MF = MMI->getMachineFunction(*F); in collectReqs()
1199 for (const MachineInstr &MI : MBB) in collectReqs() local
1200 addInstrRequirements(MI, MAI.Reqs, ST); in collectReqs()
1208 for (unsigned i = 0; i < Node->getNumOperands(); i++) { in collectReqs()
1209 MDNode *MDN = cast<MDNode>(Node->getOperand(i)); in collectReqs()
1210 const MDOperand &MDOp = MDN->getOperand(1); in collectReqs()
1212 Constant *C = CMeta->getValue(); in collectReqs()
1214 auto EM = Const->getZExtValue(); in collectReqs()
1311 // Walk all functions and add decorations related to MI flags.
1316 MachineFunction *MF = MMI->getMachineFunction(*F); in addDecorations()
1320 for (auto &MI : MBB) in addDecorations() local
1321 handleMIFlagDecoration(MI, ST, TII, MAI.Reqs); in addDecorations()
1336 GR = ST->getSPIRVGlobalRegistry(); in runOnModule()
1337 TII = ST->getInstrInfo(); in runOnModule()
1355 if (GR->hasConstFunPtr()) in runOnModule()
1366 GR->setBound(MAI.MaxID); in runOnModule()