46#define DEBUG_TYPE "asm-printer"
49enum class SPIRVFPContractMode { On, Off,
Fast };
53 cl::desc(
"Override FP contraction policy for SPIR-V kernel entry points"),
56 "Follow IR metadata (default)"),
58 "Force ContractionOff on all kernel entry points"),
60 "Suppress ContractionOff on all kernel entry points")),
69 std::unique_ptr<MCStreamer> Streamer)
70 :
AsmPrinter(TM, std::move(Streamer), ID), ModuleSectionsEmitted(
false),
71 ST(
nullptr),
TII(
nullptr), MAI(
nullptr) {}
73 bool ModuleSectionsEmitted;
77 StringRef getPassName()
const override {
return "SPIRV Assembly Printer"; }
82 void outputMCInst(
MCInst &Inst);
85 void outputGlobalRequirements();
86 void outputEntryPoints();
87 void outputDebugSourceAndStrings(
const Module &M);
88 void outputOpExtInstImports(
const Module &M);
89 void outputOpMemoryModel();
90 void outputOpFunctionEnd();
91 void outputExtFuncDecls();
93 SPIRV::ExecutionMode::ExecutionMode EM,
94 unsigned ExpectMDOps, int64_t DefVal);
95 void outputExecutionModeFromNumthreadsAttribute(
97 SPIRV::ExecutionMode::ExecutionMode EM);
98 void outputExecutionModeFromEnableMaximalReconvergenceAttr(
101 SPIRV::ExecutionMode::ExecutionMode EM);
102 void outputExecutionMode(
const Module &M);
103 void outputAnnotations(
const Module &M);
104 void outputModuleSections();
105 void outputFPFastMathDefaultInfo();
107 return MF->getFunction()
113 void emitFunctionEntryLabel()
override {}
114 void emitFunctionHeader()
override;
115 void emitFunctionBodyStart()
override {}
116 void emitFunctionBodyEnd()
override;
121 void emitEndOfAsmFile(
Module &M)
override;
122 bool doInitialization(
Module &M)
override;
132 std::unique_ptr<SPIRVAuxDataHandler> AuxDataHandler;
139void SPIRVAsmPrinter::getAnalysisUsage(
AnalysisUsage &AU)
const {
146void SPIRVAsmPrinter::emitEndOfAsmFile(
Module &M) {
147 if (!ModuleSectionsEmitted) {
148 outputModuleSections();
149 ModuleSectionsEmitted =
true;
152 ST =
static_cast<const SPIRVTargetMachine &
>(TM).getSubtargetImpl();
160 uint32_t Major = SPIRVVersion.
getMajor();
161 uint32_t Minor = SPIRVVersion.
getMinor().value_or(0);
164 unsigned Bound = 2 * (ST->
getBound() + 1) + NLabels;
165 if (MCAssembler *Asm = OutStreamer->getAssemblerPtr())
166 static_cast<SPIRVObjectWriter &
>(
Asm->getWriter())
167 .setBuildVersion(Major, Minor, Bound);
174void SPIRVAsmPrinter::cleanUp(
Module &M) {
176 for (StringRef GVName :
177 {
"llvm.global_ctors",
"llvm.global_dtors",
"llvm.used"}) {
178 if (GlobalVariable *GV =
M.getNamedGlobal(GVName))
183void SPIRVAsmPrinter::emitFunctionHeader() {
184 if (!ModuleSectionsEmitted) {
185 outputModuleSections();
186 ModuleSectionsEmitted =
true;
189 ST = &MF->getSubtarget<SPIRVSubtarget>();
193 if (isVerbose() && !isHidden()) {
194 OutStreamer->getCommentOS()
195 <<
"-- Begin function "
199 auto Section = getObjFileLowering().SectionForGlobal(&
F, TM);
200 MF->setSection(Section);
206 for (
auto &Handler : Handlers) {
207 Handler->beginFunction(MF);
208 Handler->beginBasicBlockSection(MF->front());
212void SPIRVAsmPrinter::outputOpFunctionEnd() {
213 MCInst FunctionEndInst;
214 FunctionEndInst.
setOpcode(SPIRV::OpFunctionEnd);
215 outputMCInst(FunctionEndInst);
218void SPIRVAsmPrinter::emitFunctionBodyEnd() {
220 outputOpFunctionEnd();
223void SPIRVAsmPrinter::emitOpLabel(
const MachineBasicBlock &
MBB) {
231 outputMCInst(LabelInst);
236void SPIRVAsmPrinter::emitBasicBlockStart(
const MachineBasicBlock &
MBB) {
244 for (
const MachineInstr &
MI :
MBB)
245 if (
MI.getOpcode() == SPIRV::OpFunction)
253void SPIRVAsmPrinter::printOperand(
const MachineInstr *
MI,
int OpNum,
255 const MachineOperand &MO =
MI->getOperand(OpNum);
295bool SPIRVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
296 const char *ExtraCode, raw_ostream &O) {
297 if (ExtraCode && ExtraCode[0])
306 return TII->isHeaderInstr(*
MI) ||
MI->getOpcode() == SPIRV::OpFunction ||
307 MI->getOpcode() == SPIRV::OpFunctionParameter;
310void SPIRVAsmPrinter::outputMCInst(MCInst &Inst) {
311 OutStreamer->emitInstruction(Inst, *OutContext.getSubtargetInfo());
314void SPIRVAsmPrinter::outputInstruction(
const MachineInstr *
MI) {
315 SPIRVMCInstLower MCInstLowering;
317 MCInstLowering.
lower(
MI, TmpInst, MAI);
318 outputMCInst(TmpInst);
321void SPIRVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
322 SPIRV_MC::verifyInstructionPredicates(
MI->getOpcode(),
323 getSubtargetInfo().getFeatureBits());
325 bool InstructionEmitted = !MAI->getSkipEmission(
MI);
326 if (InstructionEmitted)
327 outputInstruction(
MI);
330 const MachineInstr *NextMI =
MI->getNextNode();
331 bool BlockHasLabel = LabeledMBB.
contains(
MI->getParent());
333 bool IsNextInstructionFunctionPreamble =
335 bool ShouldEmitEntryLabel = !BlockHasLabel && IsFunctionPreambleInstruction &&
336 !IsNextInstructionFunctionPreamble;
337 if (ShouldEmitEntryLabel) {
338 assert(
MI->getParent()->getNumber() == MF->front().getNumber() &&
339 "OpFunction is not in the front MBB of MF");
340 emitOpLabel(*
MI->getParent());
341 if (NSDebugHandler && !isHidden())
346void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) {
347 for (
const MachineInstr *
MI : MAI->getMSInstrs(MSType))
348 outputInstruction(
MI);
351void SPIRVAsmPrinter::outputDebugSourceAndStrings(
const Module &M) {
353 for (
auto &Str : MAI->SrcExt) {
355 Inst.
setOpcode(SPIRV::OpSourceExtension);
360 outputModuleSection(SPIRV::MB_DebugStrings);
376 AuxDataHandler->emitAuxDataStrings(*MAI);
379void SPIRVAsmPrinter::outputOpExtInstImports(
const Module &M) {
380 for (
auto &CU : MAI->ExtInstSetMap) {
381 unsigned Set = CU.first;
382 MCRegister
Reg = CU.second;
387 static_cast<SPIRV::InstructionSet::InstructionSet
>(Set)),
393void SPIRVAsmPrinter::outputOpMemoryModel() {
405void SPIRVAsmPrinter::outputEntryPoints() {
407 DenseSet<MCRegister> InterfaceIDs;
408 for (
const MachineInstr *
MI : MAI->GlobalVarList) {
409 assert(
MI->getOpcode() == SPIRV::OpVariable ||
410 MI->getOpcode() == SPIRV::OpUntypedVariableKHR);
411 auto SC =
static_cast<SPIRV::StorageClass::StorageClass
>(
418 SC == SPIRV::StorageClass::Input || SC == SPIRV::StorageClass::Output) {
419 const MachineFunction *MF =
MI->getMF();
420 MCRegister
Reg = MAI->getRegisterAlias(MF,
MI->getOperand(0).getReg());
426 for (
const MachineInstr *
MI : MAI->getMSInstrs(SPIRV::MB_EntryPoints)) {
427 SPIRVMCInstLower MCInstLowering;
429 MCInstLowering.
lower(
MI, TmpInst, MAI);
430 for (MCRegister
Reg : InterfaceIDs) {
434 outputMCInst(TmpInst);
439void SPIRVAsmPrinter::outputGlobalRequirements() {
441 MAI->Reqs.checkSatisfiable(*ST);
443 for (
const auto &Cap : MAI->Reqs.getMinimalCapabilities()) {
451 for (
const auto &Ext : MAI->Reqs.getExtensions()) {
455 SPIRV::OperandCategory::ExtensionOperand, Ext),
462void SPIRVAsmPrinter::outputExtFuncDecls() {
464 auto I = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).begin(),
465 E = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).end();
466 for (;
I !=
E; ++
I) {
467 outputInstruction(*
I);
468 if ((
I + 1) ==
E || (*(
I + 1))->
getOpcode() == SPIRV::OpFunction)
469 outputOpFunctionEnd();
479 if (Ty->isDoubleTy())
482 switch (IntTy->getIntegerBitWidth()) {
496 Type *EleTy = VecTy->getElementType();
497 unsigned Size = VecTy->getNumElements();
519void SPIRVAsmPrinter::outputExecutionModeFromMDNode(
520 MCRegister
Reg, MDNode *Node, SPIRV::ExecutionMode::ExecutionMode EM,
521 unsigned ExpectMDOps, int64_t DefVal) {
529 unsigned NodeSz =
Node->getNumOperands();
530 if (ExpectMDOps > 0 && NodeSz < ExpectMDOps)
531 for (
unsigned i = NodeSz; i < ExpectMDOps; ++i)
536void SPIRVAsmPrinter::outputExecutionModeFromNumthreadsAttribute(
538 SPIRV::ExecutionMode::ExecutionMode EM) {
539 assert(Attr.
isValid() &&
"Function called with an invalid attribute.");
548 assert(NumThreads.size() == 3 &&
"invalid numthreads");
549 for (uint32_t i = 0; i < 3; ++i) {
551 [[maybe_unused]]
bool Result = NumThreads[i].getAsInteger(10, V);
552 assert(!Result &&
"Failed to parse numthreads");
559void SPIRVAsmPrinter::emitSimpleExecutionMode(
560 MCRegister
Reg, SPIRV::ExecutionMode::ExecutionMode EM) {
568void SPIRVAsmPrinter::outputExecutionModeFromEnableMaximalReconvergenceAttr(
569 const MCRegister &
Reg,
const SPIRVSubtarget &ST) {
570 assert(
ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence) &&
571 "Function called when SPV_KHR_maximal_reconvergence is not enabled.");
573 emitSimpleExecutionMode(
Reg, SPIRV::ExecutionMode::MaximallyReconvergesKHR);
576void SPIRVAsmPrinter::outputExecutionMode(
const Module &M) {
577 NamedMDNode *
Node =
M.getNamedMetadata(
"spirv.ExecutionMode");
579 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
586 if (EM == SPIRV::ExecutionMode::ArithmeticPoisonKHR)
592 if (EM == SPIRV::ExecutionMode::FPFastMathDefault ||
593 EM == SPIRV::ExecutionMode::ContractionOff ||
594 EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve)
603 outputFPFastMathDefaultInfo();
605 for (
auto FI =
M.begin(),
E =
M.end(); FI !=
E; ++FI) {
611 MCRegister FReg = MAI->getGlobalObjReg(&
F);
620 emitSimpleExecutionMode(FReg, SPIRV::ExecutionMode::OriginUpperLeft);
623 if (MDNode *Node =
F.getMetadata(
"reqd_work_group_size"))
624 outputExecutionModeFromMDNode(FReg, Node, SPIRV::ExecutionMode::LocalSize,
627 outputExecutionModeFromNumthreadsAttribute(
628 FReg, Attr, SPIRV::ExecutionMode::LocalSize);
629 if (
Attribute Attr =
F.getFnAttribute(
"enable-maximal-reconvergence");
631 outputExecutionModeFromEnableMaximalReconvergenceAttr(FReg, *ST);
633 if (MDNode *Node =
F.getMetadata(
"work_group_size_hint"))
634 outputExecutionModeFromMDNode(FReg, Node,
635 SPIRV::ExecutionMode::LocalSizeHint, 3, 1);
636 if (MDNode *Node =
F.getMetadata(
"reqd_sub_group_size"))
637 outputExecutionModeFromMDNode(FReg, Node,
638 SPIRV::ExecutionMode::SubgroupSize, 0, 0);
639 if (MDNode *Node =
F.getMetadata(
"intel_reqd_sub_group_size"))
640 outputExecutionModeFromMDNode(FReg, Node,
641 SPIRV::ExecutionMode::SubgroupSize, 0, 0);
642 if (MDNode *Node =
F.getMetadata(
"max_work_group_size")) {
643 if (ST->
canUseExtension(SPIRV::Extension::SPV_INTEL_kernel_attributes))
644 outputExecutionModeFromMDNode(
645 FReg, Node, SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, 3, 1);
647 if (MDNode *Node =
F.getMetadata(
"vec_type_hint")) {
651 unsigned EM =
static_cast<unsigned>(SPIRV::ExecutionMode::VecTypeHint);
660 SPIRV::Capability::PoisonFreezeKHR)) {
661 emitSimpleExecutionMode(FReg, SPIRV::ExecutionMode::ArithmeticPoisonKHR);
665 bool EmitContractionOff =
666 ST->
isKernel() && !
M.getNamedMetadata(
"spirv.ExecutionMode") &&
667 SPIRVFPContract != SPIRVFPContractMode::Fast &&
668 (SPIRVFPContract == SPIRVFPContractMode::Off ||
669 !
M.getNamedMetadata(
"opencl.enable.FP_CONTRACT"));
670 if (EmitContractionOff) {
688 std::vector<const MachineInstr *> SPIRVFloatTypes;
689 const MachineInstr *ConstZeroInt32 =
nullptr;
690 for (
const MachineInstr *
MI :
691 MAI->getMSInstrs(SPIRV::MB_TypeConstVars)) {
695 if (OpCode == SPIRV::OpTypeFloat) {
697 const unsigned OpTypeFloatSize =
MI->getOperand(1).getImm();
698 if (OpTypeFloatSize != 16 && OpTypeFloatSize != 32 &&
699 OpTypeFloatSize != 64) {
702 SPIRVFloatTypes.push_back(
MI);
706 if (OpCode == SPIRV::OpConstantNull) {
708 const MachineRegisterInfo &MRI =
MI->getMF()->getRegInfo();
709 MachineInstr *TypeMI = MRI.
getVRegDef(
MI->getOperand(1).getReg());
710 bool IsInt32Ty = TypeMI &&
711 TypeMI->
getOpcode() == SPIRV::OpTypeInt &&
724 for (
const MachineInstr *
MI : SPIRVFloatTypes) {
726 Inst.
setOpcode(SPIRV::OpExecutionModeId);
729 static_cast<unsigned>(SPIRV::ExecutionMode::FPFastMathDefault);
731 const MachineFunction *MF =
MI->getMF();
733 MAI->getRegisterAlias(MF,
MI->getOperand(0).getReg());
735 assert(ConstZeroInt32 &&
"There should be a constant zero.");
736 MCRegister ConstReg = MAI->getRegisterAlias(
742 emitSimpleExecutionMode(FReg, SPIRV::ExecutionMode::ContractionOff);
748void SPIRVAsmPrinter::outputAnnotations(
const Module &M) {
749 outputModuleSection(SPIRV::MB_Annotations);
751 if (
const GlobalVariable *V =
M.getNamedGlobal(
"llvm.global.annotations")) {
759 MCRegister
Reg = GO ? MAI->getGlobalObjReg(GO) : MCRegister();
762 raw_string_ostream OS(DiagMsg);
763 AnnotatedVar->
print(OS);
764 DiagMsg =
"Unsupported value in llvm.global.annotations: " + DiagMsg;
772 StringRef AnnotationString;
773 [[maybe_unused]]
bool Success =
779 unsigned Dec =
static_cast<unsigned>(SPIRV::Decoration::UserSemantic);
787void SPIRVAsmPrinter::outputFPFastMathDefaultInfo() {
790 std::vector<const MachineInstr *> SPIRVFloatTypes;
792 DenseMap<int, const MachineInstr *>
ConstMap;
793 for (
const MachineInstr *
MI : MAI->getMSInstrs(SPIRV::MB_TypeConstVars)) {
796 if (OpCode != SPIRV::OpTypeFloat && OpCode != SPIRV::OpConstantI &&
797 OpCode != SPIRV::OpConstantNull)
801 if (OpCode == SPIRV::OpTypeFloat) {
802 SPIRVFloatTypes.push_back(
MI);
805 const MachineRegisterInfo &MRI =
MI->getMF()->getRegInfo();
806 MachineInstr *TypeMI = MRI.
getVRegDef(
MI->getOperand(1).getReg());
807 if (!TypeMI || TypeMI->
getOpcode() != SPIRV::OpTypeInt ||
811 if (OpCode == SPIRV::OpConstantI)
818 for (
const auto &[Func, FPFastMathDefaultInfoVec] :
819 MAI->FPFastMathDefaultInfoMap) {
820 if (FPFastMathDefaultInfoVec.empty())
823 for (
const MachineInstr *
MI : SPIRVFloatTypes) {
824 unsigned OpTypeFloatSize =
MI->getOperand(1).getImm();
827 assert(Index < FPFastMathDefaultInfoVec.size() &&
828 "Index out of bounds for FPFastMathDefaultInfoVec");
829 const auto &FPFastMathDefaultInfo = FPFastMathDefaultInfoVec[
Index];
830 assert(FPFastMathDefaultInfo.Ty &&
831 "Expected target type for FPFastMathDefaultInfo");
832 assert(FPFastMathDefaultInfo.Ty->getScalarSizeInBits() ==
834 "Mismatched float type size");
836 Inst.
setOpcode(SPIRV::OpExecutionModeId);
837 MCRegister FuncReg = MAI->getGlobalObjReg(Func);
843 MAI->getRegisterAlias(
MI->getMF(),
MI->getOperand(0).getReg());
845 unsigned Flags = FPFastMathDefaultInfo.FastMathFlags;
846 if (FPFastMathDefaultInfo.ContractionOff &&
847 (Flags & SPIRV::FPFastMathMode::AllowContract))
849 "Conflicting FPFastMathFlags: ContractionOff and AllowContract");
851 if (FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
853 (SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
854 SPIRV::FPFastMathMode::NSZ))) {
855 if (FPFastMathDefaultInfo.FPFastMathDefault)
857 "SignedZeroInfNanPreserve but at least one of "
858 "NotNaN/NotInf/NSZ is enabled.");
862 if (Flags == SPIRV::FPFastMathMode::None &&
863 !FPFastMathDefaultInfo.ContractionOff &&
864 !FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
865 !FPFastMathDefaultInfo.FPFastMathDefault)
872 "Mode operand of FPFastMathDefault execution mode.");
873 const MachineInstr *ConstMI = It->second;
874 MCRegister ConstReg = MAI->getRegisterAlias(
882void SPIRVAsmPrinter::outputModuleSections() {
883 const Module *
M = MMI->getModule();
885 ST =
static_cast<const SPIRVTargetMachine &
>(TM).getSubtargetImpl();
887 MAI = &getAnalysis<SPIRVModuleAnalysis>().MAI;
888 assert(ST &&
TII && MAI && M &&
"Module analysis is required");
890 if (!AuxDataHandler) {
891 auto Handler = std::make_unique<SPIRVAuxDataHandler>(*
this, *M);
892 if (Handler->hasWork())
893 AuxDataHandler = std::move(Handler);
901 AuxDataHandler->prepareModuleOutput(*ST, *MAI);
906 outputGlobalRequirements();
908 outputOpExtInstImports(*M);
910 outputOpMemoryModel();
915 outputExecutionMode(*M);
918 outputDebugSourceAndStrings(*M);
920 outputModuleSection(SPIRV::MB_DebugNames);
922 outputModuleSection(SPIRV::MB_DebugModuleProcessed);
925 outputModuleSection(SPIRV::MB_AliasingInsts);
927 outputAnnotations(*M);
932 outputModuleSection(SPIRV::MB_TypeConstVars);
939 AuxDataHandler->emitAuxData(*MAI);
941 outputExtFuncDecls();
946bool SPIRVAsmPrinter::doInitialization(
Module &M) {
947 ModuleSectionsEmitted =
false;
948 if (!
M.getModuleInlineAsm().empty()) {
949 M.getContext().emitError(
950 "SPIR-V does not support module-level inline assembly");
951 M.removeModuleInlineAsm();
956 if (
M.getNamedMetadata(
"llvm.dbg.cu")) {
957 auto Handler = std::make_unique<SPIRVNonSemanticDebugHandler>(*
this);
958 NSDebugHandler = Handler.get();
959 addAsmPrinterHandler(std::move(Handler));
965char SPIRVAsmPrinter::ID = 0;
972LLVMInitializeSPIRVAsmPrinter() {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_EXTERNAL_VISIBILITY
This file defines the DenseMap class.
const HexagonInstrInfo * TII
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)
static bool isFuncOrHeaderInstr(const MachineInstr *MI, const SPIRVInstrInfo *TII)
static unsigned encodeVecTypeHint(Type *Ty)
#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")
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.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
A Module instance is used to store all the information related to an LLVM module.
constexpr bool isValid() const
void setBound(unsigned V)
static const char * getRegisterName(MCRegister Reg)
void lower(const MachineInstr *MI, MCInst &OutMI, SPIRV::ModuleAnalysisInfo *MAI) const
AsmPrinter handler that emits NonSemantic.Shader.DebugInfo.100 (NSDI) instructions for the SPIR-V bac...
void emitNonSemanticDebugStrings(SPIRV::ModuleAnalysisInfo &MAI)
Emit OpString instructions for all NSDI file paths and basic type names into the debug section (secti...
void emitNonSemanticGlobalDebugInfo(SPIRV::ModuleAnalysisInfo &MAI)
Emit module-scope NSDI instructions (DebugSource, DebugCompilationUnit, DebugTypeBasic,...
void prepareModuleOutput(const SPIRVSubtarget &ST, SPIRV::ModuleAnalysisInfo &MAI)
Add SPV_KHR_non_semantic_info extension and NonSemantic.Shader.DebugInfo.100 ext inst set entry to MA...
void notifyEntryLabelEmitted(const MachineFunction &MF)
Called after the synthesized entry OpLabel has been emitted.
const SPIRVInstrInfo * getInstrInfo() const override
bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
VersionTuple getSPIRVVersion() const
unsigned getBound() const
bool canUseExtension(SPIRV::Extension::Extension E) 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.
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.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
NodeAddr< NodeBase * > Node
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
void addStringImm(StringRef Str, MCInst &Inst)
Target & getTheSPIRV32Target()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - 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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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...
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<X> - Return the argument parameter cast to the specified type.
Type * getMDOperandAsType(const MDNode *N, unsigned I)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
static size_t computeFPFastMathDefaultInfoVecIndex(size_t BitWidth)
MCRegister getGlobalObjReg(const GlobalObject *GO)