xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp (revision e6bfd18d21b225af6a0ed67ceeaf1293b7b9eba5)
1 //===-- SPIRVInstPrinter.cpp - Output SPIR-V MCInsts as ASM -----*- 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 // This class prints a SPIR-V MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "SPIRVInstPrinter.h"
14 #include "SPIRV.h"
15 #include "SPIRVBaseInfo.h"
16 #include "llvm/CodeGen/Register.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/FormattedStream.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "asm-printer"
29 
30 // Include the auto-generated portion of the assembly writer.
31 #include "SPIRVGenAsmWriter.inc"
32 
33 void SPIRVInstPrinter::printRemainingVariableOps(const MCInst *MI,
34                                                  unsigned StartIndex,
35                                                  raw_ostream &O,
36                                                  bool SkipFirstSpace,
37                                                  bool SkipImmediates) {
38   const unsigned NumOps = MI->getNumOperands();
39   for (unsigned i = StartIndex; i < NumOps; ++i) {
40     if (!SkipImmediates || !MI->getOperand(i).isImm()) {
41       if (!SkipFirstSpace || i != StartIndex)
42         O << ' ';
43       printOperand(MI, i, O);
44     }
45   }
46 }
47 
48 void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
49                                              unsigned StartIndex,
50                                              raw_ostream &O) {
51   O << ' ';
52   if (MI->getNumOperands() - StartIndex == 2) { // Handle 64 bit literals.
53     uint64_t Imm = MI->getOperand(StartIndex).getImm();
54     Imm |= (MI->getOperand(StartIndex + 1).getImm() << 32);
55     O << Imm;
56   } else {
57     printRemainingVariableOps(MI, StartIndex, O, true, false);
58   }
59 }
60 
61 void SPIRVInstPrinter::recordOpExtInstImport(const MCInst *MI) {
62   // TODO: insert {Reg, Set} into ExtInstSetIDs map.
63 }
64 
65 void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address,
66                                  StringRef Annot, const MCSubtargetInfo &STI,
67                                  raw_ostream &OS) {
68   const unsigned OpCode = MI->getOpcode();
69   printInstruction(MI, Address, OS);
70 
71   if (OpCode == SPIRV::OpDecorate) {
72     printOpDecorate(MI, OS);
73   } else if (OpCode == SPIRV::OpExtInstImport) {
74     recordOpExtInstImport(MI);
75   } else if (OpCode == SPIRV::OpExtInst) {
76     printOpExtInst(MI, OS);
77   } else {
78     // Print any extra operands for variadic instructions.
79     MCInstrDesc MCDesc = MII.get(OpCode);
80     if (MCDesc.isVariadic()) {
81       const unsigned NumFixedOps = MCDesc.getNumOperands();
82       const unsigned LastFixedIndex = NumFixedOps - 1;
83       const int FirstVariableIndex = NumFixedOps;
84       if (NumFixedOps > 0 &&
85           MCDesc.OpInfo[LastFixedIndex].OperandType == MCOI::OPERAND_UNKNOWN) {
86         // For instructions where a custom type (not reg or immediate) comes as
87         // the last operand before the variable_ops. This is usually a StringImm
88         // operand, but there are a few other cases.
89         switch (OpCode) {
90         case SPIRV::OpTypeImage:
91           OS << ' ';
92           printAccessQualifier(MI, FirstVariableIndex, OS);
93           break;
94         case SPIRV::OpVariable:
95           OS << ' ';
96           printOperand(MI, FirstVariableIndex, OS);
97           break;
98         case SPIRV::OpEntryPoint: {
99           // Print the interface ID operands, skipping the name's string
100           // literal.
101           printRemainingVariableOps(MI, NumFixedOps, OS, false, true);
102           break;
103         }
104         case SPIRV::OpExecutionMode:
105         case SPIRV::OpExecutionModeId:
106         case SPIRV::OpLoopMerge: {
107           // Print any literals after the OPERAND_UNKNOWN argument normally.
108           printRemainingVariableOps(MI, NumFixedOps, OS);
109           break;
110         }
111         default:
112           break; // printStringImm has already been handled
113         }
114       } else {
115         // For instructions with no fixed ops or a reg/immediate as the final
116         // fixed operand, we can usually print the rest with "printOperand", but
117         // check for a few cases with custom types first.
118         switch (OpCode) {
119         case SPIRV::OpLoad:
120         case SPIRV::OpStore:
121           OS << ' ';
122           printMemoryOperand(MI, FirstVariableIndex, OS);
123           printRemainingVariableOps(MI, FirstVariableIndex + 1, OS);
124           break;
125         case SPIRV::OpImageSampleImplicitLod:
126         case SPIRV::OpImageSampleDrefImplicitLod:
127         case SPIRV::OpImageSampleProjImplicitLod:
128         case SPIRV::OpImageSampleProjDrefImplicitLod:
129         case SPIRV::OpImageFetch:
130         case SPIRV::OpImageGather:
131         case SPIRV::OpImageDrefGather:
132         case SPIRV::OpImageRead:
133         case SPIRV::OpImageWrite:
134         case SPIRV::OpImageSparseSampleImplicitLod:
135         case SPIRV::OpImageSparseSampleDrefImplicitLod:
136         case SPIRV::OpImageSparseSampleProjImplicitLod:
137         case SPIRV::OpImageSparseSampleProjDrefImplicitLod:
138         case SPIRV::OpImageSparseFetch:
139         case SPIRV::OpImageSparseGather:
140         case SPIRV::OpImageSparseDrefGather:
141         case SPIRV::OpImageSparseRead:
142         case SPIRV::OpImageSampleFootprintNV:
143           OS << ' ';
144           printImageOperand(MI, FirstVariableIndex, OS);
145           printRemainingVariableOps(MI, NumFixedOps + 1, OS);
146           break;
147         case SPIRV::OpCopyMemory:
148         case SPIRV::OpCopyMemorySized: {
149           const unsigned NumOps = MI->getNumOperands();
150           for (unsigned i = NumFixedOps; i < NumOps; ++i) {
151             OS << ' ';
152             printMemoryOperand(MI, i, OS);
153             if (MI->getOperand(i).getImm() &
154                 static_cast<unsigned>(SPIRV::MemoryOperand::Aligned)) {
155               assert(i + 1 < NumOps && "Missing alignment operand");
156               OS << ' ';
157               printOperand(MI, i + 1, OS);
158               i += 1;
159             }
160           }
161           break;
162         }
163         case SPIRV::OpConstantI:
164         case SPIRV::OpConstantF:
165           printOpConstantVarOps(MI, NumFixedOps, OS);
166           break;
167         default:
168           printRemainingVariableOps(MI, NumFixedOps, OS);
169           break;
170         }
171       }
172     }
173   }
174 
175   printAnnotation(OS, Annot);
176 }
177 
178 void SPIRVInstPrinter::printOpExtInst(const MCInst *MI, raw_ostream &O) {
179   // The fixed operands have already been printed, so just need to decide what
180   // type of ExtInst operands to print based on the instruction set and number.
181   MCInstrDesc MCDesc = MII.get(MI->getOpcode());
182   unsigned NumFixedOps = MCDesc.getNumOperands();
183   const auto NumOps = MI->getNumOperands();
184   if (NumOps == NumFixedOps)
185     return;
186 
187   O << ' ';
188 
189   // TODO: implement special printing for OpenCLExtInst::vstor*.
190   printRemainingVariableOps(MI, NumFixedOps, O, true);
191 }
192 
193 void SPIRVInstPrinter::printOpDecorate(const MCInst *MI, raw_ostream &O) {
194   // The fixed operands have already been printed, so just need to decide what
195   // type of decoration operands to print based on the Decoration type.
196   MCInstrDesc MCDesc = MII.get(MI->getOpcode());
197   unsigned NumFixedOps = MCDesc.getNumOperands();
198 
199   if (NumFixedOps != MI->getNumOperands()) {
200     auto DecOp = MI->getOperand(NumFixedOps - 1);
201     auto Dec = static_cast<SPIRV::Decoration>(DecOp.getImm());
202 
203     O << ' ';
204 
205     switch (Dec) {
206     case SPIRV::Decoration::BuiltIn:
207       printBuiltIn(MI, NumFixedOps, O);
208       break;
209     case SPIRV::Decoration::UniformId:
210       printScope(MI, NumFixedOps, O);
211       break;
212     case SPIRV::Decoration::FuncParamAttr:
213       printFunctionParameterAttribute(MI, NumFixedOps, O);
214       break;
215     case SPIRV::Decoration::FPRoundingMode:
216       printFPRoundingMode(MI, NumFixedOps, O);
217       break;
218     case SPIRV::Decoration::FPFastMathMode:
219       printFPFastMathMode(MI, NumFixedOps, O);
220       break;
221     case SPIRV::Decoration::LinkageAttributes:
222     case SPIRV::Decoration::UserSemantic:
223       printStringImm(MI, NumFixedOps, O);
224       break;
225     default:
226       printRemainingVariableOps(MI, NumFixedOps, O, true);
227       break;
228     }
229   }
230 }
231 
232 static void printExpr(const MCExpr *Expr, raw_ostream &O) {
233 #ifndef NDEBUG
234   const MCSymbolRefExpr *SRE;
235 
236   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
237     SRE = cast<MCSymbolRefExpr>(BE->getLHS());
238   else
239     SRE = cast<MCSymbolRefExpr>(Expr);
240 
241   MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
242 
243   assert(Kind == MCSymbolRefExpr::VK_None);
244 #endif
245   O << *Expr;
246 }
247 
248 void SPIRVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
249                                     raw_ostream &O, const char *Modifier) {
250   assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
251   if (OpNo < MI->getNumOperands()) {
252     const MCOperand &Op = MI->getOperand(OpNo);
253     if (Op.isReg())
254       O << '%' << (Register::virtReg2Index(Op.getReg()) + 1);
255     else if (Op.isImm())
256       O << formatImm((int64_t)Op.getImm());
257     else if (Op.isDFPImm())
258       O << formatImm((double)Op.getDFPImm());
259     else if (Op.isExpr())
260       printExpr(Op.getExpr(), O);
261     else
262       llvm_unreachable("Unexpected operand type");
263   }
264 }
265 
266 void SPIRVInstPrinter::printStringImm(const MCInst *MI, unsigned OpNo,
267                                       raw_ostream &O) {
268   const unsigned NumOps = MI->getNumOperands();
269   unsigned StrStartIndex = OpNo;
270   while (StrStartIndex < NumOps) {
271     if (MI->getOperand(StrStartIndex).isReg())
272       break;
273 
274     std::string Str = getSPIRVStringOperand(*MI, OpNo);
275     if (StrStartIndex != OpNo)
276       O << ' '; // Add a space if we're starting a new string/argument.
277     O << '"';
278     for (char c : Str) {
279       if (c == '"')
280         O.write('\\'); // Escape " characters (might break for complex UTF-8).
281       O.write(c);
282     }
283     O << '"';
284 
285     unsigned numOpsInString = (Str.size() / 4) + 1;
286     StrStartIndex += numOpsInString;
287 
288     // Check for final Op of "OpDecorate %x %stringImm %linkageAttribute".
289     if (MI->getOpcode() == SPIRV::OpDecorate &&
290         MI->getOperand(1).getImm() ==
291             static_cast<unsigned>(SPIRV::Decoration::LinkageAttributes)) {
292       O << ' ';
293       printLinkageType(MI, StrStartIndex, O);
294       break;
295     }
296   }
297 }
298 
299 void SPIRVInstPrinter::printExtInst(const MCInst *MI, unsigned OpNo,
300                                     raw_ostream &O) {
301   llvm_unreachable("Unimplemented printExtInst");
302 }
303 
304 void SPIRVInstPrinter::printCapability(const MCInst *MI, unsigned OpNo,
305                                        raw_ostream &O) {
306   if (OpNo < MI->getNumOperands()) {
307     SPIRV::Capability e =
308         static_cast<SPIRV::Capability>(MI->getOperand(OpNo).getImm());
309     O << SPIRV::getCapabilityName(e);
310   }
311 }
312 
313 void SPIRVInstPrinter::printSourceLanguage(const MCInst *MI, unsigned OpNo,
314                                            raw_ostream &O) {
315   if (OpNo < MI->getNumOperands()) {
316     SPIRV::SourceLanguage e =
317         static_cast<SPIRV::SourceLanguage>(MI->getOperand(OpNo).getImm());
318     O << SPIRV::getSourceLanguageName(e);
319   }
320 }
321 
322 void SPIRVInstPrinter::printExecutionModel(const MCInst *MI, unsigned OpNo,
323                                            raw_ostream &O) {
324   if (OpNo < MI->getNumOperands()) {
325     SPIRV::ExecutionModel e =
326         static_cast<SPIRV::ExecutionModel>(MI->getOperand(OpNo).getImm());
327     O << SPIRV::getExecutionModelName(e);
328   }
329 }
330 
331 void SPIRVInstPrinter::printAddressingModel(const MCInst *MI, unsigned OpNo,
332                                             raw_ostream &O) {
333   if (OpNo < MI->getNumOperands()) {
334     SPIRV::AddressingModel e =
335         static_cast<SPIRV::AddressingModel>(MI->getOperand(OpNo).getImm());
336     O << SPIRV::getAddressingModelName(e);
337   }
338 }
339 
340 void SPIRVInstPrinter::printMemoryModel(const MCInst *MI, unsigned OpNo,
341                                         raw_ostream &O) {
342   if (OpNo < MI->getNumOperands()) {
343     SPIRV::MemoryModel e =
344         static_cast<SPIRV::MemoryModel>(MI->getOperand(OpNo).getImm());
345     O << SPIRV::getMemoryModelName(e);
346   }
347 }
348 
349 void SPIRVInstPrinter::printExecutionMode(const MCInst *MI, unsigned OpNo,
350                                           raw_ostream &O) {
351   if (OpNo < MI->getNumOperands()) {
352     SPIRV::ExecutionMode e =
353         static_cast<SPIRV::ExecutionMode>(MI->getOperand(OpNo).getImm());
354     O << SPIRV::getExecutionModeName(e);
355   }
356 }
357 
358 void SPIRVInstPrinter::printStorageClass(const MCInst *MI, unsigned OpNo,
359                                          raw_ostream &O) {
360   if (OpNo < MI->getNumOperands()) {
361     SPIRV::StorageClass e =
362         static_cast<SPIRV::StorageClass>(MI->getOperand(OpNo).getImm());
363     O << SPIRV::getStorageClassName(e);
364   }
365 }
366 
367 void SPIRVInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
368                                 raw_ostream &O) {
369   if (OpNo < MI->getNumOperands()) {
370     SPIRV::Dim e = static_cast<SPIRV::Dim>(MI->getOperand(OpNo).getImm());
371     O << SPIRV::getDimName(e);
372   }
373 }
374 
375 void SPIRVInstPrinter::printSamplerAddressingMode(const MCInst *MI,
376                                                   unsigned OpNo,
377                                                   raw_ostream &O) {
378   if (OpNo < MI->getNumOperands()) {
379     SPIRV::SamplerAddressingMode e = static_cast<SPIRV::SamplerAddressingMode>(
380         MI->getOperand(OpNo).getImm());
381     O << SPIRV::getSamplerAddressingModeName(e);
382   }
383 }
384 
385 void SPIRVInstPrinter::printSamplerFilterMode(const MCInst *MI, unsigned OpNo,
386                                               raw_ostream &O) {
387   if (OpNo < MI->getNumOperands()) {
388     SPIRV::SamplerFilterMode e =
389         static_cast<SPIRV::SamplerFilterMode>(MI->getOperand(OpNo).getImm());
390     O << SPIRV::getSamplerFilterModeName(e);
391   }
392 }
393 
394 void SPIRVInstPrinter::printImageFormat(const MCInst *MI, unsigned OpNo,
395                                         raw_ostream &O) {
396   if (OpNo < MI->getNumOperands()) {
397     SPIRV::ImageFormat e =
398         static_cast<SPIRV::ImageFormat>(MI->getOperand(OpNo).getImm());
399     O << SPIRV::getImageFormatName(e);
400   }
401 }
402 
403 void SPIRVInstPrinter::printImageChannelOrder(const MCInst *MI, unsigned OpNo,
404                                               raw_ostream &O) {
405   if (OpNo < MI->getNumOperands()) {
406     SPIRV::ImageChannelOrder e =
407         static_cast<SPIRV::ImageChannelOrder>(MI->getOperand(OpNo).getImm());
408     O << SPIRV::getImageChannelOrderName(e);
409   }
410 }
411 
412 void SPIRVInstPrinter::printImageChannelDataType(const MCInst *MI,
413                                                  unsigned OpNo,
414                                                  raw_ostream &O) {
415   if (OpNo < MI->getNumOperands()) {
416     SPIRV::ImageChannelDataType e =
417         static_cast<SPIRV::ImageChannelDataType>(MI->getOperand(OpNo).getImm());
418     O << SPIRV::getImageChannelDataTypeName(e);
419   }
420 }
421 
422 void SPIRVInstPrinter::printImageOperand(const MCInst *MI, unsigned OpNo,
423                                          raw_ostream &O) {
424   if (OpNo < MI->getNumOperands()) {
425     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
426     O << SPIRV::getImageOperandName(e);
427   }
428 }
429 
430 void SPIRVInstPrinter::printFPFastMathMode(const MCInst *MI, unsigned OpNo,
431                                            raw_ostream &O) {
432   if (OpNo < MI->getNumOperands()) {
433     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
434     O << SPIRV::getFPFastMathModeName(e);
435   }
436 }
437 
438 void SPIRVInstPrinter::printFPRoundingMode(const MCInst *MI, unsigned OpNo,
439                                            raw_ostream &O) {
440   if (OpNo < MI->getNumOperands()) {
441     SPIRV::FPRoundingMode e =
442         static_cast<SPIRV::FPRoundingMode>(MI->getOperand(OpNo).getImm());
443     O << SPIRV::getFPRoundingModeName(e);
444   }
445 }
446 
447 void SPIRVInstPrinter::printLinkageType(const MCInst *MI, unsigned OpNo,
448                                         raw_ostream &O) {
449   if (OpNo < MI->getNumOperands()) {
450     SPIRV::LinkageType e =
451         static_cast<SPIRV::LinkageType>(MI->getOperand(OpNo).getImm());
452     O << SPIRV::getLinkageTypeName(e);
453   }
454 }
455 
456 void SPIRVInstPrinter::printAccessQualifier(const MCInst *MI, unsigned OpNo,
457                                             raw_ostream &O) {
458   if (OpNo < MI->getNumOperands()) {
459     SPIRV::AccessQualifier e =
460         static_cast<SPIRV::AccessQualifier>(MI->getOperand(OpNo).getImm());
461     O << SPIRV::getAccessQualifierName(e);
462   }
463 }
464 
465 void SPIRVInstPrinter::printFunctionParameterAttribute(const MCInst *MI,
466                                                        unsigned OpNo,
467                                                        raw_ostream &O) {
468   if (OpNo < MI->getNumOperands()) {
469     SPIRV::FunctionParameterAttribute e =
470         static_cast<SPIRV::FunctionParameterAttribute>(
471             MI->getOperand(OpNo).getImm());
472     O << SPIRV::getFunctionParameterAttributeName(e);
473   }
474 }
475 
476 void SPIRVInstPrinter::printDecoration(const MCInst *MI, unsigned OpNo,
477                                        raw_ostream &O) {
478   if (OpNo < MI->getNumOperands()) {
479     SPIRV::Decoration e =
480         static_cast<SPIRV::Decoration>(MI->getOperand(OpNo).getImm());
481     O << SPIRV::getDecorationName(e);
482   }
483 }
484 
485 void SPIRVInstPrinter::printBuiltIn(const MCInst *MI, unsigned OpNo,
486                                     raw_ostream &O) {
487   if (OpNo < MI->getNumOperands()) {
488     SPIRV::BuiltIn e =
489         static_cast<SPIRV::BuiltIn>(MI->getOperand(OpNo).getImm());
490     O << SPIRV::getBuiltInName(e);
491   }
492 }
493 
494 void SPIRVInstPrinter::printSelectionControl(const MCInst *MI, unsigned OpNo,
495                                              raw_ostream &O) {
496   if (OpNo < MI->getNumOperands()) {
497     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
498     O << SPIRV::getSelectionControlName(e);
499   }
500 }
501 
502 void SPIRVInstPrinter::printLoopControl(const MCInst *MI, unsigned OpNo,
503                                         raw_ostream &O) {
504   if (OpNo < MI->getNumOperands()) {
505     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
506     O << SPIRV::getLoopControlName(e);
507   }
508 }
509 
510 void SPIRVInstPrinter::printFunctionControl(const MCInst *MI, unsigned OpNo,
511                                             raw_ostream &O) {
512   if (OpNo < MI->getNumOperands()) {
513     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
514     O << SPIRV::getFunctionControlName(e);
515   }
516 }
517 
518 void SPIRVInstPrinter::printMemorySemantics(const MCInst *MI, unsigned OpNo,
519                                             raw_ostream &O) {
520   if (OpNo < MI->getNumOperands()) {
521     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
522     O << SPIRV::getMemorySemanticsName(e);
523   }
524 }
525 
526 void SPIRVInstPrinter::printMemoryOperand(const MCInst *MI, unsigned OpNo,
527                                           raw_ostream &O) {
528   if (OpNo < MI->getNumOperands()) {
529     unsigned e = static_cast<unsigned>(MI->getOperand(OpNo).getImm());
530     O << SPIRV::getMemoryOperandName(e);
531   }
532 }
533 
534 void SPIRVInstPrinter::printScope(const MCInst *MI, unsigned OpNo,
535                                   raw_ostream &O) {
536   if (OpNo < MI->getNumOperands()) {
537     SPIRV::Scope e = static_cast<SPIRV::Scope>(MI->getOperand(OpNo).getImm());
538     O << SPIRV::getScopeName(e);
539   }
540 }
541 
542 void SPIRVInstPrinter::printGroupOperation(const MCInst *MI, unsigned OpNo,
543                                            raw_ostream &O) {
544   if (OpNo < MI->getNumOperands()) {
545     SPIRV::GroupOperation e =
546         static_cast<SPIRV::GroupOperation>(MI->getOperand(OpNo).getImm());
547     O << SPIRV::getGroupOperationName(e);
548   }
549 }
550 
551 void SPIRVInstPrinter::printKernelEnqueueFlags(const MCInst *MI, unsigned OpNo,
552                                                raw_ostream &O) {
553   if (OpNo < MI->getNumOperands()) {
554     SPIRV::KernelEnqueueFlags e =
555         static_cast<SPIRV::KernelEnqueueFlags>(MI->getOperand(OpNo).getImm());
556     O << SPIRV::getKernelEnqueueFlagsName(e);
557   }
558 }
559 
560 void SPIRVInstPrinter::printKernelProfilingInfo(const MCInst *MI, unsigned OpNo,
561                                                 raw_ostream &O) {
562   if (OpNo < MI->getNumOperands()) {
563     SPIRV::KernelProfilingInfo e =
564         static_cast<SPIRV::KernelProfilingInfo>(MI->getOperand(OpNo).getImm());
565     O << SPIRV::getKernelProfilingInfoName(e);
566   }
567 }
568