33#define DEBUG_TYPE "si-peephole-sdwa"
35STATISTIC(NumSDWAPatternsFound,
"Number of SDWA patterns found.");
37 "Number of instruction converted to SDWA.");
56 SDWAOperandsMap PotentialMatches;
65 bool convertToSDWA(
MachineInstr &
MI,
const SDWAOperandsVector &SDWAOperands);
95 :
Target(TargetOp), Replaced(ReplacedOp) {
100 virtual ~SDWAOperand() =
default;
104 SDWAOperandsMap *PotentialMatches =
nullptr) = 0;
112 return &getParentInst()->getParent()->getParent()->getRegInfo();
115#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
121using namespace AMDGPU::SDWA;
123class SDWASrcOperand :
public SDWAOperand {
132 SdwaSel SrcSel_ =
DWORD,
bool Abs_ =
false,
bool Neg_ =
false,
134 : SDWAOperand(TargetOp, ReplacedOp),
135 SrcSel(SrcSel_), Abs(Abs_), Neg(Neg_), Sext(Sext_) {}
139 SDWAOperandsMap *PotentialMatches =
nullptr)
override;
142 SdwaSel getSrcSel()
const {
return SrcSel; }
143 bool getAbs()
const {
return Abs; }
144 bool getNeg()
const {
return Neg; }
145 bool getSext()
const {
return Sext; }
150#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
155class SDWADstOperand :
public SDWAOperand {
164 : SDWAOperand(TargetOp, ReplacedOp), DstSel(DstSel_), DstUn(DstUn_) {}
168 SDWAOperandsMap *PotentialMatches =
nullptr)
override;
171 SdwaSel getDstSel()
const {
return DstSel; }
172 DstUnused getDstUnused()
const {
return DstUn; }
174#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
179class SDWADstPreserveOperand :
public SDWADstOperand {
187 Preserve(PreserveOp) {}
193#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
203char SIPeepholeSDWALegacy::
ID = 0;
208 return new SIPeepholeSDWALegacy();
211#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
220 case DWORD:
OS <<
"DWORD";
break;
236 OS <<
"SDWA src: " << *getTargetOperand()
237 <<
" src_sel:" << getSrcSel()
238 <<
" abs:" << getAbs() <<
" neg:" << getNeg()
239 <<
" sext:" << getSext() <<
'\n';
244 OS <<
"SDWA dst: " << *getTargetOperand()
245 <<
" dst_sel:" << getDstSel()
246 <<
" dst_unused:" << getDstUnused() <<
'\n';
251 OS <<
"SDWA preserve dst: " << *getTargetOperand()
252 <<
" dst_sel:" << getDstSel()
253 <<
" preserve:" << *getPreservedOperand() <<
'\n';
271 return LHS.isReg() &&
273 LHS.getReg() ==
RHS.getReg() &&
274 LHS.getSubReg() ==
RHS.getSubReg();
279 if (!Reg->isReg() || !Reg->isDef())
308 for (
auto &DefMO : DefInstr->
defs()) {
309 if (DefMO.isReg() && DefMO.getReg() == Reg->getReg())
320 const auto *
MI =
SrcOp->getParent();
321 if (
TII->getNamedOperand(*
MI, AMDGPU::OpName::src0) ==
SrcOp) {
322 if (
auto *
Mod =
TII->getNamedOperand(*
MI, AMDGPU::OpName::src0_modifiers)) {
323 Mods =
Mod->getImm();
325 }
else if (
TII->getNamedOperand(*
MI, AMDGPU::OpName::src1) ==
SrcOp) {
326 if (
auto *
Mod =
TII->getNamedOperand(*
MI, AMDGPU::OpName::src1_modifiers)) {
327 Mods =
Mod->getImm();
332 "Float and integer src modifiers can't be set simultaneously");
344 SDWAOperandsMap *PotentialMatches) {
345 if (PotentialMatches !=
nullptr) {
348 if (!
Reg->isReg() || !
Reg->isDef())
353 if (!isConvertibleToSDWA(
UseMI, ST,
TII))
362 SDWAOperandsMap &potentialMatchesMap = *PotentialMatches;
364 potentialMatchesMap[
UseMI].push_back(
this);
379 switch (
MI.getOpcode()) {
380 case AMDGPU::V_CVT_F32_FP8_sdwa:
381 case AMDGPU::V_CVT_F32_BF8_sdwa:
382 case AMDGPU::V_CVT_PK_F32_FP8_sdwa:
383 case AMDGPU::V_CVT_PK_F32_BF8_sdwa:
390 bool IsPreserveSrc =
false;
394 TII->getNamedOperand(
MI, AMDGPU::OpName::src0_modifiers);
395 assert(Src && (Src->isReg() || Src->isImm()));
396 if (!
isSameReg(*Src, *getReplacedOperand())) {
398 Src =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
399 SrcSel =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_sel);
400 SrcMods =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_modifiers);
403 !
isSameReg(*Src, *getReplacedOperand())) {
412 TII->getNamedOperand(
MI, AMDGPU::OpName::dst_unused);
415 DstUnused->getImm() == AMDGPU::SDWA::DstUnused::UNUSED_PRESERVE) {
421 TII->getNamedImmOperand(
MI, AMDGPU::OpName::dst_sel));
422 if (DstSel == AMDGPU::SDWA::SdwaSel::WORD_1 &&
423 getSrcSel() == AMDGPU::SDWA::SdwaSel::WORD_0) {
424 IsPreserveSrc =
true;
426 AMDGPU::OpName::vdst);
427 auto TiedIdx =
MI.findTiedOperandIdx(DstIdx);
428 Src = &
MI.getOperand(TiedIdx);
437 assert(Src && Src->isReg());
439 if ((
MI.getOpcode() == AMDGPU::V_FMAC_F16_sdwa ||
440 MI.getOpcode() == AMDGPU::V_FMAC_F32_sdwa ||
441 MI.getOpcode() == AMDGPU::V_MAC_F16_sdwa ||
442 MI.getOpcode() == AMDGPU::V_MAC_F32_sdwa) &&
443 !
isSameReg(*Src, *getReplacedOperand())) {
450 (IsPreserveSrc || (SrcSel && SrcMods)));
453 if (!IsPreserveSrc) {
454 SrcSel->
setImm(getSrcSel());
457 getTargetOperand()->setIsKill(
false);
463 SDWAOperandsMap *PotentialMatches) {
475 if (&UseInst != ParentMI)
485 if ((
MI.getOpcode() == AMDGPU::V_FMAC_F16_sdwa ||
486 MI.getOpcode() == AMDGPU::V_FMAC_F32_sdwa ||
487 MI.getOpcode() == AMDGPU::V_MAC_F16_sdwa ||
488 MI.getOpcode() == AMDGPU::V_MAC_F32_sdwa) &&
497 isSameReg(*Operand, *getReplacedOperand()));
501 DstSel->
setImm(getDstSel());
508 getParentInst()->eraseFromParent();
520 getMRI()->clearKillFlags(MO.getReg());
524 MI.getParent()->remove(&
MI);
525 getParentInst()->getParent()->insert(getParentInst(), &
MI);
529 MIB.addReg(getPreservedOperand()->
getReg(),
531 getPreservedOperand()->getSubReg());
535 MI.getNumOperands() - 1);
538 return SDWADstOperand::convertToSDWA(
MI,
TII);
541std::optional<int64_t>
555 if (!
TII->isFoldableCopy(*DefInst))
569std::unique_ptr<SDWAOperand>
571 unsigned Opcode =
MI.getOpcode();
573 case AMDGPU::V_LSHRREV_B32_e32:
574 case AMDGPU::V_ASHRREV_I32_e32:
575 case AMDGPU::V_LSHLREV_B32_e32:
576 case AMDGPU::V_LSHRREV_B32_e64:
577 case AMDGPU::V_ASHRREV_I32_e64:
578 case AMDGPU::V_LSHLREV_B32_e64: {
588 auto Imm = foldToImm(*Src0);
592 if (*Imm != 16 && *Imm != 24)
598 Dst->getReg().isPhysical())
601 if (Opcode == AMDGPU::V_LSHLREV_B32_e32 ||
602 Opcode == AMDGPU::V_LSHLREV_B32_e64) {
603 return std::make_unique<SDWADstOperand>(
606 return std::make_unique<SDWASrcOperand>(
608 Opcode != AMDGPU::V_LSHRREV_B32_e32 &&
609 Opcode != AMDGPU::V_LSHRREV_B32_e64);
613 case AMDGPU::V_LSHRREV_B16_e32:
614 case AMDGPU::V_ASHRREV_I16_e32:
615 case AMDGPU::V_LSHLREV_B16_e32:
616 case AMDGPU::V_LSHRREV_B16_e64:
617 case AMDGPU::V_ASHRREV_I16_e64:
618 case AMDGPU::V_LSHLREV_B16_e64: {
628 auto Imm = foldToImm(*Src0);
629 if (!Imm || *Imm != 8)
636 Dst->getReg().isPhysical())
639 if (Opcode == AMDGPU::V_LSHLREV_B16_e32 ||
640 Opcode == AMDGPU::V_LSHLREV_B16_e64)
642 return std::make_unique<SDWASrcOperand>(
643 Src1, Dst,
BYTE_1,
false,
false,
644 Opcode != AMDGPU::V_LSHRREV_B16_e32 &&
645 Opcode != AMDGPU::V_LSHRREV_B16_e64);
649 case AMDGPU::V_BFE_I32_e64:
650 case AMDGPU::V_BFE_U32_e64: {
666 auto Offset = foldToImm(*Src1);
671 auto Width = foldToImm(*Src2);
677 if (*
Offset == 0 && *Width == 8)
679 else if (*
Offset == 0 && *Width == 16)
681 else if (*
Offset == 0 && *Width == 32)
683 else if (*
Offset == 8 && *Width == 8)
685 else if (*
Offset == 16 && *Width == 8)
687 else if (*
Offset == 16 && *Width == 16)
689 else if (*
Offset == 24 && *Width == 8)
698 Dst->getReg().isPhysical())
701 return std::make_unique<SDWASrcOperand>(
702 Src0, Dst, SrcSel,
false,
false, Opcode != AMDGPU::V_BFE_U32_e64);
705 case AMDGPU::V_AND_B32_e32:
706 case AMDGPU::V_AND_B32_e64: {
714 auto Imm = foldToImm(*Src0);
717 Imm = foldToImm(*Src1);
721 if (!Imm || (*Imm != 0x0000ffff && *Imm != 0x000000ff))
726 if (!ValSrc->isReg() || ValSrc->getReg().isPhysical() ||
727 Dst->getReg().isPhysical())
730 return std::make_unique<SDWASrcOperand>(
734 case AMDGPU::V_OR_B32_e32:
735 case AMDGPU::V_OR_B32_e64: {
746 std::optional<std::pair<MachineOperand *, MachineOperand *>>;
747 auto CheckOROperandsForSDWA =
749 if (!Op1 || !Op1->
isReg() || !Op2 || !Op2->isReg())
750 return CheckRetType(std::nullopt);
754 return CheckRetType(std::nullopt);
757 if (!
TII->isSDWA(*Op1Inst))
758 return CheckRetType(std::nullopt);
762 return CheckRetType(std::nullopt);
764 return CheckRetType(std::pair(Op1Def, Op2Def));
769 assert(OrSDWA && OrOther);
770 auto Res = CheckOROperandsForSDWA(OrSDWA, OrOther);
772 OrSDWA =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
773 OrOther =
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
774 assert(OrSDWA && OrOther);
775 Res = CheckOROperandsForSDWA(OrSDWA, OrOther);
782 assert(OrSDWADef && OrOtherDef);
807 if (!
TII->isSDWA(*OtherInst))
811 TII->getNamedImmOperand(*SDWAInst, AMDGPU::OpName::dst_sel));
813 TII->getNamedImmOperand(*OtherInst, AMDGPU::OpName::dst_sel));
815 bool DstSelAgree =
false;
818 (OtherDstSel ==
BYTE_3) ||
822 (OtherDstSel ==
BYTE_1) ||
826 (OtherDstSel ==
BYTE_2) ||
827 (OtherDstSel ==
BYTE_3) ||
831 (OtherDstSel ==
BYTE_2) ||
832 (OtherDstSel ==
BYTE_3) ||
836 (OtherDstSel ==
BYTE_1) ||
837 (OtherDstSel ==
BYTE_3) ||
841 (OtherDstSel ==
BYTE_1) ||
842 (OtherDstSel ==
BYTE_2) ||
845 default: DstSelAgree =
false;
853 TII->getNamedImmOperand(*OtherInst, AMDGPU::OpName::dst_unused));
854 if (OtherDstUnused != DstUnused::UNUSED_PAD)
861 return std::make_unique<SDWADstPreserveOperand>(
862 OrDst, OrSDWADef, OrOtherDef, DstSel);
867 return std::unique_ptr<SDWAOperand>(
nullptr);
879 if (
auto Operand = matchSDWAOperand(
MI)) {
881 SDWAOperands[&
MI] = std::move(Operand);
882 ++NumSDWAPatternsFound;
907 int Opc =
MI.getOpcode();
908 assert((Opc == AMDGPU::V_ADD_CO_U32_e64 || Opc == AMDGPU::V_SUB_CO_U32_e64) &&
909 "Currently only handles V_ADD_CO_U32_e64 or V_SUB_CO_U32_e64");
939 for (
auto I = std::next(
MI.getIterator()), E = MISucc.
getIterator();
941 if (
I->modifiesRegister(AMDGPU::VCC,
TRI))
947 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::vdst))
948 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::src0))
949 .
add(*
TII->getNamedOperand(
MI, AMDGPU::OpName::src1))
952 MI.eraseFromParent();
964 unsigned Opc =
MI.getOpcode();
965 if (
TII->isSDWA(Opc)) {
978 if (!
ST.hasSDWAOmod() &&
TII->hasModifiersSet(
MI, AMDGPU::OpName::omod))
981 if (
TII->isVOPC(Opc)) {
982 if (!
ST.hasSDWASdst()) {
984 if (SDst && (SDst->
getReg() != AMDGPU::VCC &&
985 SDst->
getReg() != AMDGPU::VCC_LO))
989 if (!
ST.hasSDWAOutModsVOPC() &&
990 (
TII->hasModifiersSet(
MI, AMDGPU::OpName::clamp) ||
991 TII->hasModifiersSet(
MI, AMDGPU::OpName::omod)))
994 }
else if (
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst) ||
995 !
TII->getNamedOperand(
MI, AMDGPU::OpName::vdst)) {
999 if (!
ST.hasSDWAMac() && (Opc == AMDGPU::V_FMAC_F16_e32 ||
1000 Opc == AMDGPU::V_FMAC_F32_e32 ||
1001 Opc == AMDGPU::V_MAC_F16_e32 ||
1002 Opc == AMDGPU::V_MAC_F32_e32))
1006 if (
TII->pseudoToMCOpcode(Opc) == -1)
1010 if (Opc == AMDGPU::V_CNDMASK_B32_e32)
1028 const SDWAOperandsVector &SDWAOperands) {
1034 unsigned Opcode =
MI.getOpcode();
1035 if (
TII->isSDWA(Opcode)) {
1036 SDWAOpcode = Opcode;
1039 if (SDWAOpcode == -1)
1042 assert(SDWAOpcode != -1);
1056 }
else if ((Dst =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst))) {
1069 if (
auto *
Mod =
TII->getNamedOperand(
MI, AMDGPU::OpName::src0_modifiers))
1073 SDWAInst.
add(*Src0);
1080 if (
auto *
Mod =
TII->getNamedOperand(
MI, AMDGPU::OpName::src1_modifiers))
1084 SDWAInst.
add(*Src1);
1087 if (SDWAOpcode == AMDGPU::V_FMAC_F16_sdwa ||
1088 SDWAOpcode == AMDGPU::V_FMAC_F32_sdwa ||
1089 SDWAOpcode == AMDGPU::V_MAC_F16_sdwa ||
1090 SDWAOpcode == AMDGPU::V_MAC_F32_sdwa) {
1094 SDWAInst.
add(*Src2);
1101 SDWAInst.
add(*Clamp);
1110 SDWAInst.
add(*OMod);
1120 SDWAInst.
add(*DstSel);
1122 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1132 SDWAInst.
addImm(AMDGPU::SDWA::DstUnused::UNUSED_PAD);
1140 SDWAInst.
add(*Src0Sel);
1142 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1150 SDWAInst.
add(*Src1Sel);
1152 SDWAInst.
addImm(AMDGPU::SDWA::SdwaSel::DWORD);
1157 auto *
DstUnused =
TII->getNamedOperand(
MI, AMDGPU::OpName::dst_unused);
1159 DstUnused->getImm() == AMDGPU::SDWA::DstUnused::UNUSED_PRESERVE) {
1162 assert(Dst && Dst->isTied());
1163 assert(Opcode ==
static_cast<unsigned int>(SDWAOpcode));
1166 assert(PreserveDstIdx != -1);
1168 auto TiedIdx =
MI.findTiedOperandIdx(PreserveDstIdx);
1169 auto Tied =
MI.getOperand(TiedIdx);
1176 bool Converted =
false;
1177 for (
auto &Operand : SDWAOperands) {
1189 if (PotentialMatches.count(Operand->getParentInst()) == 0)
1190 Converted |= Operand->convertToSDWA(*SDWAInst,
TII);
1194 ConvertedInstructions.push_back(SDWAInst);
1199 MRI->clearKillFlags(MO.getReg());
1207 ++NumSDWAInstructionsPeepholed;
1209 MI.eraseFromParent();
1218 unsigned ConstantBusCount = 0;
1220 if (!
Op.isImm() && !(
Op.isReg() && !
TRI->isVGPR(*
MRI,
Op.getReg())))
1223 unsigned I =
Op.getOperandNo();
1224 if (
Desc.operands()[
I].RegClass == -1 ||
1225 !
TRI->isVSSuperClass(
TRI->getRegClass(
Desc.operands()[
I].RegClass)))
1228 if (
ST.hasSDWAScalar() && ConstantBusCount == 0 &&
Op.isReg() &&
1229 TRI->isSGPRReg(*
MRI,
Op.getReg())) {
1234 Register VGPR =
MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1236 TII->get(AMDGPU::V_MOV_B32_e32), VGPR);
1238 Copy.addImm(
Op.getImm());
1239 else if (
Op.isReg())
1242 Op.ChangeToRegister(VGPR,
false);
1250 return SIPeepholeSDWA().run(MF);
1260 TRI =
ST.getRegisterInfo();
1261 TII =
ST.getInstrInfo();
1266 bool Changed =
false;
1272 matchSDWAOperands(
MBB);
1273 for (
const auto &OperandPair : SDWAOperands) {
1274 const auto &Operand = OperandPair.second;
1277 (PotentialMI->
getOpcode() == AMDGPU::V_ADD_CO_U32_e64 ||
1278 PotentialMI->
getOpcode() == AMDGPU::V_SUB_CO_U32_e64))
1279 pseudoOpConvertToVOP2(*PotentialMI, ST);
1281 SDWAOperands.clear();
1284 matchSDWAOperands(
MBB);
1286 for (
const auto &OperandPair : SDWAOperands) {
1287 const auto &Operand = OperandPair.second;
1288 MachineInstr *PotentialMI = Operand->potentialToConvert(
TII, ST, &PotentialMatches);
1289 if (PotentialMI && isConvertibleToSDWA(*PotentialMI, ST,
TII)) {
1290 PotentialMatches[PotentialMI].push_back(Operand.get());
1294 for (
auto &PotentialPair : PotentialMatches) {
1296 convertToSDWA(PotentialMI, PotentialPair.second);
1299 PotentialMatches.clear();
1300 SDWAOperands.clear();
1302 Changed = !ConvertedInstructions.empty();
1306 while (!ConvertedInstructions.empty())
1307 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)
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptNone() const
Do not optimize this function (-O0).
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 which may be 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.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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 * createSIPeepholeSDWALegacyPass()
PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char & SIPeepholeSDWALegacyID
Description of the encoding of one expression Op.