xref: /llvm-project/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp (revision df122fc734ce002632f3bfe8a5fc5010349dba16)
1 //===- SPIRVModuleAnalysis.cpp - analysis of global instrs & regs - C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // The analysis collects instructions that should be output at the module level
10 // and performs the global register numbering.
11 //
12 // The results of this analysis are used in AsmPrinter to rename registers
13 // globally and to output required instructions at the module level.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "SPIRVModuleAnalysis.h"
18 #include "MCTargetDesc/SPIRVBaseInfo.h"
19 #include "MCTargetDesc/SPIRVMCTargetDesc.h"
20 #include "SPIRV.h"
21 #include "SPIRVSubtarget.h"
22 #include "SPIRVTargetMachine.h"
23 #include "SPIRVUtils.h"
24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/TargetPassConfig.h"
27 
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "spirv-module-analysis"
31 
32 static cl::opt<bool>
33     SPVDumpDeps("spv-dump-deps",
34                 cl::desc("Dump MIR with SPIR-V dependencies info"),
35                 cl::Optional, cl::init(false));
36 
37 static cl::list<SPIRV::Capability::Capability>
38     AvoidCapabilities("avoid-spirv-capabilities",
39                       cl::desc("SPIR-V capabilities to avoid if there are "
40                                "other options enabling a feature"),
41                       cl::ZeroOrMore, cl::Hidden,
42                       cl::values(clEnumValN(SPIRV::Capability::Shader, "Shader",
43                                             "SPIR-V Shader capability")));
44 // Use sets instead of cl::list to check "if contains" condition
45 struct AvoidCapabilitiesSet {
46   SmallSet<SPIRV::Capability::Capability, 4> S;
47   AvoidCapabilitiesSet() {
48     for (auto Cap : AvoidCapabilities)
49       S.insert(Cap);
50   }
51 };
52 
53 char llvm::SPIRVModuleAnalysis::ID = 0;
54 
55 namespace llvm {
56 void initializeSPIRVModuleAnalysisPass(PassRegistry &);
57 } // namespace llvm
58 
59 INITIALIZE_PASS(SPIRVModuleAnalysis, DEBUG_TYPE, "SPIRV module analysis", true,
60                 true)
61 
62 // Retrieve an unsigned from an MDNode with a list of them as operands.
63 static unsigned getMetadataUInt(MDNode *MdNode, unsigned OpIndex,
64                                 unsigned DefaultVal = 0) {
65   if (MdNode && OpIndex < MdNode->getNumOperands()) {
66     const auto &Op = MdNode->getOperand(OpIndex);
67     return mdconst::extract<ConstantInt>(Op)->getZExtValue();
68   }
69   return DefaultVal;
70 }
71 
72 static SPIRV::Requirements
73 getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
74                                unsigned i, const SPIRVSubtarget &ST,
75                                SPIRV::RequirementHandler &Reqs) {
76   // A set of capabilities to avoid if there is another option.
77   AvoidCapabilitiesSet AvoidCaps;
78   if (ST.isOpenCLEnv())
79     AvoidCaps.S.insert(SPIRV::Capability::Shader);
80 
81   VersionTuple ReqMinVer = getSymbolicOperandMinVersion(Category, i);
82   VersionTuple ReqMaxVer = getSymbolicOperandMaxVersion(Category, i);
83   VersionTuple SPIRVVersion = ST.getSPIRVVersion();
84   bool MinVerOK = SPIRVVersion.empty() || SPIRVVersion >= ReqMinVer;
85   bool MaxVerOK =
86       ReqMaxVer.empty() || SPIRVVersion.empty() || SPIRVVersion <= ReqMaxVer;
87   CapabilityList ReqCaps = getSymbolicOperandCapabilities(Category, i);
88   ExtensionList ReqExts = getSymbolicOperandExtensions(Category, i);
89   if (ReqCaps.empty()) {
90     if (ReqExts.empty()) {
91       if (MinVerOK && MaxVerOK)
92         return {true, {}, {}, ReqMinVer, ReqMaxVer};
93       return {false, {}, {}, VersionTuple(), VersionTuple()};
94     }
95   } else if (MinVerOK && MaxVerOK) {
96     if (ReqCaps.size() == 1) {
97       auto Cap = ReqCaps[0];
98       if (Reqs.isCapabilityAvailable(Cap))
99         return {true, {Cap}, ReqExts, ReqMinVer, ReqMaxVer};
100     } else {
101       // By SPIR-V specification: "If an instruction, enumerant, or other
102       // feature specifies multiple enabling capabilities, only one such
103       // capability needs to be declared to use the feature." However, one
104       // capability may be preferred over another. We use command line
105       // argument(s) and AvoidCapabilities to avoid selection of certain
106       // capabilities if there are other options.
107       CapabilityList UseCaps;
108       for (auto Cap : ReqCaps)
109         if (Reqs.isCapabilityAvailable(Cap))
110           UseCaps.push_back(Cap);
111       for (size_t i = 0, Sz = UseCaps.size(); i < Sz; ++i) {
112         auto Cap = UseCaps[i];
113         if (i == Sz - 1 || !AvoidCaps.S.contains(Cap))
114           return {true, {Cap}, ReqExts, ReqMinVer, ReqMaxVer};
115       }
116     }
117   }
118   // If there are no capabilities, or we can't satisfy the version or
119   // capability requirements, use the list of extensions (if the subtarget
120   // can handle them all).
121   if (llvm::all_of(ReqExts, [&ST](const SPIRV::Extension::Extension &Ext) {
122         return ST.canUseExtension(Ext);
123       })) {
124     return {true,
125             {},
126             ReqExts,
127             VersionTuple(),
128             VersionTuple()}; // TODO: add versions to extensions.
129   }
130   return {false, {}, {}, VersionTuple(), VersionTuple()};
131 }
132 
133 void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
134   MAI.MaxID = 0;
135   for (int i = 0; i < SPIRV::NUM_MODULE_SECTIONS; i++)
136     MAI.MS[i].clear();
137   MAI.RegisterAliasTable.clear();
138   MAI.InstrsToDelete.clear();
139   MAI.FuncMap.clear();
140   MAI.GlobalVarList.clear();
141   MAI.ExtInstSetMap.clear();
142   MAI.Reqs.clear();
143   MAI.Reqs.initAvailableCapabilities(*ST);
144 
145   // TODO: determine memory model and source language from the configuratoin.
146   if (auto MemModel = M.getNamedMetadata("spirv.MemoryModel")) {
147     auto MemMD = MemModel->getOperand(0);
148     MAI.Addr = static_cast<SPIRV::AddressingModel::AddressingModel>(
149         getMetadataUInt(MemMD, 0));
150     MAI.Mem =
151         static_cast<SPIRV::MemoryModel::MemoryModel>(getMetadataUInt(MemMD, 1));
152   } else {
153     // TODO: Add support for VulkanMemoryModel.
154     MAI.Mem = ST->isOpenCLEnv() ? SPIRV::MemoryModel::OpenCL
155                                 : SPIRV::MemoryModel::GLSL450;
156     if (MAI.Mem == SPIRV::MemoryModel::OpenCL) {
157       unsigned PtrSize = ST->getPointerSize();
158       MAI.Addr = PtrSize == 32   ? SPIRV::AddressingModel::Physical32
159                  : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
160                                  : SPIRV::AddressingModel::Logical;
161     } else {
162       // TODO: Add support for PhysicalStorageBufferAddress.
163       MAI.Addr = SPIRV::AddressingModel::Logical;
164     }
165   }
166   // Get the OpenCL version number from metadata.
167   // TODO: support other source languages.
168   if (auto VerNode = M.getNamedMetadata("opencl.ocl.version")) {
169     MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_C;
170     // Construct version literal in accordance with SPIRV-LLVM-Translator.
171     // TODO: support multiple OCL version metadata.
172     assert(VerNode->getNumOperands() > 0 && "Invalid SPIR");
173     auto VersionMD = VerNode->getOperand(0);
174     unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
175     unsigned MinorNum = getMetadataUInt(VersionMD, 1);
176     unsigned RevNum = getMetadataUInt(VersionMD, 2);
177     // Prevent Major part of OpenCL version to be 0
178     MAI.SrcLangVersion =
179         (std::max(1U, MajorNum) * 100 + MinorNum) * 1000 + RevNum;
180   } else {
181     // If there is no information about OpenCL version we are forced to generate
182     // OpenCL 1.0 by default for the OpenCL environment to avoid puzzling
183     // run-times with Unknown/0.0 version output. For a reference, LLVM-SPIRV
184     // Translator avoids potential issues with run-times in a similar manner.
185     if (ST->isOpenCLEnv()) {
186       MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_CPP;
187       MAI.SrcLangVersion = 100000;
188     } else {
189       MAI.SrcLang = SPIRV::SourceLanguage::Unknown;
190       MAI.SrcLangVersion = 0;
191     }
192   }
193 
194   if (auto ExtNode = M.getNamedMetadata("opencl.used.extensions")) {
195     for (unsigned I = 0, E = ExtNode->getNumOperands(); I != E; ++I) {
196       MDNode *MD = ExtNode->getOperand(I);
197       if (!MD || MD->getNumOperands() == 0)
198         continue;
199       for (unsigned J = 0, N = MD->getNumOperands(); J != N; ++J)
200         MAI.SrcExt.insert(cast<MDString>(MD->getOperand(J))->getString());
201     }
202   }
203 
204   // Update required capabilities for this memory model, addressing model and
205   // source language.
206   MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand,
207                                  MAI.Mem, *ST);
208   MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::SourceLanguageOperand,
209                                  MAI.SrcLang, *ST);
210   MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
211                                  MAI.Addr, *ST);
212 
213   if (ST->isOpenCLEnv()) {
214     // TODO: check if it's required by default.
215     MAI.ExtInstSetMap[static_cast<unsigned>(
216         SPIRV::InstructionSet::OpenCL_std)] =
217         Register::index2VirtReg(MAI.getNextID());
218   }
219 }
220 
221 // Returns a representation of an instruction as a vector of MachineOperand
222 // hash values, see llvm::hash_value(const MachineOperand &MO) for details.
223 // This creates a signature of the instruction with the same content
224 // that MachineOperand::isIdenticalTo uses for comparison.
225 static InstrSignature instrToSignature(const MachineInstr &MI,
226                                        SPIRV::ModuleAnalysisInfo &MAI,
227                                        bool UseDefReg) {
228   InstrSignature Signature{MI.getOpcode()};
229   for (unsigned i = 0; i < MI.getNumOperands(); ++i) {
230     const MachineOperand &MO = MI.getOperand(i);
231     size_t h;
232     if (MO.isReg()) {
233       if (!UseDefReg && MO.isDef())
234         continue;
235       Register RegAlias = MAI.getRegisterAlias(MI.getMF(), MO.getReg());
236       if (!RegAlias.isValid()) {
237         LLVM_DEBUG({
238           dbgs() << "Unexpectedly, no global id found for the operand ";
239           MO.print(dbgs());
240           dbgs() << "\nInstruction: ";
241           MI.print(dbgs());
242           dbgs() << "\n";
243         });
244         report_fatal_error("All v-regs must have been mapped to global id's");
245       }
246       // mimic llvm::hash_value(const MachineOperand &MO)
247       h = hash_combine(MO.getType(), (unsigned)RegAlias, MO.getSubReg(),
248                        MO.isDef());
249     } else {
250       h = hash_value(MO);
251     }
252     Signature.push_back(h);
253   }
254   return Signature;
255 }
256 
257 bool SPIRVModuleAnalysis::isDeclSection(const MachineRegisterInfo &MRI,
258                                         const MachineInstr &MI) {
259   unsigned Opcode = MI.getOpcode();
260   switch (Opcode) {
261   case SPIRV::OpTypeForwardPointer:
262     // omit now, collect later
263     return false;
264   case SPIRV::OpVariable:
265     return static_cast<SPIRV::StorageClass::StorageClass>(
266                MI.getOperand(2).getImm()) != SPIRV::StorageClass::Function;
267   case SPIRV::OpFunction:
268   case SPIRV::OpFunctionParameter:
269     return true;
270   }
271   if (GR->hasConstFunPtr() && Opcode == SPIRV::OpUndef) {
272     Register DefReg = MI.getOperand(0).getReg();
273     for (MachineInstr &UseMI : MRI.use_instructions(DefReg)) {
274       if (UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
275         continue;
276       // it's a dummy definition, FP constant refers to a function,
277       // and this is resolved in another way; let's skip this definition
278       assert(UseMI.getOperand(2).isReg() &&
279              UseMI.getOperand(2).getReg() == DefReg);
280       MAI.setSkipEmission(&MI);
281       return false;
282     }
283   }
284   return TII->isTypeDeclInstr(MI) || TII->isConstantInstr(MI) ||
285          TII->isInlineAsmDefInstr(MI);
286 }
287 
288 // This is a special case of a function pointer refering to a possibly
289 // forward function declaration. The operand is a dummy OpUndef that
290 // requires a special treatment.
291 void SPIRVModuleAnalysis::visitFunPtrUse(
292     Register OpReg, InstrGRegsMap &SignatureToGReg,
293     std::map<const Value *, unsigned> &GlobalToGReg, const MachineFunction *MF,
294     const MachineInstr &MI) {
295   const MachineOperand *OpFunDef =
296       GR->getFunctionDefinitionByUse(&MI.getOperand(2));
297   assert(OpFunDef && OpFunDef->isReg());
298   // find the actual function definition and number it globally in advance
299   const MachineInstr *OpDefMI = OpFunDef->getParent();
300   assert(OpDefMI && OpDefMI->getOpcode() == SPIRV::OpFunction);
301   const MachineFunction *FunDefMF = OpDefMI->getParent()->getParent();
302   const MachineRegisterInfo &FunDefMRI = FunDefMF->getRegInfo();
303   do {
304     visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
305     OpDefMI = OpDefMI->getNextNode();
306   } while (OpDefMI && (OpDefMI->getOpcode() == SPIRV::OpFunction ||
307                        OpDefMI->getOpcode() == SPIRV::OpFunctionParameter));
308   // associate the function pointer with the newly assigned global number
309   Register GlobalFunDefReg = MAI.getRegisterAlias(FunDefMF, OpFunDef->getReg());
310   assert(GlobalFunDefReg.isValid() &&
311          "Function definition must refer to a global register");
312   MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
313 }
314 
315 // Depth first recursive traversal of dependencies. Repeated visits are guarded
316 // by MAI.hasRegisterAlias().
317 void SPIRVModuleAnalysis::visitDecl(
318     const MachineRegisterInfo &MRI, InstrGRegsMap &SignatureToGReg,
319     std::map<const Value *, unsigned> &GlobalToGReg, const MachineFunction *MF,
320     const MachineInstr &MI) {
321   unsigned Opcode = MI.getOpcode();
322   DenseSet<Register> Deps;
323 
324   // Process each operand of the instruction to resolve dependencies
325   for (const MachineOperand &MO : MI.operands()) {
326     if (!MO.isReg() || MO.isDef())
327       continue;
328     Register OpReg = MO.getReg();
329     // Handle function pointers special case
330     if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
331         MRI.getRegClass(OpReg) == &SPIRV::pIDRegClass) {
332       visitFunPtrUse(OpReg, SignatureToGReg, GlobalToGReg, MF, MI);
333       continue;
334     }
335     // Skip already processed instructions
336     if (MAI.hasRegisterAlias(MF, MO.getReg()))
337       continue;
338     // Recursively visit dependencies
339     if (const MachineInstr *OpDefMI = MRI.getUniqueVRegDef(OpReg)) {
340       if (isDeclSection(MRI, *OpDefMI))
341         visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
342       continue;
343     }
344     // Handle the unexpected case of no unique definition for the SPIR-V
345     // instruction
346     LLVM_DEBUG({
347       dbgs() << "Unexpectedly, no unique definition for the operand ";
348       MO.print(dbgs());
349       dbgs() << "\nInstruction: ";
350       MI.print(dbgs());
351       dbgs() << "\n";
352     });
353     report_fatal_error(
354         "No unique definition is found for the virtual register");
355   }
356 
357   Register GReg;
358   bool IsFunDef = false;
359   if (TII->isSpecConstantInstr(MI)) {
360     GReg = Register::index2VirtReg(MAI.getNextID());
361     MAI.MS[SPIRV::MB_TypeConstVars].push_back(&MI);
362   } else if (Opcode == SPIRV::OpFunction ||
363              Opcode == SPIRV::OpFunctionParameter) {
364     GReg = handleFunctionOrParameter(MF, MI, GlobalToGReg, IsFunDef);
365   } else if (TII->isTypeDeclInstr(MI) || TII->isConstantInstr(MI) ||
366              TII->isInlineAsmDefInstr(MI)) {
367     GReg = handleTypeDeclOrConstant(MI, SignatureToGReg);
368   } else if (Opcode == SPIRV::OpVariable) {
369     GReg = handleVariable(MF, MI, GlobalToGReg);
370   } else {
371     LLVM_DEBUG({
372       dbgs() << "\nInstruction: ";
373       MI.print(dbgs());
374       dbgs() << "\n";
375     });
376     llvm_unreachable("Unexpected instruction is visited");
377   }
378   MAI.setRegisterAlias(MF, MI.getOperand(0).getReg(), GReg);
379   if (!IsFunDef)
380     MAI.setSkipEmission(&MI);
381 }
382 
383 Register SPIRVModuleAnalysis::handleFunctionOrParameter(
384     const MachineFunction *MF, const MachineInstr &MI,
385     std::map<const Value *, unsigned> &GlobalToGReg, bool &IsFunDef) {
386   const Value *GObj = GR->getGlobalObject(MF, MI.getOperand(0).getReg());
387   assert(GObj && "Unregistered global definition");
388   const Function *F = dyn_cast<Function>(GObj);
389   if (!F)
390     F = dyn_cast<Argument>(GObj)->getParent();
391   assert(F && "Expected a reference to a function or an argument");
392   IsFunDef = !F->isDeclaration();
393   auto It = GlobalToGReg.find(GObj);
394   if (It != GlobalToGReg.end())
395     return It->second;
396   Register GReg = Register::index2VirtReg(MAI.getNextID());
397   GlobalToGReg[GObj] = GReg;
398   if (!IsFunDef)
399     MAI.MS[SPIRV::MB_ExtFuncDecls].push_back(&MI);
400   return GReg;
401 }
402 
403 Register
404 SPIRVModuleAnalysis::handleTypeDeclOrConstant(const MachineInstr &MI,
405                                               InstrGRegsMap &SignatureToGReg) {
406   InstrSignature MISign = instrToSignature(MI, MAI, false);
407   auto It = SignatureToGReg.find(MISign);
408   if (It != SignatureToGReg.end())
409     return It->second;
410   Register GReg = Register::index2VirtReg(MAI.getNextID());
411   SignatureToGReg[MISign] = GReg;
412   MAI.MS[SPIRV::MB_TypeConstVars].push_back(&MI);
413   return GReg;
414 }
415 
416 Register SPIRVModuleAnalysis::handleVariable(
417     const MachineFunction *MF, const MachineInstr &MI,
418     std::map<const Value *, unsigned> &GlobalToGReg) {
419   MAI.GlobalVarList.push_back(&MI);
420   const Value *GObj = GR->getGlobalObject(MF, MI.getOperand(0).getReg());
421   assert(GObj && "Unregistered global definition");
422   auto It = GlobalToGReg.find(GObj);
423   if (It != GlobalToGReg.end())
424     return It->second;
425   Register GReg = Register::index2VirtReg(MAI.getNextID());
426   GlobalToGReg[GObj] = GReg;
427   MAI.MS[SPIRV::MB_TypeConstVars].push_back(&MI);
428   return GReg;
429 }
430 
431 void SPIRVModuleAnalysis::collectDeclarations(const Module &M) {
432   InstrGRegsMap SignatureToGReg;
433   std::map<const Value *, unsigned> GlobalToGReg;
434   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
435     MachineFunction *MF = MMI->getMachineFunction(*F);
436     if (!MF)
437       continue;
438     const MachineRegisterInfo &MRI = MF->getRegInfo();
439     unsigned PastHeader = 0;
440     for (MachineBasicBlock &MBB : *MF) {
441       for (MachineInstr &MI : MBB) {
442         if (MI.getNumOperands() == 0)
443           continue;
444         unsigned Opcode = MI.getOpcode();
445         if (Opcode == SPIRV::OpFunction) {
446           if (PastHeader == 0) {
447             PastHeader = 1;
448             continue;
449           }
450         } else if (Opcode == SPIRV::OpFunctionParameter) {
451           if (PastHeader < 2)
452             continue;
453         } else if (PastHeader > 0) {
454           PastHeader = 2;
455         }
456 
457         const MachineOperand &DefMO = MI.getOperand(0);
458         switch (Opcode) {
459         case SPIRV::OpExtension:
460           MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.getImm()));
461           MAI.setSkipEmission(&MI);
462           break;
463         case SPIRV::OpCapability:
464           MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.getImm()));
465           MAI.setSkipEmission(&MI);
466           if (PastHeader > 0)
467             PastHeader = 2;
468           break;
469         default:
470           if (DefMO.isReg() && isDeclSection(MRI, MI) &&
471               !MAI.hasRegisterAlias(MF, DefMO.getReg()))
472             visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, MI);
473         }
474       }
475     }
476   }
477 }
478 
479 // Look for IDs declared with Import linkage, and map the corresponding function
480 // to the register defining that variable (which will usually be the result of
481 // an OpFunction). This lets us call externally imported functions using
482 // the correct ID registers.
483 void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI,
484                                            const Function *F) {
485   if (MI.getOpcode() == SPIRV::OpDecorate) {
486     // If it's got Import linkage.
487     auto Dec = MI.getOperand(1).getImm();
488     if (Dec == static_cast<unsigned>(SPIRV::Decoration::LinkageAttributes)) {
489       auto Lnk = MI.getOperand(MI.getNumOperands() - 1).getImm();
490       if (Lnk == static_cast<unsigned>(SPIRV::LinkageType::Import)) {
491         // Map imported function name to function ID register.
492         const Function *ImportedFunc =
493             F->getParent()->getFunction(getStringImm(MI, 2));
494         Register Target = MI.getOperand(0).getReg();
495         MAI.FuncMap[ImportedFunc] = MAI.getRegisterAlias(MI.getMF(), Target);
496       }
497     }
498   } else if (MI.getOpcode() == SPIRV::OpFunction) {
499     // Record all internal OpFunction declarations.
500     Register Reg = MI.defs().begin()->getReg();
501     Register GlobalReg = MAI.getRegisterAlias(MI.getMF(), Reg);
502     assert(GlobalReg.isValid());
503     MAI.FuncMap[F] = GlobalReg;
504   }
505 }
506 
507 // Collect the given instruction in the specified MS. We assume global register
508 // numbering has already occurred by this point. We can directly compare reg
509 // arguments when detecting duplicates.
510 static void collectOtherInstr(MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI,
511                               SPIRV::ModuleSectionType MSType, InstrTraces &IS,
512                               bool Append = true) {
513   MAI.setSkipEmission(&MI);
514   InstrSignature MISign = instrToSignature(MI, MAI, true);
515   auto FoundMI = IS.insert(MISign);
516   if (!FoundMI.second)
517     return; // insert failed, so we found a duplicate; don't add it to MAI.MS
518   // No duplicates, so add it.
519   if (Append)
520     MAI.MS[MSType].push_back(&MI);
521   else
522     MAI.MS[MSType].insert(MAI.MS[MSType].begin(), &MI);
523 }
524 
525 // Some global instructions make reference to function-local ID regs, so cannot
526 // be correctly collected until these registers are globally numbered.
527 void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
528   InstrTraces IS;
529   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
530     if ((*F).isDeclaration())
531       continue;
532     MachineFunction *MF = MMI->getMachineFunction(*F);
533     assert(MF);
534 
535     for (MachineBasicBlock &MBB : *MF)
536       for (MachineInstr &MI : MBB) {
537         if (MAI.getSkipEmission(&MI))
538           continue;
539         const unsigned OpCode = MI.getOpcode();
540         if (OpCode == SPIRV::OpString) {
541           collectOtherInstr(MI, MAI, SPIRV::MB_DebugStrings, IS);
542         } else if (OpCode == SPIRV::OpExtInst && MI.getOperand(2).isImm() &&
543                    MI.getOperand(2).getImm() ==
544                        SPIRV::InstructionSet::
545                            NonSemantic_Shader_DebugInfo_100) {
546           MachineOperand Ins = MI.getOperand(3);
547           namespace NS = SPIRV::NonSemanticExtInst;
548           static constexpr int64_t GlobalNonSemanticDITy[] = {
549               NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
550               NS::DebugTypeBasic, NS::DebugTypePointer};
551           bool IsGlobalDI = false;
552           for (unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
553             IsGlobalDI |= Ins.getImm() == GlobalNonSemanticDITy[Idx];
554           if (IsGlobalDI)
555             collectOtherInstr(MI, MAI, SPIRV::MB_NonSemanticGlobalDI, IS);
556         } else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
557           collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames, IS);
558         } else if (OpCode == SPIRV::OpEntryPoint) {
559           collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints, IS);
560         } else if (TII->isDecorationInstr(MI)) {
561           collectOtherInstr(MI, MAI, SPIRV::MB_Annotations, IS);
562           collectFuncNames(MI, &*F);
563         } else if (TII->isConstantInstr(MI)) {
564           // Now OpSpecConstant*s are not in DT,
565           // but they need to be collected anyway.
566           collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, IS);
567         } else if (OpCode == SPIRV::OpFunction) {
568           collectFuncNames(MI, &*F);
569         } else if (OpCode == SPIRV::OpTypeForwardPointer) {
570           collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, IS, false);
571         }
572       }
573   }
574 }
575 
576 // Number registers in all functions globally from 0 onwards and store
577 // the result in global register alias table. Some registers are already
578 // numbered.
579 void SPIRVModuleAnalysis::numberRegistersGlobally(const Module &M) {
580   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
581     if ((*F).isDeclaration())
582       continue;
583     MachineFunction *MF = MMI->getMachineFunction(*F);
584     assert(MF);
585     for (MachineBasicBlock &MBB : *MF) {
586       for (MachineInstr &MI : MBB) {
587         for (MachineOperand &Op : MI.operands()) {
588           if (!Op.isReg())
589             continue;
590           Register Reg = Op.getReg();
591           if (MAI.hasRegisterAlias(MF, Reg))
592             continue;
593           Register NewReg = Register::index2VirtReg(MAI.getNextID());
594           MAI.setRegisterAlias(MF, Reg, NewReg);
595         }
596         if (MI.getOpcode() != SPIRV::OpExtInst)
597           continue;
598         auto Set = MI.getOperand(2).getImm();
599         if (!MAI.ExtInstSetMap.contains(Set))
600           MAI.ExtInstSetMap[Set] = Register::index2VirtReg(MAI.getNextID());
601       }
602     }
603   }
604 }
605 
606 // RequirementHandler implementations.
607 void SPIRV::RequirementHandler::getAndAddRequirements(
608     SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
609     const SPIRVSubtarget &ST) {
610   addRequirements(getSymbolicOperandRequirements(Category, i, ST, *this));
611 }
612 
613 void SPIRV::RequirementHandler::recursiveAddCapabilities(
614     const CapabilityList &ToPrune) {
615   for (const auto &Cap : ToPrune) {
616     AllCaps.insert(Cap);
617     CapabilityList ImplicitDecls =
618         getSymbolicOperandCapabilities(OperandCategory::CapabilityOperand, Cap);
619     recursiveAddCapabilities(ImplicitDecls);
620   }
621 }
622 
623 void SPIRV::RequirementHandler::addCapabilities(const CapabilityList &ToAdd) {
624   for (const auto &Cap : ToAdd) {
625     bool IsNewlyInserted = AllCaps.insert(Cap).second;
626     if (!IsNewlyInserted) // Don't re-add if it's already been declared.
627       continue;
628     CapabilityList ImplicitDecls =
629         getSymbolicOperandCapabilities(OperandCategory::CapabilityOperand, Cap);
630     recursiveAddCapabilities(ImplicitDecls);
631     MinimalCaps.push_back(Cap);
632   }
633 }
634 
635 void SPIRV::RequirementHandler::addRequirements(
636     const SPIRV::Requirements &Req) {
637   if (!Req.IsSatisfiable)
638     report_fatal_error("Adding SPIR-V requirements this target can't satisfy.");
639 
640   if (Req.Cap.has_value())
641     addCapabilities({Req.Cap.value()});
642 
643   addExtensions(Req.Exts);
644 
645   if (!Req.MinVer.empty()) {
646     if (!MaxVersion.empty() && Req.MinVer > MaxVersion) {
647       LLVM_DEBUG(dbgs() << "Conflicting version requirements: >= " << Req.MinVer
648                         << " and <= " << MaxVersion << "\n");
649       report_fatal_error("Adding SPIR-V requirements that can't be satisfied.");
650     }
651 
652     if (MinVersion.empty() || Req.MinVer > MinVersion)
653       MinVersion = Req.MinVer;
654   }
655 
656   if (!Req.MaxVer.empty()) {
657     if (!MinVersion.empty() && Req.MaxVer < MinVersion) {
658       LLVM_DEBUG(dbgs() << "Conflicting version requirements: <= " << Req.MaxVer
659                         << " and >= " << MinVersion << "\n");
660       report_fatal_error("Adding SPIR-V requirements that can't be satisfied.");
661     }
662 
663     if (MaxVersion.empty() || Req.MaxVer < MaxVersion)
664       MaxVersion = Req.MaxVer;
665   }
666 }
667 
668 void SPIRV::RequirementHandler::checkSatisfiable(
669     const SPIRVSubtarget &ST) const {
670   // Report as many errors as possible before aborting the compilation.
671   bool IsSatisfiable = true;
672   auto TargetVer = ST.getSPIRVVersion();
673 
674   if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
675     LLVM_DEBUG(
676         dbgs() << "Target SPIR-V version too high for required features\n"
677                << "Required max version: " << MaxVersion << " target version "
678                << TargetVer << "\n");
679     IsSatisfiable = false;
680   }
681 
682   if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
683     LLVM_DEBUG(dbgs() << "Target SPIR-V version too low for required features\n"
684                       << "Required min version: " << MinVersion
685                       << " target version " << TargetVer << "\n");
686     IsSatisfiable = false;
687   }
688 
689   if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
690     LLVM_DEBUG(
691         dbgs()
692         << "Version is too low for some features and too high for others.\n"
693         << "Required SPIR-V min version: " << MinVersion
694         << " required SPIR-V max version " << MaxVersion << "\n");
695     IsSatisfiable = false;
696   }
697 
698   for (auto Cap : MinimalCaps) {
699     if (AvailableCaps.contains(Cap))
700       continue;
701     LLVM_DEBUG(dbgs() << "Capability not supported: "
702                       << getSymbolicOperandMnemonic(
703                              OperandCategory::CapabilityOperand, Cap)
704                       << "\n");
705     IsSatisfiable = false;
706   }
707 
708   for (auto Ext : AllExtensions) {
709     if (ST.canUseExtension(Ext))
710       continue;
711     LLVM_DEBUG(dbgs() << "Extension not supported: "
712                       << getSymbolicOperandMnemonic(
713                              OperandCategory::ExtensionOperand, Ext)
714                       << "\n");
715     IsSatisfiable = false;
716   }
717 
718   if (!IsSatisfiable)
719     report_fatal_error("Unable to meet SPIR-V requirements for this target.");
720 }
721 
722 // Add the given capabilities and all their implicitly defined capabilities too.
723 void SPIRV::RequirementHandler::addAvailableCaps(const CapabilityList &ToAdd) {
724   for (const auto Cap : ToAdd)
725     if (AvailableCaps.insert(Cap).second)
726       addAvailableCaps(getSymbolicOperandCapabilities(
727           SPIRV::OperandCategory::CapabilityOperand, Cap));
728 }
729 
730 void SPIRV::RequirementHandler::removeCapabilityIf(
731     const Capability::Capability ToRemove,
732     const Capability::Capability IfPresent) {
733   if (AllCaps.contains(IfPresent))
734     AllCaps.erase(ToRemove);
735 }
736 
737 namespace llvm {
738 namespace SPIRV {
739 void RequirementHandler::initAvailableCapabilities(const SPIRVSubtarget &ST) {
740   // Provided by both all supported Vulkan versions and OpenCl.
741   addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
742                     Capability::Int16});
743 
744   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
745     addAvailableCaps({Capability::GroupNonUniform,
746                       Capability::GroupNonUniformVote,
747                       Capability::GroupNonUniformArithmetic,
748                       Capability::GroupNonUniformBallot,
749                       Capability::GroupNonUniformClustered,
750                       Capability::GroupNonUniformShuffle,
751                       Capability::GroupNonUniformShuffleRelative});
752 
753   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
754     addAvailableCaps({Capability::DotProduct, Capability::DotProductInputAll,
755                       Capability::DotProductInput4x8Bit,
756                       Capability::DotProductInput4x8BitPacked,
757                       Capability::DemoteToHelperInvocation});
758 
759   // Add capabilities enabled by extensions.
760   for (auto Extension : ST.getAllAvailableExtensions()) {
761     CapabilityList EnabledCapabilities =
762         getCapabilitiesEnabledByExtension(Extension);
763     addAvailableCaps(EnabledCapabilities);
764   }
765 
766   if (ST.isOpenCLEnv()) {
767     initAvailableCapabilitiesForOpenCL(ST);
768     return;
769   }
770 
771   if (ST.isVulkanEnv()) {
772     initAvailableCapabilitiesForVulkan(ST);
773     return;
774   }
775 
776   report_fatal_error("Unimplemented environment for SPIR-V generation.");
777 }
778 
779 void RequirementHandler::initAvailableCapabilitiesForOpenCL(
780     const SPIRVSubtarget &ST) {
781   // Add the min requirements for different OpenCL and SPIR-V versions.
782   addAvailableCaps({Capability::Addresses, Capability::Float16Buffer,
783                     Capability::Kernel, Capability::Vector16,
784                     Capability::Groups, Capability::GenericPointer,
785                     Capability::StorageImageWriteWithoutFormat,
786                     Capability::StorageImageReadWithoutFormat});
787   if (ST.hasOpenCLFullProfile())
788     addAvailableCaps({Capability::Int64, Capability::Int64Atomics});
789   if (ST.hasOpenCLImageSupport()) {
790     addAvailableCaps({Capability::ImageBasic, Capability::LiteralSampler,
791                       Capability::Image1D, Capability::SampledBuffer,
792                       Capability::ImageBuffer});
793     if (ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
794       addAvailableCaps({Capability::ImageReadWrite});
795   }
796   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
797       ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
798     addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage});
799   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
800     addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
801                       Capability::SignedZeroInfNanPreserve,
802                       Capability::RoundingModeRTE,
803                       Capability::RoundingModeRTZ});
804   // TODO: verify if this needs some checks.
805   addAvailableCaps({Capability::Float16, Capability::Float64});
806 
807   // TODO: add OpenCL extensions.
808 }
809 
810 void RequirementHandler::initAvailableCapabilitiesForVulkan(
811     const SPIRVSubtarget &ST) {
812 
813   // Core in Vulkan 1.1 and earlier.
814   addAvailableCaps({Capability::Int64, Capability::Float16, Capability::Float64,
815                     Capability::GroupNonUniform, Capability::Image1D,
816                     Capability::SampledBuffer, Capability::ImageBuffer,
817                     Capability::UniformBufferArrayDynamicIndexing,
818                     Capability::SampledImageArrayDynamicIndexing,
819                     Capability::StorageBufferArrayDynamicIndexing,
820                     Capability::StorageImageArrayDynamicIndexing});
821 
822   // Became core in Vulkan 1.2
823   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
824     addAvailableCaps(
825         {Capability::ShaderNonUniformEXT, Capability::RuntimeDescriptorArrayEXT,
826          Capability::InputAttachmentArrayDynamicIndexingEXT,
827          Capability::UniformTexelBufferArrayDynamicIndexingEXT,
828          Capability::StorageTexelBufferArrayDynamicIndexingEXT,
829          Capability::UniformBufferArrayNonUniformIndexingEXT,
830          Capability::SampledImageArrayNonUniformIndexingEXT,
831          Capability::StorageBufferArrayNonUniformIndexingEXT,
832          Capability::StorageImageArrayNonUniformIndexingEXT,
833          Capability::InputAttachmentArrayNonUniformIndexingEXT,
834          Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
835          Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
836   }
837 
838   // Became core in Vulkan 1.3
839   if (ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
840     addAvailableCaps({Capability::StorageImageWriteWithoutFormat,
841                       Capability::StorageImageReadWithoutFormat});
842 }
843 
844 } // namespace SPIRV
845 } // namespace llvm
846 
847 // Add the required capabilities from a decoration instruction (including
848 // BuiltIns).
849 static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
850                               SPIRV::RequirementHandler &Reqs,
851                               const SPIRVSubtarget &ST) {
852   int64_t DecOp = MI.getOperand(DecIndex).getImm();
853   auto Dec = static_cast<SPIRV::Decoration::Decoration>(DecOp);
854   Reqs.addRequirements(getSymbolicOperandRequirements(
855       SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
856 
857   if (Dec == SPIRV::Decoration::BuiltIn) {
858     int64_t BuiltInOp = MI.getOperand(DecIndex + 1).getImm();
859     auto BuiltIn = static_cast<SPIRV::BuiltIn::BuiltIn>(BuiltInOp);
860     Reqs.addRequirements(getSymbolicOperandRequirements(
861         SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
862   } else if (Dec == SPIRV::Decoration::LinkageAttributes) {
863     int64_t LinkageOp = MI.getOperand(MI.getNumOperands() - 1).getImm();
864     SPIRV::LinkageType::LinkageType LnkType =
865         static_cast<SPIRV::LinkageType::LinkageType>(LinkageOp);
866     if (LnkType == SPIRV::LinkageType::LinkOnceODR)
867       Reqs.addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
868   } else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
869              Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
870     Reqs.addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
871   } else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
872     Reqs.addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
873   } else if (Dec == SPIRV::Decoration::InitModeINTEL ||
874              Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
875     Reqs.addExtension(
876         SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
877   } else if (Dec == SPIRV::Decoration::NonUniformEXT) {
878     Reqs.addRequirements(SPIRV::Capability::ShaderNonUniformEXT);
879   }
880 }
881 
882 // Add requirements for image handling.
883 static void addOpTypeImageReqs(const MachineInstr &MI,
884                                SPIRV::RequirementHandler &Reqs,
885                                const SPIRVSubtarget &ST) {
886   assert(MI.getNumOperands() >= 8 && "Insufficient operands for OpTypeImage");
887   // The operand indices used here are based on the OpTypeImage layout, which
888   // the MachineInstr follows as well.
889   int64_t ImgFormatOp = MI.getOperand(7).getImm();
890   auto ImgFormat = static_cast<SPIRV::ImageFormat::ImageFormat>(ImgFormatOp);
891   Reqs.getAndAddRequirements(SPIRV::OperandCategory::ImageFormatOperand,
892                              ImgFormat, ST);
893 
894   bool IsArrayed = MI.getOperand(4).getImm() == 1;
895   bool IsMultisampled = MI.getOperand(5).getImm() == 1;
896   bool NoSampler = MI.getOperand(6).getImm() == 2;
897   // Add dimension requirements.
898   assert(MI.getOperand(2).isImm());
899   switch (MI.getOperand(2).getImm()) {
900   case SPIRV::Dim::DIM_1D:
901     Reqs.addRequirements(NoSampler ? SPIRV::Capability::Image1D
902                                    : SPIRV::Capability::Sampled1D);
903     break;
904   case SPIRV::Dim::DIM_2D:
905     if (IsMultisampled && NoSampler)
906       Reqs.addRequirements(SPIRV::Capability::ImageMSArray);
907     break;
908   case SPIRV::Dim::DIM_Cube:
909     Reqs.addRequirements(SPIRV::Capability::Shader);
910     if (IsArrayed)
911       Reqs.addRequirements(NoSampler ? SPIRV::Capability::ImageCubeArray
912                                      : SPIRV::Capability::SampledCubeArray);
913     break;
914   case SPIRV::Dim::DIM_Rect:
915     Reqs.addRequirements(NoSampler ? SPIRV::Capability::ImageRect
916                                    : SPIRV::Capability::SampledRect);
917     break;
918   case SPIRV::Dim::DIM_Buffer:
919     Reqs.addRequirements(NoSampler ? SPIRV::Capability::ImageBuffer
920                                    : SPIRV::Capability::SampledBuffer);
921     break;
922   case SPIRV::Dim::DIM_SubpassData:
923     Reqs.addRequirements(SPIRV::Capability::InputAttachment);
924     break;
925   }
926 
927   // Has optional access qualifier.
928   if (ST.isOpenCLEnv()) {
929     if (MI.getNumOperands() > 8 &&
930         MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
931       Reqs.addRequirements(SPIRV::Capability::ImageReadWrite);
932     else
933       Reqs.addRequirements(SPIRV::Capability::ImageBasic);
934   }
935 }
936 
937 // Add requirements for handling atomic float instructions
938 #define ATOM_FLT_REQ_EXT_MSG(ExtName)                                          \
939   "The atomic float instruction requires the following SPIR-V "                \
940   "extension: SPV_EXT_shader_atomic_float" ExtName
941 static void AddAtomicFloatRequirements(const MachineInstr &MI,
942                                        SPIRV::RequirementHandler &Reqs,
943                                        const SPIRVSubtarget &ST) {
944   assert(MI.getOperand(1).isReg() &&
945          "Expect register operand in atomic float instruction");
946   Register TypeReg = MI.getOperand(1).getReg();
947   SPIRVType *TypeDef = MI.getMF()->getRegInfo().getVRegDef(TypeReg);
948   if (TypeDef->getOpcode() != SPIRV::OpTypeFloat)
949     report_fatal_error("Result type of an atomic float instruction must be a "
950                        "floating-point type scalar");
951 
952   unsigned BitWidth = TypeDef->getOperand(1).getImm();
953   unsigned Op = MI.getOpcode();
954   if (Op == SPIRV::OpAtomicFAddEXT) {
955     if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
956       report_fatal_error(ATOM_FLT_REQ_EXT_MSG("_add"), false);
957     Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
958     switch (BitWidth) {
959     case 16:
960       if (!ST.canUseExtension(
961               SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
962         report_fatal_error(ATOM_FLT_REQ_EXT_MSG("16_add"), false);
963       Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
964       Reqs.addCapability(SPIRV::Capability::AtomicFloat16AddEXT);
965       break;
966     case 32:
967       Reqs.addCapability(SPIRV::Capability::AtomicFloat32AddEXT);
968       break;
969     case 64:
970       Reqs.addCapability(SPIRV::Capability::AtomicFloat64AddEXT);
971       break;
972     default:
973       report_fatal_error(
974           "Unexpected floating-point type width in atomic float instruction");
975     }
976   } else {
977     if (!ST.canUseExtension(
978             SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
979       report_fatal_error(ATOM_FLT_REQ_EXT_MSG("_min_max"), false);
980     Reqs.addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
981     switch (BitWidth) {
982     case 16:
983       Reqs.addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
984       break;
985     case 32:
986       Reqs.addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
987       break;
988     case 64:
989       Reqs.addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
990       break;
991     default:
992       report_fatal_error(
993           "Unexpected floating-point type width in atomic float instruction");
994     }
995   }
996 }
997 
998 bool isUniformTexelBuffer(MachineInstr *ImageInst) {
999   if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
1000     return false;
1001   uint32_t Dim = ImageInst->getOperand(2).getImm();
1002   uint32_t Sampled = ImageInst->getOperand(6).getImm();
1003   return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1004 }
1005 
1006 bool isStorageTexelBuffer(MachineInstr *ImageInst) {
1007   if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
1008     return false;
1009   uint32_t Dim = ImageInst->getOperand(2).getImm();
1010   uint32_t Sampled = ImageInst->getOperand(6).getImm();
1011   return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1012 }
1013 
1014 bool isSampledImage(MachineInstr *ImageInst) {
1015   if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
1016     return false;
1017   uint32_t Dim = ImageInst->getOperand(2).getImm();
1018   uint32_t Sampled = ImageInst->getOperand(6).getImm();
1019   return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1020 }
1021 
1022 bool isInputAttachment(MachineInstr *ImageInst) {
1023   if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
1024     return false;
1025   uint32_t Dim = ImageInst->getOperand(2).getImm();
1026   uint32_t Sampled = ImageInst->getOperand(6).getImm();
1027   return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1028 }
1029 
1030 bool isStorageImage(MachineInstr *ImageInst) {
1031   if (ImageInst->getOpcode() != SPIRV::OpTypeImage)
1032     return false;
1033   uint32_t Dim = ImageInst->getOperand(2).getImm();
1034   uint32_t Sampled = ImageInst->getOperand(6).getImm();
1035   return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1036 }
1037 
1038 bool isCombinedImageSampler(MachineInstr *SampledImageInst) {
1039   if (SampledImageInst->getOpcode() != SPIRV::OpTypeSampledImage)
1040     return false;
1041 
1042   const MachineRegisterInfo &MRI = SampledImageInst->getMF()->getRegInfo();
1043   Register ImageReg = SampledImageInst->getOperand(1).getReg();
1044   auto *ImageInst = MRI.getUniqueVRegDef(ImageReg);
1045   return isSampledImage(ImageInst);
1046 }
1047 
1048 bool hasNonUniformDecoration(Register Reg, const MachineRegisterInfo &MRI) {
1049   for (const auto &MI : MRI.reg_instructions(Reg)) {
1050     if (MI.getOpcode() != SPIRV::OpDecorate)
1051       continue;
1052 
1053     uint32_t Dec = MI.getOperand(1).getImm();
1054     if (Dec == SPIRV::Decoration::NonUniformEXT)
1055       return true;
1056   }
1057   return false;
1058 }
1059 
1060 void addOpAccessChainReqs(const MachineInstr &Instr,
1061                           SPIRV::RequirementHandler &Handler,
1062                           const SPIRVSubtarget &Subtarget) {
1063   const MachineRegisterInfo &MRI = Instr.getMF()->getRegInfo();
1064   // Get the result type. If it is an image type, then the shader uses
1065   // descriptor indexing. The appropriate capabilities will be added based
1066   // on the specifics of the image.
1067   Register ResTypeReg = Instr.getOperand(1).getReg();
1068   MachineInstr *ResTypeInst = MRI.getUniqueVRegDef(ResTypeReg);
1069 
1070   assert(ResTypeInst->getOpcode() == SPIRV::OpTypePointer);
1071   uint32_t StorageClass = ResTypeInst->getOperand(1).getImm();
1072   if (StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1073       StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1074       StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1075     return;
1076   }
1077 
1078   Register PointeeTypeReg = ResTypeInst->getOperand(2).getReg();
1079   MachineInstr *PointeeType = MRI.getUniqueVRegDef(PointeeTypeReg);
1080   if (PointeeType->getOpcode() != SPIRV::OpTypeImage &&
1081       PointeeType->getOpcode() != SPIRV::OpTypeSampledImage &&
1082       PointeeType->getOpcode() != SPIRV::OpTypeSampler) {
1083     return;
1084   }
1085 
1086   bool IsNonUniform =
1087       hasNonUniformDecoration(Instr.getOperand(0).getReg(), MRI);
1088   if (isUniformTexelBuffer(PointeeType)) {
1089     if (IsNonUniform)
1090       Handler.addRequirements(
1091           SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1092     else
1093       Handler.addRequirements(
1094           SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1095   } else if (isInputAttachment(PointeeType)) {
1096     if (IsNonUniform)
1097       Handler.addRequirements(
1098           SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1099     else
1100       Handler.addRequirements(
1101           SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1102   } else if (isStorageTexelBuffer(PointeeType)) {
1103     if (IsNonUniform)
1104       Handler.addRequirements(
1105           SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1106     else
1107       Handler.addRequirements(
1108           SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1109   } else if (isSampledImage(PointeeType) ||
1110              isCombinedImageSampler(PointeeType) ||
1111              PointeeType->getOpcode() == SPIRV::OpTypeSampler) {
1112     if (IsNonUniform)
1113       Handler.addRequirements(
1114           SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1115     else
1116       Handler.addRequirements(
1117           SPIRV::Capability::SampledImageArrayDynamicIndexing);
1118   } else if (isStorageImage(PointeeType)) {
1119     if (IsNonUniform)
1120       Handler.addRequirements(
1121           SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1122     else
1123       Handler.addRequirements(
1124           SPIRV::Capability::StorageImageArrayDynamicIndexing);
1125   }
1126 }
1127 
1128 static bool isImageTypeWithUnknownFormat(SPIRVType *TypeInst) {
1129   if (TypeInst->getOpcode() != SPIRV::OpTypeImage)
1130     return false;
1131   assert(TypeInst->getOperand(7).isImm() && "The image format must be an imm.");
1132   return TypeInst->getOperand(7).getImm() == 0;
1133 }
1134 
1135 static void AddDotProductRequirements(const MachineInstr &MI,
1136                                       SPIRV::RequirementHandler &Reqs,
1137                                       const SPIRVSubtarget &ST) {
1138   if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1139     Reqs.addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1140   Reqs.addCapability(SPIRV::Capability::DotProduct);
1141 
1142   const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
1143   assert(MI.getOperand(2).isReg() && "Unexpected operand in dot");
1144   // We do not consider what the previous instruction is. This is just used
1145   // to get the input register and to check the type.
1146   const MachineInstr *Input = MRI.getVRegDef(MI.getOperand(2).getReg());
1147   assert(Input->getOperand(1).isReg() && "Unexpected operand in dot input");
1148   Register InputReg = Input->getOperand(1).getReg();
1149 
1150   SPIRVType *TypeDef = MRI.getVRegDef(InputReg);
1151   if (TypeDef->getOpcode() == SPIRV::OpTypeInt) {
1152     assert(TypeDef->getOperand(1).getImm() == 32);
1153     Reqs.addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1154   } else if (TypeDef->getOpcode() == SPIRV::OpTypeVector) {
1155     SPIRVType *ScalarTypeDef = MRI.getVRegDef(TypeDef->getOperand(1).getReg());
1156     assert(ScalarTypeDef->getOpcode() == SPIRV::OpTypeInt);
1157     if (ScalarTypeDef->getOperand(1).getImm() == 8) {
1158       assert(TypeDef->getOperand(2).getImm() == 4 &&
1159              "Dot operand of 8-bit integer type requires 4 components");
1160       Reqs.addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1161     } else {
1162       Reqs.addCapability(SPIRV::Capability::DotProductInputAll);
1163     }
1164   }
1165 }
1166 
1167 void addInstrRequirements(const MachineInstr &MI,
1168                           SPIRV::RequirementHandler &Reqs,
1169                           const SPIRVSubtarget &ST) {
1170   switch (MI.getOpcode()) {
1171   case SPIRV::OpMemoryModel: {
1172     int64_t Addr = MI.getOperand(0).getImm();
1173     Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
1174                                Addr, ST);
1175     int64_t Mem = MI.getOperand(1).getImm();
1176     Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand, Mem,
1177                                ST);
1178     break;
1179   }
1180   case SPIRV::OpEntryPoint: {
1181     int64_t Exe = MI.getOperand(0).getImm();
1182     Reqs.getAndAddRequirements(SPIRV::OperandCategory::ExecutionModelOperand,
1183                                Exe, ST);
1184     break;
1185   }
1186   case SPIRV::OpExecutionMode:
1187   case SPIRV::OpExecutionModeId: {
1188     int64_t Exe = MI.getOperand(1).getImm();
1189     Reqs.getAndAddRequirements(SPIRV::OperandCategory::ExecutionModeOperand,
1190                                Exe, ST);
1191     break;
1192   }
1193   case SPIRV::OpTypeMatrix:
1194     Reqs.addCapability(SPIRV::Capability::Matrix);
1195     break;
1196   case SPIRV::OpTypeInt: {
1197     unsigned BitWidth = MI.getOperand(1).getImm();
1198     if (BitWidth == 64)
1199       Reqs.addCapability(SPIRV::Capability::Int64);
1200     else if (BitWidth == 16)
1201       Reqs.addCapability(SPIRV::Capability::Int16);
1202     else if (BitWidth == 8)
1203       Reqs.addCapability(SPIRV::Capability::Int8);
1204     break;
1205   }
1206   case SPIRV::OpTypeFloat: {
1207     unsigned BitWidth = MI.getOperand(1).getImm();
1208     if (BitWidth == 64)
1209       Reqs.addCapability(SPIRV::Capability::Float64);
1210     else if (BitWidth == 16)
1211       Reqs.addCapability(SPIRV::Capability::Float16);
1212     break;
1213   }
1214   case SPIRV::OpTypeVector: {
1215     unsigned NumComponents = MI.getOperand(2).getImm();
1216     if (NumComponents == 8 || NumComponents == 16)
1217       Reqs.addCapability(SPIRV::Capability::Vector16);
1218     break;
1219   }
1220   case SPIRV::OpTypePointer: {
1221     auto SC = MI.getOperand(1).getImm();
1222     Reqs.getAndAddRequirements(SPIRV::OperandCategory::StorageClassOperand, SC,
1223                                ST);
1224     // If it's a type of pointer to float16 targeting OpenCL, add Float16Buffer
1225     // capability.
1226     if (!ST.isOpenCLEnv())
1227       break;
1228     assert(MI.getOperand(2).isReg());
1229     const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
1230     SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(2).getReg());
1231     if (TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
1232         TypeDef->getOperand(1).getImm() == 16)
1233       Reqs.addCapability(SPIRV::Capability::Float16Buffer);
1234     break;
1235   }
1236   case SPIRV::OpExtInst: {
1237     if (MI.getOperand(2).getImm() ==
1238         static_cast<int64_t>(
1239             SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1240       Reqs.addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1241     }
1242     break;
1243   }
1244   case SPIRV::OpBitReverse:
1245   case SPIRV::OpBitFieldInsert:
1246   case SPIRV::OpBitFieldSExtract:
1247   case SPIRV::OpBitFieldUExtract:
1248     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1249       Reqs.addCapability(SPIRV::Capability::Shader);
1250       break;
1251     }
1252     Reqs.addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1253     Reqs.addCapability(SPIRV::Capability::BitInstructions);
1254     break;
1255   case SPIRV::OpTypeRuntimeArray:
1256     Reqs.addCapability(SPIRV::Capability::Shader);
1257     break;
1258   case SPIRV::OpTypeOpaque:
1259   case SPIRV::OpTypeEvent:
1260     Reqs.addCapability(SPIRV::Capability::Kernel);
1261     break;
1262   case SPIRV::OpTypePipe:
1263   case SPIRV::OpTypeReserveId:
1264     Reqs.addCapability(SPIRV::Capability::Pipes);
1265     break;
1266   case SPIRV::OpTypeDeviceEvent:
1267   case SPIRV::OpTypeQueue:
1268   case SPIRV::OpBuildNDRange:
1269     Reqs.addCapability(SPIRV::Capability::DeviceEnqueue);
1270     break;
1271   case SPIRV::OpDecorate:
1272   case SPIRV::OpDecorateId:
1273   case SPIRV::OpDecorateString:
1274     addOpDecorateReqs(MI, 1, Reqs, ST);
1275     break;
1276   case SPIRV::OpMemberDecorate:
1277   case SPIRV::OpMemberDecorateString:
1278     addOpDecorateReqs(MI, 2, Reqs, ST);
1279     break;
1280   case SPIRV::OpInBoundsPtrAccessChain:
1281     Reqs.addCapability(SPIRV::Capability::Addresses);
1282     break;
1283   case SPIRV::OpConstantSampler:
1284     Reqs.addCapability(SPIRV::Capability::LiteralSampler);
1285     break;
1286   case SPIRV::OpInBoundsAccessChain:
1287   case SPIRV::OpAccessChain:
1288     addOpAccessChainReqs(MI, Reqs, ST);
1289     break;
1290   case SPIRV::OpTypeImage:
1291     addOpTypeImageReqs(MI, Reqs, ST);
1292     break;
1293   case SPIRV::OpTypeSampler:
1294     if (!ST.isVulkanEnv()) {
1295       Reqs.addCapability(SPIRV::Capability::ImageBasic);
1296     }
1297     break;
1298   case SPIRV::OpTypeForwardPointer:
1299     // TODO: check if it's OpenCL's kernel.
1300     Reqs.addCapability(SPIRV::Capability::Addresses);
1301     break;
1302   case SPIRV::OpAtomicFlagTestAndSet:
1303   case SPIRV::OpAtomicLoad:
1304   case SPIRV::OpAtomicStore:
1305   case SPIRV::OpAtomicExchange:
1306   case SPIRV::OpAtomicCompareExchange:
1307   case SPIRV::OpAtomicIIncrement:
1308   case SPIRV::OpAtomicIDecrement:
1309   case SPIRV::OpAtomicIAdd:
1310   case SPIRV::OpAtomicISub:
1311   case SPIRV::OpAtomicUMin:
1312   case SPIRV::OpAtomicUMax:
1313   case SPIRV::OpAtomicSMin:
1314   case SPIRV::OpAtomicSMax:
1315   case SPIRV::OpAtomicAnd:
1316   case SPIRV::OpAtomicOr:
1317   case SPIRV::OpAtomicXor: {
1318     const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
1319     const MachineInstr *InstrPtr = &MI;
1320     if (MI.getOpcode() == SPIRV::OpAtomicStore) {
1321       assert(MI.getOperand(3).isReg());
1322       InstrPtr = MRI.getVRegDef(MI.getOperand(3).getReg());
1323       assert(InstrPtr && "Unexpected type instruction for OpAtomicStore");
1324     }
1325     assert(InstrPtr->getOperand(1).isReg() && "Unexpected operand in atomic");
1326     Register TypeReg = InstrPtr->getOperand(1).getReg();
1327     SPIRVType *TypeDef = MRI.getVRegDef(TypeReg);
1328     if (TypeDef->getOpcode() == SPIRV::OpTypeInt) {
1329       unsigned BitWidth = TypeDef->getOperand(1).getImm();
1330       if (BitWidth == 64)
1331         Reqs.addCapability(SPIRV::Capability::Int64Atomics);
1332     }
1333     break;
1334   }
1335   case SPIRV::OpGroupNonUniformIAdd:
1336   case SPIRV::OpGroupNonUniformFAdd:
1337   case SPIRV::OpGroupNonUniformIMul:
1338   case SPIRV::OpGroupNonUniformFMul:
1339   case SPIRV::OpGroupNonUniformSMin:
1340   case SPIRV::OpGroupNonUniformUMin:
1341   case SPIRV::OpGroupNonUniformFMin:
1342   case SPIRV::OpGroupNonUniformSMax:
1343   case SPIRV::OpGroupNonUniformUMax:
1344   case SPIRV::OpGroupNonUniformFMax:
1345   case SPIRV::OpGroupNonUniformBitwiseAnd:
1346   case SPIRV::OpGroupNonUniformBitwiseOr:
1347   case SPIRV::OpGroupNonUniformBitwiseXor:
1348   case SPIRV::OpGroupNonUniformLogicalAnd:
1349   case SPIRV::OpGroupNonUniformLogicalOr:
1350   case SPIRV::OpGroupNonUniformLogicalXor: {
1351     assert(MI.getOperand(3).isImm());
1352     int64_t GroupOp = MI.getOperand(3).getImm();
1353     switch (GroupOp) {
1354     case SPIRV::GroupOperation::Reduce:
1355     case SPIRV::GroupOperation::InclusiveScan:
1356     case SPIRV::GroupOperation::ExclusiveScan:
1357       Reqs.addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1358       break;
1359     case SPIRV::GroupOperation::ClusteredReduce:
1360       Reqs.addCapability(SPIRV::Capability::GroupNonUniformClustered);
1361       break;
1362     case SPIRV::GroupOperation::PartitionedReduceNV:
1363     case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1364     case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1365       Reqs.addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1366       break;
1367     }
1368     break;
1369   }
1370   case SPIRV::OpGroupNonUniformShuffle:
1371   case SPIRV::OpGroupNonUniformShuffleXor:
1372     Reqs.addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1373     break;
1374   case SPIRV::OpGroupNonUniformShuffleUp:
1375   case SPIRV::OpGroupNonUniformShuffleDown:
1376     Reqs.addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1377     break;
1378   case SPIRV::OpGroupAll:
1379   case SPIRV::OpGroupAny:
1380   case SPIRV::OpGroupBroadcast:
1381   case SPIRV::OpGroupIAdd:
1382   case SPIRV::OpGroupFAdd:
1383   case SPIRV::OpGroupFMin:
1384   case SPIRV::OpGroupUMin:
1385   case SPIRV::OpGroupSMin:
1386   case SPIRV::OpGroupFMax:
1387   case SPIRV::OpGroupUMax:
1388   case SPIRV::OpGroupSMax:
1389     Reqs.addCapability(SPIRV::Capability::Groups);
1390     break;
1391   case SPIRV::OpGroupNonUniformElect:
1392     Reqs.addCapability(SPIRV::Capability::GroupNonUniform);
1393     break;
1394   case SPIRV::OpGroupNonUniformAll:
1395   case SPIRV::OpGroupNonUniformAny:
1396   case SPIRV::OpGroupNonUniformAllEqual:
1397     Reqs.addCapability(SPIRV::Capability::GroupNonUniformVote);
1398     break;
1399   case SPIRV::OpGroupNonUniformBroadcast:
1400   case SPIRV::OpGroupNonUniformBroadcastFirst:
1401   case SPIRV::OpGroupNonUniformBallot:
1402   case SPIRV::OpGroupNonUniformInverseBallot:
1403   case SPIRV::OpGroupNonUniformBallotBitExtract:
1404   case SPIRV::OpGroupNonUniformBallotBitCount:
1405   case SPIRV::OpGroupNonUniformBallotFindLSB:
1406   case SPIRV::OpGroupNonUniformBallotFindMSB:
1407     Reqs.addCapability(SPIRV::Capability::GroupNonUniformBallot);
1408     break;
1409   case SPIRV::OpSubgroupShuffleINTEL:
1410   case SPIRV::OpSubgroupShuffleDownINTEL:
1411   case SPIRV::OpSubgroupShuffleUpINTEL:
1412   case SPIRV::OpSubgroupShuffleXorINTEL:
1413     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1414       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1415       Reqs.addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1416     }
1417     break;
1418   case SPIRV::OpSubgroupBlockReadINTEL:
1419   case SPIRV::OpSubgroupBlockWriteINTEL:
1420     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1421       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1422       Reqs.addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1423     }
1424     break;
1425   case SPIRV::OpSubgroupImageBlockReadINTEL:
1426   case SPIRV::OpSubgroupImageBlockWriteINTEL:
1427     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1428       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1429       Reqs.addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1430     }
1431     break;
1432   case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1433   case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1434     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1435       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1436       Reqs.addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1437     }
1438     break;
1439   case SPIRV::OpAssumeTrueKHR:
1440   case SPIRV::OpExpectKHR:
1441     if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1442       Reqs.addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1443       Reqs.addCapability(SPIRV::Capability::ExpectAssumeKHR);
1444     }
1445     break;
1446   case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1447   case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1448     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1449       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1450       Reqs.addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1451     }
1452     break;
1453   case SPIRV::OpConstantFunctionPointerINTEL:
1454     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1455       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1456       Reqs.addCapability(SPIRV::Capability::FunctionPointersINTEL);
1457     }
1458     break;
1459   case SPIRV::OpGroupNonUniformRotateKHR:
1460     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1461       report_fatal_error("OpGroupNonUniformRotateKHR instruction requires the "
1462                          "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1463                          false);
1464     Reqs.addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1465     Reqs.addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1466     Reqs.addCapability(SPIRV::Capability::GroupNonUniform);
1467     break;
1468   case SPIRV::OpGroupIMulKHR:
1469   case SPIRV::OpGroupFMulKHR:
1470   case SPIRV::OpGroupBitwiseAndKHR:
1471   case SPIRV::OpGroupBitwiseOrKHR:
1472   case SPIRV::OpGroupBitwiseXorKHR:
1473   case SPIRV::OpGroupLogicalAndKHR:
1474   case SPIRV::OpGroupLogicalOrKHR:
1475   case SPIRV::OpGroupLogicalXorKHR:
1476     if (ST.canUseExtension(
1477             SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1478       Reqs.addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1479       Reqs.addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1480     }
1481     break;
1482   case SPIRV::OpReadClockKHR:
1483     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1484       report_fatal_error("OpReadClockKHR instruction requires the "
1485                          "following SPIR-V extension: SPV_KHR_shader_clock",
1486                          false);
1487     Reqs.addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1488     Reqs.addCapability(SPIRV::Capability::ShaderClockKHR);
1489     break;
1490   case SPIRV::OpFunctionPointerCallINTEL:
1491     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1492       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1493       Reqs.addCapability(SPIRV::Capability::FunctionPointersINTEL);
1494     }
1495     break;
1496   case SPIRV::OpAtomicFAddEXT:
1497   case SPIRV::OpAtomicFMinEXT:
1498   case SPIRV::OpAtomicFMaxEXT:
1499     AddAtomicFloatRequirements(MI, Reqs, ST);
1500     break;
1501   case SPIRV::OpConvertBF16ToFINTEL:
1502   case SPIRV::OpConvertFToBF16INTEL:
1503     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1504       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1505       Reqs.addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1506     }
1507     break;
1508   case SPIRV::OpVariableLengthArrayINTEL:
1509   case SPIRV::OpSaveMemoryINTEL:
1510   case SPIRV::OpRestoreMemoryINTEL:
1511     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
1512       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
1513       Reqs.addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
1514     }
1515     break;
1516   case SPIRV::OpAsmTargetINTEL:
1517   case SPIRV::OpAsmINTEL:
1518   case SPIRV::OpAsmCallINTEL:
1519     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
1520       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
1521       Reqs.addCapability(SPIRV::Capability::AsmINTEL);
1522     }
1523     break;
1524   case SPIRV::OpTypeCooperativeMatrixKHR:
1525     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1526       report_fatal_error(
1527           "OpTypeCooperativeMatrixKHR type requires the "
1528           "following SPIR-V extension: SPV_KHR_cooperative_matrix",
1529           false);
1530     Reqs.addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1531     Reqs.addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1532     break;
1533   case SPIRV::OpArithmeticFenceEXT:
1534     if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
1535       report_fatal_error("OpArithmeticFenceEXT requires the "
1536                          "following SPIR-V extension: SPV_EXT_arithmetic_fence",
1537                          false);
1538     Reqs.addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
1539     Reqs.addCapability(SPIRV::Capability::ArithmeticFenceEXT);
1540     break;
1541   case SPIRV::OpControlBarrierArriveINTEL:
1542   case SPIRV::OpControlBarrierWaitINTEL:
1543     if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
1544       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
1545       Reqs.addCapability(SPIRV::Capability::SplitBarrierINTEL);
1546     }
1547     break;
1548   case SPIRV::OpCooperativeMatrixMulAddKHR: {
1549     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1550       report_fatal_error("Cooperative matrix instructions require the "
1551                          "following SPIR-V extension: "
1552                          "SPV_KHR_cooperative_matrix",
1553                          false);
1554     Reqs.addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1555     Reqs.addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1556     constexpr unsigned MulAddMaxSize = 6;
1557     if (MI.getNumOperands() != MulAddMaxSize)
1558       break;
1559     const int64_t CoopOperands = MI.getOperand(MulAddMaxSize - 1).getImm();
1560     if (CoopOperands &
1561         SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
1562       if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1563         report_fatal_error("MatrixAAndBTF32ComponentsINTEL type interpretation "
1564                            "require the following SPIR-V extension: "
1565                            "SPV_INTEL_joint_matrix",
1566                            false);
1567       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1568       Reqs.addCapability(
1569           SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
1570     }
1571     if (CoopOperands & SPIRV::CooperativeMatrixOperands::
1572                            MatrixAAndBBFloat16ComponentsINTEL ||
1573         CoopOperands &
1574             SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
1575         CoopOperands & SPIRV::CooperativeMatrixOperands::
1576                            MatrixResultBFloat16ComponentsINTEL) {
1577       if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1578         report_fatal_error("***BF16ComponentsINTEL type interpretations "
1579                            "require the following SPIR-V extension: "
1580                            "SPV_INTEL_joint_matrix",
1581                            false);
1582       Reqs.addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1583       Reqs.addCapability(
1584           SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
1585     }
1586     break;
1587   }
1588   case SPIRV::OpCooperativeMatrixLoadKHR:
1589   case SPIRV::OpCooperativeMatrixStoreKHR:
1590   case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
1591   case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
1592   case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
1593     if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1594       report_fatal_error("Cooperative matrix instructions require the "
1595                          "following SPIR-V extension: "
1596                          "SPV_KHR_cooperative_matrix",
1597                          false);
1598     Reqs.addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1599     Reqs.addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1600 
1601     // Check Layout operand in case if it's not a standard one and add the
1602     // appropriate capability.
1603     std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
1604         {SPIRV::OpCooperativeMatrixLoadKHR, 3},
1605         {SPIRV::OpCooperativeMatrixStoreKHR, 2},
1606         {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
1607         {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
1608         {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
1609 
1610     const auto OpCode = MI.getOpcode();
1611     const unsigned LayoutNum = LayoutToInstMap[OpCode];
1612     Register RegLayout = MI.getOperand(LayoutNum).getReg();
1613     const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
1614     MachineInstr *MILayout = MRI.getUniqueVRegDef(RegLayout);
1615     if (MILayout->getOpcode() == SPIRV::OpConstantI) {
1616       const unsigned LayoutVal = MILayout->getOperand(2).getImm();
1617       if (LayoutVal ==
1618           static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
1619         if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1620           report_fatal_error("PackedINTEL layout require the following SPIR-V "
1621                              "extension: SPV_INTEL_joint_matrix",
1622                              false);
1623         Reqs.addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1624         Reqs.addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
1625       }
1626     }
1627 
1628     // Nothing to do.
1629     if (OpCode == SPIRV::OpCooperativeMatrixLoadKHR ||
1630         OpCode == SPIRV::OpCooperativeMatrixStoreKHR)
1631       break;
1632 
1633     std::string InstName;
1634     switch (OpCode) {
1635     case SPIRV::OpCooperativeMatrixPrefetchINTEL:
1636       InstName = "OpCooperativeMatrixPrefetchINTEL";
1637       break;
1638     case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
1639       InstName = "OpCooperativeMatrixLoadCheckedINTEL";
1640       break;
1641     case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
1642       InstName = "OpCooperativeMatrixStoreCheckedINTEL";
1643       break;
1644     }
1645 
1646     if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
1647       const std::string ErrorMsg =
1648           InstName + " instruction requires the "
1649                      "following SPIR-V extension: SPV_INTEL_joint_matrix";
1650       report_fatal_error(ErrorMsg.c_str(), false);
1651     }
1652     Reqs.addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1653     if (OpCode == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
1654       Reqs.addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
1655       break;
1656     }
1657     Reqs.addCapability(
1658         SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
1659     break;
1660   }
1661   case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
1662     if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1663       report_fatal_error("OpCooperativeMatrixConstructCheckedINTEL "
1664                          "instructions require the following SPIR-V extension: "
1665                          "SPV_INTEL_joint_matrix",
1666                          false);
1667     Reqs.addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1668     Reqs.addCapability(
1669         SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
1670     break;
1671   case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
1672     if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1673       report_fatal_error("OpCooperativeMatrixGetElementCoordINTEL requires the "
1674                          "following SPIR-V extension: SPV_INTEL_joint_matrix",
1675                          false);
1676     Reqs.addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1677     Reqs.addCapability(
1678         SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
1679     break;
1680   case SPIRV::OpKill: {
1681     Reqs.addCapability(SPIRV::Capability::Shader);
1682   } break;
1683   case SPIRV::OpDemoteToHelperInvocation:
1684     Reqs.addCapability(SPIRV::Capability::DemoteToHelperInvocation);
1685 
1686     if (ST.canUseExtension(
1687             SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
1688       if (!ST.isAtLeastSPIRVVer(llvm::VersionTuple(1, 6)))
1689         Reqs.addExtension(
1690             SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
1691     }
1692     break;
1693   case SPIRV::OpSDot:
1694   case SPIRV::OpUDot:
1695     AddDotProductRequirements(MI, Reqs, ST);
1696     break;
1697   case SPIRV::OpImageRead: {
1698     Register ImageReg = MI.getOperand(2).getReg();
1699     SPIRVType *TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
1700         ImageReg, const_cast<MachineFunction *>(MI.getMF()));
1701     if (isImageTypeWithUnknownFormat(TypeDef))
1702       Reqs.addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
1703     break;
1704   }
1705   case SPIRV::OpImageWrite: {
1706     Register ImageReg = MI.getOperand(0).getReg();
1707     SPIRVType *TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
1708         ImageReg, const_cast<MachineFunction *>(MI.getMF()));
1709     if (isImageTypeWithUnknownFormat(TypeDef))
1710       Reqs.addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
1711     break;
1712   }
1713 
1714   default:
1715     break;
1716   }
1717 
1718   // If we require capability Shader, then we can remove the requirement for
1719   // the BitInstructions capability, since Shader is a superset capability
1720   // of BitInstructions.
1721   Reqs.removeCapabilityIf(SPIRV::Capability::BitInstructions,
1722                           SPIRV::Capability::Shader);
1723 }
1724 
1725 static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
1726                         MachineModuleInfo *MMI, const SPIRVSubtarget &ST) {
1727   // Collect requirements for existing instructions.
1728   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
1729     MachineFunction *MF = MMI->getMachineFunction(*F);
1730     if (!MF)
1731       continue;
1732     for (const MachineBasicBlock &MBB : *MF)
1733       for (const MachineInstr &MI : MBB)
1734         addInstrRequirements(MI, MAI.Reqs, ST);
1735   }
1736   // Collect requirements for OpExecutionMode instructions.
1737   auto Node = M.getNamedMetadata("spirv.ExecutionMode");
1738   if (Node) {
1739     bool RequireFloatControls = false, RequireFloatControls2 = false,
1740          VerLower14 = !ST.isAtLeastSPIRVVer(VersionTuple(1, 4));
1741     bool HasFloatControls2 =
1742         ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
1743     for (unsigned i = 0; i < Node->getNumOperands(); i++) {
1744       MDNode *MDN = cast<MDNode>(Node->getOperand(i));
1745       const MDOperand &MDOp = MDN->getOperand(1);
1746       if (auto *CMeta = dyn_cast<ConstantAsMetadata>(MDOp)) {
1747         Constant *C = CMeta->getValue();
1748         if (ConstantInt *Const = dyn_cast<ConstantInt>(C)) {
1749           auto EM = Const->getZExtValue();
1750           // SPV_KHR_float_controls is not available until v1.4:
1751           // add SPV_KHR_float_controls if the version is too low
1752           switch (EM) {
1753           case SPIRV::ExecutionMode::DenormPreserve:
1754           case SPIRV::ExecutionMode::DenormFlushToZero:
1755           case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
1756           case SPIRV::ExecutionMode::RoundingModeRTE:
1757           case SPIRV::ExecutionMode::RoundingModeRTZ:
1758             RequireFloatControls = VerLower14;
1759             MAI.Reqs.getAndAddRequirements(
1760                 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
1761             break;
1762           case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
1763           case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
1764           case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
1765           case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
1766             if (HasFloatControls2) {
1767               RequireFloatControls2 = true;
1768               MAI.Reqs.getAndAddRequirements(
1769                   SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
1770             }
1771             break;
1772           default:
1773             MAI.Reqs.getAndAddRequirements(
1774                 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
1775           }
1776         }
1777       }
1778     }
1779     if (RequireFloatControls &&
1780         ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
1781       MAI.Reqs.addExtension(SPIRV::Extension::SPV_KHR_float_controls);
1782     if (RequireFloatControls2)
1783       MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
1784   }
1785   for (auto FI = M.begin(), E = M.end(); FI != E; ++FI) {
1786     const Function &F = *FI;
1787     if (F.isDeclaration())
1788       continue;
1789     if (F.getMetadata("reqd_work_group_size"))
1790       MAI.Reqs.getAndAddRequirements(
1791           SPIRV::OperandCategory::ExecutionModeOperand,
1792           SPIRV::ExecutionMode::LocalSize, ST);
1793     if (F.getFnAttribute("hlsl.numthreads").isValid()) {
1794       MAI.Reqs.getAndAddRequirements(
1795           SPIRV::OperandCategory::ExecutionModeOperand,
1796           SPIRV::ExecutionMode::LocalSize, ST);
1797     }
1798     if (F.getMetadata("work_group_size_hint"))
1799       MAI.Reqs.getAndAddRequirements(
1800           SPIRV::OperandCategory::ExecutionModeOperand,
1801           SPIRV::ExecutionMode::LocalSizeHint, ST);
1802     if (F.getMetadata("intel_reqd_sub_group_size"))
1803       MAI.Reqs.getAndAddRequirements(
1804           SPIRV::OperandCategory::ExecutionModeOperand,
1805           SPIRV::ExecutionMode::SubgroupSize, ST);
1806     if (F.getMetadata("vec_type_hint"))
1807       MAI.Reqs.getAndAddRequirements(
1808           SPIRV::OperandCategory::ExecutionModeOperand,
1809           SPIRV::ExecutionMode::VecTypeHint, ST);
1810 
1811     if (F.hasOptNone()) {
1812       if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
1813         MAI.Reqs.addExtension(SPIRV::Extension::SPV_INTEL_optnone);
1814         MAI.Reqs.addCapability(SPIRV::Capability::OptNoneINTEL);
1815       } else if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
1816         MAI.Reqs.addExtension(SPIRV::Extension::SPV_EXT_optnone);
1817         MAI.Reqs.addCapability(SPIRV::Capability::OptNoneEXT);
1818       }
1819     }
1820   }
1821 }
1822 
1823 static unsigned getFastMathFlags(const MachineInstr &I) {
1824   unsigned Flags = SPIRV::FPFastMathMode::None;
1825   if (I.getFlag(MachineInstr::MIFlag::FmNoNans))
1826     Flags |= SPIRV::FPFastMathMode::NotNaN;
1827   if (I.getFlag(MachineInstr::MIFlag::FmNoInfs))
1828     Flags |= SPIRV::FPFastMathMode::NotInf;
1829   if (I.getFlag(MachineInstr::MIFlag::FmNsz))
1830     Flags |= SPIRV::FPFastMathMode::NSZ;
1831   if (I.getFlag(MachineInstr::MIFlag::FmArcp))
1832     Flags |= SPIRV::FPFastMathMode::AllowRecip;
1833   if (I.getFlag(MachineInstr::MIFlag::FmReassoc))
1834     Flags |= SPIRV::FPFastMathMode::Fast;
1835   return Flags;
1836 }
1837 
1838 static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST,
1839                                    const SPIRVInstrInfo &TII,
1840                                    SPIRV::RequirementHandler &Reqs) {
1841   if (I.getFlag(MachineInstr::MIFlag::NoSWrap) && TII.canUseNSW(I) &&
1842       getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
1843                                      SPIRV::Decoration::NoSignedWrap, ST, Reqs)
1844           .IsSatisfiable) {
1845     buildOpDecorate(I.getOperand(0).getReg(), I, TII,
1846                     SPIRV::Decoration::NoSignedWrap, {});
1847   }
1848   if (I.getFlag(MachineInstr::MIFlag::NoUWrap) && TII.canUseNUW(I) &&
1849       getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
1850                                      SPIRV::Decoration::NoUnsignedWrap, ST,
1851                                      Reqs)
1852           .IsSatisfiable) {
1853     buildOpDecorate(I.getOperand(0).getReg(), I, TII,
1854                     SPIRV::Decoration::NoUnsignedWrap, {});
1855   }
1856   if (!TII.canUseFastMathFlags(I))
1857     return;
1858   unsigned FMFlags = getFastMathFlags(I);
1859   if (FMFlags == SPIRV::FPFastMathMode::None)
1860     return;
1861   Register DstReg = I.getOperand(0).getReg();
1862   buildOpDecorate(DstReg, I, TII, SPIRV::Decoration::FPFastMathMode, {FMFlags});
1863 }
1864 
1865 // Walk all functions and add decorations related to MI flags.
1866 static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
1867                            MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
1868                            SPIRV::ModuleAnalysisInfo &MAI) {
1869   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
1870     MachineFunction *MF = MMI->getMachineFunction(*F);
1871     if (!MF)
1872       continue;
1873     for (auto &MBB : *MF)
1874       for (auto &MI : MBB)
1875         handleMIFlagDecoration(MI, ST, TII, MAI.Reqs);
1876   }
1877 }
1878 
1879 static void addMBBNames(const Module &M, const SPIRVInstrInfo &TII,
1880                         MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
1881                         SPIRV::ModuleAnalysisInfo &MAI) {
1882   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
1883     MachineFunction *MF = MMI->getMachineFunction(*F);
1884     if (!MF)
1885       continue;
1886     MachineRegisterInfo &MRI = MF->getRegInfo();
1887     for (auto &MBB : *MF) {
1888       if (!MBB.hasName() || MBB.empty())
1889         continue;
1890       // Emit basic block names.
1891       Register Reg = MRI.createGenericVirtualRegister(LLT::scalar(64));
1892       MRI.setRegClass(Reg, &SPIRV::IDRegClass);
1893       buildOpName(Reg, MBB.getName(), *std::prev(MBB.end()), TII);
1894       Register GlobalReg = MAI.getOrCreateMBBRegister(MBB);
1895       MAI.setRegisterAlias(MF, Reg, GlobalReg);
1896     }
1897   }
1898 }
1899 
1900 // patching Instruction::PHI to SPIRV::OpPhi
1901 static void patchPhis(const Module &M, SPIRVGlobalRegistry *GR,
1902                       const SPIRVInstrInfo &TII, MachineModuleInfo *MMI) {
1903   for (auto F = M.begin(), E = M.end(); F != E; ++F) {
1904     MachineFunction *MF = MMI->getMachineFunction(*F);
1905     if (!MF)
1906       continue;
1907     for (auto &MBB : *MF) {
1908       for (MachineInstr &MI : MBB) {
1909         if (MI.getOpcode() != TargetOpcode::PHI)
1910           continue;
1911         MI.setDesc(TII.get(SPIRV::OpPhi));
1912         Register ResTypeReg = GR->getSPIRVTypeID(
1913             GR->getSPIRVTypeForVReg(MI.getOperand(0).getReg(), MF));
1914         MI.insert(MI.operands_begin() + 1,
1915                   {MachineOperand::CreateReg(ResTypeReg, false)});
1916       }
1917     }
1918   }
1919 }
1920 
1921 struct SPIRV::ModuleAnalysisInfo SPIRVModuleAnalysis::MAI;
1922 
1923 void SPIRVModuleAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
1924   AU.addRequired<TargetPassConfig>();
1925   AU.addRequired<MachineModuleInfoWrapperPass>();
1926 }
1927 
1928 bool SPIRVModuleAnalysis::runOnModule(Module &M) {
1929   SPIRVTargetMachine &TM =
1930       getAnalysis<TargetPassConfig>().getTM<SPIRVTargetMachine>();
1931   ST = TM.getSubtargetImpl();
1932   GR = ST->getSPIRVGlobalRegistry();
1933   TII = ST->getInstrInfo();
1934 
1935   MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
1936 
1937   setBaseInfo(M);
1938 
1939   patchPhis(M, GR, *TII, MMI);
1940 
1941   addMBBNames(M, *TII, MMI, *ST, MAI);
1942   addDecorations(M, *TII, MMI, *ST, MAI);
1943 
1944   collectReqs(M, MAI, MMI, *ST);
1945 
1946   // Process type/const/global var/func decl instructions, number their
1947   // destination registers from 0 to N, collect Extensions and Capabilities.
1948   collectDeclarations(M);
1949 
1950   // Number rest of registers from N+1 onwards.
1951   numberRegistersGlobally(M);
1952 
1953   // Collect OpName, OpEntryPoint, OpDecorate etc, process other instructions.
1954   processOtherInstrs(M);
1955 
1956   // If there are no entry points, we need the Linkage capability.
1957   if (MAI.MS[SPIRV::MB_EntryPoints].empty())
1958     MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
1959 
1960   // Set maximum ID used.
1961   GR->setBound(MAI.MaxID);
1962 
1963   return false;
1964 }
1965