LLVM: lib/Target/SPIRV/SPIRVAsmPrinter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
40
41using namespace llvm;
42
43#define DEBUG_TYPE "asm-printer"
44
45namespace {
46class SPIRVAsmPrinter : public AsmPrinter {
47 unsigned NLabels = 0;
49
50public:
52 std::unique_ptr Streamer)
53 : AsmPrinter(TM, std::move(Streamer), ID), ModuleSectionsEmitted(false),
54 ST(nullptr), TII(nullptr), MAI(nullptr) {}
55 static char ID;
56 bool ModuleSectionsEmitted;
59
60 StringRef getPassName() const override { return "SPIRV Assembly Printer"; }
62 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
63 const char *ExtraCode, raw_ostream &O) override;
64
65 void outputMCInst(MCInst &Inst);
68 void outputGlobalRequirements();
69 void outputEntryPoints();
70 void outputDebugSourceAndStrings(const Module &M);
71 void outputOpExtInstImports(const Module &M);
72 void outputOpMemoryModel();
73 void outputOpFunctionEnd();
74 void outputExtFuncDecls();
76 SPIRV::ExecutionMode::ExecutionMode EM,
77 unsigned ExpectMDOps, int64_t DefVal);
78 void outputExecutionModeFromNumthreadsAttribute(
80 SPIRV::ExecutionMode::ExecutionMode EM);
81 void outputExecutionModeFromEnableMaximalReconvergenceAttr(
83 void outputExecutionMode(const Module &M);
84 void outputAnnotations(const Module &M);
85 void outputModuleSections();
86 void outputFPFastMathDefaultInfo();
87 bool isHidden() {
88 return MF->getFunction()
90 .isValid();
91 }
92
93 void emitInstruction(const MachineInstr *MI) override;
94 void emitFunctionEntryLabel() override {}
95 void emitFunctionHeader() override;
96 void emitFunctionBodyStart() override {}
97 void emitFunctionBodyEnd() override;
100 void emitGlobalVariable(const GlobalVariable *GV) override {}
102 void emitEndOfAsmFile(Module &M) override;
103 bool doInitialization(Module &M) override;
104
105 void getAnalysisUsage(AnalysisUsage &AU) const override;
107
108protected:
109 void cleanUp(Module &M);
110};
111}
112
113void SPIRVAsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
117}
118
119
120void SPIRVAsmPrinter::emitEndOfAsmFile(Module &M) {
121 if (ModuleSectionsEmitted == false) {
122 outputModuleSections();
123 ModuleSectionsEmitted = true;
124 }
125
126 ST = static_cast<const SPIRVTargetMachine &>(TM).getSubtargetImpl();
128 uint32_t Major = SPIRVVersion.getMajor();
129 uint32_t Minor = SPIRVVersion.getMinor().value_or(0);
130
131
132 unsigned Bound = 2 * (ST->getBound() + 1) + NLabels;
133 if (MCAssembler *Asm = OutStreamer->getAssemblerPtr())
134 static_cast<SPIRVObjectWriter &>(Asm->getWriter())
135 .setBuildVersion(Major, Minor, Bound);
136
137 cleanUp(M);
138}
139
140
141
142void SPIRVAsmPrinter::cleanUp(Module &M) {
143
144 for (StringRef GVName :
145 {"llvm.global_ctors", "llvm.global_dtors", "llvm.used"}) {
146 if (GlobalVariable *GV = M.getNamedGlobal(GVName))
147 GV->setName("");
148 }
149}
150
151void SPIRVAsmPrinter::emitFunctionHeader() {
152 if (ModuleSectionsEmitted == false) {
153 outputModuleSections();
154 ModuleSectionsEmitted = true;
155 }
156
157 ST = &MF->getSubtarget();
159 const Function &F = MF->getFunction();
160
161 if (isVerbose() && !isHidden()) {
162 OutStreamer->getCommentOS()
163 << "-- Begin function "
165 }
166
167 auto Section = getObjFileLowering().SectionForGlobal(&F, TM);
168 MF->setSection(Section);
169}
170
171void SPIRVAsmPrinter::outputOpFunctionEnd() {
172 MCInst FunctionEndInst;
173 FunctionEndInst.setOpcode(SPIRV::OpFunctionEnd);
174 outputMCInst(FunctionEndInst);
175}
176
177void SPIRVAsmPrinter::emitFunctionBodyEnd() {
178 if (!isHidden())
179 outputOpFunctionEnd();
180}
181
182void SPIRVAsmPrinter::emitOpLabel(const MachineBasicBlock &MBB) {
183
184 if (isHidden())
185 return;
186
187 MCInst LabelInst;
188 LabelInst.setOpcode(SPIRV::OpLabel);
190 outputMCInst(LabelInst);
191 ++NLabels;
193}
194
195void SPIRVAsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
196
198 return;
199
200
201
202 if (MBB.getNumber() == MF->front().getNumber()) {
203 for (const MachineInstr &MI : MBB)
204 if (MI.getOpcode() == SPIRV::OpFunction)
205 return;
206
208 }
209 emitOpLabel(MBB);
210}
211
212void SPIRVAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
213 raw_ostream &O) {
214 const MachineOperand &MO = MI->getOperand(OpNum);
215
219 break;
220
223 break;
224
227 break;
228
231 break;
232
235 break;
236
240 break;
241 }
242
245 break;
246
249 default:
251 }
252}
253
254bool SPIRVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
255 const char *ExtraCode, raw_ostream &O) {
256 if (ExtraCode && ExtraCode[0])
257 return true;
258
260 return false;
261}
262
265 return TII->isHeaderInstr(*MI) || MI->getOpcode() == SPIRV::OpFunction ||
266 MI->getOpcode() == SPIRV::OpFunctionParameter;
267}
268
269void SPIRVAsmPrinter::outputMCInst(MCInst &Inst) {
270 OutStreamer->emitInstruction(Inst, *OutContext.getSubtargetInfo());
271}
272
273void SPIRVAsmPrinter::outputInstruction(const MachineInstr *MI) {
274 SPIRVMCInstLower MCInstLowering;
275 MCInst TmpInst;
276 MCInstLowering.lower(MI, TmpInst, MAI);
277 outputMCInst(TmpInst);
278}
279
280void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) {
281 SPIRV_MC::verifyInstructionPredicates(MI->getOpcode(),
282 getSubtargetInfo().getFeatureBits());
283
284 if (!MAI->getSkipEmission(MI))
285 outputInstruction(MI);
286
287
288 const MachineInstr *NextMI = MI->getNextNode();
291 assert(MI->getParent()->getNumber() == MF->front().getNumber() &&
292 "OpFunction is not in the front MBB of MF");
293 emitOpLabel(*MI->getParent());
294 }
295}
296
297void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) {
298 for (const MachineInstr *MI : MAI->getMSInstrs(MSType))
299 outputInstruction(MI);
300}
301
302void SPIRVAsmPrinter::outputDebugSourceAndStrings(const Module &M) {
303
304 for (auto &Str : MAI->SrcExt) {
305 MCInst Inst;
306 Inst.setOpcode(SPIRV::OpSourceExtension);
308 outputMCInst(Inst);
309 }
310
311 outputModuleSection(SPIRV::MB_DebugStrings);
312
313 MCInst Inst;
318 outputMCInst(Inst);
319}
320
321void SPIRVAsmPrinter::outputOpExtInstImports(const Module &M) {
322 for (auto &CU : MAI->ExtInstSetMap) {
323 unsigned Set = CU.first;
324 MCRegister Reg = CU.second;
325 MCInst Inst;
326 Inst.setOpcode(SPIRV::OpExtInstImport);
329 static_castSPIRV::InstructionSet::InstructionSet\(Set)),
330 Inst);
331 outputMCInst(Inst);
332 }
333}
334
335void SPIRVAsmPrinter::outputOpMemoryModel() {
336 MCInst Inst;
337 Inst.setOpcode(SPIRV::OpMemoryModel);
340 outputMCInst(Inst);
341}
342
343
344
345
346
347void SPIRVAsmPrinter::outputEntryPoints() {
348
349 DenseSet InterfaceIDs;
350 for (const MachineInstr *MI : MAI->GlobalVarList) {
351 assert(MI->getOpcode() == SPIRV::OpVariable);
352 auto SC = static_castSPIRV::StorageClass::StorageClass\(
354
355
356
357
359 SC == SPIRV::StorageClass::Input || SC == SPIRV::StorageClass::Output) {
360 const MachineFunction *MF = MI->getMF();
361 MCRegister Reg = MAI->getRegisterAlias(MF, MI->getOperand(0).getReg());
363 }
364 }
365
366
367 for (const MachineInstr *MI : MAI->getMSInstrs(SPIRV::MB_EntryPoints)) {
368 SPIRVMCInstLower MCInstLowering;
369 MCInst TmpInst;
370 MCInstLowering.lower(MI, TmpInst, MAI);
371 for (MCRegister Reg : InterfaceIDs) {
374 }
375 outputMCInst(TmpInst);
376 }
377}
378
379
380void SPIRVAsmPrinter::outputGlobalRequirements() {
381
382 MAI->Reqs.checkSatisfiable(*ST);
383
384 for (const auto &Cap : MAI->Reqs.getMinimalCapabilities()) {
385 MCInst Inst;
386 Inst.setOpcode(SPIRV::OpCapability);
388 outputMCInst(Inst);
389 }
390
391
392 for (const auto &Ext : MAI->Reqs.getExtensions()) {
393 MCInst Inst;
394 Inst.setOpcode(SPIRV::OpExtension);
396 SPIRV::OperandCategory::ExtensionOperand, Ext),
397 Inst);
398 outputMCInst(Inst);
399 }
400
401}
402
403void SPIRVAsmPrinter::outputExtFuncDecls() {
404
405 auto I = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).begin(),
406 E = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).end();
408 outputInstruction(*I);
409 if ((I + 1) == E || (*(I + 1))->getOpcode() == SPIRV::OpFunction)
410 outputOpFunctionEnd();
411 }
412}
413
414
416 if (Ty->isHalfTy())
417 return 4;
418 if (Ty->isFloatTy())
419 return 5;
420 if (Ty->isDoubleTy())
421 return 6;
423 switch (IntTy->getIntegerBitWidth()) {
424 case 8:
425 return 0;
426 case 16:
427 return 1;
428 case 32:
429 return 2;
430 case 64:
431 return 3;
432 default:
434 }
435 }
437 Type *EleTy = VecTy->getElementType();
438 unsigned Size = VecTy->getNumElements();
440 }
442}
443
459
460void SPIRVAsmPrinter::outputExecutionModeFromMDNode(
461 MCRegister Reg, MDNode *Node, SPIRV::ExecutionMode::ExecutionMode EM,
462 unsigned ExpectMDOps, int64_t DefVal) {
463 MCInst Inst;
464 Inst.setOpcode(SPIRV::OpExecutionMode);
468
469
470 unsigned NodeSz = Node->getNumOperands();
471 if (ExpectMDOps > 0 && NodeSz < ExpectMDOps)
472 for (unsigned i = NodeSz; i < ExpectMDOps; ++i)
474 outputMCInst(Inst);
475}
476
477void SPIRVAsmPrinter::outputExecutionModeFromNumthreadsAttribute(
478 const MCRegister &Reg, const Attribute &Attr,
479 SPIRV::ExecutionMode::ExecutionMode EM) {
480 assert(Attr.isValid() && "Function called with an invalid attribute.");
481
482 MCInst Inst;
483 Inst.setOpcode(SPIRV::OpExecutionMode);
486
489 assert(NumThreads.size() == 3 && "invalid numthreads");
490 for (uint32_t i = 0; i < 3; ++i) {
491 uint32_t V;
492 [[maybe_unused]] bool Result = NumThreads[i].getAsInteger(10, V);
493 assert(!Result && "Failed to parse numthreads");
495 }
496
497 outputMCInst(Inst);
498}
499
500void SPIRVAsmPrinter::outputExecutionModeFromEnableMaximalReconvergenceAttr(
501 const MCRegister &Reg, const SPIRVSubtarget &ST) {
502 assert(ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence) &&
503 "Function called when SPV_KHR_maximal_reconvergence is not enabled.");
504
505 MCInst Inst;
506 Inst.setOpcode(SPIRV::OpExecutionMode);
508 unsigned EM =
509 static_cast<unsigned>(SPIRV::ExecutionMode::MaximallyReconvergesKHR);
511 outputMCInst(Inst);
512}
513
514void SPIRVAsmPrinter::outputExecutionMode(const Module &M) {
515 NamedMDNode *Node = M.getNamedMetadata("spirv.ExecutionMode");
516 if (Node) {
517 for (unsigned i = 0; i < Node->getNumOperands(); i++) {
518
519
520
521 if (ST->canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
522 const auto EM =
525 ->getValue())
526 ->getZExtValue();
527 if (EM == SPIRV::ExecutionMode::FPFastMathDefault ||
528 EM == SPIRV::ExecutionMode::ContractionOff ||
529 EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve)
530 continue;
531 }
532
533 MCInst Inst;
534 Inst.setOpcode(SPIRV::OpExecutionMode);
536 outputMCInst(Inst);
537 }
538 outputFPFastMathDefaultInfo();
539 }
540 for (auto FI = M.begin(), E = M.end(); FI != E; ++FI) {
542
543
545 continue;
546 MCRegister FReg = MAI->getFuncReg(&F);
548
549 if (Attribute Attr = F.getFnAttribute("hlsl.shader"); Attr.isValid()) {
550
551
552
553
555 MCInst Inst;
556 Inst.setOpcode(SPIRV::OpExecutionMode);
558 unsigned EM =
559 static_cast<unsigned>(SPIRV::ExecutionMode::OriginUpperLeft);
561 outputMCInst(Inst);
562 }
563 }
564 if (MDNode *Node = F.getMetadata("reqd_work_group_size"))
565 outputExecutionModeFromMDNode(FReg, Node, SPIRV::ExecutionMode::LocalSize,
566 3, 1);
567 if (Attribute Attr = F.getFnAttribute("hlsl.numthreads"); Attr.isValid())
568 outputExecutionModeFromNumthreadsAttribute(
569 FReg, Attr, SPIRV::ExecutionMode::LocalSize);
570 if (Attribute Attr = F.getFnAttribute("enable-maximal-reconvergence");
572 outputExecutionModeFromEnableMaximalReconvergenceAttr(FReg, *ST);
573 }
574 if (MDNode *Node = F.getMetadata("work_group_size_hint"))
575 outputExecutionModeFromMDNode(FReg, Node,
576 SPIRV::ExecutionMode::LocalSizeHint, 3, 1);
577 if (MDNode *Node = F.getMetadata("intel_reqd_sub_group_size"))
578 outputExecutionModeFromMDNode(FReg, Node,
579 SPIRV::ExecutionMode::SubgroupSize, 0, 0);
580 if (MDNode *Node = F.getMetadata("max_work_group_size")) {
581 if (ST->canUseExtension(SPIRV::Extension::SPV_INTEL_kernel_attributes))
582 outputExecutionModeFromMDNode(
583 FReg, Node, SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, 3, 1);
584 }
585 if (MDNode *Node = F.getMetadata("vec_type_hint")) {
586 MCInst Inst;
587 Inst.setOpcode(SPIRV::OpExecutionMode);
589 unsigned EM = static_cast<unsigned>(SPIRV::ExecutionMode::VecTypeHint);
593 outputMCInst(Inst);
594 }
595 if (ST->isKernel() && .getNamedMetadata("spirv.ExecutionMode") &&
596 .getNamedMetadata("opencl.enable.FP_CONTRACT")) {
597 if (ST->canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614 std::vector<const MachineInstr *> SPIRVFloatTypes;
615 const MachineInstr *ConstZeroInt32 = nullptr;
616 for (const MachineInstr *MI :
617 MAI->getMSInstrs(SPIRV::MB_TypeConstVars)) {
618 unsigned OpCode = MI->getOpcode();
619
620
621 if (OpCode == SPIRV::OpTypeFloat) {
622
623 const unsigned OpTypeFloatSize = MI->getOperand(1).getImm();
624 if (OpTypeFloatSize != 16 && OpTypeFloatSize != 32 &&
625 OpTypeFloatSize != 64) {
626 continue;
627 }
628 SPIRVFloatTypes.push_back(MI);
629 continue;
630 }
631
632 if (OpCode == SPIRV::OpConstantNull) {
633
634 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
635 MachineInstr *TypeMI = MRI.getVRegDef(MI->getOperand(1).getReg());
636 bool IsInt32Ty = TypeMI &&
637 TypeMI->getOpcode() == SPIRV::OpTypeInt &&
639 if (IsInt32Ty)
640 ConstZeroInt32 = MI;
641 }
642 }
643
644
645
646
647
648
649
650 for (const MachineInstr *MI : SPIRVFloatTypes) {
651 MCInst Inst;
652 Inst.setOpcode(SPIRV::OpExecutionModeId);
654 unsigned EM =
655 static_cast<unsigned>(SPIRV::ExecutionMode::FPFastMathDefault);
657 const MachineFunction *MF = MI->getMF();
658 MCRegister TypeReg =
659 MAI->getRegisterAlias(MF, MI->getOperand(0).getReg());
661 assert(ConstZeroInt32 && "There should be a constant zero.");
662 MCRegister ConstReg = MAI->getRegisterAlias(
665 outputMCInst(Inst);
666 }
667 } else {
668 MCInst Inst;
669 Inst.setOpcode(SPIRV::OpExecutionMode);
671 unsigned EM =
672 static_cast<unsigned>(SPIRV::ExecutionMode::ContractionOff);
674 outputMCInst(Inst);
675 }
676 }
677 }
678}
679
680void SPIRVAsmPrinter::outputAnnotations(const Module &M) {
681 outputModuleSection(SPIRV::MB_Annotations);
682
683 for (auto F = M.global_begin(), E = M.global_end(); F != E; ++F) {
684 if ((*F).getName() != "llvm.global.annotations")
685 continue;
686 const GlobalVariable *V = &(*F);
690
691
696 MCRegister Reg = MAI->getFuncReg(Func);
698 std::string DiagMsg;
699 raw_string_ostream OS(DiagMsg);
700 AnnotatedVar->print(OS);
701 DiagMsg = "Unknown function in llvm.global.annotations: " + DiagMsg;
703 }
704
705
706 GlobalVariable *GV =
708
709 StringRef AnnotationString;
710 [[maybe_unused]] bool Success =
712 assert(Success && "Failed to get annotation string");
713 MCInst Inst;
714 Inst.setOpcode(SPIRV::OpDecorate);
716 unsigned Dec = static_cast<unsigned>(SPIRV::Decoration::UserSemantic);
719 outputMCInst(Inst);
720 }
721 }
722}
723
724void SPIRVAsmPrinter::outputFPFastMathDefaultInfo() {
725
726
727 std::vector<const MachineInstr *> SPIRVFloatTypes;
728
729 std::unordered_map<int, const MachineInstr *> ConstMap;
730 for (const MachineInstr *MI : MAI->getMSInstrs(SPIRV::MB_TypeConstVars)) {
731
732 unsigned OpCode = MI->getOpcode();
733 if (OpCode != SPIRV::OpTypeFloat && OpCode != SPIRV::OpConstantI &&
734 OpCode != SPIRV::OpConstantNull)
735 continue;
736
737
738 if (OpCode == SPIRV::OpTypeFloat) {
739 SPIRVFloatTypes.push_back(MI);
740 } else {
741
742 const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
743 MachineInstr *TypeMI = MRI.getVRegDef(MI->getOperand(1).getReg());
744 if (!TypeMI || TypeMI->getOpcode() != SPIRV::OpTypeInt ||
746 continue;
747
748 if (OpCode == SPIRV::OpConstantI)
750 else
752 }
753 }
754
755 for (const auto &[Func, FPFastMathDefaultInfoVec] :
756 MAI->FPFastMathDefaultInfoMap) {
757 if (FPFastMathDefaultInfoVec.empty())
758 continue;
759
760 for (const MachineInstr *MI : SPIRVFloatTypes) {
761 unsigned OpTypeFloatSize = MI->getOperand(1).getImm();
764 assert(Index < FPFastMathDefaultInfoVec.size() &&
765 "Index out of bounds for FPFastMathDefaultInfoVec");
766 const auto &FPFastMathDefaultInfo = FPFastMathDefaultInfoVec[Index];
767 assert(FPFastMathDefaultInfo.Ty &&
768 "Expected target type for FPFastMathDefaultInfo");
769 assert(FPFastMathDefaultInfo.Ty->getScalarSizeInBits() ==
770 OpTypeFloatSize &&
771 "Mismatched float type size");
772 MCInst Inst;
773 Inst.setOpcode(SPIRV::OpExecutionModeId);
774 MCRegister FuncReg = MAI->getFuncReg(Func);
779 MCRegister TypeReg =
780 MAI->getRegisterAlias(MI->getMF(), MI->getOperand(0).getReg());
782 unsigned Flags = FPFastMathDefaultInfo.FastMathFlags;
783 if (FPFastMathDefaultInfo.ContractionOff &&
784 (Flags & SPIRV::FPFastMathMode::AllowContract))
786 "Conflicting FPFastMathFlags: ContractionOff and AllowContract");
787
788 if (FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
789 !(Flags &
790 (SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
791 SPIRV::FPFastMathMode::NSZ))) {
792 if (FPFastMathDefaultInfo.FPFastMathDefault)
794 "SignedZeroInfNanPreserve but at least one of "
795 "NotNaN/NotInf/NSZ is enabled.");
796 }
797
798
799 if (Flags == SPIRV::FPFastMathMode::None &&
800 !FPFastMathDefaultInfo.ContractionOff &&
801 !FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
802 !FPFastMathDefaultInfo.FPFastMathDefault)
803 continue;
804
805
809 "Mode operand of FPFastMathDefault execution mode.");
810 const MachineInstr *ConstMI = It->second;
811 MCRegister ConstReg = MAI->getRegisterAlias(
814 outputMCInst(Inst);
815 }
816 }
817}
818
819void SPIRVAsmPrinter::outputModuleSections() {
820 const Module *M = MMI->getModule();
821
822 ST = static_cast<const SPIRVTargetMachine &>(TM).getSubtargetImpl();
825 assert(ST && TII && MAI && M && "Module analysis is required");
826
827
828
829 outputGlobalRequirements();
830
831 outputOpExtInstImports(*M);
832
833 outputOpMemoryModel();
834
835 outputEntryPoints();
836
837
838 outputExecutionMode(*M);
839
840
841 outputDebugSourceAndStrings(*M);
842
843 outputModuleSection(SPIRV::MB_DebugNames);
844
845 outputModuleSection(SPIRV::MB_DebugModuleProcessed);
846
847
848 outputModuleSection(SPIRV::MB_AliasingInsts);
849
850 outputAnnotations(*M);
851
852
853
854
855 outputModuleSection(SPIRV::MB_TypeConstVars);
856
857 outputModuleSection(SPIRV::MB_NonSemanticGlobalDI);
858
859 outputExtFuncDecls();
860
861
862}
863
864bool SPIRVAsmPrinter::doInitialization(Module &M) {
865 ModuleSectionsEmitted = false;
866
868}
869
870char SPIRVAsmPrinter::ID = 0;
871
872INITIALIZE_PASS(SPIRVAsmPrinter, "spirv-asm-printer", "SPIRV Assembly Printer",
873 false, false)
874
875
877LLVMInitializeSPIRVAsmPrinter() {
881}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
This file defines the DenseMap class.
Machine Check Debug Module
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static void addOpsFromMDNode(MDNode *MDN, MCInst &Inst, SPIRV::ModuleAnalysisInfo *MAI)
Definition SPIRVAsmPrinter.cpp:444
static bool isFuncOrHeaderInstr(const MachineInstr *MI, const SPIRVInstrInfo *TII)
Definition SPIRVAsmPrinter.cpp:263
static unsigned encodeVecTypeHint(Type *Ty)
Definition SPIRVAsmPrinter.cpp:415
#define SPIRV_BACKEND_SERVICE_FUN_NAME
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class is intended to be used as a driving class for all asm writers.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM_ABI bool getValueAsBool() const
Return the attribute's value as a boolean.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
iterator find(const_arg_type_t< KeyT > Val)
Class to represent fixed width SIMD vectors.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
Class to represent integer types.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
StringRef getName() const
getName - Get the symbol name.
ArrayRef< MDOperand > operands() const
Tracking metadata reference owned by Metadata.
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
const GlobalValue * getGlobal() const
MachineBasicBlock * getMBB() const
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
@ MO_FPImmediate
Floating-point immediate operand.
A Module instance is used to store all the information related to an LLVM module.
constexpr bool isValid() const
static const char * getRegisterName(MCRegister Reg)
void lower(const MachineInstr *MI, MCInst &OutMI, SPIRV::ModuleAnalysisInfo *MAI) const
const SPIRVInstrInfo * getInstrInfo() const override
bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const
VersionTuple getSPIRVVersion() const
unsigned getBound() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
Value * getOperand(unsigned i) const
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
unsigned getMajor() const
Retrieve the major version number.
std::optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Target & getTheSPIRV32Target()
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
DenseMap< Value *, Constant * > ConstMap
LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
std::string getExtInstSetName(SPIRV::InstructionSet::InstructionSet Set)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
bool isEntryPoint(const Function &F)
Target & getTheSPIRV64Target()
Target & getTheSPIRVLogicalTarget()
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
Type * getMDOperandAsType(const MDNode *N, unsigned I)
void addStringImm(const StringRef &Str, MCInst &Inst)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
static struct SPIRV::ModuleAnalysisInfo MAI
static size_t computeFPFastMathDefaultInfoVecIndex(size_t BitWidth)
MCRegister getFuncReg(const Function *F)