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(
100 void outputExecutionMode(
const Module &M);
101 void outputAnnotations(
const Module &M);
102 void outputModuleSections();
103 void outputFPFastMathDefaultInfo();
105 return MF->getFunction()
111 void emitFunctionEntryLabel()
override {}
112 void emitFunctionHeader()
override;
113 void emitFunctionBodyStart()
override {}
114 void emitFunctionBodyEnd()
override;
119 void emitEndOfAsmFile(
Module &M)
override;
120 bool doInitialization(
Module &M)
override;
130 std::unique_ptr<SPIRVAuxDataHandler> AuxDataHandler;
137void SPIRVAsmPrinter::getAnalysisUsage(
AnalysisUsage &AU)
const {
144void SPIRVAsmPrinter::emitEndOfAsmFile(
Module &M) {
145 if (!ModuleSectionsEmitted) {
146 outputModuleSections();
147 ModuleSectionsEmitted =
true;
150 ST =
static_cast<const SPIRVTargetMachine &
>(TM).getSubtargetImpl();
158 uint32_t Major = SPIRVVersion.
getMajor();
159 uint32_t Minor = SPIRVVersion.
getMinor().value_or(0);
162 unsigned Bound = 2 * (ST->
getBound() + 1) + NLabels;
163 if (MCAssembler *Asm = OutStreamer->getAssemblerPtr())
164 static_cast<SPIRVObjectWriter &
>(
Asm->getWriter())
165 .setBuildVersion(Major, Minor, Bound);
172void SPIRVAsmPrinter::cleanUp(
Module &M) {
174 for (StringRef GVName :
175 {
"llvm.global_ctors",
"llvm.global_dtors",
"llvm.used"}) {
176 if (GlobalVariable *GV =
M.getNamedGlobal(GVName))
181void SPIRVAsmPrinter::emitFunctionHeader() {
182 if (!ModuleSectionsEmitted) {
183 outputModuleSections();
184 ModuleSectionsEmitted =
true;
187 ST = &MF->getSubtarget<SPIRVSubtarget>();
191 if (isVerbose() && !isHidden()) {
192 OutStreamer->getCommentOS()
193 <<
"-- Begin function "
197 auto Section = getObjFileLowering().SectionForGlobal(&
F, TM);
198 MF->setSection(Section);
204 for (
auto &Handler : Handlers) {
205 Handler->beginFunction(MF);
206 Handler->beginBasicBlockSection(MF->front());
210void SPIRVAsmPrinter::outputOpFunctionEnd() {
211 MCInst FunctionEndInst;
212 FunctionEndInst.
setOpcode(SPIRV::OpFunctionEnd);
213 outputMCInst(FunctionEndInst);
216void SPIRVAsmPrinter::emitFunctionBodyEnd() {
218 outputOpFunctionEnd();
221void SPIRVAsmPrinter::emitOpLabel(
const MachineBasicBlock &
MBB) {
229 outputMCInst(LabelInst);
234void SPIRVAsmPrinter::emitBasicBlockStart(
const MachineBasicBlock &
MBB) {
242 for (
const MachineInstr &
MI :
MBB)
243 if (
MI.getOpcode() == SPIRV::OpFunction)
251void SPIRVAsmPrinter::printOperand(
const MachineInstr *
MI,
int OpNum,
253 const MachineOperand &MO =
MI->getOperand(OpNum);
293bool SPIRVAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
294 const char *ExtraCode, raw_ostream &O) {
295 if (ExtraCode && ExtraCode[0])
304 return TII->isHeaderInstr(*
MI) ||
MI->getOpcode() == SPIRV::OpFunction ||
305 MI->getOpcode() == SPIRV::OpFunctionParameter;
308void SPIRVAsmPrinter::outputMCInst(MCInst &Inst) {
309 OutStreamer->emitInstruction(Inst, *OutContext.getSubtargetInfo());
312void SPIRVAsmPrinter::outputInstruction(
const MachineInstr *
MI) {
313 SPIRVMCInstLower MCInstLowering;
315 MCInstLowering.
lower(
MI, TmpInst, MAI);
316 outputMCInst(TmpInst);
319void SPIRVAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
320 SPIRV_MC::verifyInstructionPredicates(
MI->getOpcode(),
321 getSubtargetInfo().getFeatureBits());
323 if (!MAI->getSkipEmission(
MI))
324 outputInstruction(
MI);
327 const MachineInstr *NextMI =
MI->getNextNode();
330 assert(
MI->getParent()->getNumber() == MF->front().getNumber() &&
331 "OpFunction is not in the front MBB of MF");
332 emitOpLabel(*
MI->getParent());
336void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) {
337 for (
const MachineInstr *
MI : MAI->getMSInstrs(MSType))
338 outputInstruction(
MI);
341void SPIRVAsmPrinter::outputDebugSourceAndStrings(
const Module &M) {
343 for (
auto &Str : MAI->SrcExt) {
345 Inst.
setOpcode(SPIRV::OpSourceExtension);
350 outputModuleSection(SPIRV::MB_DebugStrings);
366 AuxDataHandler->emitAuxDataStrings(*MAI);
369void SPIRVAsmPrinter::outputOpExtInstImports(
const Module &M) {
370 for (
auto &CU : MAI->ExtInstSetMap) {
371 unsigned Set = CU.first;
372 MCRegister
Reg = CU.second;
377 static_cast<SPIRV::InstructionSet::InstructionSet
>(Set)),
383void SPIRVAsmPrinter::outputOpMemoryModel() {
395void SPIRVAsmPrinter::outputEntryPoints() {
397 DenseSet<MCRegister> InterfaceIDs;
398 for (
const MachineInstr *
MI : MAI->GlobalVarList) {
399 assert(
MI->getOpcode() == SPIRV::OpVariable);
400 auto SC =
static_cast<SPIRV::StorageClass::StorageClass
>(
407 SC == SPIRV::StorageClass::Input || SC == SPIRV::StorageClass::Output) {
408 const MachineFunction *MF =
MI->getMF();
409 MCRegister
Reg = MAI->getRegisterAlias(MF,
MI->getOperand(0).getReg());
415 for (
const MachineInstr *
MI : MAI->getMSInstrs(SPIRV::MB_EntryPoints)) {
416 SPIRVMCInstLower MCInstLowering;
418 MCInstLowering.
lower(
MI, TmpInst, MAI);
419 for (MCRegister
Reg : InterfaceIDs) {
423 outputMCInst(TmpInst);
428void SPIRVAsmPrinter::outputGlobalRequirements() {
430 MAI->Reqs.checkSatisfiable(*ST);
432 for (
const auto &Cap : MAI->Reqs.getMinimalCapabilities()) {
440 for (
const auto &Ext : MAI->Reqs.getExtensions()) {
444 SPIRV::OperandCategory::ExtensionOperand, Ext),
451void SPIRVAsmPrinter::outputExtFuncDecls() {
453 auto I = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).begin(),
454 E = MAI->getMSInstrs(SPIRV::MB_ExtFuncDecls).end();
455 for (;
I !=
E; ++
I) {
456 outputInstruction(*
I);
457 if ((
I + 1) ==
E || (*(
I + 1))->getOpcode() == SPIRV::OpFunction)
458 outputOpFunctionEnd();
468 if (Ty->isDoubleTy())
471 switch (IntTy->getIntegerBitWidth()) {
485 Type *EleTy = VecTy->getElementType();
486 unsigned Size = VecTy->getNumElements();
508void SPIRVAsmPrinter::outputExecutionModeFromMDNode(
509 MCRegister
Reg, MDNode *Node, SPIRV::ExecutionMode::ExecutionMode EM,
510 unsigned ExpectMDOps, int64_t DefVal) {
518 unsigned NodeSz =
Node->getNumOperands();
519 if (ExpectMDOps > 0 && NodeSz < ExpectMDOps)
520 for (
unsigned i = NodeSz; i < ExpectMDOps; ++i)
525void SPIRVAsmPrinter::outputExecutionModeFromNumthreadsAttribute(
527 SPIRV::ExecutionMode::ExecutionMode EM) {
528 assert(Attr.
isValid() &&
"Function called with an invalid attribute.");
537 assert(NumThreads.size() == 3 &&
"invalid numthreads");
538 for (uint32_t i = 0; i < 3; ++i) {
540 [[maybe_unused]]
bool Result = NumThreads[i].getAsInteger(10, V);
541 assert(!Result &&
"Failed to parse numthreads");
548void SPIRVAsmPrinter::outputExecutionModeFromEnableMaximalReconvergenceAttr(
549 const MCRegister &
Reg,
const SPIRVSubtarget &ST) {
550 assert(
ST.canUseExtension(SPIRV::Extension::SPV_KHR_maximal_reconvergence) &&
551 "Function called when SPV_KHR_maximal_reconvergence is not enabled.");
557 static_cast<unsigned>(SPIRV::ExecutionMode::MaximallyReconvergesKHR);
562void SPIRVAsmPrinter::outputExecutionMode(
const Module &M) {
563 NamedMDNode *
Node =
M.getNamedMetadata(
"spirv.ExecutionMode");
565 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
572 if (EM == SPIRV::ExecutionMode::ArithmeticPoisonKHR)
577 if (
ST->canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
578 if (EM == SPIRV::ExecutionMode::FPFastMathDefault ||
579 EM == SPIRV::ExecutionMode::ContractionOff ||
580 EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve)
589 outputFPFastMathDefaultInfo();
591 for (
auto FI =
M.begin(),
E =
M.end(); FI !=
E; ++FI) {
597 MCRegister FReg = MAI->getGlobalObjReg(&
F);
610 static_cast<unsigned>(SPIRV::ExecutionMode::OriginUpperLeft);
615 if (MDNode *Node =
F.getMetadata(
"reqd_work_group_size"))
616 outputExecutionModeFromMDNode(FReg, Node, SPIRV::ExecutionMode::LocalSize,
619 outputExecutionModeFromNumthreadsAttribute(
620 FReg, Attr, SPIRV::ExecutionMode::LocalSize);
621 if (
Attribute Attr =
F.getFnAttribute(
"enable-maximal-reconvergence");
623 outputExecutionModeFromEnableMaximalReconvergenceAttr(FReg, *ST);
625 if (MDNode *Node =
F.getMetadata(
"work_group_size_hint"))
626 outputExecutionModeFromMDNode(FReg, Node,
627 SPIRV::ExecutionMode::LocalSizeHint, 3, 1);
628 if (MDNode *Node =
F.getMetadata(
"reqd_sub_group_size"))
629 outputExecutionModeFromMDNode(FReg, Node,
630 SPIRV::ExecutionMode::SubgroupSize, 0, 0);
631 if (MDNode *Node =
F.getMetadata(
"intel_reqd_sub_group_size"))
632 outputExecutionModeFromMDNode(FReg, Node,
633 SPIRV::ExecutionMode::SubgroupSize, 0, 0);
634 if (MDNode *Node =
F.getMetadata(
"max_work_group_size")) {
635 if (
ST->canUseExtension(SPIRV::Extension::SPV_INTEL_kernel_attributes))
636 outputExecutionModeFromMDNode(
637 FReg, Node, SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, 3, 1);
639 if (MDNode *Node =
F.getMetadata(
"vec_type_hint")) {
643 unsigned EM =
static_cast<unsigned>(SPIRV::ExecutionMode::VecTypeHint);
652 SPIRV::Capability::PoisonFreezeKHR)) {
657 static_cast<unsigned>(SPIRV::ExecutionMode::ArithmeticPoisonKHR);
663 bool EmitContractionOff =
664 ST->isKernel() && !
M.getNamedMetadata(
"spirv.ExecutionMode") &&
665 SPIRVFPContract != SPIRVFPContractMode::Fast &&
666 (SPIRVFPContract == SPIRVFPContractMode::Off ||
667 !
M.getNamedMetadata(
"opencl.enable.FP_CONTRACT"));
668 if (EmitContractionOff) {
669 if (
ST->canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
686 std::vector<const MachineInstr *> SPIRVFloatTypes;
687 const MachineInstr *ConstZeroInt32 =
nullptr;
688 for (
const MachineInstr *
MI :
689 MAI->getMSInstrs(SPIRV::MB_TypeConstVars)) {
693 if (OpCode == SPIRV::OpTypeFloat) {
695 const unsigned OpTypeFloatSize =
MI->getOperand(1).getImm();
696 if (OpTypeFloatSize != 16 && OpTypeFloatSize != 32 &&
697 OpTypeFloatSize != 64) {
700 SPIRVFloatTypes.push_back(
MI);
704 if (OpCode == SPIRV::OpConstantNull) {
706 const MachineRegisterInfo &MRI =
MI->getMF()->getRegInfo();
707 MachineInstr *TypeMI = MRI.
getVRegDef(
MI->getOperand(1).getReg());
708 bool IsInt32Ty = TypeMI &&
709 TypeMI->
getOpcode() == SPIRV::OpTypeInt &&
722 for (
const MachineInstr *
MI : SPIRVFloatTypes) {
724 Inst.
setOpcode(SPIRV::OpExecutionModeId);
727 static_cast<unsigned>(SPIRV::ExecutionMode::FPFastMathDefault);
729 const MachineFunction *MF =
MI->getMF();
731 MAI->getRegisterAlias(MF,
MI->getOperand(0).getReg());
733 assert(ConstZeroInt32 &&
"There should be a constant zero.");
734 MCRegister ConstReg = MAI->getRegisterAlias(
744 static_cast<unsigned>(SPIRV::ExecutionMode::ContractionOff);
752void SPIRVAsmPrinter::outputAnnotations(
const Module &M) {
753 outputModuleSection(SPIRV::MB_Annotations);
755 for (
auto F =
M.global_begin(),
E =
M.global_end();
F !=
E; ++
F) {
756 if ((*F).getName() !=
"llvm.global.annotations")
758 const GlobalVariable *
V = &(*F);
766 MCRegister
Reg = GO ? MAI->getGlobalObjReg(GO) : MCRegister();
769 raw_string_ostream OS(DiagMsg);
770 AnnotatedVar->
print(OS);
771 DiagMsg =
"Unsupported value in llvm.global.annotations: " + DiagMsg;
779 StringRef AnnotationString;
780 [[maybe_unused]]
bool Success =
786 unsigned Dec =
static_cast<unsigned>(SPIRV::Decoration::UserSemantic);
794void SPIRVAsmPrinter::outputFPFastMathDefaultInfo() {
797 std::vector<const MachineInstr *> SPIRVFloatTypes;
799 DenseMap<int, const MachineInstr *>
ConstMap;
800 for (
const MachineInstr *
MI : MAI->getMSInstrs(SPIRV::MB_TypeConstVars)) {
803 if (OpCode != SPIRV::OpTypeFloat && OpCode != SPIRV::OpConstantI &&
804 OpCode != SPIRV::OpConstantNull)
808 if (OpCode == SPIRV::OpTypeFloat) {
809 SPIRVFloatTypes.push_back(
MI);
812 const MachineRegisterInfo &MRI =
MI->getMF()->getRegInfo();
813 MachineInstr *TypeMI = MRI.
getVRegDef(
MI->getOperand(1).getReg());
814 if (!TypeMI || TypeMI->
getOpcode() != SPIRV::OpTypeInt ||
818 if (OpCode == SPIRV::OpConstantI)
825 for (
const auto &[Func, FPFastMathDefaultInfoVec] :
826 MAI->FPFastMathDefaultInfoMap) {
827 if (FPFastMathDefaultInfoVec.empty())
830 for (
const MachineInstr *
MI : SPIRVFloatTypes) {
831 unsigned OpTypeFloatSize =
MI->getOperand(1).getImm();
834 assert(Index < FPFastMathDefaultInfoVec.size() &&
835 "Index out of bounds for FPFastMathDefaultInfoVec");
836 const auto &FPFastMathDefaultInfo = FPFastMathDefaultInfoVec[
Index];
837 assert(FPFastMathDefaultInfo.Ty &&
838 "Expected target type for FPFastMathDefaultInfo");
839 assert(FPFastMathDefaultInfo.Ty->getScalarSizeInBits() ==
841 "Mismatched float type size");
843 Inst.
setOpcode(SPIRV::OpExecutionModeId);
844 MCRegister FuncReg = MAI->getGlobalObjReg(Func);
850 MAI->getRegisterAlias(
MI->getMF(),
MI->getOperand(0).getReg());
852 unsigned Flags = FPFastMathDefaultInfo.FastMathFlags;
853 if (FPFastMathDefaultInfo.ContractionOff &&
854 (Flags & SPIRV::FPFastMathMode::AllowContract))
856 "Conflicting FPFastMathFlags: ContractionOff and AllowContract");
858 if (FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
860 (SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
861 SPIRV::FPFastMathMode::NSZ))) {
862 if (FPFastMathDefaultInfo.FPFastMathDefault)
864 "SignedZeroInfNanPreserve but at least one of "
865 "NotNaN/NotInf/NSZ is enabled.");
869 if (Flags == SPIRV::FPFastMathMode::None &&
870 !FPFastMathDefaultInfo.ContractionOff &&
871 !FPFastMathDefaultInfo.SignedZeroInfNanPreserve &&
872 !FPFastMathDefaultInfo.FPFastMathDefault)
879 "Mode operand of FPFastMathDefault execution mode.");
880 const MachineInstr *ConstMI = It->second;
881 MCRegister ConstReg = MAI->getRegisterAlias(
889void SPIRVAsmPrinter::outputModuleSections() {
890 const Module *
M = MMI->getModule();
892 ST =
static_cast<const SPIRVTargetMachine &
>(TM).getSubtargetImpl();
893 TII =
ST->getInstrInfo();
894 MAI = &getAnalysis<SPIRVModuleAnalysis>().MAI;
895 assert(ST &&
TII && MAI && M &&
"Module analysis is required");
897 if (!AuxDataHandler) {
898 auto Handler = std::make_unique<SPIRVAuxDataHandler>(*
this, *M);
899 if (Handler->hasWork())
900 AuxDataHandler = std::move(Handler);
908 AuxDataHandler->prepareModuleOutput(*ST, *MAI);
913 outputGlobalRequirements();
915 outputOpExtInstImports(*M);
917 outputOpMemoryModel();
922 outputExecutionMode(*M);
925 outputDebugSourceAndStrings(*M);
927 outputModuleSection(SPIRV::MB_DebugNames);
929 outputModuleSection(SPIRV::MB_DebugModuleProcessed);
932 outputModuleSection(SPIRV::MB_AliasingInsts);
934 outputAnnotations(*M);
939 outputModuleSection(SPIRV::MB_TypeConstVars);
946 AuxDataHandler->emitAuxData(*MAI);
948 outputExtFuncDecls();
953bool SPIRVAsmPrinter::doInitialization(
Module &M) {
954 ModuleSectionsEmitted =
false;
955 if (!
M.getModuleInlineAsm().empty()) {
956 M.getContext().emitError(
957 "SPIR-V does not support module-level inline assembly");
958 M.setModuleInlineAsm(
"");
963 if (
M.getNamedMetadata(
"llvm.dbg.cu")) {
964 auto Handler = std::make_unique<SPIRVNonSemanticDebugHandler>(*
this);
965 NSDebugHandler = Handler.get();
966 addAsmPrinterHandler(std::move(Handler));
972char SPIRVAsmPrinter::ID = 0;
979LLVMInitializeSPIRVAsmPrinter() {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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...
const SPIRVInstrInfo * getInstrInfo() const override
bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() 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.
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.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
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
This is an optimization pass for GlobalISel generic memory operations.
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.
void addStringImm(const StringRef &Str, MCInst &Inst)
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
static size_t computeFPFastMathDefaultInfoVecIndex(size_t BitWidth)
MCRegister getGlobalObjReg(const GlobalObject *GO)