32#define DEBUG_TYPE "si-peephole-sdwa"
34STATISTIC(NumSDWAPatternsFound,
"Number of SDWA patterns found.");
36 "Number of instruction converted to SDWA.");
71 bool convertToSDWA(
MachineInstr &
MI,
const SDWAOperandsVector &SDWAOperands);
89 :
Target(TargetOp), Replaced(ReplacedOp) {
94 virtual ~SDWAOperand() =
default;
104 return &getParentInst()->getParent()->getParent()->getRegInfo();
107#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
113using namespace AMDGPU::SDWA;
115class SDWASrcOperand :
public SDWAOperand {
124 SdwaSel SrcSel_ =
DWORD,
bool Abs_ =
false,
bool Neg_ =
false,
126 : SDWAOperand(TargetOp, ReplacedOp),
127 SrcSel(SrcSel_), Abs(Abs_), Neg(Neg_), Sext(Sext_) {}
132 SdwaSel getSrcSel()
const {
return SrcSel; }
133 bool getAbs()
const {
return Abs; }
134 bool getNeg()
const {
return Neg; }
135 bool getSext()
const {
return Sext; }
140#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
145class SDWADstOperand :
public SDWAOperand {
154 : SDWAOperand(TargetOp, ReplacedOp), DstSel(DstSel_), DstUn(DstUn_) {}
159 SdwaSel getDstSel()
const {
return DstSel; }
160 DstUnused getDstUnused()
const {
return DstUn; }
162#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
167class SDWADstPreserveOperand :
public SDWADstOperand {
175 Preserve(PreserveOp) {}
181#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
190char SIPeepholeSDWA::
ID = 0;
195 return new SIPeepholeSDWA();
199#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
208 case DWORD:
OS <<
"DWORD";
break;
224 OS <<
"SDWA src: " << *getTargetOperand()
225 <<
" src_sel:" << getSrcSel()
226 <<
" abs:" << getAbs() <<
" neg:" << getNeg()
227 <<
" sext:" << getSext() <<
'\n';
232 OS <<
"SDWA dst: " << *getTargetOperand()
233 <<
" dst_sel:" << getDstSel()
234 <<
" dst_unused:" << getDstUnused() <<
'\n';
239 OS <<
"SDWA preserve dst: " << *getTargetOperand()
240 <<
" dst_sel:" << getDstSel()
241 <<
" preserve:" << *getPreservedOperand() <<
'\n';
259 return LHS.isReg() &&
261 LHS.getReg() ==
RHS.getReg() &&
262 LHS.getSubReg() ==
RHS.getSubReg();
267 if (!Reg->isReg() || !Reg->isDef())
296 for (
auto &DefMO : DefInstr->
defs()) {
297 if (DefMO.isReg() && DefMO.getReg() == Reg->getReg())
308 const auto *
MI =
SrcOp->getParent();
309 if (
TII->getNamedOperand(*
MI, AMDGPU::OpName::src0) ==
SrcOp) {
310 if (
auto *
Mod =
TII->getNamedOperand(*
MI, AMDGPU::OpName::src0_modifiers)) {
311 Mods =
Mod->getImm();
313 }
else if (
TII->getNamedOperand(*
MI, AMDGPU::OpName::src1) ==
SrcOp) {
314 if (
auto *
Mod =
TII->getNamedOperand(*
MI, AMDGPU::OpName::src1_modifiers)) {
315 Mods =
Mod->getImm();
320 "Float and integer src modifiers can't be set simultaneously");
341 switch (
MI.getOpcode()) {
342 case AMDGPU::V_CVT_F32_FP8_sdwa:
343 case AMDGPU::V_CVT_F32_BF8_sdwa:
344 case AMDGPU::V_CVT_PK_F32_FP8_sdwa:
345 case AMDGPU::V_CVT_PK_F32_BF8_sdwa:
352 bool IsPreserveSrc =
false;
356 TII->getNamedOperand(
MI, AMDGPU::OpName::src0_modifiers);
357 assert(Src && (Src->isReg() || Src->isImm()));
358 if (!
isSameReg(*Src, *getReplacedOperand())) {
360 Src =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
361 SrcSel =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_sel);
362 SrcMods =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_modifiers);
365 !
isSameReg(*Src, *getReplacedOperand())) {
374 TII->getNamedOperand(
MI, AMDGPU::OpName::dst_unused);
377 DstUnused->getImm() == AMDGPU::SDWA::DstUnused::UNUSED_PRESERVE) {
383 TII->getNamedImmOperand(
MI, AMDGPU::OpName::dst_sel));
384 if (DstSel == AMDGPU::SDWA::SdwaSel::WORD_1 &&
385 getSrcSel() == AMDGPU::SDWA::SdwaSel::WORD_0) {
386 IsPreserveSrc =
true;
388 AMDGPU::OpName::vdst);
389 auto TiedIdx =
MI.findTiedOperandIdx(DstIdx);
390 Src = &
MI.getOperand(TiedIdx);
399 assert(Src && Src->isReg());
401 if ((
MI.getOpcode() == AMDGPU::V_FMAC_F16_sdwa ||
402 MI.getOpcode() == AMDGPU::V_FMAC_F32_sdwa ||
403 MI.getOpcode() == AMDGPU::V_MAC_F16_sdwa ||
404 MI.getOpcode() == AMDGPU::V_MAC_F32_sdwa) &&
405 !
isSameReg(*Src, *getReplacedOperand())) {
412 (IsPreserveSrc || (SrcSel && SrcMods)));
415 if (!IsPreserveSrc) {
416 SrcSel->
setImm(getSrcSel());
419 getTargetOperand()->setIsKill(
false);
435 if (&UseInst != ParentMI)
445 if ((
MI.getOpcode() == AMDGPU::V_FMAC_F16_sdwa ||
446 MI.getOpcode() == AMDGPU::V_FMAC_F32_sdwa ||
447 MI.getOpcode() == AMDGPU::V_MAC_F16_sdwa ||
448 MI.getOpcode() == AMDGPU::V_MAC_F32_sdwa) &&
457 isSameReg(*Operand, *getReplacedOperand()));
461 DstSel->
setImm(getDstSel());
468 getParentInst()->eraseFromParent();
480 getMRI()->clearKillFlags(MO.getReg());
484 MI.getParent()->remove(&
MI);
485 getParentInst()->getParent()->insert(getParentInst(), &
MI);
489 MIB.addReg(getPreservedOperand()->
getReg(),
491 getPreservedOperand()->getSubReg());
495 MI.getNumOperands() - 1);
498 return SDWADstOperand::convertToSDWA(
MI,
TII);
501std::optional<int64_t>
515 if (!
TII->isFoldableCopy(*DefInst))
529std::unique_ptr<SDWAOperand>
531 unsigned Opcode =
MI.getOpcode();
533 case AMDGPU::V_LSHRREV_B32_e32:
534 case AMDGPU::V_ASHRREV_I32_e32:
535 case AMDGPU::V_LSHLREV_B32_e32:
536 case AMDGPU::V_LSHRREV_B32_e64:
537 case AMDGPU::V_ASHRREV_I32_e64:
538 case AMDGPU::V_LSHLREV_B32_e64: {
548 auto Imm = foldToImm(*Src0);
552 if (*Imm != 16 && *Imm != 24)
558 Dst->getReg().isPhysical())
561 if (Opcode == AMDGPU::V_LSHLREV_B32_e32 ||
562 Opcode == AMDGPU::V_LSHLREV_B32_e64) {
563 return std::make_unique<SDWADstOperand>(
566 return std::make_unique<SDWASrcOperand>(
568 Opcode != AMDGPU::V_LSHRREV_B32_e32 &&
569 Opcode != AMDGPU::V_LSHRREV_B32_e64);
574 case AMDGPU::V_LSHRREV_B16_e32:
575 case AMDGPU::V_ASHRREV_I16_e32:
576 case AMDGPU::V_LSHLREV_B16_e32:
577 case AMDGPU::V_LSHRREV_B16_e64:
578 case AMDGPU::V_ASHRREV_I16_e64:
579 case AMDGPU::V_LSHLREV_B16_e64: {
589 auto Imm = foldToImm(*Src0);
590 if (!Imm || *Imm != 8)
597 Dst->getReg().isPhysical())
600 if (Opcode == AMDGPU::V_LSHLREV_B16_e32 ||
601 Opcode == AMDGPU::V_LSHLREV_B16_e64) {
604 return std::make_unique<SDWASrcOperand>(
605 Src1, Dst,
BYTE_1,
false,
false,
606 Opcode != AMDGPU::V_LSHRREV_B16_e32 &&
607 Opcode != AMDGPU::V_LSHRREV_B16_e64);
612 case AMDGPU::V_BFE_I32_e64:
613 case AMDGPU::V_BFE_U32_e64: {
629 auto Offset = foldToImm(*Src1);
634 auto Width = foldToImm(*Src2);
640 if (*
Offset == 0 && *Width == 8)
642 else if (*
Offset == 0 && *Width == 16)
644 else if (*
Offset == 0 && *Width == 32)
646 else if (*
Offset == 8 && *Width == 8)
648 else if (*
Offset == 16 && *Width == 8)
650 else if (*
Offset == 16 && *Width == 16)
652 else if (*
Offset == 24 && *Width == 8)
661 Dst->getReg().isPhysical())
664 return std::make_unique<SDWASrcOperand>(
665 Src0, Dst, SrcSel,
false,
false, Opcode != AMDGPU::V_BFE_U32_e64);
668 case AMDGPU::V_AND_B32_e32:
669 case AMDGPU::V_AND_B32_e64: {
677 auto Imm = foldToImm(*Src0);
680 Imm = foldToImm(*Src1);
684 if (!Imm || (*Imm != 0x0000ffff && *Imm != 0x000000ff))
689 if (!ValSrc->isReg() || ValSrc->getReg().isPhysical() ||
690 Dst->getReg().isPhysical())
693 return std::make_unique<SDWASrcOperand>(
697 case AMDGPU::V_OR_B32_e32:
698 case AMDGPU::V_OR_B32_e64: {
709 std::optional<std::pair<MachineOperand *, MachineOperand *>>;
710 auto CheckOROperandsForSDWA =
712 if (!Op1 || !Op1->
isReg() || !Op2 || !Op2->isReg())
713 return CheckRetType(std::nullopt);
717 return CheckRetType(std::nullopt);
720 if (!
TII->isSDWA(*Op1Inst))
721 return CheckRetType(std::nullopt);
725 return CheckRetType(std::nullopt);
727 return CheckRetType(std::pair(Op1Def, Op2Def));
732 assert(OrSDWA && OrOther);
733 auto Res = CheckOROperandsForSDWA(OrSDWA, OrOther);
735 OrSDWA =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
736 OrOther =
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
737 assert(OrSDWA && OrOther);
738 Res = CheckOROperandsForSDWA(OrSDWA, OrOther);
745 assert(OrSDWADef && OrOtherDef);
770 if (!
TII->isSDWA(*OtherInst))
774 TII->getNamedImmOperand(*SDWAInst, AMDGPU::OpName::dst_sel));
776 TII->getNamedImmOperand(*OtherInst, AMDGPU::OpName::dst_sel));
778 bool DstSelAgree =
false;
781 (OtherDstSel ==
BYTE_3) ||
785 (OtherDstSel ==
BYTE_1) ||
789 (OtherDstSel ==
BYTE_2) ||
790 (OtherDstSel ==
BYTE_3) ||
794 (OtherDstSel ==
BYTE_2) ||
795 (OtherDstSel ==
BYTE_3) ||
799 (OtherDstSel ==
BYTE_1) ||
800 (OtherDstSel ==
BYTE_3) ||
804 (OtherDstSel ==
BYTE_1) ||
805 (OtherDstSel ==
BYTE_2) ||
808 default: DstSelAgree =
false;
816 TII->getNamedImmOperand(*OtherInst, AMDGPU::OpName::dst_unused));
817 if (OtherDstUnused != DstUnused::UNUSED_PAD)
824 return std::make_unique<SDWADstPreserveOperand>(
825 OrDst, OrSDWADef, OrOtherDef, DstSel);
830 return std::unique_ptr<SDWAOperand>(
nullptr);
842 if (
auto Operand = matchSDWAOperand(
MI)) {
844 SDWAOperands[&
MI] = std::move(Operand);
845 ++NumSDWAPatternsFound;
870 int Opc =
MI.getOpcode();
871 assert((Opc == AMDGPU::V_ADD_CO_U32_e64 || Opc == AMDGPU::V_SUB_CO_U32_e64) &&
872 "Currently only handles V_ADD_CO_U32_e64 or V_SUB_CO_U32_e64");
902 for (
auto I = std::next(
MI.getIterator()), E = MISucc.
getIterator();
904 if (
I->modifiesRegister(AMDGPU::VCC,
TRI))
910 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::vdst))
911 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::src0))
912 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::src1))
915 MI.eraseFromParent();
925 unsigned Opc =
MI.getOpcode();
926 if (
TII->isSDWA(Opc))
936 if (!
ST.hasSDWAOmod() &&
TII->hasModifiersSet(
MI, AMDGPU::OpName::omod))
939 if (
TII->isVOPC(Opc)) {
940 if (!
ST.hasSDWASdst()) {
942 if (SDst && (SDst->
getReg() != AMDGPU::VCC &&
943 SDst->
getReg() != AMDGPU::VCC_LO))
947 if (!
ST.hasSDWAOutModsVOPC() &&
948 (
TII->hasModifiersSet(
MI, AMDGPU::OpName::clamp) ||
949 TII->hasModifiersSet(
MI, AMDGPU::OpName::omod)))
952 }
else if (
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst) ||
953 !
TII->getNamedOperand(
MI, AMDGPU::OpName::vdst)) {
957 if (!
ST.hasSDWAMac() && (Opc == AMDGPU::V_FMAC_F16_e32 ||
958 Opc == AMDGPU::V_FMAC_F32_e32 ||
959 Opc == AMDGPU::V_MAC_F16_e32 ||
960 Opc == AMDGPU::V_MAC_F32_e32))
964 if (
TII->pseudoToMCOpcode(Opc) == -1)
968 if (Opc == AMDGPU::V_CNDMASK_B32_e32)
985 const SDWAOperandsVector &SDWAOperands) {
991 unsigned Opcode =
MI.getOpcode();
992 if (
TII->isSDWA(Opcode)) {
996 if (SDWAOpcode == -1)
1013 }
else if ((Dst =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst))) {
1026 if (
auto *
Mod =
TII->getNamedOperand(
MI, AMDGPU::OpName::src0_modifiers))
1030 SDWAInst.
add(*Src0);
1037 if (
auto *
Mod =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_modifiers))
1041 SDWAInst.
add(*Src1);
1044 if (SDWAOpcode == AMDGPU::V_FMAC_F16_sdwa ||
1045 SDWAOpcode == AMDGPU::V_FMAC_F32_sdwa ||
1046 SDWAOpcode == AMDGPU::V_MAC_F16_sdwa ||
1047 SDWAOpcode == AMDGPU::V_MAC_F32_sdwa) {
1051 SDWAInst.
add(*Src2);
1058 SDWAInst.
add(*Clamp);
1067 SDWAInst.
add(*OMod);
1077 SDWAInst.
add(*DstSel);
1079 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1089 SDWAInst.
addImm(AMDGPU::SDWA::DstUnused::UNUSED_PAD);
1097 SDWAInst.
add(*Src0Sel);
1099 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1107 SDWAInst.
add(*Src1Sel);
1109 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1114 auto DstUnused =
TII->getNamedOperand(
MI, AMDGPU::OpName::dst_unused);
1116 DstUnused->getImm() == AMDGPU::SDWA::DstUnused::UNUSED_PRESERVE) {
1119 assert(Dst && Dst->isTied());
1120 assert(Opcode ==
static_cast<unsigned int>(SDWAOpcode));
1123 assert(PreserveDstIdx != -1);
1125 auto TiedIdx =
MI.findTiedOperandIdx(PreserveDstIdx);
1126 auto Tied =
MI.getOperand(TiedIdx);
1133 bool Converted =
false;
1134 for (
auto &Operand : SDWAOperands) {
1146 if (PotentialMatches.
count(Operand->getParentInst()) == 0)
1147 Converted |= Operand->convertToSDWA(*SDWAInst,
TII);
1150 ConvertedInstructions.
push_back(SDWAInst);
1157 ++NumSDWAInstructionsPeepholed;
1159 MI.eraseFromParent();
1168 unsigned ConstantBusCount = 0;
1170 if (!
Op.isImm() && !(
Op.isReg() && !
TRI->isVGPR(*
MRI,
Op.getReg())))
1173 unsigned I =
Op.getOperandNo();
1174 if (
Desc.operands()[
I].RegClass == -1 ||
1175 !
TRI->isVSSuperClass(
TRI->getRegClass(
Desc.operands()[
I].RegClass)))
1178 if (
ST.hasSDWAScalar() && ConstantBusCount == 0 &&
Op.isReg() &&
1179 TRI->isSGPRReg(*
MRI,
Op.getReg())) {
1184 Register VGPR =
MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1186 TII->get(AMDGPU::V_MOV_B32_e32), VGPR);
1188 Copy.addImm(
Op.getImm());
1189 else if (
Op.isReg())
1192 Op.ChangeToRegister(VGPR,
false);
1203 TRI =
ST.getRegisterInfo();
1204 TII =
ST.getInstrInfo();
1209 bool Changed =
false;
1215 matchSDWAOperands(
MBB);
1216 for (
const auto &OperandPair : SDWAOperands) {
1217 const auto &Operand = OperandPair.second;
1220 (PotentialMI->
getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
1221 PotentialMI->
getOpcode() == AMDGPU::V_SUB_CO_U32_e64))
1222 pseudoOpConvertToVOP2(*PotentialMI, ST);
1224 SDWAOperands.clear();
1227 matchSDWAOperands(
MBB);
1229 for (
const auto &OperandPair : SDWAOperands) {
1230 const auto &Operand = OperandPair.second;
1232 if (PotentialMI && isConvertibleToSDWA(*PotentialMI, ST)) {
1233 PotentialMatches[PotentialMI].push_back(Operand.get());
1237 for (
auto &PotentialPair : PotentialMatches) {
1239 convertToSDWA(PotentialMI, PotentialPair.second);
1242 PotentialMatches.clear();
1243 SDWAOperands.clear();
1245 Changed = !ConvertedInstructions.
empty();
1249 while (!ConvertedInstructions.
empty())
1250 legalizeScalarOperands(*ConvertedInstructions.
pop_back_val(), ST);
unsigned const MachineRegisterInfo * MRI
Provides AMDGPU specific target descriptions.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
BlockVerifier::State From
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MachineOperand * findSingleRegDef(const MachineOperand *Reg, const MachineRegisterInfo *MRI)
static void copyRegOperand(MachineOperand &To, const MachineOperand &From)
static MachineOperand * findSingleRegUse(const MachineOperand *Reg, const MachineRegisterInfo *MRI)
static bool isSameReg(const MachineOperand &LHS, const MachineOperand &RHS)
static raw_ostream & operator<<(raw_ostream &OS, SdwaSel Sel)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, MCRegister Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been defined and not killed as of just before Before.
@ LQR_Dead
Register is known to be fully dead.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
size_type count(const KeyT &Key) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
LLVM_READONLY int getVOPe32(uint16_t Opcode)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
LLVM_READONLY int getSDWAOp(uint16_t Opcode)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
@ Kill
The last use of a register.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createSIPeepholeSDWAPass()
void initializeSIPeepholeSDWAPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Description of the encoding of one expression Op.