32#define DEBUG_TYPE "si-peephole-sdwa"
34STATISTIC(NumSDWAPatternsFound,
"Number of SDWA patterns found.");
36 "Number of instruction converted to SDWA.");
55 SDWAOperandsMap PotentialMatches;
72 bool convertToSDWA(
MachineInstr &
MI,
const SDWAOperandsVector &SDWAOperands);
90 :
Target(TargetOp), Replaced(ReplacedOp) {
95 virtual ~SDWAOperand() =
default;
99 SDWAOperandsMap *PotentialMatches =
nullptr) = 0;
107 return &getParentInst()->getParent()->getParent()->getRegInfo();
110#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
116using namespace AMDGPU::SDWA;
118class SDWASrcOperand :
public SDWAOperand {
127 SdwaSel SrcSel_ =
DWORD,
bool Abs_ =
false,
bool Neg_ =
false,
129 : SDWAOperand(TargetOp, ReplacedOp),
130 SrcSel(SrcSel_), Abs(Abs_), Neg(Neg_), Sext(Sext_) {}
134 SDWAOperandsMap *PotentialMatches =
nullptr)
override;
137 SdwaSel getSrcSel()
const {
return SrcSel; }
138 bool getAbs()
const {
return Abs; }
139 bool getNeg()
const {
return Neg; }
140 bool getSext()
const {
return Sext; }
145#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
150class SDWADstOperand :
public SDWAOperand {
159 : SDWAOperand(TargetOp, ReplacedOp), DstSel(DstSel_), DstUn(DstUn_) {}
163 SDWAOperandsMap *PotentialMatches =
nullptr)
override;
166 SdwaSel getDstSel()
const {
return DstSel; }
167 DstUnused getDstUnused()
const {
return DstUn; }
169#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
174class SDWADstPreserveOperand :
public SDWADstOperand {
182 Preserve(PreserveOp) {}
188#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
197char SIPeepholeSDWA::
ID = 0;
202 return new SIPeepholeSDWA();
206#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
215 case DWORD:
OS <<
"DWORD";
break;
231 OS <<
"SDWA src: " << *getTargetOperand()
232 <<
" src_sel:" << getSrcSel()
233 <<
" abs:" << getAbs() <<
" neg:" << getNeg()
234 <<
" sext:" << getSext() <<
'\n';
239 OS <<
"SDWA dst: " << *getTargetOperand()
240 <<
" dst_sel:" << getDstSel()
241 <<
" dst_unused:" << getDstUnused() <<
'\n';
246 OS <<
"SDWA preserve dst: " << *getTargetOperand()
247 <<
" dst_sel:" << getDstSel()
248 <<
" preserve:" << *getPreservedOperand() <<
'\n';
266 return LHS.isReg() &&
268 LHS.getReg() ==
RHS.getReg() &&
269 LHS.getSubReg() ==
RHS.getSubReg();
274 if (!Reg->isReg() || !Reg->isDef())
303 for (
auto &DefMO : DefInstr->
defs()) {
304 if (DefMO.isReg() && DefMO.getReg() == Reg->getReg())
315 const auto *
MI =
SrcOp->getParent();
316 if (
TII->getNamedOperand(*
MI, AMDGPU::OpName::src0) ==
SrcOp) {
317 if (
auto *
Mod =
TII->getNamedOperand(*
MI, AMDGPU::OpName::src0_modifiers)) {
318 Mods =
Mod->getImm();
320 }
else if (
TII->getNamedOperand(*
MI, AMDGPU::OpName::src1) ==
SrcOp) {
321 if (
auto *
Mod =
TII->getNamedOperand(*
MI, AMDGPU::OpName::src1_modifiers)) {
322 Mods =
Mod->getImm();
327 "Float and integer src modifiers can't be set simultaneously");
339 SDWAOperandsMap *PotentialMatches) {
340 if (PotentialMatches !=
nullptr) {
343 if (!
Reg->isReg() || !
Reg->isDef())
348 if (!isConvertibleToSDWA(
UseMI, ST,
TII))
357 SDWAOperandsMap &potentialMatchesMap = *PotentialMatches;
359 potentialMatchesMap[
UseMI].push_back(
this);
374 switch (
MI.getOpcode()) {
375 case AMDGPU::V_CVT_F32_FP8_sdwa:
376 case AMDGPU::V_CVT_F32_BF8_sdwa:
377 case AMDGPU::V_CVT_PK_F32_FP8_sdwa:
378 case AMDGPU::V_CVT_PK_F32_BF8_sdwa:
385 bool IsPreserveSrc =
false;
389 TII->getNamedOperand(
MI, AMDGPU::OpName::src0_modifiers);
390 assert(Src && (Src->isReg() || Src->isImm()));
391 if (!
isSameReg(*Src, *getReplacedOperand())) {
393 Src =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
394 SrcSel =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_sel);
395 SrcMods =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_modifiers);
398 !
isSameReg(*Src, *getReplacedOperand())) {
407 TII->getNamedOperand(
MI, AMDGPU::OpName::dst_unused);
410 DstUnused->getImm() == AMDGPU::SDWA::DstUnused::UNUSED_PRESERVE) {
416 TII->getNamedImmOperand(
MI, AMDGPU::OpName::dst_sel));
417 if (DstSel == AMDGPU::SDWA::SdwaSel::WORD_1 &&
418 getSrcSel() == AMDGPU::SDWA::SdwaSel::WORD_0) {
419 IsPreserveSrc =
true;
421 AMDGPU::OpName::vdst);
422 auto TiedIdx =
MI.findTiedOperandIdx(DstIdx);
423 Src = &
MI.getOperand(TiedIdx);
432 assert(Src && Src->isReg());
434 if ((
MI.getOpcode() == AMDGPU::V_FMAC_F16_sdwa ||
435 MI.getOpcode() == AMDGPU::V_FMAC_F32_sdwa ||
436 MI.getOpcode() == AMDGPU::V_MAC_F16_sdwa ||
437 MI.getOpcode() == AMDGPU::V_MAC_F32_sdwa) &&
438 !
isSameReg(*Src, *getReplacedOperand())) {
445 (IsPreserveSrc || (SrcSel && SrcMods)));
448 if (!IsPreserveSrc) {
449 SrcSel->
setImm(getSrcSel());
452 getTargetOperand()->setIsKill(
false);
458 SDWAOperandsMap *PotentialMatches) {
470 if (&UseInst != ParentMI)
480 if ((
MI.getOpcode() == AMDGPU::V_FMAC_F16_sdwa ||
481 MI.getOpcode() == AMDGPU::V_FMAC_F32_sdwa ||
482 MI.getOpcode() == AMDGPU::V_MAC_F16_sdwa ||
483 MI.getOpcode() == AMDGPU::V_MAC_F32_sdwa) &&
492 isSameReg(*Operand, *getReplacedOperand()));
496 DstSel->
setImm(getDstSel());
503 getParentInst()->eraseFromParent();
515 getMRI()->clearKillFlags(MO.getReg());
519 MI.getParent()->remove(&
MI);
520 getParentInst()->getParent()->insert(getParentInst(), &
MI);
524 MIB.addReg(getPreservedOperand()->
getReg(),
526 getPreservedOperand()->getSubReg());
530 MI.getNumOperands() - 1);
533 return SDWADstOperand::convertToSDWA(
MI,
TII);
536std::optional<int64_t>
550 if (!
TII->isFoldableCopy(*DefInst))
564std::unique_ptr<SDWAOperand>
566 unsigned Opcode =
MI.getOpcode();
568 case AMDGPU::V_LSHRREV_B32_e32:
569 case AMDGPU::V_ASHRREV_I32_e32:
570 case AMDGPU::V_LSHLREV_B32_e32:
571 case AMDGPU::V_LSHRREV_B32_e64:
572 case AMDGPU::V_ASHRREV_I32_e64:
573 case AMDGPU::V_LSHLREV_B32_e64: {
583 auto Imm = foldToImm(*Src0);
587 if (*Imm != 16 && *Imm != 24)
593 Dst->getReg().isPhysical())
596 if (Opcode == AMDGPU::V_LSHLREV_B32_e32 ||
597 Opcode == AMDGPU::V_LSHLREV_B32_e64) {
598 return std::make_unique<SDWADstOperand>(
601 return std::make_unique<SDWASrcOperand>(
603 Opcode != AMDGPU::V_LSHRREV_B32_e32 &&
604 Opcode != AMDGPU::V_LSHRREV_B32_e64);
608 case AMDGPU::V_LSHRREV_B16_e32:
609 case AMDGPU::V_ASHRREV_I16_e32:
610 case AMDGPU::V_LSHLREV_B16_e32:
611 case AMDGPU::V_LSHRREV_B16_e64:
612 case AMDGPU::V_ASHRREV_I16_e64:
613 case AMDGPU::V_LSHLREV_B16_e64: {
623 auto Imm = foldToImm(*Src0);
624 if (!Imm || *Imm != 8)
631 Dst->getReg().isPhysical())
634 if (Opcode == AMDGPU::V_LSHLREV_B16_e32 ||
635 Opcode == AMDGPU::V_LSHLREV_B16_e64)
637 return std::make_unique<SDWASrcOperand>(
638 Src1, Dst,
BYTE_1,
false,
false,
639 Opcode != AMDGPU::V_LSHRREV_B16_e32 &&
640 Opcode != AMDGPU::V_LSHRREV_B16_e64);
644 case AMDGPU::V_BFE_I32_e64:
645 case AMDGPU::V_BFE_U32_e64: {
661 auto Offset = foldToImm(*Src1);
666 auto Width = foldToImm(*Src2);
672 if (*
Offset == 0 && *Width == 8)
674 else if (*
Offset == 0 && *Width == 16)
676 else if (*
Offset == 0 && *Width == 32)
678 else if (*
Offset == 8 && *Width == 8)
680 else if (*
Offset == 16 && *Width == 8)
682 else if (*
Offset == 16 && *Width == 16)
684 else if (*
Offset == 24 && *Width == 8)
693 Dst->getReg().isPhysical())
696 return std::make_unique<SDWASrcOperand>(
697 Src0, Dst, SrcSel,
false,
false, Opcode != AMDGPU::V_BFE_U32_e64);
700 case AMDGPU::V_AND_B32_e32:
701 case AMDGPU::V_AND_B32_e64: {
709 auto Imm = foldToImm(*Src0);
712 Imm = foldToImm(*Src1);
716 if (!Imm || (*Imm != 0x0000ffff && *Imm != 0x000000ff))
721 if (!ValSrc->isReg() || ValSrc->getReg().isPhysical() ||
722 Dst->getReg().isPhysical())
725 return std::make_unique<SDWASrcOperand>(
729 case AMDGPU::V_OR_B32_e32:
730 case AMDGPU::V_OR_B32_e64: {
741 std::optional<std::pair<MachineOperand *, MachineOperand *>>;
742 auto CheckOROperandsForSDWA =
744 if (!Op1 || !Op1->
isReg() || !Op2 || !Op2->isReg())
745 return CheckRetType(std::nullopt);
749 return CheckRetType(std::nullopt);
752 if (!
TII->isSDWA(*Op1Inst))
753 return CheckRetType(std::nullopt);
757 return CheckRetType(std::nullopt);
759 return CheckRetType(std::pair(Op1Def, Op2Def));
764 assert(OrSDWA && OrOther);
765 auto Res = CheckOROperandsForSDWA(OrSDWA, OrOther);
767 OrSDWA =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
768 OrOther =
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
769 assert(OrSDWA && OrOther);
770 Res = CheckOROperandsForSDWA(OrSDWA, OrOther);
777 assert(OrSDWADef && OrOtherDef);
802 if (!
TII->isSDWA(*OtherInst))
806 TII->getNamedImmOperand(*SDWAInst, AMDGPU::OpName::dst_sel));
808 TII->getNamedImmOperand(*OtherInst, AMDGPU::OpName::dst_sel));
810 bool DstSelAgree =
false;
813 (OtherDstSel ==
BYTE_3) ||
817 (OtherDstSel ==
BYTE_1) ||
821 (OtherDstSel ==
BYTE_2) ||
822 (OtherDstSel ==
BYTE_3) ||
826 (OtherDstSel ==
BYTE_2) ||
827 (OtherDstSel ==
BYTE_3) ||
831 (OtherDstSel ==
BYTE_1) ||
832 (OtherDstSel ==
BYTE_3) ||
836 (OtherDstSel ==
BYTE_1) ||
837 (OtherDstSel ==
BYTE_2) ||
840 default: DstSelAgree =
false;
848 TII->getNamedImmOperand(*OtherInst, AMDGPU::OpName::dst_unused));
849 if (OtherDstUnused != DstUnused::UNUSED_PAD)
856 return std::make_unique<SDWADstPreserveOperand>(
857 OrDst, OrSDWADef, OrOtherDef, DstSel);
862 return std::unique_ptr<SDWAOperand>(
nullptr);
874 if (
auto Operand = matchSDWAOperand(
MI)) {
876 SDWAOperands[&
MI] = std::move(Operand);
877 ++NumSDWAPatternsFound;
902 int Opc =
MI.getOpcode();
903 assert((Opc == AMDGPU::V_ADD_CO_U32_e64 || Opc == AMDGPU::V_SUB_CO_U32_e64) &&
904 "Currently only handles V_ADD_CO_U32_e64 or V_SUB_CO_U32_e64");
934 for (
auto I = std::next(
MI.getIterator()), E = MISucc.
getIterator();
936 if (
I->modifiesRegister(AMDGPU::VCC,
TRI))
942 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::vdst))
943 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::src0))
944 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::src1))
947 MI.eraseFromParent();
959 unsigned Opc =
MI.getOpcode();
960 if (
TII->isSDWA(Opc))
970 if (!
ST.hasSDWAOmod() &&
TII->hasModifiersSet(
MI, AMDGPU::OpName::omod))
973 if (
TII->isVOPC(Opc)) {
974 if (!
ST.hasSDWASdst()) {
976 if (SDst && (SDst->
getReg() != AMDGPU::VCC &&
977 SDst->
getReg() != AMDGPU::VCC_LO))
981 if (!
ST.hasSDWAOutModsVOPC() &&
982 (
TII->hasModifiersSet(
MI, AMDGPU::OpName::clamp) ||
983 TII->hasModifiersSet(
MI, AMDGPU::OpName::omod)))
986 }
else if (
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst) ||
987 !
TII->getNamedOperand(
MI, AMDGPU::OpName::vdst)) {
991 if (!
ST.hasSDWAMac() && (Opc == AMDGPU::V_FMAC_F16_e32 ||
992 Opc == AMDGPU::V_FMAC_F32_e32 ||
993 Opc == AMDGPU::V_MAC_F16_e32 ||
994 Opc == AMDGPU::V_MAC_F32_e32))
998 if (
TII->pseudoToMCOpcode(Opc) == -1)
1002 if (Opc == AMDGPU::V_CNDMASK_B32_e32)
1020 const SDWAOperandsVector &SDWAOperands) {
1026 unsigned Opcode =
MI.getOpcode();
1027 if (
TII->isSDWA(Opcode)) {
1028 SDWAOpcode = Opcode;
1031 if (SDWAOpcode == -1)
1034 assert(SDWAOpcode != -1);
1048 }
else if ((Dst =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst))) {
1061 if (
auto *
Mod =
TII->getNamedOperand(
MI, AMDGPU::OpName::src0_modifiers))
1065 SDWAInst.
add(*Src0);
1072 if (
auto *
Mod =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_modifiers))
1076 SDWAInst.
add(*Src1);
1079 if (SDWAOpcode == AMDGPU::V_FMAC_F16_sdwa ||
1080 SDWAOpcode == AMDGPU::V_FMAC_F32_sdwa ||
1081 SDWAOpcode == AMDGPU::V_MAC_F16_sdwa ||
1082 SDWAOpcode == AMDGPU::V_MAC_F32_sdwa) {
1086 SDWAInst.
add(*Src2);
1093 SDWAInst.
add(*Clamp);
1102 SDWAInst.
add(*OMod);
1112 SDWAInst.
add(*DstSel);
1114 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1124 SDWAInst.
addImm(AMDGPU::SDWA::DstUnused::UNUSED_PAD);
1132 SDWAInst.
add(*Src0Sel);
1134 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1142 SDWAInst.
add(*Src1Sel);
1144 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1149 auto DstUnused =
TII->getNamedOperand(
MI, AMDGPU::OpName::dst_unused);
1151 DstUnused->getImm() == AMDGPU::SDWA::DstUnused::UNUSED_PRESERVE) {
1154 assert(Dst && Dst->isTied());
1155 assert(Opcode ==
static_cast<unsigned int>(SDWAOpcode));
1158 assert(PreserveDstIdx != -1);
1160 auto TiedIdx =
MI.findTiedOperandIdx(PreserveDstIdx);
1161 auto Tied =
MI.getOperand(TiedIdx);
1168 bool Converted =
false;
1169 for (
auto &Operand : SDWAOperands) {
1181 if (PotentialMatches.count(Operand->getParentInst()) == 0)
1182 Converted |= Operand->convertToSDWA(*SDWAInst,
TII);
1186 ConvertedInstructions.
push_back(SDWAInst);
1191 MRI->clearKillFlags(MO.getReg());
1199 ++NumSDWAInstructionsPeepholed;
1201 MI.eraseFromParent();
1210 unsigned ConstantBusCount = 0;
1212 if (!
Op.isImm() && !(
Op.isReg() && !
TRI->isVGPR(*
MRI,
Op.getReg())))
1215 unsigned I =
Op.getOperandNo();
1216 if (
Desc.operands()[
I].RegClass == -1 ||
1217 !
TRI->isVSSuperClass(
TRI->getRegClass(
Desc.operands()[
I].RegClass)))
1220 if (
ST.hasSDWAScalar() && ConstantBusCount == 0 &&
Op.isReg() &&
1221 TRI->isSGPRReg(*
MRI,
Op.getReg())) {
1226 Register VGPR =
MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1228 TII->get(AMDGPU::V_MOV_B32_e32), VGPR);
1230 Copy.addImm(
Op.getImm());
1231 else if (
Op.isReg())
1234 Op.ChangeToRegister(VGPR,
false);
1245 TRI =
ST.getRegisterInfo();
1246 TII =
ST.getInstrInfo();
1251 bool Changed =
false;
1257 matchSDWAOperands(
MBB);
1258 for (
const auto &OperandPair : SDWAOperands) {
1259 const auto &Operand = OperandPair.second;
1262 (PotentialMI->
getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
1263 PotentialMI->
getOpcode() == AMDGPU::V_SUB_CO_U32_e64))
1264 pseudoOpConvertToVOP2(*PotentialMI, ST);
1266 SDWAOperands.clear();
1269 matchSDWAOperands(
MBB);
1271 for (
const auto &OperandPair : SDWAOperands) {
1272 const auto &Operand = OperandPair.second;
1273 MachineInstr *PotentialMI = Operand->potentialToConvert(
TII, ST, &PotentialMatches);
1274 if (PotentialMI && isConvertibleToSDWA(*PotentialMI, ST,
TII)) {
1275 PotentialMatches[PotentialMI].push_back(Operand.get());
1279 for (
auto &PotentialPair : PotentialMatches) {
1281 convertToSDWA(PotentialMI, PotentialPair.second);
1284 PotentialMatches.clear();
1285 SDWAOperands.clear();
1287 Changed = !ConvertedInstructions.
empty();
1291 while (!ConvertedInstructions.
empty())
1292 legalizeScalarOperands(*ConvertedInstructions.
pop_back_val(), ST);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
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)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#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
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
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.
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.
Reg
All possible values of the reg field in the ModR/M byte.
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.