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)
239 auto WLSIt =
find_if(
MRI->use_nodbg_instructions(LR), [](
auto &
MI) {
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()) {
366 for (MachineInstr &
MI :
MRI->use_nodbg_instructions(
Reg)) {
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) {
393 MRI->constrainRegClass(StartReg, &ARM::GPRlrRegClass);
394 MRI->constrainRegClass(PhiReg, &ARM::GPRlrRegClass);
395 MRI->constrainRegClass(DecReg, &ARM::GPRlrRegClass);
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)
528 MRI->constrainRegClass(CountReg, &ARM::rGPRRegClass);
535 for (MachineInstr *
MI : MVEInstrs) {
537 MI->getOperand(Idx + 2).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,
630 Register NewResult =
MRI->createVirtualRegister(
MRI->getRegClass(Target));
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) {
775 MRI->replaceRegWith(Result, LastVPNOTResult);
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()) {
937 MachineInstr *
Copy =
MRI->getVRegDef(VPR);
938 if (!Copy ||
Copy->getOpcode() != TargetOpcode::COPY ||
939 !
Copy->getOperand(1).getReg().isVirtual() ||
940 MRI->getRegClass(
Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {
948 MachineInstr *
Def =
MRI->getVRegDef(GPR);
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) {
962 MRI->clearKillFlags(LastVPTReg);
963 Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
964 if (
MRI->use_empty(VPR)) {
965 DeadInstructions.
insert(Copy);
966 if (
MRI->hasOneUse(GPR))
967 DeadInstructions.
insert(
MRI->getVRegDef(GPR));
971 }
else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
974 Register NewVPR =
MRI->createVirtualRegister(&ARM::VCCRRegClass);
976 TII->get(ARM::MVE_VPNOT), NewVPR)
981 Instr.getOperand(PIdx + 1).setReg(NewVPR);
982 if (
MRI->use_empty(VPR)) {
983 DeadInstructions.
insert(Copy);
984 if (
MRI->hasOneUse(GPR))
985 DeadInstructions.
insert(
MRI->getVRegDef(GPR));
987 MRI->clearKillFlags(LastVPTReg);
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();
unsigned const MachineRegisterInfo * MRI
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 & 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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
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,...
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
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.
@ Define
Register definition.
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)
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.