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();

407 for (; I != E; ++I) {

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() && M.getNamedMetadata("spirv.ExecutionMode") &&

596 M.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();

823 TII = ST->getInstrInfo();

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)