LLVM  16.0.0git
SPIRVModuleAnalysis.cpp
Go to the documentation of this file.
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 "SPIRV.h"
19 #include "SPIRVSubtarget.h"
20 #include "SPIRVTargetMachine.h"
21 #include "SPIRVUtils.h"
23 #include "llvm/ADT/STLExtras.h"
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "spirv-module-analysis"
30 
31 static cl::opt<bool>
32  SPVDumpDeps("spv-dump-deps",
33  cl::desc("Dump MIR with SPIR-V dependencies info"),
34  cl::Optional, cl::init(false));
35 
37 
38 namespace llvm {
40 } // namespace llvm
41 
42 INITIALIZE_PASS(SPIRVModuleAnalysis, DEBUG_TYPE, "SPIRV module analysis", true,
43  true)
44 
45 // Retrieve an unsigned from an MDNode with a list of them as operands.
46 static unsigned getMetadataUInt(MDNode *MdNode, unsigned OpIndex,
47  unsigned DefaultVal = 0) {
48  if (MdNode && OpIndex < MdNode->getNumOperands()) {
49  const auto &Op = MdNode->getOperand(OpIndex);
50  return mdconst::extract<ConstantInt>(Op)->getZExtValue();
51  }
52  return DefaultVal;
53 }
54 
56 getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
57  unsigned i, const SPIRVSubtarget &ST,
59  unsigned ReqMinVer = getSymbolicOperandMinVersion(Category, i);
60  unsigned ReqMaxVer = getSymbolicOperandMaxVersion(Category, i);
61  unsigned TargetVer = ST.getSPIRVVersion();
62  bool MinVerOK = !ReqMinVer || !TargetVer || TargetVer >= ReqMinVer;
63  bool MaxVerOK = !ReqMaxVer || !TargetVer || TargetVer <= ReqMaxVer;
64  CapabilityList ReqCaps = getSymbolicOperandCapabilities(Category, i);
65  ExtensionList ReqExts = getSymbolicOperandExtensions(Category, i);
66  if (ReqCaps.empty()) {
67  if (ReqExts.empty()) {
68  if (MinVerOK && MaxVerOK)
69  return {true, {}, {}, ReqMinVer, ReqMaxVer};
70  return {false, {}, {}, 0, 0};
71  }
72  } else if (MinVerOK && MaxVerOK) {
73  for (auto Cap : ReqCaps) { // Only need 1 of the capabilities to work.
74  if (Reqs.isCapabilityAvailable(Cap))
75  return {true, {Cap}, {}, ReqMinVer, ReqMaxVer};
76  }
77  }
78  // If there are no capabilities, or we can't satisfy the version or
79  // capability requirements, use the list of extensions (if the subtarget
80  // can handle them all).
81  if (llvm::all_of(ReqExts, [&ST](const SPIRV::Extension::Extension &Ext) {
82  return ST.canUseExtension(Ext);
83  })) {
84  return {true, {}, ReqExts, 0, 0}; // TODO: add versions to extensions.
85  }
86  return {false, {}, {}, 0, 0};
87 }
88 
89 void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
90  MAI.MaxID = 0;
91  for (int i = 0; i < SPIRV::NUM_MODULE_SECTIONS; i++)
92  MAI.MS[i].clear();
93  MAI.RegisterAliasTable.clear();
94  MAI.InstrsToDelete.clear();
95  MAI.FuncNameMap.clear();
97  MAI.ExtInstSetMap.clear();
98  MAI.Reqs.clear();
100 
101  // TODO: determine memory model and source language from the configuratoin.
102  if (auto MemModel = M.getNamedMetadata("spirv.MemoryModel")) {
103  auto MemMD = MemModel->getOperand(0);
104  MAI.Addr = static_cast<SPIRV::AddressingModel::AddressingModel>(
105  getMetadataUInt(MemMD, 0));
106  MAI.Mem =
107  static_cast<SPIRV::MemoryModel::MemoryModel>(getMetadataUInt(MemMD, 1));
108  } else {
109  MAI.Mem = SPIRV::MemoryModel::OpenCL;
110  unsigned PtrSize = ST->getPointerSize();
111  MAI.Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
112  : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
113  : SPIRV::AddressingModel::Logical;
114  }
115  // Get the OpenCL version number from metadata.
116  // TODO: support other source languages.
117  if (auto VerNode = M.getNamedMetadata("opencl.ocl.version")) {
118  MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_C;
119  // Construct version literal in accordance with SPIRV-LLVM-Translator.
120  // TODO: support multiple OCL version metadata.
121  assert(VerNode->getNumOperands() > 0 && "Invalid SPIR");
122  auto VersionMD = VerNode->getOperand(0);
123  unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
124  unsigned MinorNum = getMetadataUInt(VersionMD, 1);
125  unsigned RevNum = getMetadataUInt(VersionMD, 2);
126  MAI.SrcLangVersion = (MajorNum * 100 + MinorNum) * 1000 + RevNum;
127  } else {
128  MAI.SrcLang = SPIRV::SourceLanguage::Unknown;
129  MAI.SrcLangVersion = 0;
130  }
131 
132  if (auto ExtNode = M.getNamedMetadata("opencl.used.extensions")) {
133  for (unsigned I = 0, E = ExtNode->getNumOperands(); I != E; ++I) {
134  MDNode *MD = ExtNode->getOperand(I);
135  if (!MD || MD->getNumOperands() == 0)
136  continue;
137  for (unsigned J = 0, N = MD->getNumOperands(); J != N; ++J)
138  MAI.SrcExt.insert(cast<MDString>(MD->getOperand(J))->getString());
139  }
140  }
141 
142  // Update required capabilities for this memory model, addressing model and
143  // source language.
144  MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand,
145  MAI.Mem, *ST);
146  MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::SourceLanguageOperand,
147  MAI.SrcLang, *ST);
148  MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
149  MAI.Addr, *ST);
150 
151  // TODO: check if it's required by default.
152  MAI.ExtInstSetMap[static_cast<unsigned>(SPIRV::InstructionSet::OpenCL_std)] =
154 }
155 
156 // Collect MI which defines the register in the given machine function.
157 static void collectDefInstr(Register Reg, const MachineFunction *MF,
160  bool DoInsert = true) {
161  assert(MAI->hasRegisterAlias(MF, Reg) && "Cannot find register alias");
163  assert(MI && "There should be an instruction that defines the register");
164  MAI->setSkipEmission(MI);
165  if (DoInsert)
166  MAI->MS[MSType].push_back(MI);
167 }
168 
169 void SPIRVModuleAnalysis::collectGlobalEntities(
170  const std::vector<SPIRV::DTSortableEntry *> &DepsGraph,
172  std::function<bool(const SPIRV::DTSortableEntry *)> Pred,
173  bool UsePreOrder = false) {
175  for (const auto *E : DepsGraph) {
176  std::function<void(const SPIRV::DTSortableEntry *)> RecHoistUtil;
177  // NOTE: here we prefer recursive approach over iterative because
178  // we don't expect depchains long enough to cause SO.
179  RecHoistUtil = [MSType, UsePreOrder, &Visited, &Pred,
180  &RecHoistUtil](const SPIRV::DTSortableEntry *E) {
181  if (Visited.count(E) || !Pred(E))
182  return;
183  Visited.insert(E);
184 
185  // Traversing deps graph in post-order allows us to get rid of
186  // register aliases preprocessing.
187  // But pre-order is required for correct processing of function
188  // declaration and arguments processing.
189  if (!UsePreOrder)
190  for (auto *S : E->getDeps())
191  RecHoistUtil(S);
192 
194  bool IsFirst = true;
195  for (auto &U : *E) {
196  const MachineFunction *MF = U.first;
197  Register Reg = U.second;
198  MAI.setRegisterAlias(MF, Reg, GlobalReg);
199  if (!MF->getRegInfo().getUniqueVRegDef(Reg))
200  continue;
201  collectDefInstr(Reg, MF, &MAI, MSType, IsFirst);
202  IsFirst = false;
203  if (E->getIsGV())
204  MAI.GlobalVarList.push_back(MF->getRegInfo().getUniqueVRegDef(Reg));
205  }
206 
207  if (UsePreOrder)
208  for (auto *S : E->getDeps())
209  RecHoistUtil(S);
210  };
211  RecHoistUtil(E);
212  }
213 }
214 
215 // The function initializes global register alias table for types, consts,
216 // global vars and func decls and collects these instruction for output
217 // at module level. Also it collects explicit OpExtension/OpCapability
218 // instructions.
219 void SPIRVModuleAnalysis::processDefInstrs(const Module &M) {
220  std::vector<SPIRV::DTSortableEntry *> DepsGraph;
221 
222  GR->buildDepsGraph(DepsGraph, SPVDumpDeps ? MMI : nullptr);
223 
224  collectGlobalEntities(
225  DepsGraph, SPIRV::MB_TypeConstVars,
226  [](const SPIRV::DTSortableEntry *E) { return !E->getIsFunc(); });
227 
228  for (auto F = M.begin(), E = M.end(); F != E; ++F) {
229  MachineFunction *MF = MMI->getMachineFunction(*F);
230  if (!MF)
231  continue;
232  // Iterate through and collect OpExtension/OpCapability instructions.
233  for (MachineBasicBlock &MBB : *MF) {
234  for (MachineInstr &MI : MBB) {
235  if (MI.getOpcode() == SPIRV::OpExtension) {
236  // Here, OpExtension just has a single enum operand, not a string.
237  auto Ext = SPIRV::Extension::Extension(MI.getOperand(0).getImm());
240  } else if (MI.getOpcode() == SPIRV::OpCapability) {
241  auto Cap = SPIRV::Capability::Capability(MI.getOperand(0).getImm());
242  MAI.Reqs.addCapability(Cap);
244  }
245  }
246  }
247  }
248 
249  collectGlobalEntities(
250  DepsGraph, SPIRV::MB_ExtFuncDecls,
251  [](const SPIRV::DTSortableEntry *E) { return E->getIsFunc(); }, true);
252 }
253 
254 // True if there is an instruction in the MS list with all the same operands as
255 // the given instruction has (after the given starting index).
256 // TODO: maybe it needs to check Opcodes too.
257 static bool findSameInstrInMS(const MachineInstr &A,
260  unsigned StartOpIndex = 0) {
261  for (const auto *B : MAI.MS[MSType]) {
262  const unsigned NumAOps = A.getNumOperands();
263  if (NumAOps != B->getNumOperands() || A.getNumDefs() != B->getNumDefs())
264  continue;
265  bool AllOpsMatch = true;
266  for (unsigned i = StartOpIndex; i < NumAOps && AllOpsMatch; ++i) {
267  if (A.getOperand(i).isReg() && B->getOperand(i).isReg()) {
268  Register RegA = A.getOperand(i).getReg();
269  Register RegB = B->getOperand(i).getReg();
270  AllOpsMatch = MAI.getRegisterAlias(A.getMF(), RegA) ==
271  MAI.getRegisterAlias(B->getMF(), RegB);
272  } else {
273  AllOpsMatch = A.getOperand(i).isIdenticalTo(B->getOperand(i));
274  }
275  }
276  if (AllOpsMatch)
277  return true;
278  }
279  return false;
280 }
281 
282 // Look for IDs declared with Import linkage, and map the imported name string
283 // to the register defining that variable (which will usually be the result of
284 // an OpFunction). This lets us call externally imported functions using
285 // the correct ID registers.
286 void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI,
287  const Function &F) {
288  if (MI.getOpcode() == SPIRV::OpDecorate) {
289  // If it's got Import linkage.
290  auto Dec = MI.getOperand(1).getImm();
291  if (Dec == static_cast<unsigned>(SPIRV::Decoration::LinkageAttributes)) {
292  auto Lnk = MI.getOperand(MI.getNumOperands() - 1).getImm();
293  if (Lnk == static_cast<unsigned>(SPIRV::LinkageType::Import)) {
294  // Map imported function name to function ID register.
295  std::string Name = getStringImm(MI, 2);
296  Register Target = MI.getOperand(0).getReg();
297  // TODO: check defs from different MFs.
299  }
300  }
301  } else if (MI.getOpcode() == SPIRV::OpFunction) {
302  // Record all internal OpFunction declarations.
303  Register Reg = MI.defs().begin()->getReg();
304  Register GlobalReg = MAI.getRegisterAlias(MI.getMF(), Reg);
305  assert(GlobalReg.isValid());
306  // TODO: check that it does not conflict with existing entries.
308  }
309 }
310 
311 // Collect the given instruction in the specified MS. We assume global register
312 // numbering has already occurred by this point. We can directly compare reg
313 // arguments when detecting duplicates.
314 static void collectOtherInstr(MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI,
316  bool Append = true) {
317  MAI.setSkipEmission(&MI);
318  if (findSameInstrInMS(MI, MSType, MAI))
319  return; // Found a duplicate, so don't add it.
320  // No duplicates, so add it.
321  if (Append)
322  MAI.MS[MSType].push_back(&MI);
323  else
324  MAI.MS[MSType].insert(MAI.MS[MSType].begin(), &MI);
325 }
326 
327 // Some global instructions make reference to function-local ID regs, so cannot
328 // be correctly collected until these registers are globally numbered.
329 void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
330  for (auto F = M.begin(), E = M.end(); F != E; ++F) {
331  if ((*F).isDeclaration())
332  continue;
333  MachineFunction *MF = MMI->getMachineFunction(*F);
334  assert(MF);
335  for (MachineBasicBlock &MBB : *MF)
336  for (MachineInstr &MI : MBB) {
337  if (MAI.getSkipEmission(&MI))
338  continue;
339  const unsigned OpCode = MI.getOpcode();
340  if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
341  collectOtherInstr(MI, MAI, SPIRV::MB_DebugNames);
342  } else if (OpCode == SPIRV::OpEntryPoint) {
343  collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints);
344  } else if (TII->isDecorationInstr(MI)) {
345  collectOtherInstr(MI, MAI, SPIRV::MB_Annotations);
346  collectFuncNames(MI, *F);
347  } else if (TII->isConstantInstr(MI)) {
348  // Now OpSpecConstant*s are not in DT,
349  // but they need to be collected anyway.
350  collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars);
351  } else if (OpCode == SPIRV::OpFunction) {
352  collectFuncNames(MI, *F);
353  } else if (OpCode == SPIRV::OpTypeForwardPointer) {
354  collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, false);
355  }
356  }
357  }
358 }
359 
360 // Number registers in all functions globally from 0 onwards and store
361 // the result in global register alias table. Some registers are already
362 // numbered in collectGlobalEntities.
363 void SPIRVModuleAnalysis::numberRegistersGlobally(const Module &M) {
364  for (auto F = M.begin(), E = M.end(); F != E; ++F) {
365  if ((*F).isDeclaration())
366  continue;
367  MachineFunction *MF = MMI->getMachineFunction(*F);
368  assert(MF);
369  for (MachineBasicBlock &MBB : *MF) {
370  for (MachineInstr &MI : MBB) {
371  for (MachineOperand &Op : MI.operands()) {
372  if (!Op.isReg())
373  continue;
374  Register Reg = Op.getReg();
375  if (MAI.hasRegisterAlias(MF, Reg))
376  continue;
378  MAI.setRegisterAlias(MF, Reg, NewReg);
379  }
380  if (MI.getOpcode() != SPIRV::OpExtInst)
381  continue;
382  auto Set = MI.getOperand(2).getImm();
383  if (MAI.ExtInstSetMap.find(Set) == MAI.ExtInstSetMap.end())
385  }
386  }
387  }
388 }
389 
390 // Find OpIEqual and OpBranchConditional instructions originating from
391 // OpSwitches, mark them skipped for emission. Also mark MBB skipped if it
392 // contains only these instructions.
393 static void processSwitches(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
394  MachineModuleInfo *MMI) {
395  DenseSet<Register> SwitchRegs;
396  for (auto F = M.begin(), E = M.end(); F != E; ++F) {
397  MachineFunction *MF = MMI->getMachineFunction(*F);
398  if (!MF)
399  continue;
400  for (MachineBasicBlock &MBB : *MF)
401  for (MachineInstr &MI : MBB) {
402  if (MAI.getSkipEmission(&MI))
403  continue;
404  if (MI.getOpcode() == SPIRV::OpSwitch) {
405  assert(MI.getOperand(0).isReg());
406  SwitchRegs.insert(MI.getOperand(0).getReg());
407  }
408  if (MI.getOpcode() == SPIRV::OpISubS &&
409  SwitchRegs.contains(MI.getOperand(2).getReg())) {
410  SwitchRegs.insert(MI.getOperand(0).getReg());
411  MAI.setSkipEmission(&MI);
412  }
413  if ((MI.getOpcode() != SPIRV::OpIEqual &&
414  MI.getOpcode() != SPIRV::OpULessThanEqual) ||
415  !MI.getOperand(2).isReg() ||
416  !SwitchRegs.contains(MI.getOperand(2).getReg()))
417  continue;
418  Register CmpReg = MI.getOperand(0).getReg();
419  MachineInstr *CBr = MI.getNextNode();
420  assert(CBr && CBr->getOpcode() == SPIRV::OpBranchConditional &&
421  CBr->getOperand(0).isReg() &&
422  CBr->getOperand(0).getReg() == CmpReg);
423  MAI.setSkipEmission(&MI);
424  MAI.setSkipEmission(CBr);
425  if (&MBB.front() == &MI && &MBB.back() == CBr)
426  MAI.MBBsToSkip.insert(&MBB);
427  }
428  }
429 }
430 
431 // RequirementHandler implementations.
433  SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
434  const SPIRVSubtarget &ST) {
435  addRequirements(getSymbolicOperandRequirements(Category, i, ST, *this));
436 }
437 
438 void SPIRV::RequirementHandler::pruneCapabilities(
439  const CapabilityList &ToPrune) {
440  for (const auto &Cap : ToPrune) {
441  AllCaps.insert(Cap);
442  auto FoundIndex = std::find(MinimalCaps.begin(), MinimalCaps.end(), Cap);
443  if (FoundIndex != MinimalCaps.end())
444  MinimalCaps.erase(FoundIndex);
445  CapabilityList ImplicitDecls =
446  getSymbolicOperandCapabilities(OperandCategory::CapabilityOperand, Cap);
447  pruneCapabilities(ImplicitDecls);
448  }
449 }
450 
452  for (const auto &Cap : ToAdd) {
453  bool IsNewlyInserted = AllCaps.insert(Cap).second;
454  if (!IsNewlyInserted) // Don't re-add if it's already been declared.
455  continue;
456  CapabilityList ImplicitDecls =
457  getSymbolicOperandCapabilities(OperandCategory::CapabilityOperand, Cap);
458  pruneCapabilities(ImplicitDecls);
459  MinimalCaps.push_back(Cap);
460  }
461 }
462 
464  const SPIRV::Requirements &Req) {
465  if (!Req.IsSatisfiable)
466  report_fatal_error("Adding SPIR-V requirements this target can't satisfy.");
467 
468  if (Req.Cap.has_value())
469  addCapabilities({Req.Cap.value()});
470 
471  addExtensions(Req.Exts);
472 
473  if (Req.MinVer) {
474  if (MaxVersion && Req.MinVer > MaxVersion) {
475  LLVM_DEBUG(dbgs() << "Conflicting version requirements: >= " << Req.MinVer
476  << " and <= " << MaxVersion << "\n");
477  report_fatal_error("Adding SPIR-V requirements that can't be satisfied.");
478  }
479 
480  if (MinVersion == 0 || Req.MinVer > MinVersion)
481  MinVersion = Req.MinVer;
482  }
483 
484  if (Req.MaxVer) {
485  if (MinVersion && Req.MaxVer < MinVersion) {
486  LLVM_DEBUG(dbgs() << "Conflicting version requirements: <= " << Req.MaxVer
487  << " and >= " << MinVersion << "\n");
488  report_fatal_error("Adding SPIR-V requirements that can't be satisfied.");
489  }
490 
491  if (MaxVersion == 0 || Req.MaxVer < MaxVersion)
492  MaxVersion = Req.MaxVer;
493  }
494 }
495 
497  const SPIRVSubtarget &ST) const {
498  // Report as many errors as possible before aborting the compilation.
499  bool IsSatisfiable = true;
500  auto TargetVer = ST.getSPIRVVersion();
501 
502  if (MaxVersion && TargetVer && MaxVersion < TargetVer) {
503  LLVM_DEBUG(
504  dbgs() << "Target SPIR-V version too high for required features\n"
505  << "Required max version: " << MaxVersion << " target version "
506  << TargetVer << "\n");
507  IsSatisfiable = false;
508  }
509 
510  if (MinVersion && TargetVer && MinVersion > TargetVer) {
511  LLVM_DEBUG(dbgs() << "Target SPIR-V version too low for required features\n"
512  << "Required min version: " << MinVersion
513  << " target version " << TargetVer << "\n");
514  IsSatisfiable = false;
515  }
516 
517  if (MinVersion && MaxVersion && MinVersion > MaxVersion) {
518  LLVM_DEBUG(
519  dbgs()
520  << "Version is too low for some features and too high for others.\n"
521  << "Required SPIR-V min version: " << MinVersion
522  << " required SPIR-V max version " << MaxVersion << "\n");
523  IsSatisfiable = false;
524  }
525 
526  for (auto Cap : MinimalCaps) {
527  if (AvailableCaps.contains(Cap))
528  continue;
529  LLVM_DEBUG(dbgs() << "Capability not supported: "
531  OperandCategory::CapabilityOperand, Cap)
532  << "\n");
533  IsSatisfiable = false;
534  }
535 
536  for (auto Ext : AllExtensions) {
537  if (ST.canUseExtension(Ext))
538  continue;
539  LLVM_DEBUG(dbgs() << "Extension not suported: "
541  OperandCategory::ExtensionOperand, Ext)
542  << "\n");
543  IsSatisfiable = false;
544  }
545 
546  if (!IsSatisfiable)
547  report_fatal_error("Unable to meet SPIR-V requirements for this target.");
548 }
549 
550 // Add the given capabilities and all their implicitly defined capabilities too.
552  for (const auto Cap : ToAdd)
553  if (AvailableCaps.insert(Cap).second)
554  addAvailableCaps(getSymbolicOperandCapabilities(
555  SPIRV::OperandCategory::CapabilityOperand, Cap));
556 }
557 
558 namespace llvm {
559 namespace SPIRV {
561  // TODO: Implemented for other targets other then OpenCL.
562  if (!ST.isOpenCLEnv())
563  return;
564  // Add the min requirements for different OpenCL and SPIR-V versions.
565  addAvailableCaps({Capability::Addresses, Capability::Float16Buffer,
566  Capability::Int16, Capability::Int8, Capability::Kernel,
567  Capability::Linkage, Capability::Vector16,
568  Capability::Groups, Capability::GenericPointer,
569  Capability::Shader});
570  if (ST.hasOpenCLFullProfile())
571  addAvailableCaps({Capability::Int64, Capability::Int64Atomics});
572  if (ST.hasOpenCLImageSupport()) {
573  addAvailableCaps({Capability::ImageBasic, Capability::LiteralSampler,
574  Capability::Image1D, Capability::SampledBuffer,
575  Capability::ImageBuffer});
576  if (ST.isAtLeastOpenCLVer(20))
577  addAvailableCaps({Capability::ImageReadWrite});
578  }
579  if (ST.isAtLeastSPIRVVer(11) && ST.isAtLeastOpenCLVer(22))
580  addAvailableCaps({Capability::SubgroupDispatch, Capability::PipeStorage});
581  if (ST.isAtLeastSPIRVVer(13))
582  addAvailableCaps({Capability::GroupNonUniform,
583  Capability::GroupNonUniformVote,
584  Capability::GroupNonUniformArithmetic,
585  Capability::GroupNonUniformBallot,
586  Capability::GroupNonUniformClustered,
587  Capability::GroupNonUniformShuffle,
588  Capability::GroupNonUniformShuffleRelative});
589  if (ST.isAtLeastSPIRVVer(14))
590  addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
591  Capability::SignedZeroInfNanPreserve,
592  Capability::RoundingModeRTE,
593  Capability::RoundingModeRTZ});
594  // TODO: verify if this needs some checks.
595  addAvailableCaps({Capability::Float16, Capability::Float64});
596 
597  // TODO: add OpenCL extensions.
598 }
599 } // namespace SPIRV
600 } // namespace llvm
601 
602 // Add the required capabilities from a decoration instruction (including
603 // BuiltIns).
604 static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
606  const SPIRVSubtarget &ST) {
607  int64_t DecOp = MI.getOperand(DecIndex).getImm();
608  auto Dec = static_cast<SPIRV::Decoration::Decoration>(DecOp);
609  Reqs.addRequirements(getSymbolicOperandRequirements(
610  SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
611 
612  if (Dec == SPIRV::Decoration::BuiltIn) {
613  int64_t BuiltInOp = MI.getOperand(DecIndex + 1).getImm();
614  auto BuiltIn = static_cast<SPIRV::BuiltIn::BuiltIn>(BuiltInOp);
615  Reqs.addRequirements(getSymbolicOperandRequirements(
616  SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
617  }
618 }
619 
620 // Add requirements for image handling.
621 static void addOpTypeImageReqs(const MachineInstr &MI,
623  const SPIRVSubtarget &ST) {
624  assert(MI.getNumOperands() >= 8 && "Insufficient operands for OpTypeImage");
625  // The operand indices used here are based on the OpTypeImage layout, which
626  // the MachineInstr follows as well.
627  int64_t ImgFormatOp = MI.getOperand(7).getImm();
628  auto ImgFormat = static_cast<SPIRV::ImageFormat::ImageFormat>(ImgFormatOp);
629  Reqs.getAndAddRequirements(SPIRV::OperandCategory::ImageFormatOperand,
630  ImgFormat, ST);
631 
632  bool IsArrayed = MI.getOperand(4).getImm() == 1;
633  bool IsMultisampled = MI.getOperand(5).getImm() == 1;
634  bool NoSampler = MI.getOperand(6).getImm() == 2;
635  // Add dimension requirements.
636  assert(MI.getOperand(2).isImm());
637  switch (MI.getOperand(2).getImm()) {
638  case SPIRV::Dim::DIM_1D:
639  Reqs.addRequirements(NoSampler ? SPIRV::Capability::Image1D
640  : SPIRV::Capability::Sampled1D);
641  break;
642  case SPIRV::Dim::DIM_2D:
643  if (IsMultisampled && NoSampler)
644  Reqs.addRequirements(SPIRV::Capability::ImageMSArray);
645  break;
646  case SPIRV::Dim::DIM_Cube:
647  Reqs.addRequirements(SPIRV::Capability::Shader);
648  if (IsArrayed)
649  Reqs.addRequirements(NoSampler ? SPIRV::Capability::ImageCubeArray
650  : SPIRV::Capability::SampledCubeArray);
651  break;
652  case SPIRV::Dim::DIM_Rect:
653  Reqs.addRequirements(NoSampler ? SPIRV::Capability::ImageRect
654  : SPIRV::Capability::SampledRect);
655  break;
656  case SPIRV::Dim::DIM_Buffer:
657  Reqs.addRequirements(NoSampler ? SPIRV::Capability::ImageBuffer
658  : SPIRV::Capability::SampledBuffer);
659  break;
660  case SPIRV::Dim::DIM_SubpassData:
661  Reqs.addRequirements(SPIRV::Capability::InputAttachment);
662  break;
663  }
664 
665  // Has optional access qualifier.
666  // TODO: check if it's OpenCL's kernel.
667  if (MI.getNumOperands() > 8 &&
668  MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
669  Reqs.addRequirements(SPIRV::Capability::ImageReadWrite);
670  else
671  Reqs.addRequirements(SPIRV::Capability::ImageBasic);
672 }
673 
674 void addInstrRequirements(const MachineInstr &MI,
676  const SPIRVSubtarget &ST) {
677  switch (MI.getOpcode()) {
678  case SPIRV::OpMemoryModel: {
679  int64_t Addr = MI.getOperand(0).getImm();
680  Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
681  Addr, ST);
682  int64_t Mem = MI.getOperand(1).getImm();
683  Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand, Mem,
684  ST);
685  break;
686  }
687  case SPIRV::OpEntryPoint: {
688  int64_t Exe = MI.getOperand(0).getImm();
689  Reqs.getAndAddRequirements(SPIRV::OperandCategory::ExecutionModelOperand,
690  Exe, ST);
691  break;
692  }
693  case SPIRV::OpExecutionMode:
694  case SPIRV::OpExecutionModeId: {
695  int64_t Exe = MI.getOperand(1).getImm();
696  Reqs.getAndAddRequirements(SPIRV::OperandCategory::ExecutionModeOperand,
697  Exe, ST);
698  break;
699  }
700  case SPIRV::OpTypeMatrix:
701  Reqs.addCapability(SPIRV::Capability::Matrix);
702  break;
703  case SPIRV::OpTypeInt: {
704  unsigned BitWidth = MI.getOperand(1).getImm();
705  if (BitWidth == 64)
706  Reqs.addCapability(SPIRV::Capability::Int64);
707  else if (BitWidth == 16)
708  Reqs.addCapability(SPIRV::Capability::Int16);
709  else if (BitWidth == 8)
711  break;
712  }
713  case SPIRV::OpTypeFloat: {
714  unsigned BitWidth = MI.getOperand(1).getImm();
715  if (BitWidth == 64)
716  Reqs.addCapability(SPIRV::Capability::Float64);
717  else if (BitWidth == 16)
718  Reqs.addCapability(SPIRV::Capability::Float16);
719  break;
720  }
721  case SPIRV::OpTypeVector: {
722  unsigned NumComponents = MI.getOperand(2).getImm();
723  if (NumComponents == 8 || NumComponents == 16)
724  Reqs.addCapability(SPIRV::Capability::Vector16);
725  break;
726  }
727  case SPIRV::OpTypePointer: {
728  auto SC = MI.getOperand(1).getImm();
729  Reqs.getAndAddRequirements(SPIRV::OperandCategory::StorageClassOperand, SC,
730  ST);
731  // If it's a type of pointer to float16, add Float16Buffer capability.
732  assert(MI.getOperand(2).isReg());
733  const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
734  SPIRVType *TypeDef = MRI.getVRegDef(MI.getOperand(2).getReg());
735  if (TypeDef->getOpcode() == SPIRV::OpTypeFloat &&
736  TypeDef->getOperand(1).getImm() == 16)
737  Reqs.addCapability(SPIRV::Capability::Float16Buffer);
738  break;
739  }
740  case SPIRV::OpBitReverse:
741  case SPIRV::OpTypeRuntimeArray:
742  Reqs.addCapability(SPIRV::Capability::Shader);
743  break;
744  case SPIRV::OpTypeOpaque:
745  case SPIRV::OpTypeEvent:
747  break;
748  case SPIRV::OpTypePipe:
749  case SPIRV::OpTypeReserveId:
750  Reqs.addCapability(SPIRV::Capability::Pipes);
751  break;
752  case SPIRV::OpTypeDeviceEvent:
753  case SPIRV::OpTypeQueue:
754  case SPIRV::OpBuildNDRange:
755  Reqs.addCapability(SPIRV::Capability::DeviceEnqueue);
756  break;
757  case SPIRV::OpDecorate:
758  case SPIRV::OpDecorateId:
759  case SPIRV::OpDecorateString:
760  addOpDecorateReqs(MI, 1, Reqs, ST);
761  break;
762  case SPIRV::OpMemberDecorate:
763  case SPIRV::OpMemberDecorateString:
764  addOpDecorateReqs(MI, 2, Reqs, ST);
765  break;
766  case SPIRV::OpInBoundsPtrAccessChain:
767  Reqs.addCapability(SPIRV::Capability::Addresses);
768  break;
769  case SPIRV::OpConstantSampler:
770  Reqs.addCapability(SPIRV::Capability::LiteralSampler);
771  break;
772  case SPIRV::OpTypeImage:
773  addOpTypeImageReqs(MI, Reqs, ST);
774  break;
775  case SPIRV::OpTypeSampler:
776  Reqs.addCapability(SPIRV::Capability::ImageBasic);
777  break;
778  case SPIRV::OpTypeForwardPointer:
779  // TODO: check if it's OpenCL's kernel.
780  Reqs.addCapability(SPIRV::Capability::Addresses);
781  break;
782  case SPIRV::OpAtomicFlagTestAndSet:
783  case SPIRV::OpAtomicLoad:
784  case SPIRV::OpAtomicStore:
785  case SPIRV::OpAtomicExchange:
786  case SPIRV::OpAtomicCompareExchange:
787  case SPIRV::OpAtomicIIncrement:
788  case SPIRV::OpAtomicIDecrement:
789  case SPIRV::OpAtomicIAdd:
790  case SPIRV::OpAtomicISub:
791  case SPIRV::OpAtomicUMin:
792  case SPIRV::OpAtomicUMax:
793  case SPIRV::OpAtomicSMin:
794  case SPIRV::OpAtomicSMax:
795  case SPIRV::OpAtomicAnd:
796  case SPIRV::OpAtomicOr:
797  case SPIRV::OpAtomicXor: {
798  const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
799  const MachineInstr *InstrPtr = &MI;
800  if (MI.getOpcode() == SPIRV::OpAtomicStore) {
801  assert(MI.getOperand(3).isReg());
802  InstrPtr = MRI.getVRegDef(MI.getOperand(3).getReg());
803  assert(InstrPtr && "Unexpected type instruction for OpAtomicStore");
804  }
805  assert(InstrPtr->getOperand(1).isReg() && "Unexpected operand in atomic");
806  Register TypeReg = InstrPtr->getOperand(1).getReg();
807  SPIRVType *TypeDef = MRI.getVRegDef(TypeReg);
808  if (TypeDef->getOpcode() == SPIRV::OpTypeInt) {
809  unsigned BitWidth = TypeDef->getOperand(1).getImm();
810  if (BitWidth == 64)
811  Reqs.addCapability(SPIRV::Capability::Int64Atomics);
812  }
813  break;
814  }
815  case SPIRV::OpGroupNonUniformIAdd:
816  case SPIRV::OpGroupNonUniformFAdd:
817  case SPIRV::OpGroupNonUniformIMul:
818  case SPIRV::OpGroupNonUniformFMul:
819  case SPIRV::OpGroupNonUniformSMin:
820  case SPIRV::OpGroupNonUniformUMin:
821  case SPIRV::OpGroupNonUniformFMin:
822  case SPIRV::OpGroupNonUniformSMax:
823  case SPIRV::OpGroupNonUniformUMax:
824  case SPIRV::OpGroupNonUniformFMax:
825  case SPIRV::OpGroupNonUniformBitwiseAnd:
826  case SPIRV::OpGroupNonUniformBitwiseOr:
827  case SPIRV::OpGroupNonUniformBitwiseXor:
828  case SPIRV::OpGroupNonUniformLogicalAnd:
829  case SPIRV::OpGroupNonUniformLogicalOr:
830  case SPIRV::OpGroupNonUniformLogicalXor: {
831  assert(MI.getOperand(3).isImm());
832  int64_t GroupOp = MI.getOperand(3).getImm();
833  switch (GroupOp) {
834  case SPIRV::GroupOperation::Reduce:
835  case SPIRV::GroupOperation::InclusiveScan:
836  case SPIRV::GroupOperation::ExclusiveScan:
838  Reqs.addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
839  Reqs.addCapability(SPIRV::Capability::GroupNonUniformBallot);
840  break;
841  case SPIRV::GroupOperation::ClusteredReduce:
842  Reqs.addCapability(SPIRV::Capability::GroupNonUniformClustered);
843  break;
844  case SPIRV::GroupOperation::PartitionedReduceNV:
845  case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
846  case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
847  Reqs.addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
848  break;
849  }
850  break;
851  }
852  case SPIRV::OpGroupNonUniformShuffle:
853  case SPIRV::OpGroupNonUniformShuffleXor:
854  Reqs.addCapability(SPIRV::Capability::GroupNonUniformShuffle);
855  break;
856  case SPIRV::OpGroupNonUniformShuffleUp:
857  case SPIRV::OpGroupNonUniformShuffleDown:
858  Reqs.addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
859  break;
860  case SPIRV::OpGroupAll:
861  case SPIRV::OpGroupAny:
862  case SPIRV::OpGroupBroadcast:
863  case SPIRV::OpGroupIAdd:
864  case SPIRV::OpGroupFAdd:
865  case SPIRV::OpGroupFMin:
866  case SPIRV::OpGroupUMin:
867  case SPIRV::OpGroupSMin:
868  case SPIRV::OpGroupFMax:
869  case SPIRV::OpGroupUMax:
870  case SPIRV::OpGroupSMax:
872  break;
873  case SPIRV::OpGroupNonUniformElect:
874  Reqs.addCapability(SPIRV::Capability::GroupNonUniform);
875  break;
876  case SPIRV::OpGroupNonUniformAll:
877  case SPIRV::OpGroupNonUniformAny:
878  case SPIRV::OpGroupNonUniformAllEqual:
879  Reqs.addCapability(SPIRV::Capability::GroupNonUniformVote);
880  break;
881  case SPIRV::OpGroupNonUniformBroadcast:
882  case SPIRV::OpGroupNonUniformBroadcastFirst:
883  case SPIRV::OpGroupNonUniformBallot:
884  case SPIRV::OpGroupNonUniformInverseBallot:
885  case SPIRV::OpGroupNonUniformBallotBitExtract:
886  case SPIRV::OpGroupNonUniformBallotBitCount:
887  case SPIRV::OpGroupNonUniformBallotFindLSB:
888  case SPIRV::OpGroupNonUniformBallotFindMSB:
889  Reqs.addCapability(SPIRV::Capability::GroupNonUniformBallot);
890  break;
891  default:
892  break;
893  }
894 }
895 
896 static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
897  MachineModuleInfo *MMI, const SPIRVSubtarget &ST) {
898  // Collect requirements for existing instructions.
899  for (auto F = M.begin(), E = M.end(); F != E; ++F) {
900  MachineFunction *MF = MMI->getMachineFunction(*F);
901  if (!MF)
902  continue;
903  for (const MachineBasicBlock &MBB : *MF)
904  for (const MachineInstr &MI : MBB)
905  addInstrRequirements(MI, MAI.Reqs, ST);
906  }
907  // Collect requirements for OpExecutionMode instructions.
908  auto Node = M.getNamedMetadata("spirv.ExecutionMode");
909  if (Node) {
910  for (unsigned i = 0; i < Node->getNumOperands(); i++) {
911  MDNode *MDN = cast<MDNode>(Node->getOperand(i));
912  const MDOperand &MDOp = MDN->getOperand(1);
913  if (auto *CMeta = dyn_cast<ConstantAsMetadata>(MDOp)) {
914  Constant *C = CMeta->getValue();
915  if (ConstantInt *Const = dyn_cast<ConstantInt>(C)) {
916  auto EM = Const->getZExtValue();
918  SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
919  }
920  }
921  }
922  }
923  for (auto FI = M.begin(), E = M.end(); FI != E; ++FI) {
924  const Function &F = *FI;
925  if (F.isDeclaration())
926  continue;
927  if (F.getMetadata("reqd_work_group_size"))
929  SPIRV::OperandCategory::ExecutionModeOperand,
930  SPIRV::ExecutionMode::LocalSize, ST);
931  if (F.getMetadata("work_group_size_hint"))
933  SPIRV::OperandCategory::ExecutionModeOperand,
934  SPIRV::ExecutionMode::LocalSizeHint, ST);
935  if (F.getMetadata("intel_reqd_sub_group_size"))
937  SPIRV::OperandCategory::ExecutionModeOperand,
938  SPIRV::ExecutionMode::SubgroupSize, ST);
939  if (F.getMetadata("vec_type_hint"))
941  SPIRV::OperandCategory::ExecutionModeOperand,
943  }
944 }
945 
946 static unsigned getFastMathFlags(const MachineInstr &I) {
947  unsigned Flags = SPIRV::FPFastMathMode::None;
948  if (I.getFlag(MachineInstr::MIFlag::FmNoNans))
949  Flags |= SPIRV::FPFastMathMode::NotNaN;
950  if (I.getFlag(MachineInstr::MIFlag::FmNoInfs))
951  Flags |= SPIRV::FPFastMathMode::NotInf;
952  if (I.getFlag(MachineInstr::MIFlag::FmNsz))
953  Flags |= SPIRV::FPFastMathMode::NSZ;
954  if (I.getFlag(MachineInstr::MIFlag::FmArcp))
955  Flags |= SPIRV::FPFastMathMode::AllowRecip;
956  if (I.getFlag(MachineInstr::MIFlag::FmReassoc))
957  Flags |= SPIRV::FPFastMathMode::Fast;
958  return Flags;
959 }
960 
961 static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST,
962  const SPIRVInstrInfo &TII,
964  if (I.getFlag(MachineInstr::MIFlag::NoSWrap) && TII.canUseNSW(I) &&
965  getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
966  SPIRV::Decoration::NoSignedWrap, ST, Reqs)
967  .IsSatisfiable) {
968  buildOpDecorate(I.getOperand(0).getReg(), I, TII,
969  SPIRV::Decoration::NoSignedWrap, {});
970  }
971  if (I.getFlag(MachineInstr::MIFlag::NoUWrap) && TII.canUseNUW(I) &&
972  getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
973  SPIRV::Decoration::NoUnsignedWrap, ST,
974  Reqs)
975  .IsSatisfiable) {
976  buildOpDecorate(I.getOperand(0).getReg(), I, TII,
977  SPIRV::Decoration::NoUnsignedWrap, {});
978  }
979  if (!TII.canUseFastMathFlags(I))
980  return;
981  unsigned FMFlags = getFastMathFlags(I);
982  if (FMFlags == SPIRV::FPFastMathMode::None)
983  return;
984  Register DstReg = I.getOperand(0).getReg();
985  buildOpDecorate(DstReg, I, TII, SPIRV::Decoration::FPFastMathMode, {FMFlags});
986 }
987 
988 // Walk all functions and add decorations related to MI flags.
989 static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
990  MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
992  for (auto F = M.begin(), E = M.end(); F != E; ++F) {
993  MachineFunction *MF = MMI->getMachineFunction(*F);
994  if (!MF)
995  continue;
996  for (auto &MBB : *MF)
997  for (auto &MI : MBB)
998  handleMIFlagDecoration(MI, ST, TII, MAI.Reqs);
999  }
1000 }
1001 
1003 
1005  AU.addRequired<TargetPassConfig>();
1006  AU.addRequired<MachineModuleInfoWrapperPass>();
1007 }
1008 
1011  getAnalysis<TargetPassConfig>().getTM<SPIRVTargetMachine>();
1012  ST = TM.getSubtargetImpl();
1013  GR = ST->getSPIRVGlobalRegistry();
1014  TII = ST->getInstrInfo();
1015 
1016  MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
1017 
1018  setBaseInfo(M);
1019 
1020  addDecorations(M, *TII, MMI, *ST, MAI);
1021 
1022  collectReqs(M, MAI, MMI, *ST);
1023 
1024  processSwitches(M, MAI, MMI);
1025 
1026  // Process type/const/global var/func decl instructions, number their
1027  // destination registers from 0 to N, collect Extensions and Capabilities.
1028  processDefInstrs(M);
1029 
1030  // Number rest of registers from N+1 onwards.
1031  numberRegistersGlobally(M);
1032 
1033  // Collect OpName, OpEntryPoint, OpDecorate etc, process other instructions.
1034  processOtherInstrs(M);
1035 
1036  // If there are no entry points, we need the Linkage capability.
1037  if (MAI.MS[SPIRV::MB_EntryPoints].empty())
1038  MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
1039 
1040  return false;
1041 }
llvm::SPIRV::ModuleAnalysisInfo::setRegisterAlias
void setRegisterAlias(const MachineFunction *MF, Register Reg, Register AliasReg)
Definition: SPIRVModuleAnalysis.h:166
i
i
Definition: README.txt:29
DefaultVal
unsigned unsigned DefaultVal
Definition: SPIRVModuleAnalysis.cpp:47
llvm::SPIRV::ModuleSectionType
ModuleSectionType
Definition: SPIRVModuleAnalysis.h:33
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
SPIRVModuleAnalysis.h
DEBUG_TYPE
#define DEBUG_TYPE
Definition: SPIRVModuleAnalysis.cpp:29
llvm::SPIRVInstrInfo::isDecorationInstr
bool isDecorationInstr(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:59
llvm::SPIRV::MB_TypeConstVars
@ MB_TypeConstVars
Definition: SPIRVModuleAnalysis.h:40
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::Function
Definition: Function.h:60
llvm::SPIRV::NUM_MODULE_SECTIONS
@ NUM_MODULE_SECTIONS
Definition: SPIRVModuleAnalysis.h:42
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
llvm::SmallVector< SPIRV::Capability::Capability, 8 >
llvm::SPIRV::RequirementHandler::initAvailableCapabilities
void initAvailableCapabilities(const SPIRVSubtarget &ST)
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::SPIRV::Requirements::Exts
const ExtensionList Exts
Definition: SPIRVModuleAnalysis.h:48
llvm::MachineRegisterInfo::getUniqueVRegDef
MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Definition: MachineRegisterInfo.cpp:407
Groups
static const X86InstrFMA3Group Groups[]
Definition: X86InstrFMA3Info.cpp:73
llvm::SPIRVSubtarget
Definition: SPIRVSubtarget.h:35
llvm::SPIRV::ModuleAnalysisInfo::MaxID
unsigned MaxID
Definition: SPIRVModuleAnalysis.h:148
llvm::Register::index2VirtReg
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:34
llvm::SPIRV::ModuleAnalysisInfo
Definition: SPIRVModuleAnalysis.h:124
STLExtras.h
llvm::SPIRV::ModuleAnalysisInfo::SrcExt
StringSet SrcExt
Definition: SPIRVModuleAnalysis.h:130
llvm::MachineBasicBlock::back
MachineInstr & back()
Definition: MachineBasicBlock.h:285
SPIRVSubtarget.h
llvm::SPIRVInstrInfo::isConstantInstr
bool isConstantInstr(const MachineInstr &MI) const
Definition: SPIRVInstrInfo.cpp:28
INITIALIZE_PASS
INITIALIZE_PASS(SPIRVModuleAnalysis, DEBUG_TYPE, "SPIRV module analysis", true, true) static unsigned getMetadataUInt(MDNode *MdNode
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
SPIRVTargetInfo.h
OpIndex
unsigned OpIndex
Definition: SPIRVModuleAnalysis.cpp:46
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::initializeSPIRVModuleAnalysisPass
void initializeSPIRVModuleAnalysisPass(PassRegistry &)
llvm::SPIRV::DTSortableEntry
Definition: SPIRVDuplicatesTracker.h:31
llvm::MDNode::getNumOperands
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1298
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::SPIRV::ModuleAnalysisInfo::setSkipEmission
void setSkipEmission(MachineInstr *MI)
Definition: SPIRVModuleAnalysis.h:162
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1734
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
llvm::AMDGPU::HSAMD::Kernel::Attrs::Key::VecTypeHint
constexpr char VecTypeHint[]
Key for Kernel::Attr::Metadata::mVecTypeHint.
Definition: AMDGPUMetadata.h:132
SPVDumpDeps
static cl::opt< bool > SPVDumpDeps("spv-dump-deps", cl::desc("Dump MIR with SPIR-V dependencies info"), cl::Optional, cl::init(false))
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:420
llvm::getSymbolicOperandMinVersion
uint32_t getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
Definition: SPIRVBaseInfo.cpp:92
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:546
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::SPIRV::Requirements::Cap
const Optional< Capability::Capability > Cap
Definition: SPIRVModuleAnalysis.h:47
llvm::SPIRV::RequirementHandler
Definition: SPIRVModuleAnalysis.h:61
llvm::SPIRVModuleAnalysis::MAI
static struct SPIRV::ModuleAnalysisInfo MAI
Definition: SPIRVModuleAnalysis.h:205
llvm::getSymbolicOperandExtensions
ExtensionList getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
Definition: SPIRVBaseInfo.cpp:133
llvm::SPIRV::ModuleAnalysisInfo::getNextID
unsigned getNextID()
Definition: SPIRVModuleAnalysis.h:181
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::getSymbolicOperandCapabilities
CapabilityList getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
Definition: SPIRVBaseInfo.cpp:116
llvm::MachineModuleInfo
This class contains meta information specific to a module.
Definition: MachineModuleInfo.h:74
llvm::pdb::Int8
@ Int8
Definition: PDBTypes.h:397
llvm::SPIRV::ModuleAnalysisInfo::SrcLangVersion
unsigned SrcLangVersion
Definition: SPIRVModuleAnalysis.h:129
SPIRVUtils.h
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::SPIRV::MB_Annotations
@ MB_Annotations
Definition: SPIRVModuleAnalysis.h:39
llvm::SPIRV::ModuleAnalysisInfo::RegisterAliasTable
RegisterAliasMapTy RegisterAliasTable
Definition: SPIRVModuleAnalysis.h:146
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:396
llvm::SPIRV::Requirements::MaxVer
const unsigned MaxVer
Definition: SPIRVModuleAnalysis.h:50
llvm::SPIRV::ModuleAnalysisInfo::MBBsToSkip
DenseSet< MachineBasicBlock * > MBBsToSkip
Definition: SPIRVModuleAnalysis.h:142
llvm::SPIRV::ModuleAnalysisInfo::getSkipEmission
bool getSkipEmission(const MachineInstr *MI)
Definition: SPIRVModuleAnalysis.h:163
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::SPIRV::MB_ExtFuncDecls
@ MB_ExtFuncDecls
Definition: SPIRVModuleAnalysis.h:41
llvm::TargetPassConfig
Target-Independent Code Generator Pass Configuration Options.
Definition: TargetPassConfig.h:84
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1292
SPIRVTargetMachine.h
llvm::SPIRV::ModuleAnalysisInfo::hasRegisterAlias
bool hasRegisterAlias(const MachineFunction *MF, Register Reg)
Definition: SPIRVModuleAnalysis.h:177
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::SPIRV::ModuleAnalysisInfo::ExtInstSetMap
DenseMap< unsigned, Register > ExtInstSetMap
Definition: SPIRVModuleAnalysis.h:132
llvm::cl::opt< bool >
llvm::MipsISD::Ext
@ Ext
Definition: MipsISelLowering.h:159
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::getStringImm
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
Definition: SPIRVUtils.cpp:74
llvm::SPIRVModuleAnalysis::ID
static char ID
Definition: SPIRVModuleAnalysis.h:198
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::omp::Kernel
Function * Kernel
Summary of a kernel (=entry point for target offloading).
Definition: OpenMPOpt.h:21
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1754
llvm::MachineModuleInfoWrapperPass
Definition: MachineModuleInfo.h:214
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
llvm::SPIRV::ModuleAnalysisInfo::GlobalVarList
SmallVector< MachineInstr *, 4 > GlobalVarList
Definition: SPIRVModuleAnalysis.h:134
llvm::SPIRV::RequirementHandler::addCapabilities
void addCapabilities(const CapabilityList &ToAdd)
llvm::SPIRV::ModuleAnalysisInfo::FuncNameMap
StringMap< Register > FuncNameMap
Definition: SPIRVModuleAnalysis.h:136
llvm::SPIRV::RequirementHandler::addCapability
void addCapability(Capability::Capability ToAdd)
Definition: SPIRVModuleAnalysis.h:93
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
llvm::SPIRV::Requirements::IsSatisfiable
const bool IsSatisfiable
Definition: SPIRVModuleAnalysis.h:46
llvm::SPIRV::ModuleAnalysisInfo::MS
InstrList MS[NUM_MODULE_SECTIONS]
Definition: SPIRVModuleAnalysis.h:150
TargetPassConfig.h
SPIRV.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::SPIRV::RequirementHandler::clear
void clear()
Definition: SPIRVModuleAnalysis.h:75
llvm::SPIRVGlobalRegistry::buildDepsGraph
void buildDepsGraph(std::vector< SPIRV::DTSortableEntry * > &Graph, MachineModuleInfo *MMI=nullptr)
Definition: SPIRVGlobalRegistry.h:99
llvm::SPIRV::MB_DebugNames
@ MB_DebugNames
Definition: SPIRVModuleAnalysis.h:37
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
MachineModuleInfo.h
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::SPIRV::RequirementHandler::addExtension
void addExtension(Extension::Extension ToAdd)
Definition: SPIRVModuleAnalysis.h:97
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MDNode
Metadata node.
Definition: Metadata.h:944
llvm::SPIRV::Requirements::MinVer
const unsigned MinVer
Definition: SPIRVModuleAnalysis.h:49
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::SPIRVInstrInfo
Definition: SPIRVInstrInfo.h:24
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::contains
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:185
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::SPIRVModuleAnalysis
Definition: SPIRVModuleAnalysis.h:197
llvm::SPIRV::ModuleAnalysisInfo::getRegisterAlias
Register getRegisterAlias(const MachineFunction *MF, Register Reg)
Definition: SPIRVModuleAnalysis.h:170
llvm::SPIRV::RequirementHandler::isCapabilityAvailable
bool isCapabilityAvailable(Capability::Capability Cap) const
Definition: SPIRVModuleAnalysis.h:111
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::SPIRVTargetMachine
Definition: SPIRVTargetMachine.h:20
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::cl::Optional
@ Optional
Definition: CommandLine.h:116
llvm::getSymbolicOperandMaxVersion
uint32_t getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
Definition: SPIRVBaseInfo.cpp:104
llvm::SPIRV::RequirementHandler::addAvailableCaps
void addAvailableCaps(const CapabilityList &ToAdd)
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::MachineModuleInfo::getMachineFunction
MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
Definition: MachineModuleInfo.cpp:103
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:348
llvm::BitWidth
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:147
llvm::MachineBasicBlock::front
MachineInstr & front()
Definition: MachineBasicBlock.h:284
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:614
llvm::SPIRV::ModuleAnalysisInfo::Addr
AddressingModel::AddressingModel Addr
Definition: SPIRVModuleAnalysis.h:127
llvm::codeview::ModifierOptions::Const
@ Const
llvm::getSymbolicOperandMnemonic
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
Definition: SPIRVBaseInfo.cpp:57
llvm::SPIRV::RequirementHandler::checkSatisfiable
void checkSatisfiable(const SPIRVSubtarget &ST) const
llvm::SPIRV::MB_EntryPoints
@ MB_EntryPoints
Definition: SPIRVModuleAnalysis.h:35
llvm::pdb::PDB_SymType::Exe
@ Exe
llvm::Register::isValid
bool isValid() const
Definition: Register.h:126
N
#define N
llvm::getFunctionGlobalIdentifier
std::string getFunctionGlobalIdentifier(const Function *F)
Definition: SPIRVUtils.cpp:358
llvm::SPIRVModuleAnalysis::runOnModule
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
Definition: SPIRVModuleAnalysis.cpp:1009
llvm::SPIRV::ModuleAnalysisInfo::Mem
MemoryModel::MemoryModel Mem
Definition: SPIRVModuleAnalysis.h:126
llvm::buildOpDecorate
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Definition: SPIRVUtils.cpp:117
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::SPIRV::Requirements
Definition: SPIRVModuleAnalysis.h:45
llvm::omp::RTLDependInfoFields::Flags
@ Flags
llvm::SPIRV::ModuleAnalysisInfo::SrcLang
SourceLanguage::SourceLanguage SrcLang
Definition: SPIRVModuleAnalysis.h:128
llvm::SPIRV::RequirementHandler::getAndAddRequirements
void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category, uint32_t i, const SPIRVSubtarget &ST)
llvm::SPIRV::RequirementHandler::addRequirements
void addRequirements(const Requirements &Req)
llvm::cl::desc
Definition: CommandLine.h:413
llvm::SPIRV::ModuleAnalysisInfo::InstrsToDelete
DenseSet< MachineInstr * > InstrsToDelete
Definition: SPIRVModuleAnalysis.h:139
llvm::SPIRVModuleAnalysis::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: SPIRVModuleAnalysis.cpp:1004
llvm::MDOperand
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:773
processSwitches
static void processSwitches(MachineFunction &MF, SPIRVGlobalRegistry *GR, MachineIRBuilder MIB)
Definition: SPIRVPreLegalizer.cpp:390
llvm::SPIRV::ModuleAnalysisInfo::Reqs
RequirementHandler Reqs
Definition: SPIRVModuleAnalysis.h:125
llvm::SmallVectorImpl::insert
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:809