49#define DEBUG_TYPE "gcn-dpp-combine"
51STATISTIC(NumDPPMovsCombined,
"Number of DPP moves combined.");
67 bool IsShrinkable)
const;
71 bool IsShrinkable)
const;
74 int64_t Mask = -1)
const;
78 int getDPPOp(
unsigned Op,
bool IsShrinkable)
const;
110char GCNDPPCombineLegacy::
ID = 0;
115 return new GCNDPPCombineLegacy();
119 unsigned Op =
MI.getOpcode();
120 if (!
TII->isVOP3(
Op)) {
123 if (!
TII->hasVALU32BitEncoding(
Op)) {
131 if (
const auto *SDst =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst)) {
136 if (!
MRI->use_nodbg_empty(SDst->getReg()))
141 if (!hasNoImmOrEqual(
MI, AMDGPU::OpName::src0_modifiers, 0, Mask) ||
142 !hasNoImmOrEqual(
MI, AMDGPU::OpName::src1_modifiers, 0, Mask) ||
143 !hasNoImmOrEqual(
MI, AMDGPU::OpName::clamp, 0) ||
144 !hasNoImmOrEqual(
MI, AMDGPU::OpName::omod, 0) ||
145 !hasNoImmOrEqual(
MI, AMDGPU::OpName::byte_sel, 0)) {
152int GCNDPPCombine::getDPPOp(
unsigned Op,
bool IsShrinkable)
const {
159 if (DPP32 != -1 &&
TII->pseudoToMCOpcode(DPP32) != -1)
162 if (
ST->hasVOP3DPP())
164 if (DPP64 != -1 &&
TII->pseudoToMCOpcode(DPP64) != -1)
178 switch(
Def->getOpcode()) {
180 case AMDGPU::IMPLICIT_DEF:
183 case AMDGPU::V_MOV_B32_e32:
184 case AMDGPU::V_MOV_B64_PSEUDO:
185 case AMDGPU::V_MOV_B64_e32:
186 case AMDGPU::V_MOV_B64_e64: {
187 auto &Op1 =
Def->getOperand(1);
198 int16_t RegClass =
MI.getDesc().operands()[
Idx].RegClass;
203 return TRI->getRegSizeInBits(*
TRI->getRegClass(RegClass));
210 bool IsShrinkable)
const {
212 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_dpp ||
213 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO);
215 bool HasVOP3DPP =
ST->hasVOP3DPP();
219 dbgs() <<
" failed: Did not expect any 16-bit uses of dpp values\n");
222 auto DPPOp = getDPPOp(OrigOp, IsShrinkable);
229 auto *RowMaskOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::row_mask);
230 assert(RowMaskOpnd && RowMaskOpnd->isImm());
231 auto *BankMaskOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::bank_mask);
232 assert(BankMaskOpnd && BankMaskOpnd->isImm());
233 const bool MaskAllLanes =
234 RowMaskOpnd->getImm() == 0xF && BankMaskOpnd->getImm() == 0xF;
237 !(
TII->isVOPC(DPPOp) || (
TII->isVOP3(DPPOp) && OrigOpE32 != -1 &&
238 TII->isVOPC(OrigOpE32)))) &&
239 "VOPC cannot form DPP unless mask is full");
248 if (
auto *Dst =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::vdst)) {
252 if (
auto *SDst =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::sdst)) {
260 const int OldIdx = AMDGPU::getNamedOperandIdx(DPPOp, AMDGPU::OpName::old);
262 assert(OldIdx == NumOperands);
266 TII->getNamedOperand(MovMI, AMDGPU::OpName::vdst)->getReg()),
272 }
else if (
TII->isVOPC(DPPOp) || (
TII->isVOP3(DPPOp) && OrigOpE32 != -1 &&
273 TII->isVOPC(OrigOpE32))) {
278 LLVM_DEBUG(
dbgs() <<
" failed: no old operand in DPP instruction,"
284 auto *Mod0 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src0_modifiers);
286 assert(NumOperands == AMDGPU::getNamedOperandIdx(DPPOp,
287 AMDGPU::OpName::src0_modifiers));
290 DPPInst.addImm(Mod0->getImm());
296 auto *Src0 =
TII->getNamedOperand(MovMI, AMDGPU::OpName::src0);
298 [[maybe_unused]]
int Src0Idx = NumOperands;
301 DPPInst->getOperand(NumOperands).setIsKill(
false);
304 auto *Mod1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1_modifiers);
306 assert(NumOperands == AMDGPU::getNamedOperandIdx(DPPOp,
307 AMDGPU::OpName::src1_modifiers));
310 DPPInst.addImm(Mod1->getImm());
316 auto *Src1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1);
319 "dpp version of instruction missing src1");
323 if (!
ST->hasDPPSrc1SGPR()) {
326 "Src0 and Src1 operands should have the same size");
333 auto *Mod2 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src2_modifiers);
336 AMDGPU::getNamedOperandIdx(DPPOp, AMDGPU::OpName::src2_modifiers));
339 DPPInst.addImm(Mod2->getImm());
342 auto *Src2 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src2);
354 auto *ClampOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::clamp);
356 DPPInst.addImm(ClampOpr->getImm());
358 auto *VdstInOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::vdst_in);
361 DPPInst.add(*VdstInOpr);
363 auto *OmodOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::omod);
365 DPPInst.addImm(OmodOpr->getImm());
369 if (
TII->getNamedOperand(OrigMI, AMDGPU::OpName::op_sel)) {
374 if (Mod0 &&
TII->isVOP3(OrigMI) && !
TII->isVOP3P(OrigMI))
383 DPPInst.addImm(OpSel);
385 if (
TII->getNamedOperand(OrigMI, AMDGPU::OpName::op_sel_hi)) {
393 assert(Src2 &&
"Expected vop3p with 3 operands");
395 LLVM_DEBUG(
dbgs() <<
" failed: op_sel_hi must be all set to one\n");
400 DPPInst.addImm(OpSelHi);
402 auto *NegOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::neg_lo);
404 DPPInst.addImm(NegOpr->getImm());
406 auto *NegHiOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::neg_hi);
408 DPPInst.addImm(NegHiOpr->getImm());
410 auto *ByteSelOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::byte_sel);
413 DPPInst.addImm(ByteSelOpr->getImm());
416 TII->getNamedOperand(OrigMI, AMDGPU::OpName::bitop3)) {
418 DPPInst.add(*BitOp3);
421 DPPInst.add(*
TII->getNamedOperand(MovMI, AMDGPU::OpName::dpp_ctrl));
422 DPPInst.add(*
TII->getNamedOperand(MovMI, AMDGPU::OpName::row_mask));
423 DPPInst.add(*
TII->getNamedOperand(MovMI, AMDGPU::OpName::bank_mask));
424 DPPInst.addImm(CombBCZ ? 1 : 0);
426 constexpr AMDGPU::OpName Srcs[] = {
427 AMDGPU::OpName::src0, AMDGPU::OpName::src1, AMDGPU::OpName::src2};
433 int OpIdx = AMDGPU::getNamedOperandIdx(DPPOp,
OpName);
437 if (!
TII->isOperandLegal(*DPPInst,
OpIdx)) {
446 DPPInst.getInstr()->eraseFromParent();
450 return DPPInst.getInstr();
457 case AMDGPU::V_ADD_U32_e32:
458 case AMDGPU::V_ADD_U32_e64:
459 case AMDGPU::V_ADD_CO_U32_e32:
460 case AMDGPU::V_ADD_CO_U32_e64:
461 case AMDGPU::V_OR_B32_e32:
462 case AMDGPU::V_OR_B32_e64:
463 case AMDGPU::V_SUBREV_U32_e32:
464 case AMDGPU::V_SUBREV_U32_e64:
465 case AMDGPU::V_SUBREV_CO_U32_e32:
466 case AMDGPU::V_SUBREV_CO_U32_e64:
467 case AMDGPU::V_MAX_U32_e32:
468 case AMDGPU::V_MAX_U32_e64:
469 case AMDGPU::V_XOR_B32_e32:
470 case AMDGPU::V_XOR_B32_e64:
471 if (OldOpnd->
getImm() == 0)
474 case AMDGPU::V_AND_B32_e32:
475 case AMDGPU::V_AND_B32_e64:
476 case AMDGPU::V_MIN_U32_e32:
477 case AMDGPU::V_MIN_U32_e64:
479 std::numeric_limits<uint32_t>::max())
482 case AMDGPU::V_MIN_I32_e32:
483 case AMDGPU::V_MIN_I32_e64:
484 if (
static_cast<int32_t
>(OldOpnd->
getImm()) ==
485 std::numeric_limits<int32_t>::max())
488 case AMDGPU::V_MAX_I32_e32:
489 case AMDGPU::V_MAX_I32_e64:
490 if (
static_cast<int32_t
>(OldOpnd->
getImm()) ==
491 std::numeric_limits<int32_t>::min())
494 case AMDGPU::V_MUL_I32_I24_e32:
495 case AMDGPU::V_MUL_I32_I24_e64:
496 case AMDGPU::V_MUL_U32_U24_e32:
497 case AMDGPU::V_MUL_U32_U24_e64:
498 if (OldOpnd->
getImm() == 1)
507 MachineOperand *OldOpndValue,
bool CombBCZ,
bool IsShrinkable)
const {
509 if (!CombBCZ && OldOpndValue && OldOpndValue->
isImm()) {
510 auto *Src1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1);
511 if (!Src1 || !Src1->isReg()) {
512 LLVM_DEBUG(
dbgs() <<
" failed: no src1 or it isn't a register\n");
516 LLVM_DEBUG(
dbgs() <<
" failed: old immediate isn't an identity\n");
520 auto *MovDst =
TII->getNamedOperand(MovMI, AMDGPU::OpName::vdst);
527 return createDPPInst(OrigMI, MovMI, CombOldVGPR, CombBCZ, IsShrinkable);
532bool GCNDPPCombine::hasNoImmOrEqual(
MachineInstr &
MI, AMDGPU::OpName OpndName,
533 int64_t
Value, int64_t Mask)
const {
534 auto *
Imm =
TII->getNamedOperand(
MI, OpndName);
539 return (
Imm->getImm() & Mask) ==
Value;
542bool GCNDPPCombine::combineDPPMov(
MachineInstr &MovMI)
const {
544 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_dpp ||
545 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO);
548 auto *DstOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::vdst);
549 assert(DstOpnd && DstOpnd->isReg());
550 auto DPPMovReg = DstOpnd->getReg();
551 if (DPPMovReg.isPhysical()) {
561 auto *
DppCtrl =
TII->getNamedOperand(MovMI, AMDGPU::OpName::dpp_ctrl);
563 unsigned DppCtrlVal =
DppCtrl->getImm();
564 if ((MovMI.
getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO ||
565 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_dpp)) {
566 if (!
ST->hasFeature(AMDGPU::FeatureDPALU_DPP)) {
567 LLVM_DEBUG(
dbgs() <<
" failed: 64 bit dpp move is unsupported\n");
579 auto *RowMaskOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::row_mask);
580 assert(RowMaskOpnd && RowMaskOpnd->isImm());
581 auto *BankMaskOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::bank_mask);
582 assert(BankMaskOpnd && BankMaskOpnd->isImm());
583 const bool MaskAllLanes = RowMaskOpnd->getImm() == 0xF &&
584 BankMaskOpnd->getImm() == 0xF;
586 auto *BCZOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::bound_ctrl);
587 assert(BCZOpnd && BCZOpnd->isImm());
588 bool BoundCtrlZero = BCZOpnd->getImm();
590 auto *OldOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::old);
591 auto *SrcOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::src0);
593 assert(SrcOpnd && SrcOpnd->isReg());
599 auto *
const OldOpndValue = getOldOpndValue(*OldOpnd);
604 assert(!OldOpndValue || OldOpndValue->
isImm() || OldOpndValue == OldOpnd);
606 bool CombBCZ =
false;
608 if (MaskAllLanes && BoundCtrlZero) {
611 if (!OldOpndValue || !OldOpndValue->
isImm()) {
616 if (OldOpndValue->
getImm() == 0) {
621 }
else if (BoundCtrlZero) {
624 " failed: old!=0 and bctrl:0 and not all lanes isn't combinable\n");
633 dbgs() << *OldOpndValue;
634 dbgs() <<
", bound_ctrl=" << CombBCZ <<
'\n');
640 if (CombBCZ && OldOpndValue) {
643 MRI->createVirtualRegister(RC));
645 TII->get(AMDGPU::IMPLICIT_DEF), CombOldVGPR.
Reg);
646 DPPMIs.push_back(UndefInst.getInstr());
649 OrigMIs.push_back(&MovMI);
650 bool Rollback =
true;
654 while (!
Uses.empty()) {
658 auto &OrigMI = *
Use->getParent();
663 "There should not be e32 True16 instructions pre-RA");
664 if (OrigOp == AMDGPU::REG_SEQUENCE) {
666 unsigned FwdSubReg = 0;
675 for (OpNo = 1; OpNo < E; OpNo += 2) {
685 for (
auto &
Op :
MRI->use_nodbg_operands(FwdReg)) {
686 if (
Op.getSubReg() == FwdSubReg)
689 RegSeqWithOpNos[&OrigMI].push_back(OpNo);
693 bool IsShrinkable = isShrinkable(OrigMI);
694 if (!(IsShrinkable ||
695 ((
TII->isVOP3P(OrigOp) ||
TII->isVOPC(OrigOp) ||
696 TII->isVOP3(OrigOp)) &&
698 TII->isVOP1(OrigOp) ||
TII->isVOP2(OrigOp))) {
707 auto *Src0 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src0);
708 auto *Src1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1);
714 auto *Src2 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src2);
715 assert(Src0 &&
"Src1 without Src0?");
716 if ((
Use == Src0 && ((Src1 && Src1->isIdenticalTo(*Src0)) ||
717 (Src2 && Src2->isIdenticalTo(*Src0)))) ||
718 (
Use == Src1 && (Src1->isIdenticalTo(*Src0) ||
719 (Src2 && Src2->isIdenticalTo(*Src1))))) {
723 <<
" failed: DPP register is used more than once per instruction\n");
727 if (!
ST->hasFeature(AMDGPU::FeatureDPALU_DPP) &&
730 <<
" failed: DPP ALU DPP is not supported\n");
737 <<
" failed: not valid 64-bit DPP control value\n");
743 if (
auto *DPPInst = createDPPInst(OrigMI, MovMI, CombOldVGPR,
744 OldOpndValue, CombBCZ, IsShrinkable)) {
745 DPPMIs.push_back(DPPInst);
752 BB->
insert(OrigMI, NewMI);
753 if (
TII->commuteInstruction(*NewMI)) {
756 createDPPInst(*NewMI, MovMI, CombOldVGPR, OldOpndValue, CombBCZ,
758 DPPMIs.push_back(DPPInst);
763 NewMI->eraseFromParent();
767 OrigMIs.push_back(&OrigMI);
770 Rollback |= !
Uses.empty();
772 for (
auto *
MI : *(Rollback? &DPPMIs : &OrigMIs))
773 MI->eraseFromParent();
776 for (
auto &S : RegSeqWithOpNos) {
777 if (
MRI->use_nodbg_empty(S.first->getOperand(0).getReg())) {
778 S.first->eraseFromParent();
781 while (!S.second.empty())
782 S.first->getOperand(S.second.pop_back_val()).setIsUndef();
793 return GCNDPPCombine().run(MF);
802 TII =
ST->getInstrInfo();
804 bool Changed =
false;
805 for (
auto &
MBB : MF) {
807 if (
MI.getOpcode() == AMDGPU::V_MOV_B32_dpp && combineDPPMov(
MI)) {
809 ++NumDPPMovsCombined;
810 }
else if (
MI.getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO ||
811 MI.getOpcode() == AMDGPU::V_MOV_B64_dpp) {
812 if (
ST->hasDPALU_DPP() && combineDPPMov(
MI)) {
814 ++NumDPPMovsCombined;
818 if (M && combineDPPMov(*M))
819 ++NumDPPMovsCombined;
836 bool Changed = GCNDPPCombine().run(MF);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static bool isIdentityValue(unsigned OrigMIOp, MachineOperand *OldOpnd)
static unsigned getOperandSize(MachineInstr &MI, unsigned Idx, MachineRegisterInfo &MRI)
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Remove Loads Into Fake Uses
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.
LLVM_ABI 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).
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM)
unsigned getSize(const MachineInstr &MI) const
An RAII based helper class to modify MachineFunctionProperties when running pass.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
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.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
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.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...
LLVM_ABI void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)
Inserts Ops BEFORE It. Can untie/retie tied operands.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
LLVM_READONLY int getVOPe32(uint16_t Opcode)
LLVM_READONLY int getDPPOp32(uint16_t Opcode)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isDPALU_DPP32BitOpc(unsigned Opc)
bool isTrue16Inst(unsigned Opc)
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCSubtargetInfo &ST)
LLVM_READONLY int getDPPOp64(uint16_t Opcode)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Undef
Value of the register doesn't matter.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O)
Create RegSubRegPair from a register MachineOperand.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
char & GCNDPPCombineLegacyID
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineInstr * getVRegSubRegDef(const TargetInstrInfo::RegSubRegPair &P, MachineRegisterInfo &MRI)
Return the defining instruction for a given reg:subreg pair skipping copy like instructions and subre...
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P, const TargetRegisterClass &TRC, MachineRegisterInfo &MRI)
Returns true if a reg:subreg pair P has a TRC class.
FunctionPass * createGCNDPPCombinePass()
bool execMayBeModifiedBeforeAnyUse(const MachineRegisterInfo &MRI, Register VReg, const MachineInstr &DefMI)
Return false if EXEC is not changed between the def of VReg at DefMI and all its uses.
A pair composed of a register and a sub-register index.