Go to the documentation of this file.
74 #define DEBUG_TYPE "arm-low-overhead-loops"
75 #define ARM_LOW_OVERHEAD_LOOPS_NAME "ARM Low Overhead Loops pass"
79 cl::desc(
"Disable tail-predication in the ARM LowOverheadLoop pass"),
84 return PIdx != -1 &&
MI->getOperand(PIdx + 1).getReg() == ARM::VPR;
88 return MI->findRegisterDefOperandIdx(ARM::VPR) != -1;
92 return MI.findRegisterUseOperandIdx(ARM::VPR) != -1;
105 return MI->getOpcode() != ARM::t2WhileLoopStartLR;
112 class PostOrderLoopTraversal {
120 : ML(ML), MLI(MLI) { }
140 Order.push_back(
MBB);
154 Order.push_back(
MBB);
160 GetPredecessor(Preheader);
162 GetPredecessor(Preheader);
166 struct PredicatedMI {
172 assert(
I &&
"Instruction must not be null!");
183 friend struct LowOverheadLoop;
190 std::unique_ptr<PredicatedMI>> PredicatedInsts;
193 assert((CurrentPredicates.
size() ||
MI->getParent()->isLiveIn(ARM::VPR))
194 &&
"Can't begin VPT without predicate");
199 PredicatedInsts.emplace(
200 MI, std::make_unique<PredicatedMI>(
MI, CurrentPredicates));
203 static void reset() {
205 PredicatedInsts.clear();
206 CurrentPredicates.
clear();
211 PredicatedInsts.emplace(
212 MI, std::make_unique<PredicatedMI>(
MI, CurrentPredicates));
222 CurrentPredicates.
clear();
229 static bool hasUniformPredicate(VPTState &Block) {
230 return getDivergent(Block) ==
nullptr;
237 for (
unsigned i = 1;
i < Insts.size(); ++
i) {
246 static bool isPredicatedOnVCTP(
MachineInstr *
MI,
bool Exclusive =
false) {
248 if (Exclusive && Predicates.
size() != 1)
250 for (
auto *PredMI : Predicates)
257 static bool isEntryPredicatedOnVCTP(VPTState &Block,
258 bool Exclusive =
false) {
260 return isPredicatedOnVCTP(Insts.front(), Exclusive);
266 static bool hasImplicitlyValidVPT(VPTState &Block,
271 "Expected VPT block to begin with VPT/VPST");
278 return Op && PredicatedInsts.count(
Op) && isPredicatedOnVCTP(
Op);
291 for (
auto *
Def : Defs)
299 return (IsOperandPredicated(VPT, 1) || IsOperandPredicated(VPT, 2)) &&
300 (IsOperandPredicated(VPT, 1) || IsOperandInvariant(VPT, 1)) &&
301 (IsOperandPredicated(VPT, 2) || IsOperandInvariant(VPT, 2));
308 for (
auto &Block : Blocks) {
309 if (isEntryPredicatedOnVCTP(Block,
false) ||
310 hasImplicitlyValidVPT(Block,
RDA))
317 "Expected VPT block to start with a VPST or VPT!");
318 if (Insts.size() == 2 && Insts.front()->getOpcode() != ARM::MVE_VPST &&
322 for (
auto *
MI : Insts) {
332 if (!isPredicatedOnVCTP(
MI)) {
346 assert(Insts.size() <= 5 &&
"Too many instructions in VPT block!");
349 bool containsVCTP()
const {
350 for (
auto *
MI : Insts)
356 unsigned size()
const {
return Insts.size(); }
360 struct LowOverheadLoop {
379 bool CannotTailPredicate =
false;
400 CannotTailPredicate = !ValidateMVEInst(
MI);
403 bool IsTailPredicationLegal()
const {
406 return !Revert && FoundAllComponents() && !VCTPs.empty() &&
417 bool ValidateTailPredicate();
421 bool ValidateLiveOuts();
432 bool FoundAllComponents()
const {
433 return Start && Dec && End;
437 return VPTState::Blocks;
443 if (IsTailPredicationLegal())
444 return TPNumElements;
445 return Start->getOperand(1);
448 unsigned getStartOpcode()
const {
449 bool IsDo =
isDo(Start);
450 if (!IsTailPredicationLegal())
451 return IsDo ? ARM::t2DLS : ARM::t2WLS;
457 if (Start)
dbgs() <<
"ARM Loops: Found Loop Start: " << *Start;
458 if (Dec)
dbgs() <<
"ARM Loops: Found Loop Dec: " << *Dec;
459 if (End)
dbgs() <<
"ARM Loops: Found Loop End: " << *End;
460 if (!VCTPs.empty()) {
461 dbgs() <<
"ARM Loops: Found VCTP(s):\n";
462 for (
auto *
MI : VCTPs)
465 if (!FoundAllComponents())
466 dbgs() <<
"ARM Loops: Not a low-overhead loop.\n";
467 else if (!(Start && Dec && End))
468 dbgs() <<
"ARM Loops: Failed to find all loop components.\n";
479 std::unique_ptr<ARMBasicBlockUtils> BBUtils =
nullptr;
508 bool RevertNonLoops();
519 void ConvertVPTBlocks(LowOverheadLoop &LoLoop);
523 void Expand(LowOverheadLoop &LoLoop);
525 void IterationCountDCE(LowOverheadLoop &LoLoop);
534 std::unique_ptr<PredicatedMI>> VPTState::PredicatedInsts;
547 for (
auto *
Dead : Killed)
551 std::map<MachineInstr *, SmallPtrSet<MachineInstr *, 2>> ITBlocks;
552 for (
auto *
MBB : BasicBlocks) {
553 for (
auto &
IT : *
MBB) {
554 if (
IT.getOpcode() != ARM::t2IT)
565 for (
auto *
Dead : Killed) {
569 auto &CurrentBlock = ITBlocks[
IT];
570 CurrentBlock.erase(
Dead);
571 if (CurrentBlock.empty())
577 if (!ModifiedITs.
empty())
579 Killed.insert(RemoveITs.
begin(), RemoveITs.
end());
590 <<
" - can also remove:\n";
596 if (WontCorruptITs(Killed,
RDA)) {
606 bool LowOverheadLoop::ValidateTailPredicate() {
607 if (!IsTailPredicationLegal()) {
609 dbgs() <<
"ARM Loops: Didn't find a VCTP instruction.\n";
610 dbgs() <<
"ARM Loops: Tail-predication is not valid.\n");
614 assert(!VCTPs.empty() &&
"VCTP instruction expected but is not set");
616 "Shouldn't be processing a loop with more than one block");
619 LLVM_DEBUG(
dbgs() <<
"ARM Loops: tail-predication is disabled\n");
623 if (!VPTState::isValid(
RDA)) {
628 if (!ValidateLiveOuts()) {
637 Register StartReg =
isDo(Start) ? Start->getOperand(1).getReg()
638 : Start->getOperand(0).getReg();
639 if (StartInsertPt == Start && StartReg == ARM::LR) {
644 if (
Use != Start &&
Use != Dec) {
657 if (Start->getOpcode() == ARM::t2DoLoopStartTP) {
658 TPNumElements = Start->getOperand(2);
659 StartInsertPt = Start;
660 StartInsertBB = Start->getParent();
669 LLVM_DEBUG(
dbgs() <<
"ARM Loops: VCTP operand is defined in the loop.\n");
677 if (StartInsertPt != StartInsertBB->
end() &&
682 ElemDef->removeFromParent();
683 StartInsertBB->
insert(StartInsertPt, ElemDef);
685 <<
"ARM Loops: Moved element count def: " << *ElemDef);
687 StartInsertPt->removeFromParent();
690 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Moved start past: " << *ElemDef);
700 TPNumElements = Operand;
701 NumElements = TPNumElements.
getReg();
704 <<
"ARM Loops: Unable to move element count to loop "
705 <<
"start instruction.\n");
732 while (
MBB &&
MBB != StartInsertBB) {
733 if (CannotProvideElements(
MBB, NumElements)) {
734 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Unable to provide element count.\n");
751 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Instruction blocks [W|D]LSTP\n");
774 Ignore.insert(VCTPs.begin(), VCTPs.end());
777 bool FoundSub =
false;
779 for (
auto *
MI : ElementChain) {
784 if (FoundSub || !IsValidSub(
MI, ExpectedVectorWidth)) {
785 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Unexpected instruction in element"
791 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Unexpected instruction in element"
796 ToRemove.insert(ElementChain.begin(), ElementChain.end());
802 if (Start->getOpcode() == ARM::t2DoLoopStartTP && Preheader &&
803 !Preheader->
empty() &&
808 Ignore.insert(VCTPs.begin(), VCTPs.end());
856 switch (
MI.getOpcode()) {
865 case ARM::MVE_VCLZs8:
866 case ARM::MVE_VCLZs16:
867 case ARM::MVE_VCLZs32:
893 Def->getOpcode() == ARM::MVE_VMOVimmi32 &&
894 Def->getOperand(1).getImm() == 0;
898 for (
auto &MO :
MI.operands()) {
910 for (
auto *
Def : Defs) {
922 bool LowOverheadLoop::ValidateLiveOuts() {
950 for (
auto &
MI : *Header) {
958 bool retainsOrReduces =
965 else if (
MI.getNumDefs() == 0)
991 for (
auto *
MI :
reverse(FalseLanesUnknown)) {
992 for (
auto &MO :
MI->operands()) {
995 if (!HasPredicatedUsers(
MI, MO, Predicated)) {
1011 assert(ExitBlocks.size() == 1 &&
"Expected a single exit block");
1016 if (RegMask.PhysReg == ARM::VPR)
1020 if (QPRs->
contains(RegMask.PhysReg))
1031 for (
auto *
MI : LiveOutMIs) {
1050 ? End->getOperand(1).getMBB()
1051 : End->getOperand(2).getMBB();
1055 LLVM_DEBUG(
dbgs() <<
"ARM Loops: LoopEnd is not targeting header.\n");
1061 if (BBUtils->getOffsetOf(End) < BBUtils->getOffsetOf(ML.
getHeader()) ||
1062 !BBUtils->isBBInRange(End, ML.
getHeader(), 4094)) {
1067 if (Start->getOpcode() == ARM::t2WhileLoopStartLR &&
1068 (BBUtils->getOffsetOf(Start) >
1069 BBUtils->getOffsetOf(Start->getOperand(2).getMBB()) ||
1070 !BBUtils->isBBInRange(Start, Start->getOperand(2).getMBB(), 4094))) {
1071 LLVM_DEBUG(
dbgs() <<
"ARM Loops: WLS offset is out-of-range!\n");
1078 StartInsertBB = Start->getParent();
1082 Revert = !ValidateRanges(Start, End, BBUtils, ML);
1083 CannotTailPredicate = !ValidateTailPredicate();
1088 if (VCTPs.empty()) {
1089 VCTPs.push_back(
MI);
1098 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Found VCTP with a different reaching "
1099 "definition from the main VCTP");
1102 VCTPs.push_back(
MI);
1107 if (CannotTailPredicate)
1113 if (
MI->getOpcode() == ARM::MVE_VPSEL ||
1114 MI->getOpcode() == ARM::MVE_VPNOT) {
1134 unsigned LastOpIdx =
MI->getNumOperands() - 1;
1141 VPTState::addInst(
MI);
1143 }
else if (
MI->getOpcode() != ARM::MVE_VPST) {
1152 bool RequiresExplicitPredication =
1156 dbgs() <<
"ARM Loops: Can't tail predicate: " << *
MI);
1171 VPTState::resetPredicate(
MI);
1173 VPTState::addPredicate(
MI);
1192 MLI = &getAnalysis<MachineLoopInfo>();
1193 RDA = &getAnalysis<ReachingDefAnalysis>();
1197 TRI =
ST.getRegisterInfo();
1199 BBUtils->computeAllBlockSizes();
1200 BBUtils->adjustBBOffsetsAfter(&MF->
front());
1202 bool Changed =
false;
1203 for (
auto ML : *MLI) {
1205 Changed |= ProcessLoop(ML);
1207 Changed |= RevertNonLoops();
1211 bool ARMLowOverheadLoops::ProcessLoop(
MachineLoop *ML) {
1213 bool Changed =
false;
1217 Changed |= ProcessLoop(*
I);
1222 else if (
auto *Preheader = MLI->findLoopPreheader(ML))
1224 else if (
auto *Preheader = MLI->findLoopPreheader(ML,
true))
1234 for (
auto &
MI : *
MBB) {
1243 LowOverheadLoop LoLoop(*ML, *MLI, *
RDA, *
TRI, *
TII);
1247 if (LoLoop.Preheader)
1248 LoLoop.Start = SearchForStart(LoLoop.Preheader);
1256 for (
auto &
MI : *
MBB) {
1257 if (
MI.isDebugValue())
1259 else if (
MI.getOpcode() == ARM::t2LoopDec)
1261 else if (
MI.getOpcode() == ARM::t2LoopEnd)
1263 else if (
MI.getOpcode() == ARM::t2LoopEndDec)
1264 LoLoop.End = LoLoop.Dec = &
MI;
1267 else if (
MI.getDesc().isCall()) {
1271 LoLoop.Revert =
true;
1276 LoLoop.AnalyseMVEInst(&
MI);
1282 if (!LoLoop.FoundAllComponents()) {
1283 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Didn't find loop start, update, end\n");
1287 assert(LoLoop.Start->getOpcode() != ARM::t2WhileLoopStart &&
1288 "Expected t2WhileLoopStart to be removed before regalloc!");
1293 if (LoLoop.Dec != LoLoop.End) {
1296 if (
Uses.size() > 1 || !
Uses.count(LoLoop.End)) {
1298 LoLoop.Revert =
true;
1301 LoLoop.Validate(BBUtils.get());
1313 unsigned BrOpc = BBUtils->isBBInRange(
MI, DestBB, 254) ?
1314 ARM::tBcc : ARM::t2Bcc;
1329 if (
I->getOpcode() == ARM::t2LoopEnd) {
1348 unsigned BrOpc = BBUtils->isBBInRange(
MI, DestBB, 254) ?
1349 ARM::tBcc : ARM::t2Bcc;
1355 void ARMLowOverheadLoops::RevertLoopEndDec(
MachineInstr *
MI)
const {
1357 assert(
MI->getOpcode() == ARM::t2LoopEndDec &&
"Expected a t2LoopEndDec!");
1363 MIB.
add(
MI->getOperand(1));
1366 MIB.
addReg(ARM::NoRegister);
1372 BBUtils->isBBInRange(
MI, DestBB, 254) ? ARM::tBcc : ARM::t2Bcc;
1376 MIB.
add(
MI->getOperand(2));
1380 MI->eraseFromParent();
1407 void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) {
1408 if (!LoLoop.IsTailPredicationLegal())
1411 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Trying DCE on loop iteration count.\n");
1416 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Couldn't find iteration count.\n");
1423 if (!TryRemove(
Def, *
RDA, LoLoop.ToRemove, Killed))
1424 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Unsafe to remove loop iteration count.\n");
1427 MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) {
1431 IterationCountDCE(LoLoop);
1436 unsigned Opc = LoLoop.getStartOpcode();
1441 if (Opc == ARM::t2DLS && Count.
isReg() && Count.
getReg() == ARM::LR) {
1442 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Didn't insert start: DLS lr, lr");
1446 BuildMI(*
MBB, InsertPt, Start->getDebugLoc(),
TII->get(Opc));
1451 MIB.
add(Start->getOperand(2));
1457 LoLoop.ToRemove.insert(Start);
1461 void ARMLowOverheadLoops::ConvertVPTBlocks(LowOverheadLoop &LoLoop) {
1463 if (
MI->isDebugInstr())
1467 assert(PIdx >= 1 &&
"Trying to unpredicate a non-predicated instruction");
1469 "Expected Then predicate!");
1471 MI->getOperand(PIdx + 1).setReg(0);
1474 for (
auto &Block : LoLoop.getVPTBlocks()) {
1478 assert(TheVCMP &&
"Replacing a removed or non-existent VCMP");
1481 BuildMI(*At->getParent(), At, At->getDebugLoc(),
1490 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Combining with VCMP to VPT: " << *MIB);
1491 LoLoop.BlockMasksToRecompute.insert(MIB.
getInstr());
1492 LoLoop.ToRemove.insert(TheVCMP);
1496 if (VPTState::isEntryPredicatedOnVCTP(Block,
true)) {
1498 if (VPTState::hasUniformPredicate(Block)) {
1504 for (
unsigned i = 1;
i < Insts.size(); ++
i)
1505 RemovePredicate(Insts[
i]);
1514 MachineInstr *Divergent = VPTState::getDivergent(Block);
1517 while (DivergentNext !=
MBB->
end() && DivergentNext->isDebugInstr())
1520 bool DivergentNextIsPredicated =
1521 DivergentNext !=
MBB->
end() &&
1526 RemovePredicate(&*
I);
1533 if (DivergentNextIsPredicated) {
1545 LoLoop.BlockMasksToRecompute.insert(MIB.
getInstr());
1554 LoLoop.ToRemove.insert(VPST);
1555 }
else if (
Block.containsVCTP()) {
1559 if (
Block.size() == 2) {
1561 "Found a VPST in an otherwise empty vpt block");
1562 LoLoop.ToRemove.insert(VPST);
1564 LoLoop.BlockMasksToRecompute.insert(VPST);
1565 }
else if (Insts.front()->getOpcode() == ARM::MVE_VPST) {
1572 "The instruction after a VPST must be predicated");
1576 !LoLoop.ToRemove.contains(VprDef)) {
1587 ReplaceVCMPWithVPT(
VCMP, VPST);
1589 LoLoop.ToRemove.insert(VPST);
1595 LoLoop.ToRemove.insert(LoLoop.VCTPs.begin(), LoLoop.VCTPs.end());
1598 void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) {
1601 auto ExpandLoopEnd = [
this](LowOverheadLoop &LoLoop) {
1604 unsigned Opc = LoLoop.IsTailPredicationLegal() ?
1605 ARM::MVE_LETP : ARM::t2LEUpdate;
1609 unsigned Off = LoLoop.Dec == LoLoop.End ? 1 : 0;
1610 MIB.
add(End->getOperand(Off + 0));
1611 MIB.
add(End->getOperand(Off + 1));
1613 LoLoop.ToRemove.insert(LoLoop.Dec);
1614 LoLoop.ToRemove.insert(End);
1628 if (
BB->isLayoutSuccessor(Succ)) {
1635 if (LoLoop.Revert) {
1636 if (LoLoop.Start->getOpcode() == ARM::t2WhileLoopStartLR)
1637 RevertWhile(LoLoop.Start);
1639 RevertDo(LoLoop.Start);
1640 if (LoLoop.Dec == LoLoop.End)
1641 RevertLoopEndDec(LoLoop.End);
1645 LoLoop.Start = ExpandLoopStart(LoLoop);
1647 RemoveDeadBranch(LoLoop.Start);
1648 LoLoop.End = ExpandLoopEnd(LoLoop);
1649 RemoveDeadBranch(LoLoop.End);
1650 if (LoLoop.IsTailPredicationLegal())
1651 ConvertVPTBlocks(LoLoop);
1652 for (
auto *
I : LoLoop.ToRemove) {
1654 I->eraseFromParent();
1656 for (
auto *
I : LoLoop.BlockMasksToRecompute) {
1657 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Recomputing VPT/VPST Block Mask: " << *
I);
1663 PostOrderLoopTraversal DFS(LoLoop.ML, *MLI);
1666 for (
auto *
MBB : PostOrder) {
1680 bool ARMLowOverheadLoops::RevertNonLoops() {
1681 LLVM_DEBUG(
dbgs() <<
"ARM Loops: Reverting any remaining pseudos...\n");
1682 bool Changed =
false;
1684 for (
auto &
MBB : *MF) {
1690 for (
auto &
I :
MBB) {
1692 Starts.push_back(&
I);
1693 else if (
I.getOpcode() == ARM::t2LoopDec)
1695 else if (
I.getOpcode() == ARM::t2LoopEnd)
1697 else if (
I.getOpcode() == ARM::t2LoopEndDec)
1698 EndDecs.push_back(&
I);
1701 if (Starts.empty() && Decs.empty() && Ends.empty() && EndDecs.empty())
1706 for (
auto *Start : Starts) {
1707 if (Start->getOpcode() == ARM::t2WhileLoopStartLR)
1712 for (
auto *Dec : Decs)
1715 for (
auto *End : Ends)
1717 for (
auto *End : EndDecs)
1718 RevertLoopEndDec(End);
1724 return new ARMLowOverheadLoops();
static bool isVectorPredicated(MachineInstr *MI)
virtual StringRef getRegAsmName(MCRegister Reg) const
Return the assembly name for Reg.
INITIALIZE_PASS(ARMLowOverheadLoops, DEBUG_TYPE, ARM_LOW_OVERHEAD_LOOPS_NAME, false, false) static bool TryRemove(MachineInstr *MI
static bool producesFalseLanesZero(MachineInstr &MI, const TargetRegisterClass *QPRs, const ReachingDefAnalysis &RDA, InstSet &FalseLanesZero)
if(!RDA.isSafeToRemove(MI, Uses, Ignore)) return false
void reset()
Re-run the analysis.
pred_iterator pred_begin()
bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, MCRegister PhysReg) const
Return whether A and B use the same def of PhysReg.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const
Return whether removing this instruction will have no effect on the program, returning the redundant ...
bool isVpred(OperandType op)
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
MachineInstr * getUniqueReachingMIDef(MachineInstr *MI, MCRegister PhysReg) const
If a single MachineInstr creates the reaching definition, then return it.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
This class provides the reaching def analysis.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
const MachineInstrBuilder & add(const MachineOperand &MO) const
FunctionPass * createARMLowOverheadLoopsPass()
void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
size_type size() const
Determine the number of elements in the SetVector.
ReachingDefAnalysis InstSet InstSet & Ignore
MachineBasicBlock * findLoopPreheader(MachineLoop *L, bool SpeculativePreheader=false) const
Find the block that either is the loop preheader, or could speculatively be used as the preheader.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
detail::enumerator< R > enumerate(R &&TheRange)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
ReachingDefAnalysis InstSet & ToRemove
static void recomputeLiveIns(MachineBasicBlock &MBB)
Convenience function for recomputing live-in's for MBB.
static bool isDomainMVE(MachineInstr *MI)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
static bool hasVPRUse(MachineInstr &MI)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
iterator_range< livein_iterator > liveins() const
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
static bool shouldInspect(MachineInstr &MI)
static bool isDo(MachineInstr *MI)
Properties which a MachineFunction may have at a given point in time.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
static ARM::PredBlockMask CreateVPTBlock(MachineBasicBlock::instr_iterator &Iter, MachineBasicBlock::instr_iterator EndIter, SmallVectorImpl< MachineInstr * > &DeadInstructions)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned const TargetRegisterInfo * TRI
static unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop)
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
bool hasLocalDefBefore(MachineInstr *MI, MCRegister PhysReg) const
Provide whether the register has been defined in the same basic block as, and before,...
MachineInstr * getLocalLiveOutMIDef(MachineBasicBlock *MBB, MCRegister PhysReg) const
Return the local MI that produces the live out value for PhysReg, or nullptr for a non-live out or no...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
SmallPtrSet< MachineInstr *, 2 > Uses
bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved backwards to just after To.
int getAddSubImmediate(MachineInstr &MI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
unsigned pred_size() const
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
static bool isLoopStart(MachineInstr &MI)
const MachineBasicBlock & front() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
void getGlobalUses(MachineInstr *MI, MCRegister PhysReg, InstSet &Uses) const
Collect the users of the value stored in PhysReg, which is defined by MI.
static bool producesDoubleWidthResult(const MachineInstr &MI)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const MachineOperand & getOperand(unsigned i) const
void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII, bool SetFlags=false)
int findFirstVPTPredOperandIdx(const MachineInstr &MI)
void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool SkipCmp=false)
Represent the analysis usage information of a pass.
const MachineFunctionProperties & getProperties() const
Get the function properties.
ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
MachineOperand class - Representation of each machine instruction operand.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
MachineFunctionProperties & set(Property P)
Pair of physical register and lane mask.
static cl::opt< bool > DisableTailPredication("arm-loloops-disable-tailpred", cl::Hidden, cl::desc("Disable tail-predication in the ARM LowOverheadLoop pass"), cl::init(false))
static bool isVectorPredicate(MachineInstr *MI)
static unsigned VCMPOpcodeToVPT(unsigned Opcode)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
static bool isVPTOpcode(int Opc)
const TargetRegisterClass * getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII)
initializer< Ty > init(const Ty &Val)
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isVCTP(const MachineInstr *MI)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
print Print MemDeps of function
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
static bool isRegInClass(const MachineOperand &MO, const TargetRegisterClass *Class)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
bool insert(const value_type &X)
Insert a new element into the SetVector.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
MachineInstrBundleIterator< MachineInstr > iterator
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate IT block based on arch"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT, "arm-no-restrict-it", "Allow IT blocks based on ARMv7")))
static bool isHorizontalReduction(const MachineInstr &MI)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< succ_iterator > successors()
StringRef - Represent a constant reference to a string, i.e.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void getReachingLocalUses(MachineInstr *MI, MCRegister PhysReg, InstSet &Uses) const
Provides the uses, in the same block as MI, of register that MI defines.
bool isOutermost() const
Return true if the loop does not have a parent (natural) loop.
void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool UseCmp=false)
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
const MachineBasicBlock * getParent() const
this could be done in SelectionDAGISel along with other special for
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const
Assuming MI is dead, recursively search the incoming operands which are killed by MI and collect thos...
void clear()
Completely clear the SetVector.
@ ValidForTailPredication
bool isSafeToDefRegAt(MachineInstr *MI, MCRegister PhysReg) const
Return whether a MachineInstr could be inserted at MI and safely define the given register without af...
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
BlockT * getHeader() const
void recomputeVPTBlockMask(MachineInstr &Instr)
void getGlobalReachingDefs(MachineInstr *MI, MCRegister PhysReg, InstSet &Defs) const
Collect all possible definitions of the value stored in PhysReg, which is used by MI.
static bool canGenerateNonZeros(const MachineInstr &MI)
iterator end()
Get an iterator to the end of the SetVector.
#define ARM_LOW_OVERHEAD_LOOPS_NAME
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
ReachingDefAnalysis & RDA
LLVM_NODISCARD bool empty() const
@ RetainsPreviousHalfElement
bool isReachingDefLiveOut(MachineInstr *MI, MCRegister PhysReg) const
Return whether the reaching def for MI also is live out of its parent block.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
FunctionPass class - This class is used to implement most global optimizations.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
MachineInstr * getMIOperand(MachineInstr *MI, unsigned Idx) const
If a single MachineInstr creates the reaching definition, for MIs operand at Idx, then return it.
AnalysisUsage & addRequired()
A vector that has set insertion semantics.
bool contains(ConstPtrType Ptr) const
static bool retainsPreviousHalfElement(const MachineInstr &MI)
static bool isMovRegOpcode(int Opc)
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
iterator_range< const_opInfo_iterator > operands() const
static bool isSubImmOpcode(int Opc)
static unsigned getTailPredVectorWidth(unsigned Opcode)
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
A Use represents the edge between a Value definition and its users.
reference emplace_back(ArgTypes &&... Args)
bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const
Return whether From can be moved forwards to just before To.
Wrapper class representing physical registers. Should be passed by value.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator insert(iterator I, T &&Elt)