36#define DEBUG_TYPE "arm-mve-vpt-opts"
40 cl::desc(
"Enable merging Loop End and Dec instructions."),
45 cl::desc(
"Enable setting lr as a predicate in tail predication regions."),
59 void getAnalysisUsage(AnalysisUsage &AU)
const override {
68 StringRef getPassName()
const override {
69 return "ARM MVE TailPred and VPT Optimisation Pass";
73 bool LowerWhileLoopStart(MachineLoop *
ML);
74 bool MergeLoopEnd(MachineLoop *
ML);
75 bool ConvertTailPredLoop(MachineLoop *
ML, MachineDominatorTree *DT);
76 MachineInstr &ReplaceRegisterUseWithVPNOT(MachineBasicBlock &
MBB,
80 bool ReduceOldVCCRValueUses(MachineBasicBlock &
MBB);
81 bool ReplaceVCMPsByVPNOTs(MachineBasicBlock &
MBB);
82 bool ReplaceConstByVPNOTs(MachineBasicBlock &
MBB, MachineDominatorTree *DT);
83 bool ConvertVPSEL(MachineBasicBlock &
MBB);
84 bool HintDoLoopStartReg(MachineBasicBlock &
MBB);
85 MachineInstr *CheckForLRUseInPredecessors(MachineBasicBlock *PreHeader,
86 MachineInstr *LoopStart);
89char MVETPAndVPTOptimisations::ID = 0;
94 "ARM MVE TailPred and VPT Optimisations pass",
false,
99 "ARM MVE TailPred and VPT Optimisations pass",
false,
false)
103 while (
MI &&
MI->getOpcode() == TargetOpcode::COPY &&
104 MI->getOperand(1).getReg().isVirtual())
105 MI =
MRI->getVRegDef(
MI->getOperand(1).getReg());
117 if (!Header || !Latch) {
125 if (
T.getOpcode() == ARM::t2LoopEnd &&
T.getOperand(1).getMBB() == Header) {
129 if (
T.getOpcode() == ARM::t2LoopEndDec &&
130 T.getOperand(2).getMBB() == Header) {
150 if (LoopEnd->
getOpcode() == ARM::t2LoopEndDec)
155 if (!LoopDec || LoopDec->
getOpcode() != ARM::t2LoopDec) {
156 LLVM_DEBUG(
dbgs() <<
" didn't find LoopDec where we expected!\n");
164 if (!LoopPhi || LoopPhi->
getOpcode() != TargetOpcode::PHI ||
177 if (!LoopStart || (LoopStart->
getOpcode() != ARM::t2DoLoopStart &&
178 LoopStart->
getOpcode() != ARM::t2WhileLoopSetup &&
179 LoopStart->
getOpcode() != ARM::t2WhileLoopStartLR)) {
190 assert(
MI->getOpcode() == ARM::t2WhileLoopSetup &&
191 "Only expected a t2WhileLoopSetup in RevertWhileLoopStart!");
196 MIB.
add(
MI->getOperand(0));
197 MIB.
add(
MI->getOperand(1));
205 if (
I.getOpcode() == ARM::t2WhileLoopStart) {
208 MIB.
add(
MI->getOperand(1));
216 MI->eraseFromParent();
229bool MVETPAndVPTOptimisations::LowerWhileLoopStart(
MachineLoop *
ML) {
231 <<
ML->getHeader()->getName() <<
"\n");
233 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
237 if (LoopStart->
getOpcode() != ARM::t2WhileLoopSetup)
242 return MI.getOpcode() == ARM::t2WhileLoopStart;
251 MachineInstrBuilder
MI =
252 BuildMI(*WLSIt->getParent(), *WLSIt, WLSIt->getDebugLoc(),
253 TII->get(ARM::t2WhileLoopStartLR), LR)
255 .
add(WLSIt->getOperand(1))
260 WLSIt->eraseFromParent();
275MachineInstr *MVETPAndVPTOptimisations::CheckForLRUseInPredecessors(
276 MachineBasicBlock *PreHeader, MachineInstr *LoopStart) {
278 SmallPtrSet<MachineBasicBlock *, 4> Visited;
282 while (!Worklist.
empty()) {
287 for (MachineInstr &
MI : *
MBB) {
296 MachineInstrBuilder MIB =
309 for (MachineOperand &MO :
311 if (MO.getParent()->getOpcode() == TargetOpcode::COPY)
330bool MVETPAndVPTOptimisations::MergeLoopEnd(MachineLoop *
ML) {
337 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
344 auto *PreHeader =
ML->getLoopPreheader();
345 if (LoopStart->
getOpcode() == ARM::t2WhileLoopStartLR && PreHeader)
346 LoopStart = CheckForLRUseInPredecessors(PreHeader, LoopStart);
348 for (MachineBasicBlock *
MBB :
ML->blocks()) {
349 for (MachineInstr &
MI : *
MBB) {
352 if (LoopStart->
getOpcode() == ARM::t2DoLoopStart)
370 SmallVector<MachineInstr *, 4>
Copies;
373 MachineRegisterInfo *
MRI) {
376 while (!Worklist.
empty()) {
381 if (
MI.getOpcode() != TargetOpcode::COPY ||
382 !
MI.getOperand(0).getReg().isVirtual()) {
392 if (!CheckUsers(PhiReg, {LoopDec},
MRI) ||
393 !CheckUsers(DecReg, {LoopPhi, LoopEnd},
MRI) ||
394 !CheckUsers(StartReg, {LoopPhi},
MRI)) {
396 if (LoopStart->
getOpcode() == ARM::t2WhileLoopStartLR) {
417 SmallVector<MachineOperand, 4>
Cond;
418 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
429 MachineInstrBuilder
MI =
431 TII->get(ARM::t2LoopEndDec), DecReg)
441 MI->eraseFromParent();
449bool MVETPAndVPTOptimisations::ConvertTailPredLoop(MachineLoop *
ML,
450 MachineDominatorTree *DT) {
452 <<
ML->getHeader()->getName() <<
"\n");
456 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
459 if (LoopDec != LoopEnd || (LoopStart->
getOpcode() != ARM::t2DoLoopStart &&
460 LoopStart->
getOpcode() != ARM::t2WhileLoopStartLR))
463 SmallVector<MachineInstr *, 4> VCTPs;
464 SmallVector<MachineInstr *, 4> MVEInstrs;
465 for (MachineBasicBlock *BB :
ML->blocks()) {
466 for (MachineInstr &
MI : *BB)
479 MachineInstr *FirstVCTP = *VCTPs.
begin();
480 for (MachineInstr *VCTP : VCTPs) {
482 if (VCTP->getOpcode() != FirstVCTP->
getOpcode() ||
505 if (!Phi ||
Phi->getOpcode() != TargetOpcode::PHI ||
506 Phi->getNumOperands() != 5 ||
507 (
Phi->getOperand(2).getMBB() !=
ML->getLoopLatch() &&
508 Phi->getOperand(4).getMBB() !=
ML->getLoopLatch())) {
512 CountReg =
Phi->getOperand(2).getMBB() ==
ML->getLoopLatch()
513 ?
Phi->getOperand(3).getReg()
514 :
Phi->getOperand(1).getReg();
521 for (MachineInstr &Use :
529 unsigned NewOpc = LoopStart->
getOpcode() == ARM::t2DoLoopStart
530 ? ARM::t2DoLoopStartTP
531 : ARM::t2WhileLoopStartTP;
532 MachineInstrBuilder
MI =
537 if (NewOpc == ARM::t2WhileLoopStartTP)
548 for (MachineInstr *
MI : MVEInstrs) {
550 MI->getOperand(Idx + ARM::SUBOP_vpred_n_tp_reg).setReg(LR);
567 case ARM::MVE_VCMPf32:
568 case ARM::MVE_VCMPf16:
569 case ARM::MVE_VCMPf32r:
570 case ARM::MVE_VCMPf16r:
571 case ARM::MVE_VCMPi8r:
572 case ARM::MVE_VCMPi16r:
573 case ARM::MVE_VCMPi32r:
574 case ARM::MVE_VCMPu8r:
575 case ARM::MVE_VCMPu16r:
576 case ARM::MVE_VCMPu32r:
577 case ARM::MVE_VCMPs8r:
578 case ARM::MVE_VCMPs16r:
579 case ARM::MVE_VCMPs32r:
586 assert(
IsVCMP(Instr.getOpcode()) &&
"Inst must be a VCMP");
607 if (CondOP1.
isIdenticalTo(PrevOP1) && CondOP2.isIdenticalTo(PrevOP2))
614 CondOP2.isIdenticalTo(PrevOP1);
619 if (Instr.getNumOperands() == 0)
629 return RegClass && (RegClass->
getID() == ARM::VCCRRegClassID);
640MachineInstr &MVETPAndVPTOptimisations::ReplaceRegisterUseWithVPNOT(
641 MachineBasicBlock &
MBB, MachineInstr &Instr, MachineOperand &User,
645 MachineInstrBuilder MIBuilder =
652 User.setReg(NewResult);
653 User.setIsKill(
false);
667 assert(Iter->getOpcode() == ARM::MVE_VPNOT &&
"Not a VPNOT!");
669 "The VPNOT cannot be predicated");
677 bool MustMove =
false, HasUser =
false;
679 for (; Iter !=
MBB.end(); ++Iter) {
681 Iter->findRegisterUseOperand(VPNOTOperand,
nullptr,
684 VPNOTOperandKiller = MO;
687 if (Iter->findRegisterUseOperandIdx(
Reg,
nullptr) != -1) {
692 if (Iter->findRegisterUseOperandIdx(VPNOTResult,
nullptr) == -1)
705 if (VPNOTOperandKiller)
726bool MVETPAndVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &
MBB) {
728 SmallVector<MachineInstr *, 4> DeadInstructions;
731 while (Iter !=
End) {
732 Register VCCRValue, OppositeVCCRValue;
736 for (; Iter !=
End; ++Iter) {
741 Register Dst = Iter->getOperand(0).getReg();
745 if (VCCRValue && Iter->getOpcode() == ARM::MVE_VPNOT &&
746 Iter->findRegisterUseOperandIdx(VCCRValue,
nullptr) != -1) {
752 OppositeVCCRValue = Dst;
765 assert(VCCRValue && OppositeVCCRValue &&
766 "VCCRValue and OppositeVCCRValue shouldn't be empty if the loop "
767 "stopped before the end of the block!");
768 assert(VCCRValue != OppositeVCCRValue &&
769 "VCCRValue should not be equal to OppositeVCCRValue!");
772 Register LastVPNOTResult = OppositeVCCRValue;
775 for (; Iter !=
End; ++Iter) {
776 bool IsInteresting =
false;
778 if (MachineOperand *MO =
779 Iter->findRegisterUseOperand(VCCRValue,
nullptr)) {
780 IsInteresting =
true;
785 if (Iter->getOpcode() == ARM::MVE_VPNOT) {
793 <<
"Replacing all uses of '" <<
printReg(Result)
794 <<
"' with '" <<
printReg(LastVPNOTResult) <<
"'\n");
796 MachineInstr &VPNOT =
797 ReplaceRegisterUseWithVPNOT(
MBB, *Iter, *MO, LastVPNOTResult);
804 <<
"' with '" <<
printReg(LastVPNOTResult)
805 <<
"' in instr: " << *Iter);
810 if (MachineOperand *MO = Iter->findRegisterUseOperand(
811 OppositeVCCRValue,
nullptr)) {
812 IsInteresting =
true;
815 if (LastVPNOTResult != OppositeVCCRValue) {
817 <<
printReg(OppositeVCCRValue) <<
"' with '"
818 <<
printReg(LastVPNOTResult) <<
" for instr: ";
820 MO->setReg(LastVPNOTResult);
824 MO->setIsKill(
false);
829 if (Iter->getOpcode() == ARM::MVE_VPNOT &&
831 Register VPNOTOperand = Iter->getOperand(1).getReg();
832 if (VPNOTOperand == LastVPNOTResult ||
833 VPNOTOperand == OppositeVCCRValue) {
834 IsInteresting =
true;
837 LastVPNOTResult = Iter->getOperand(0).getReg();
848 for (MachineInstr *DeadInstruction : DeadInstructions)
849 DeadInstruction->eraseFromParent();
855bool MVETPAndVPTOptimisations::ReplaceVCMPsByVPNOTs(MachineBasicBlock &
MBB) {
856 SmallVector<MachineInstr *, 4> DeadInstructions;
863 MachineInstr *PrevVCMP =
nullptr;
867 MachineOperand *PrevVCMPResultKiller =
nullptr;
869 for (MachineInstr &Instr :
MBB.
instrs()) {
871 if (MachineOperand *MO =
876 PrevVCMPResultKiller = MO;
902 MachineInstrBuilder MIBuilder =
905 .
addReg(PrevVCMPResultReg);
913 if (PrevVCMPResultKiller)
920 PrevVCMPResultKiller =
nullptr;
923 for (MachineInstr *DeadInstruction : DeadInstructions)
924 DeadInstruction->eraseFromParent();
926 return !DeadInstructions.empty();
929bool MVETPAndVPTOptimisations::ReplaceConstByVPNOTs(MachineBasicBlock &
MBB,
930 MachineDominatorTree *DT) {
936 unsigned LastVPTImm = 0;
938 SmallPtrSet<MachineInstr *, 4> DeadInstructions;
940 for (MachineInstr &Instr :
MBB.
instrs()) {
951 if (!Copy ||
Copy->getOpcode() != TargetOpcode::COPY ||
952 !
Copy->getOperand(1).getReg().isVirtual() ||
962 if (Def && (
Def->getOpcode() == ARM::t2MOVi ||
963 Def->getOpcode() == ARM::t2MOVi16))
964 return Def->getOperand(1).getImm();
973 unsigned NotImm = ~Imm & 0xffff;
974 if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm ==
Imm) {
976 Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
978 DeadInstructions.
insert(Copy);
984 }
else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
989 TII->get(ARM::MVE_VPNOT), NewVPR)
994 Instr.getOperand(PIdx + 1).setReg(NewVPR);
996 DeadInstructions.
insert(Copy);
1001 LLVM_DEBUG(
dbgs() <<
"Adding VPNot: " << *VPNot <<
" to replace use at "
1010 for (MachineInstr *DI : DeadInstructions)
1011 DI->eraseFromParent();
1013 return !DeadInstructions.empty();
1021bool MVETPAndVPTOptimisations::ConvertVPSEL(MachineBasicBlock &
MBB) {
1022 bool HasVCTP =
false;
1023 SmallVector<MachineInstr *, 4> DeadInstructions;
1031 if (!HasVCTP ||
MI.getOpcode() != ARM::MVE_VPSEL)
1034 MachineInstrBuilder MIBuilder =
1036 .
add(
MI.getOperand(0))
1037 .
add(
MI.getOperand(1))
1038 .
add(
MI.getOperand(1))
1040 .
add(
MI.getOperand(4))
1041 .
add(
MI.getOperand(5))
1042 .
add(
MI.getOperand(2));
1050 for (MachineInstr *DeadInstruction : DeadInstructions)
1051 DeadInstruction->eraseFromParent();
1053 return !DeadInstructions.empty();
1058bool MVETPAndVPTOptimisations::HintDoLoopStartReg(MachineBasicBlock &
MBB) {
1061 if (
MI.getOpcode() != ARM::t2DoLoopStart)
1071bool MVETPAndVPTOptimisations::runOnMachineFunction(
MachineFunction &Fn) {
1072 const ARMSubtarget &STI = Fn.
getSubtarget<ARMSubtarget>();
1074 if (!STI.
isThumb2() || !STI.hasLOB())
1079 MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1080 MachineDominatorTree *DT =
1081 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1083 LLVM_DEBUG(
dbgs() <<
"********** ARM MVE VPT Optimisations **********\n"
1084 <<
"********** Function: " << Fn.
getName() <<
'\n');
1093 for (MachineBasicBlock &
MBB : Fn) {
1101 LLVM_DEBUG(
dbgs() <<
"**************************************\n");
1107 return new MVETPAndVPTOptimisations();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
ARM MVE TailPred and VPT Optimisations static false MachineInstr * LookThroughCOPY(MachineInstr *MI, MachineRegisterInfo *MRI)
static void RevertWhileLoopSetup(MachineInstr *MI, const TargetInstrInfo *TII)
static cl::opt< bool > SetLRPredicate("arm-set-lr-predicate", cl::Hidden, cl::desc("Enable setting lr as a predicate in tail predication regions."), cl::init(true))
static bool findLoopComponents(MachineLoop *ML, MachineRegisterInfo *MRI, MachineInstr *&LoopStart, MachineInstr *&LoopPhi, MachineInstr *&LoopDec, MachineInstr *&LoopEnd)
static bool MoveVPNOTBeforeFirstUser(MachineBasicBlock &MBB, MachineBasicBlock::iterator Iter, Register Reg)
static cl::opt< bool > MergeEndDec("arm-enable-merge-loopenddec", cl::Hidden, cl::desc("Enable merging Loop End and Dec instructions."), cl::init(true))
static ARMCC::CondCodes GetCondCode(MachineInstr &Instr)
static bool IsVPNOTEquivalent(MachineInstr &Cond, MachineInstr &Prev)
static bool IsInvalidTPInstruction(MachineInstr &MI)
static bool IsVCMP(unsigned Opcode)
static bool IsWritingToVCCR(MachineInstr &Instr)
static bool CanHaveSwappedOperands(unsigned Opcode)
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file defines the SmallVector class.
const ARMBaseInstrInfo * getInstrInfo() const override
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
FunctionPass class - This class is used to implement most global optimizations.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
SmallVector< LoopT *, 4 > getLoopsInPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
unsigned getID() const
getID() - Return the register class ID number.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
iterator_range< iterator > terminators()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
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.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
iterator_range< use_iterator > use_operands(Register Reg) const
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
static use_instr_nodbg_iterator use_instr_nodbg_end()
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
TargetInstrInfo - Interface to description of machine instruction set.
self_iterator getIterator()
static CondCodes getOppositeCondition(CondCodes CC)
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< DefNode * > Def
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
int findFirstVPTPredOperandIdx(const MachineInstr &MI)
FunctionPass * createMVETPAndVPTOptimisationsPass()
createMVETPAndVPTOptimisationsPass
ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isVCTP(const MachineInstr *MI)
@ Define
Register definition.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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...
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool isLoopStart(const MachineInstr &MI)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool UseCmp=false)
ArrayRef(const T &OneElt) -> ArrayRef< T >
void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool SkipCmp=false)
void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII, bool SetFlags=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static unsigned VCMPOpcodeToVPT(unsigned Opcode)
void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII)
@ End
Run the machine verifier once, at the end of the pipeline.
void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.