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)) {
253 if (
TII->isOperandLegal(*DPPInst.getInstr(), NumOperands, 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 int Src0Idx = NumOperands;
299 if (!
TII->isOperandLegal(*DPPInst.getInstr(), NumOperands, Src0)) {
305 DPPInst->getOperand(NumOperands).setIsKill(
false);
308 auto *Mod1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1_modifiers);
310 assert(NumOperands == AMDGPU::getNamedOperandIdx(DPPOp,
311 AMDGPU::OpName::src1_modifiers));
314 DPPInst.addImm(Mod1->getImm());
320 auto *Src1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1);
322 int OpNum = NumOperands;
326 if (!
ST->hasDPPSrc1SGPR()) {
329 "Src0 and Src1 operands should have the same size");
332 if (!
TII->isOperandLegal(*DPPInst.getInstr(), OpNum, Src1)) {
341 auto *Mod2 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src2_modifiers);
344 AMDGPU::getNamedOperandIdx(DPPOp, AMDGPU::OpName::src2_modifiers));
347 DPPInst.addImm(Mod2->getImm());
350 auto *Src2 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src2);
352 if (!
TII->getNamedOperand(*DPPInst.getInstr(), AMDGPU::OpName::src2) ||
353 !
TII->isOperandLegal(*DPPInst.getInstr(), NumOperands, Src2)) {
363 auto *ClampOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::clamp);
365 DPPInst.addImm(ClampOpr->getImm());
367 auto *VdstInOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::vdst_in);
370 DPPInst.add(*VdstInOpr);
372 auto *OmodOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::omod);
374 DPPInst.addImm(OmodOpr->getImm());
378 if (
TII->getNamedOperand(OrigMI, AMDGPU::OpName::op_sel)) {
383 if (Mod0 &&
TII->isVOP3(OrigMI) && !
TII->isVOP3P(OrigMI))
392 DPPInst.addImm(OpSel);
394 if (
TII->getNamedOperand(OrigMI, AMDGPU::OpName::op_sel_hi)) {
402 assert(Src2 &&
"Expected vop3p with 3 operands");
404 LLVM_DEBUG(
dbgs() <<
" failed: op_sel_hi must be all set to one\n");
409 DPPInst.addImm(OpSelHi);
411 auto *NegOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::neg_lo);
413 DPPInst.addImm(NegOpr->getImm());
415 auto *NegHiOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::neg_hi);
417 DPPInst.addImm(NegHiOpr->getImm());
419 auto *ByteSelOpr =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::byte_sel);
422 DPPInst.addImm(ByteSelOpr->getImm());
425 TII->getNamedOperand(OrigMI, AMDGPU::OpName::bitop3)) {
427 DPPInst.add(*BitOp3);
430 DPPInst.add(*
TII->getNamedOperand(MovMI, AMDGPU::OpName::dpp_ctrl));
431 DPPInst.add(*
TII->getNamedOperand(MovMI, AMDGPU::OpName::row_mask));
432 DPPInst.add(*
TII->getNamedOperand(MovMI, AMDGPU::OpName::bank_mask));
433 DPPInst.addImm(CombBCZ ? 1 : 0);
437 DPPInst.getInstr()->eraseFromParent();
441 return DPPInst.getInstr();
448 case AMDGPU::V_ADD_U32_e32:
449 case AMDGPU::V_ADD_U32_e64:
450 case AMDGPU::V_ADD_CO_U32_e32:
451 case AMDGPU::V_ADD_CO_U32_e64:
452 case AMDGPU::V_OR_B32_e32:
453 case AMDGPU::V_OR_B32_e64:
454 case AMDGPU::V_SUBREV_U32_e32:
455 case AMDGPU::V_SUBREV_U32_e64:
456 case AMDGPU::V_SUBREV_CO_U32_e32:
457 case AMDGPU::V_SUBREV_CO_U32_e64:
458 case AMDGPU::V_MAX_U32_e32:
459 case AMDGPU::V_MAX_U32_e64:
460 case AMDGPU::V_XOR_B32_e32:
461 case AMDGPU::V_XOR_B32_e64:
462 if (OldOpnd->
getImm() == 0)
465 case AMDGPU::V_AND_B32_e32:
466 case AMDGPU::V_AND_B32_e64:
467 case AMDGPU::V_MIN_U32_e32:
468 case AMDGPU::V_MIN_U32_e64:
470 std::numeric_limits<uint32_t>::max())
473 case AMDGPU::V_MIN_I32_e32:
474 case AMDGPU::V_MIN_I32_e64:
475 if (
static_cast<int32_t
>(OldOpnd->
getImm()) ==
476 std::numeric_limits<int32_t>::max())
479 case AMDGPU::V_MAX_I32_e32:
480 case AMDGPU::V_MAX_I32_e64:
481 if (
static_cast<int32_t
>(OldOpnd->
getImm()) ==
482 std::numeric_limits<int32_t>::min())
485 case AMDGPU::V_MUL_I32_I24_e32:
486 case AMDGPU::V_MUL_I32_I24_e64:
487 case AMDGPU::V_MUL_U32_U24_e32:
488 case AMDGPU::V_MUL_U32_U24_e64:
489 if (OldOpnd->
getImm() == 1)
498 MachineOperand *OldOpndValue,
bool CombBCZ,
bool IsShrinkable)
const {
500 if (!CombBCZ && OldOpndValue && OldOpndValue->
isImm()) {
501 auto *Src1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1);
502 if (!Src1 || !Src1->isReg()) {
503 LLVM_DEBUG(
dbgs() <<
" failed: no src1 or it isn't a register\n");
507 LLVM_DEBUG(
dbgs() <<
" failed: old immediate isn't an identity\n");
511 auto *MovDst =
TII->getNamedOperand(MovMI, AMDGPU::OpName::vdst);
518 return createDPPInst(OrigMI, MovMI, CombOldVGPR, CombBCZ, IsShrinkable);
523bool GCNDPPCombine::hasNoImmOrEqual(
MachineInstr &
MI, AMDGPU::OpName OpndName,
524 int64_t
Value, int64_t Mask)
const {
525 auto *
Imm =
TII->getNamedOperand(
MI, OpndName);
530 return (
Imm->getImm() & Mask) ==
Value;
533bool GCNDPPCombine::combineDPPMov(
MachineInstr &MovMI)
const {
535 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_dpp ||
536 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO);
539 auto *DstOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::vdst);
540 assert(DstOpnd && DstOpnd->isReg());
541 auto DPPMovReg = DstOpnd->getReg();
542 if (DPPMovReg.isPhysical()) {
552 auto *
DppCtrl =
TII->getNamedOperand(MovMI, AMDGPU::OpName::dpp_ctrl);
554 unsigned DppCtrlVal =
DppCtrl->getImm();
555 if ((MovMI.
getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO ||
556 MovMI.
getOpcode() == AMDGPU::V_MOV_B64_dpp)) {
557 if (!
ST->hasFeature(AMDGPU::FeatureDPALU_DPP)) {
558 LLVM_DEBUG(
dbgs() <<
" failed: 64 bit dpp move is unsupported\n");
570 auto *RowMaskOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::row_mask);
571 assert(RowMaskOpnd && RowMaskOpnd->isImm());
572 auto *BankMaskOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::bank_mask);
573 assert(BankMaskOpnd && BankMaskOpnd->isImm());
574 const bool MaskAllLanes = RowMaskOpnd->getImm() == 0xF &&
575 BankMaskOpnd->getImm() == 0xF;
577 auto *BCZOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::bound_ctrl);
578 assert(BCZOpnd && BCZOpnd->isImm());
579 bool BoundCtrlZero = BCZOpnd->getImm();
581 auto *OldOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::old);
582 auto *SrcOpnd =
TII->getNamedOperand(MovMI, AMDGPU::OpName::src0);
584 assert(SrcOpnd && SrcOpnd->isReg());
590 auto *
const OldOpndValue = getOldOpndValue(*OldOpnd);
595 assert(!OldOpndValue || OldOpndValue->
isImm() || OldOpndValue == OldOpnd);
597 bool CombBCZ =
false;
599 if (MaskAllLanes && BoundCtrlZero) {
602 if (!OldOpndValue || !OldOpndValue->
isImm()) {
607 if (OldOpndValue->
getImm() == 0) {
612 }
else if (BoundCtrlZero) {
615 " failed: old!=0 and bctrl:0 and not all lanes isn't combinable\n");
624 dbgs() << *OldOpndValue;
625 dbgs() <<
", bound_ctrl=" << CombBCZ <<
'\n');
631 if (CombBCZ && OldOpndValue) {
634 MRI->createVirtualRegister(RC));
636 TII->get(AMDGPU::IMPLICIT_DEF), CombOldVGPR.
Reg);
637 DPPMIs.push_back(UndefInst.getInstr());
640 OrigMIs.push_back(&MovMI);
641 bool Rollback =
true;
645 while (!
Uses.empty()) {
649 auto &OrigMI = *
Use->getParent();
654 "There should not be e32 True16 instructions pre-RA");
655 if (OrigOp == AMDGPU::REG_SEQUENCE) {
657 unsigned FwdSubReg = 0;
666 for (OpNo = 1; OpNo < E; OpNo += 2) {
676 for (
auto &
Op :
MRI->use_nodbg_operands(FwdReg)) {
677 if (
Op.getSubReg() == FwdSubReg)
680 RegSeqWithOpNos[&OrigMI].push_back(OpNo);
684 bool IsShrinkable = isShrinkable(OrigMI);
685 if (!(IsShrinkable ||
686 ((
TII->isVOP3P(OrigOp) ||
TII->isVOPC(OrigOp) ||
687 TII->isVOP3(OrigOp)) &&
689 TII->isVOP1(OrigOp) ||
TII->isVOP2(OrigOp))) {
698 auto *Src0 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src0);
699 auto *Src1 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src1);
705 auto *Src2 =
TII->getNamedOperand(OrigMI, AMDGPU::OpName::src2);
706 assert(Src0 &&
"Src1 without Src0?");
707 if ((
Use == Src0 && ((Src1 && Src1->isIdenticalTo(*Src0)) ||
708 (Src2 && Src2->isIdenticalTo(*Src0)))) ||
709 (
Use == Src1 && (Src1->isIdenticalTo(*Src0) ||
710 (Src2 && Src2->isIdenticalTo(*Src1))))) {
714 <<
" failed: DPP register is used more than once per instruction\n");
718 if (!
ST->hasFeature(AMDGPU::FeatureDPALU_DPP) &&
721 <<
" failed: DPP ALU DPP is not supported\n");
728 <<
" failed: not valid 64-bit DPP control value\n");
734 if (
auto *DPPInst = createDPPInst(OrigMI, MovMI, CombOldVGPR,
735 OldOpndValue, CombBCZ, IsShrinkable)) {
736 DPPMIs.push_back(DPPInst);
743 BB->
insert(OrigMI, NewMI);
744 if (
TII->commuteInstruction(*NewMI)) {
747 createDPPInst(*NewMI, MovMI, CombOldVGPR, OldOpndValue, CombBCZ,
749 DPPMIs.push_back(DPPInst);
754 NewMI->eraseFromParent();
758 OrigMIs.push_back(&OrigMI);
761 Rollback |= !
Uses.empty();
763 for (
auto *
MI : *(Rollback? &DPPMIs : &OrigMIs))
764 MI->eraseFromParent();
767 for (
auto &S : RegSeqWithOpNos) {
768 if (
MRI->use_nodbg_empty(S.first->getOperand(0).getReg())) {
769 S.first->eraseFromParent();
772 while (!S.second.empty())
773 S.first->getOperand(S.second.pop_back_val()).setIsUndef();
784 return GCNDPPCombine().run(MF);
793 TII =
ST->getInstrInfo();
795 bool Changed =
false;
796 for (
auto &
MBB : MF) {
798 if (
MI.getOpcode() == AMDGPU::V_MOV_B32_dpp && combineDPPMov(
MI)) {
800 ++NumDPPMovsCombined;
801 }
else if (
MI.getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO ||
802 MI.getOpcode() == AMDGPU::V_MOV_B64_dpp) {
803 if (
ST->hasDPALU_DPP() && combineDPPMov(
MI)) {
805 ++NumDPPMovsCombined;
809 if (M && combineDPPMov(*M))
810 ++NumDPPMovsCombined;
827 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
#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.
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.