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."),
57 bool runOnMachineFunction(MachineFunction &Fn)
override;
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));
200 MIB.
addReg(ARM::NoRegister);
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));
259 WLSIt->eraseFromParent();
274MachineInstr *MVETPAndVPTOptimisations::CheckForLRUseInPredecessors(
275 MachineBasicBlock *PreHeader, MachineInstr *LoopStart) {
277 SmallPtrSet<MachineBasicBlock *, 4> Visited;
281 while (!Worklist.
empty()) {
286 for (MachineInstr &
MI : *
MBB) {
293 MachineInstrBuilder MIB =
320bool MVETPAndVPTOptimisations::MergeLoopEnd(MachineLoop *
ML) {
327 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
334 auto *PreHeader =
ML->getLoopPreheader();
335 if (LoopStart->
getOpcode() == ARM::t2WhileLoopStartLR && PreHeader)
336 LoopStart = CheckForLRUseInPredecessors(PreHeader, LoopStart);
338 for (MachineBasicBlock *
MBB :
ML->blocks()) {
339 for (MachineInstr &
MI : *
MBB) {
342 if (LoopStart->
getOpcode() == ARM::t2DoLoopStart)
360 SmallVector<MachineInstr *, 4>
Copies;
363 MachineRegisterInfo *MRI) {
366 while (!Worklist.
empty()) {
371 if (
MI.getOpcode() != TargetOpcode::COPY ||
372 !
MI.getOperand(0).getReg().isVirtual()) {
382 if (!CheckUsers(PhiReg, {LoopDec}, MRI) ||
383 !CheckUsers(DecReg, {LoopPhi, LoopEnd}, MRI) ||
384 !CheckUsers(StartReg, {LoopPhi}, MRI)) {
386 if (LoopStart->
getOpcode() == ARM::t2WhileLoopStartLR) {
408 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
419 MachineInstrBuilder
MI =
421 TII->get(ARM::t2LoopEndDec), DecReg)
430 MI->eraseFromParent();
438bool MVETPAndVPTOptimisations::ConvertTailPredLoop(MachineLoop *
ML,
439 MachineDominatorTree *DT) {
441 <<
ML->getHeader()->getName() <<
"\n");
445 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
448 if (LoopDec != LoopEnd || (LoopStart->
getOpcode() != ARM::t2DoLoopStart &&
449 LoopStart->
getOpcode() != ARM::t2WhileLoopStartLR))
452 SmallVector<MachineInstr *, 4> VCTPs;
453 SmallVector<MachineInstr *, 4> MVEInstrs;
454 for (MachineBasicBlock *BB :
ML->blocks()) {
455 for (MachineInstr &
MI : *BB)
468 MachineInstr *FirstVCTP = *VCTPs.
begin();
469 for (MachineInstr *VCTP : VCTPs) {
471 if (VCTP->getOpcode() != FirstVCTP->
getOpcode() ||
494 if (!Phi ||
Phi->getOpcode() != TargetOpcode::PHI ||
495 Phi->getNumOperands() != 5 ||
496 (
Phi->getOperand(2).getMBB() !=
ML->getLoopLatch() &&
497 Phi->getOperand(4).getMBB() !=
ML->getLoopLatch())) {
501 CountReg =
Phi->getOperand(2).getMBB() ==
ML->getLoopLatch()
502 ?
Phi->getOperand(3).getReg()
503 :
Phi->getOperand(1).getReg();
510 for (MachineInstr &Use :
518 unsigned NewOpc = LoopStart->
getOpcode() == ARM::t2DoLoopStart
519 ? ARM::t2DoLoopStartTP
520 : ARM::t2WhileLoopStartTP;
521 MachineInstrBuilder
MI =
526 if (NewOpc == ARM::t2WhileLoopStartTP)
537 for (MachineInstr *
MI : MVEInstrs) {
539 MI->getOperand(Idx + ARM::SUBOP_vpred_n_tp_reg).setReg(LR);
556 case ARM::MVE_VCMPf32:
557 case ARM::MVE_VCMPf16:
558 case ARM::MVE_VCMPf32r:
559 case ARM::MVE_VCMPf16r:
560 case ARM::MVE_VCMPi8r:
561 case ARM::MVE_VCMPi16r:
562 case ARM::MVE_VCMPi32r:
563 case ARM::MVE_VCMPu8r:
564 case ARM::MVE_VCMPu16r:
565 case ARM::MVE_VCMPu32r:
566 case ARM::MVE_VCMPs8r:
567 case ARM::MVE_VCMPs16r:
568 case ARM::MVE_VCMPs32r:
575 assert(
IsVCMP(Instr.getOpcode()) &&
"Inst must be a VCMP");
596 if (CondOP1.
isIdenticalTo(PrevOP1) && CondOP2.isIdenticalTo(PrevOP2))
603 CondOP2.isIdenticalTo(PrevOP1);
608 if (Instr.getNumOperands() == 0)
618 return RegClass && (RegClass->
getID() == ARM::VCCRRegClassID);
629MachineInstr &MVETPAndVPTOptimisations::ReplaceRegisterUseWithVPNOT(
630 MachineBasicBlock &
MBB, MachineInstr &Instr, MachineOperand &User,
634 MachineInstrBuilder MIBuilder =
641 User.setReg(NewResult);
642 User.setIsKill(
false);
656 assert(Iter->getOpcode() == ARM::MVE_VPNOT &&
"Not a VPNOT!");
658 "The VPNOT cannot be predicated");
666 bool MustMove =
false, HasUser =
false;
668 for (; Iter !=
MBB.end(); ++Iter) {
670 Iter->findRegisterUseOperand(VPNOTOperand,
nullptr,
673 VPNOTOperandKiller = MO;
676 if (Iter->findRegisterUseOperandIdx(
Reg,
nullptr) != -1) {
681 if (Iter->findRegisterUseOperandIdx(VPNOTResult,
nullptr) == -1)
694 if (VPNOTOperandKiller)
715bool MVETPAndVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &
MBB) {
717 SmallVector<MachineInstr *, 4> DeadInstructions;
720 while (Iter != End) {
721 Register VCCRValue, OppositeVCCRValue;
725 for (; Iter != End; ++Iter) {
730 Register Dst = Iter->getOperand(0).getReg();
734 if (VCCRValue && Iter->getOpcode() == ARM::MVE_VPNOT &&
735 Iter->findRegisterUseOperandIdx(VCCRValue,
nullptr) != -1) {
741 OppositeVCCRValue = Dst;
754 assert(VCCRValue && OppositeVCCRValue &&
755 "VCCRValue and OppositeVCCRValue shouldn't be empty if the loop "
756 "stopped before the end of the block!");
757 assert(VCCRValue != OppositeVCCRValue &&
758 "VCCRValue should not be equal to OppositeVCCRValue!");
761 Register LastVPNOTResult = OppositeVCCRValue;
764 for (; Iter != End; ++Iter) {
765 bool IsInteresting =
false;
767 if (MachineOperand *MO =
768 Iter->findRegisterUseOperand(VCCRValue,
nullptr)) {
769 IsInteresting =
true;
774 if (Iter->getOpcode() == ARM::MVE_VPNOT) {
782 <<
"Replacing all uses of '" <<
printReg(Result)
783 <<
"' with '" <<
printReg(LastVPNOTResult) <<
"'\n");
785 MachineInstr &VPNOT =
786 ReplaceRegisterUseWithVPNOT(
MBB, *Iter, *MO, LastVPNOTResult);
793 <<
"' with '" <<
printReg(LastVPNOTResult)
794 <<
"' in instr: " << *Iter);
799 if (MachineOperand *MO = Iter->findRegisterUseOperand(
800 OppositeVCCRValue,
nullptr)) {
801 IsInteresting =
true;
804 if (LastVPNOTResult != OppositeVCCRValue) {
806 <<
printReg(OppositeVCCRValue) <<
"' with '"
807 <<
printReg(LastVPNOTResult) <<
" for instr: ";
809 MO->setReg(LastVPNOTResult);
813 MO->setIsKill(
false);
818 if (Iter->getOpcode() == ARM::MVE_VPNOT &&
820 Register VPNOTOperand = Iter->getOperand(1).getReg();
821 if (VPNOTOperand == LastVPNOTResult ||
822 VPNOTOperand == OppositeVCCRValue) {
823 IsInteresting =
true;
826 LastVPNOTResult = Iter->getOperand(0).getReg();
837 for (MachineInstr *DeadInstruction : DeadInstructions)
838 DeadInstruction->eraseFromParent();
844bool MVETPAndVPTOptimisations::ReplaceVCMPsByVPNOTs(MachineBasicBlock &
MBB) {
845 SmallVector<MachineInstr *, 4> DeadInstructions;
852 MachineInstr *PrevVCMP =
nullptr;
856 MachineOperand *PrevVCMPResultKiller =
nullptr;
858 for (MachineInstr &Instr :
MBB.
instrs()) {
860 if (MachineOperand *MO =
865 PrevVCMPResultKiller = MO;
891 MachineInstrBuilder MIBuilder =
894 .
addReg(PrevVCMPResultReg);
902 if (PrevVCMPResultKiller)
909 PrevVCMPResultKiller =
nullptr;
912 for (MachineInstr *DeadInstruction : DeadInstructions)
913 DeadInstruction->eraseFromParent();
915 return !DeadInstructions.empty();
918bool MVETPAndVPTOptimisations::ReplaceConstByVPNOTs(MachineBasicBlock &
MBB,
919 MachineDominatorTree *DT) {
925 unsigned LastVPTImm = 0;
927 SmallPtrSet<MachineInstr *, 4> DeadInstructions;
929 for (MachineInstr &Instr :
MBB.
instrs()) {
940 if (!Copy ||
Copy->getOpcode() != TargetOpcode::COPY ||
941 !
Copy->getOperand(1).getReg().isVirtual() ||
942 MRI->
getRegClass(
Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {
951 if (Def && (
Def->getOpcode() == ARM::t2MOVi ||
952 Def->getOpcode() == ARM::t2MOVi16))
953 return Def->getOperand(1).getImm();
962 unsigned NotImm = ~Imm & 0xffff;
963 if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm == Imm) {
965 Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
967 DeadInstructions.
insert(Copy);
973 }
else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
978 TII->get(ARM::MVE_VPNOT), NewVPR)
983 Instr.getOperand(PIdx + 1).setReg(NewVPR);
985 DeadInstructions.
insert(Copy);
990 LLVM_DEBUG(
dbgs() <<
"Adding VPNot: " << *VPNot <<
" to replace use at "
999 for (MachineInstr *DI : DeadInstructions)
1000 DI->eraseFromParent();
1002 return !DeadInstructions.empty();
1010bool MVETPAndVPTOptimisations::ConvertVPSEL(MachineBasicBlock &
MBB) {
1011 bool HasVCTP =
false;
1012 SmallVector<MachineInstr *, 4> DeadInstructions;
1020 if (!HasVCTP ||
MI.getOpcode() != ARM::MVE_VPSEL)
1023 MachineInstrBuilder MIBuilder =
1025 .
add(
MI.getOperand(0))
1026 .
add(
MI.getOperand(1))
1027 .
add(
MI.getOperand(1))
1029 .
add(
MI.getOperand(4))
1030 .
add(
MI.getOperand(5))
1031 .
add(
MI.getOperand(2));
1039 for (MachineInstr *DeadInstruction : DeadInstructions)
1040 DeadInstruction->eraseFromParent();
1042 return !DeadInstructions.empty();
1047bool MVETPAndVPTOptimisations::HintDoLoopStartReg(MachineBasicBlock &
MBB) {
1050 if (
MI.getOpcode() != ARM::t2DoLoopStart)
1053 MachineFunction *MF =
MI.getParent()->getParent();
1060bool MVETPAndVPTOptimisations::runOnMachineFunction(MachineFunction &Fn) {
1061 const ARMSubtarget &STI = Fn.
getSubtarget<ARMSubtarget>();
1063 if (!STI.
isThumb2() || !STI.hasLOB())
1068 MachineLoopInfo *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1069 MachineDominatorTree *DT =
1070 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1072 LLVM_DEBUG(
dbgs() <<
"********** ARM MVE VPT Optimisations **********\n"
1073 <<
"********** Function: " << Fn.
getName() <<
'\n');
1082 for (MachineBasicBlock &
MBB : Fn) {
1090 LLVM_DEBUG(
dbgs() <<
"**************************************\n");
1096 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...
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 & 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 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.
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.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.