35#define DEBUG_TYPE "arm-mve-vpt-opts"
39 cl::desc(
"Enable merging Loop End and Dec instructions."),
44 cl::desc(
"Enable setting lr as a predicate in tail predication regions."),
56 bool runOnMachineFunction(MachineFunction &Fn)
override;
58 void getAnalysisUsage(AnalysisUsage &AU)
const override {
66 StringRef getPassName()
const override {
67 return "ARM MVE TailPred and VPT Optimisation Pass";
71 bool LowerWhileLoopStart(MachineLoop *
ML);
72 bool MergeLoopEnd(MachineLoop *
ML);
73 bool ConvertTailPredLoop(MachineLoop *
ML, MachineDominatorTree *DT);
74 MachineInstr &ReplaceRegisterUseWithVPNOT(MachineBasicBlock &
MBB,
78 bool ReduceOldVCCRValueUses(MachineBasicBlock &
MBB);
79 bool ReplaceVCMPsByVPNOTs(MachineBasicBlock &
MBB);
80 bool ReplaceConstByVPNOTs(MachineBasicBlock &
MBB, MachineDominatorTree *DT);
81 bool ConvertVPSEL(MachineBasicBlock &
MBB);
82 bool HintDoLoopStartReg(MachineBasicBlock &
MBB);
83 MachineInstr *CheckForLRUseInPredecessors(MachineBasicBlock *PreHeader,
84 MachineInstr *LoopStart);
87char MVETPAndVPTOptimisations::ID = 0;
92 "ARM MVE TailPred and VPT Optimisations pass",
false,
97 "ARM MVE TailPred and VPT Optimisations pass",
false,
false)
101 while (
MI &&
MI->getOpcode() == TargetOpcode::COPY &&
102 MI->getOperand(1).getReg().isVirtual())
103 MI = MRI->getVRegDef(
MI->getOperand(1).getReg());
115 if (!Header || !Latch) {
123 if (
T.getOpcode() == ARM::t2LoopEnd &&
T.getOperand(1).getMBB() == Header) {
127 if (
T.getOpcode() == ARM::t2LoopEndDec &&
128 T.getOperand(2).getMBB() == Header) {
148 if (LoopEnd->
getOpcode() == ARM::t2LoopEndDec)
153 if (!LoopDec || LoopDec->
getOpcode() != ARM::t2LoopDec) {
154 LLVM_DEBUG(
dbgs() <<
" didn't find LoopDec where we expected!\n");
162 if (!LoopPhi || LoopPhi->
getOpcode() != TargetOpcode::PHI ||
175 if (!LoopStart || (LoopStart->
getOpcode() != ARM::t2DoLoopStart &&
176 LoopStart->
getOpcode() != ARM::t2WhileLoopSetup &&
177 LoopStart->
getOpcode() != ARM::t2WhileLoopStartLR)) {
188 assert(
MI->getOpcode() == ARM::t2WhileLoopSetup &&
189 "Only expected a t2WhileLoopSetup in RevertWhileLoopStart!");
194 MIB.
add(
MI->getOperand(0));
195 MIB.
add(
MI->getOperand(1));
198 MIB.
addReg(ARM::NoRegister);
203 if (
I.getOpcode() == ARM::t2WhileLoopStart) {
206 MIB.
add(
MI->getOperand(1));
214 MI->eraseFromParent();
227bool MVETPAndVPTOptimisations::LowerWhileLoopStart(
MachineLoop *
ML) {
229 <<
ML->getHeader()->getName() <<
"\n");
231 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
235 if (LoopStart->
getOpcode() != ARM::t2WhileLoopSetup)
240 return MI.getOpcode() == ARM::t2WhileLoopStart;
249 MachineInstrBuilder
MI =
250 BuildMI(*WLSIt->getParent(), *WLSIt, WLSIt->getDebugLoc(),
251 TII->get(ARM::t2WhileLoopStartLR), LR)
253 .
add(WLSIt->getOperand(1));
257 WLSIt->eraseFromParent();
272MachineInstr *MVETPAndVPTOptimisations::CheckForLRUseInPredecessors(
273 MachineBasicBlock *PreHeader, MachineInstr *LoopStart) {
275 SmallPtrSet<MachineBasicBlock *, 4> Visited;
279 while (!Worklist.
empty()) {
284 for (MachineInstr &
MI : *
MBB) {
291 MachineInstrBuilder MIB =
318bool MVETPAndVPTOptimisations::MergeLoopEnd(MachineLoop *
ML) {
325 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
332 auto *PreHeader =
ML->getLoopPreheader();
333 if (LoopStart->
getOpcode() == ARM::t2WhileLoopStartLR && PreHeader)
334 LoopStart = CheckForLRUseInPredecessors(PreHeader, LoopStart);
336 for (MachineBasicBlock *
MBB :
ML->blocks()) {
337 for (MachineInstr &
MI : *
MBB) {
340 if (LoopStart->
getOpcode() == ARM::t2DoLoopStart)
358 SmallVector<MachineInstr *, 4>
Copies;
361 MachineRegisterInfo *MRI) {
364 while (!Worklist.
empty()) {
369 if (
MI.getOpcode() != TargetOpcode::COPY ||
370 !
MI.getOperand(0).getReg().isVirtual()) {
380 if (!CheckUsers(PhiReg, {LoopDec}, MRI) ||
381 !CheckUsers(DecReg, {LoopPhi, LoopEnd}, MRI) ||
382 !CheckUsers(StartReg, {LoopPhi}, MRI)) {
384 if (LoopStart->
getOpcode() == ARM::t2WhileLoopStartLR) {
406 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
417 MachineInstrBuilder
MI =
419 TII->get(ARM::t2LoopEndDec), DecReg)
428 MI->eraseFromParent();
436bool MVETPAndVPTOptimisations::ConvertTailPredLoop(MachineLoop *
ML,
437 MachineDominatorTree *DT) {
439 <<
ML->getHeader()->getName() <<
"\n");
443 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
446 if (LoopDec != LoopEnd || (LoopStart->
getOpcode() != ARM::t2DoLoopStart &&
447 LoopStart->
getOpcode() != ARM::t2WhileLoopStartLR))
450 SmallVector<MachineInstr *, 4> VCTPs;
451 SmallVector<MachineInstr *, 4> MVEInstrs;
452 for (MachineBasicBlock *BB :
ML->blocks()) {
453 for (MachineInstr &
MI : *BB)
466 MachineInstr *FirstVCTP = *VCTPs.
begin();
467 for (MachineInstr *VCTP : VCTPs) {
469 if (VCTP->getOpcode() != FirstVCTP->
getOpcode() ||
492 if (!Phi ||
Phi->getOpcode() != TargetOpcode::PHI ||
493 Phi->getNumOperands() != 5 ||
494 (
Phi->getOperand(2).getMBB() !=
ML->getLoopLatch() &&
495 Phi->getOperand(4).getMBB() !=
ML->getLoopLatch())) {
499 CountReg =
Phi->getOperand(2).getMBB() ==
ML->getLoopLatch()
500 ?
Phi->getOperand(3).getReg()
501 :
Phi->getOperand(1).getReg();
508 for (MachineInstr &Use :
516 unsigned NewOpc = LoopStart->
getOpcode() == ARM::t2DoLoopStart
517 ? ARM::t2DoLoopStartTP
518 : ARM::t2WhileLoopStartTP;
519 MachineInstrBuilder
MI =
524 if (NewOpc == ARM::t2WhileLoopStartTP)
535 for (MachineInstr *
MI : MVEInstrs) {
537 MI->getOperand(Idx + ARM::SUBOP_vpred_n_tp_reg).setReg(LR);
554 case ARM::MVE_VCMPf32:
555 case ARM::MVE_VCMPf16:
556 case ARM::MVE_VCMPf32r:
557 case ARM::MVE_VCMPf16r:
558 case ARM::MVE_VCMPi8r:
559 case ARM::MVE_VCMPi16r:
560 case ARM::MVE_VCMPi32r:
561 case ARM::MVE_VCMPu8r:
562 case ARM::MVE_VCMPu16r:
563 case ARM::MVE_VCMPu32r:
564 case ARM::MVE_VCMPs8r:
565 case ARM::MVE_VCMPs16r:
566 case ARM::MVE_VCMPs32r:
573 assert(
IsVCMP(Instr.getOpcode()) &&
"Inst must be a VCMP");
594 if (CondOP1.
isIdenticalTo(PrevOP1) && CondOP2.isIdenticalTo(PrevOP2))
601 CondOP2.isIdenticalTo(PrevOP1);
606 if (Instr.getNumOperands() == 0)
616 return RegClass && (RegClass->
getID() == ARM::VCCRRegClassID);
627MachineInstr &MVETPAndVPTOptimisations::ReplaceRegisterUseWithVPNOT(
628 MachineBasicBlock &
MBB, MachineInstr &Instr, MachineOperand &User,
632 MachineInstrBuilder MIBuilder =
639 User.setReg(NewResult);
640 User.setIsKill(
false);
654 assert(Iter->getOpcode() == ARM::MVE_VPNOT &&
"Not a VPNOT!");
656 "The VPNOT cannot be predicated");
664 bool MustMove =
false, HasUser =
false;
666 for (; Iter !=
MBB.end(); ++Iter) {
668 Iter->findRegisterUseOperand(VPNOTOperand,
nullptr,
671 VPNOTOperandKiller = MO;
674 if (Iter->findRegisterUseOperandIdx(
Reg,
nullptr) != -1) {
679 if (Iter->findRegisterUseOperandIdx(VPNOTResult,
nullptr) == -1)
692 if (VPNOTOperandKiller)
713bool MVETPAndVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &
MBB) {
715 SmallVector<MachineInstr *, 4> DeadInstructions;
718 while (Iter != End) {
719 Register VCCRValue, OppositeVCCRValue;
723 for (; Iter != End; ++Iter) {
728 Register Dst = Iter->getOperand(0).getReg();
732 if (VCCRValue && Iter->getOpcode() == ARM::MVE_VPNOT &&
733 Iter->findRegisterUseOperandIdx(VCCRValue,
nullptr) != -1) {
739 OppositeVCCRValue = Dst;
752 assert(VCCRValue && OppositeVCCRValue &&
753 "VCCRValue and OppositeVCCRValue shouldn't be empty if the loop "
754 "stopped before the end of the block!");
755 assert(VCCRValue != OppositeVCCRValue &&
756 "VCCRValue should not be equal to OppositeVCCRValue!");
759 Register LastVPNOTResult = OppositeVCCRValue;
762 for (; Iter != End; ++Iter) {
763 bool IsInteresting =
false;
765 if (MachineOperand *MO =
766 Iter->findRegisterUseOperand(VCCRValue,
nullptr)) {
767 IsInteresting =
true;
772 if (Iter->getOpcode() == ARM::MVE_VPNOT) {
780 <<
"Replacing all uses of '" <<
printReg(Result)
781 <<
"' with '" <<
printReg(LastVPNOTResult) <<
"'\n");
783 MachineInstr &VPNOT =
784 ReplaceRegisterUseWithVPNOT(
MBB, *Iter, *MO, LastVPNOTResult);
791 <<
"' with '" <<
printReg(LastVPNOTResult)
792 <<
"' in instr: " << *Iter);
797 if (MachineOperand *MO = Iter->findRegisterUseOperand(
798 OppositeVCCRValue,
nullptr)) {
799 IsInteresting =
true;
802 if (LastVPNOTResult != OppositeVCCRValue) {
804 <<
printReg(OppositeVCCRValue) <<
"' with '"
805 <<
printReg(LastVPNOTResult) <<
" for instr: ";
807 MO->setReg(LastVPNOTResult);
811 MO->setIsKill(
false);
816 if (Iter->getOpcode() == ARM::MVE_VPNOT &&
818 Register VPNOTOperand = Iter->getOperand(1).getReg();
819 if (VPNOTOperand == LastVPNOTResult ||
820 VPNOTOperand == OppositeVCCRValue) {
821 IsInteresting =
true;
824 LastVPNOTResult = Iter->getOperand(0).getReg();
835 for (MachineInstr *DeadInstruction : DeadInstructions)
836 DeadInstruction->eraseFromParent();
842bool MVETPAndVPTOptimisations::ReplaceVCMPsByVPNOTs(MachineBasicBlock &
MBB) {
843 SmallVector<MachineInstr *, 4> DeadInstructions;
850 MachineInstr *PrevVCMP =
nullptr;
854 MachineOperand *PrevVCMPResultKiller =
nullptr;
856 for (MachineInstr &Instr :
MBB.
instrs()) {
858 if (MachineOperand *MO =
863 PrevVCMPResultKiller = MO;
889 MachineInstrBuilder MIBuilder =
892 .
addReg(PrevVCMPResultReg);
900 if (PrevVCMPResultKiller)
907 PrevVCMPResultKiller =
nullptr;
910 for (MachineInstr *DeadInstruction : DeadInstructions)
911 DeadInstruction->eraseFromParent();
913 return !DeadInstructions.empty();
916bool MVETPAndVPTOptimisations::ReplaceConstByVPNOTs(MachineBasicBlock &
MBB,
917 MachineDominatorTree *DT) {
923 unsigned LastVPTImm = 0;
925 SmallPtrSet<MachineInstr *, 4> DeadInstructions;
927 for (MachineInstr &Instr :
MBB.
instrs()) {
938 if (!Copy ||
Copy->getOpcode() != TargetOpcode::COPY ||
939 !
Copy->getOperand(1).getReg().isVirtual() ||
940 MRI->
getRegClass(
Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {
949 if (Def && (
Def->getOpcode() == ARM::t2MOVi ||
950 Def->getOpcode() == ARM::t2MOVi16))
951 return Def->getOperand(1).getImm();
960 unsigned NotImm = ~Imm & 0xffff;
961 if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm == Imm) {
963 Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
965 DeadInstructions.
insert(Copy);
971 }
else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
976 TII->get(ARM::MVE_VPNOT), NewVPR)
981 Instr.getOperand(PIdx + 1).setReg(NewVPR);
983 DeadInstructions.
insert(Copy);
988 LLVM_DEBUG(
dbgs() <<
"Adding VPNot: " << *VPNot <<
" to replace use at "
997 for (MachineInstr *DI : DeadInstructions)
998 DI->eraseFromParent();
1000 return !DeadInstructions.empty();
1008bool MVETPAndVPTOptimisations::ConvertVPSEL(MachineBasicBlock &
MBB) {
1009 bool HasVCTP =
false;
1010 SmallVector<MachineInstr *, 4> DeadInstructions;
1018 if (!HasVCTP ||
MI.getOpcode() != ARM::MVE_VPSEL)
1021 MachineInstrBuilder MIBuilder =
1023 .
add(
MI.getOperand(0))
1024 .
add(
MI.getOperand(1))
1025 .
add(
MI.getOperand(1))
1027 .
add(
MI.getOperand(4))
1028 .
add(
MI.getOperand(5))
1029 .
add(
MI.getOperand(2));
1037 for (MachineInstr *DeadInstruction : DeadInstructions)
1038 DeadInstruction->eraseFromParent();
1040 return !DeadInstructions.empty();
1045bool MVETPAndVPTOptimisations::HintDoLoopStartReg(MachineBasicBlock &
MBB) {
1048 if (
MI.getOpcode() != ARM::t2DoLoopStart)
1051 MachineFunction *MF =
MI.getParent()->getParent();
1058bool MVETPAndVPTOptimisations::runOnMachineFunction(MachineFunction &Fn) {
1059 const ARMSubtarget &STI = Fn.
getSubtarget<ARMSubtarget>();
1061 if (!STI.
isThumb2() || !STI.hasLOB())
1066 MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1067 MachineDominatorTree *DT =
1068 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1070 LLVM_DEBUG(
dbgs() <<
"********** ARM MVE VPT Optimisations **********\n"
1071 <<
"********** Function: " << Fn.
getName() <<
'\n');
1080 for (MachineBasicBlock &
MBB : Fn) {
1088 LLVM_DEBUG(
dbgs() <<
"**************************************\n");
1094 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)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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...
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 & 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 eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
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 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...
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.
unsigned getID() const
Return the register class ID number.
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...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
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)
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.