103#define DEBUG_TYPE "peephole-opt"
107 cl::desc(
"Aggressive extension optimization"));
111 cl::desc(
"Disable the peephole optimizer"));
118 cl::desc(
"Disable advanced copy optimization"));
122 cl::desc(
"Disable non-allocatable physical register copy optimization"));
128 cl::desc(
"Limit the length of PHI chains to lookup"));
134 cl::desc(
"Maximum length of recurrence chain when evaluating the benefit "
135 "of commuting operands"));
137STATISTIC(NumReuse,
"Number of extension results reused");
139STATISTIC(NumImmFold,
"Number of move immediate folded");
142STATISTIC(NumUncoalescableCopies,
"Number of uncoalescable copies optimized");
143STATISTIC(NumRewrittenCopies,
"Number of copies rewritten");
144STATISTIC(NumNAPhysCopies,
"Number of non-allocatable physical copies removed");
148class ValueTrackerResult;
149class RecurrenceInstr;
155 int CurrentSrcIdx = 0;
158 virtual ~Rewriter() =
default;
190 virtual bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg) = 0;
194class CopyRewriter :
public Rewriter {
197 assert(
MI.isCopy() &&
"Expected copy instruction");
199 ~CopyRewriter()
override =
default;
203 if (++CurrentSrcIdx > 1)
207 const MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
210 const MachineOperand &MODef = CopyLike.getOperand(0);
215 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
216 MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
225class UncoalescableRewriter :
public Rewriter {
229 UncoalescableRewriter(MachineInstr &
MI) :
Rewriter(
MI) {
230 NumDefs =
MI.getDesc().getNumDefs();
240 if (CurrentSrcIdx == NumDefs)
243 while (CopyLike.getOperand(CurrentSrcIdx).isDead()) {
245 if (CurrentSrcIdx == NumDefs)
251 const MachineOperand &MODef = CopyLike.getOperand(CurrentSrcIdx);
258 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
264class InsertSubregRewriter :
public Rewriter {
267 assert(
MI.isInsertSubreg() &&
"Invalid instruction");
284 if (CurrentSrcIdx == 2)
288 const MachineOperand &MOInsertedReg = CopyLike.getOperand(2);
290 const MachineOperand &MODef = CopyLike.getOperand(0);
298 (
unsigned)CopyLike.getOperand(3).getImm());
302 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
303 if (CurrentSrcIdx != 2)
306 MachineOperand &MO = CopyLike.getOperand(CurrentSrcIdx);
314class ExtractSubregRewriter :
public Rewriter {
315 const TargetInstrInfo &TII;
318 ExtractSubregRewriter(MachineInstr &
MI,
const TargetInstrInfo &TII)
320 assert(
MI.isExtractSubreg() &&
"Invalid instruction");
331 if (CurrentSrcIdx == 1)
335 const MachineOperand &MOExtractedReg = CopyLike.getOperand(1);
344 const MachineOperand &MODef = CopyLike.getOperand(0);
349 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
351 if (CurrentSrcIdx != 1)
354 CopyLike.getOperand(CurrentSrcIdx).setReg(NewReg);
365 CopyLike.removeOperand(2);
367 CopyLike.setDesc(TII.get(TargetOpcode::COPY));
370 CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg);
376class RegSequenceRewriter :
public Rewriter {
379 assert(
MI.isRegSequence() &&
"Invalid instruction");
403 if (
static_cast<unsigned>(CurrentSrcIdx) >= CopyLike.getNumOperands())
406 const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
407 Src.Reg = MOInsertedReg.
getReg();
412 Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
414 const MachineOperand &MODef = CopyLike.getOperand(0);
416 assert(MODef.
getSubReg() == 0 &&
"cannot have subregister def in SSA");
420 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
421 MachineOperand &MO = CopyLike.getOperand(CurrentSrcIdx);
429 const TargetInstrInfo *TII =
nullptr;
430 const TargetRegisterInfo *TRI =
nullptr;
431 MachineRegisterInfo *MRI =
nullptr;
432 MachineDominatorTree *DT =
nullptr;
433 MachineLoopInfo *MLI =
nullptr;
436 PeepholeOptimizer(MachineDominatorTree *DT, MachineLoopInfo *MLI)
437 : DT(DT), MLI(MLI) {}
441 using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
444 using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>;
448 SmallPtrSet<MachineInstr *, 16> &LocalMIs);
449 bool optimizeExtInstr(MachineInstr &
MI, MachineBasicBlock &
MBB,
450 SmallPtrSetImpl<MachineInstr *> &LocalMIs);
451 bool optimizeSelect(MachineInstr &
MI,
452 SmallPtrSetImpl<MachineInstr *> &LocalMIs);
453 bool optimizeCondBranch(MachineInstr &
MI);
455 bool optimizeCoalescableCopyImpl(
Rewriter &&CpyRewriter);
456 bool optimizeCoalescableCopy(MachineInstr &
MI);
457 bool optimizeUncoalescableCopy(MachineInstr &
MI,
458 SmallPtrSetImpl<MachineInstr *> &LocalMIs);
459 bool optimizeRecurrence(MachineInstr &
PHI);
462 bool isMoveImmediate(MachineInstr &
MI, SmallSet<Register, 4> &ImmDefRegs,
463 DenseMap<Register, MachineInstr *> &ImmDefMIs);
464 bool foldImmediate(MachineInstr &
MI, SmallSet<Register, 4> &ImmDefRegs,
465 DenseMap<Register, MachineInstr *> &ImmDefMIs,
473 const SmallSet<Register, 2> &TargetReg,
474 RecurrenceCycle &RC);
481 bool foldRedundantCopy(MachineInstr &
MI);
492 foldRedundantNAPhysCopy(MachineInstr &
MI,
493 DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs);
495 bool isLoadFoldable(MachineInstr &
MI,
496 SmallSet<Register, 16> &FoldAsLoadDefCandidates);
503 SmallPtrSet<MachineInstr *, 16> &LocalMIs);
507 static bool isCoalescableCopy(
const MachineInstr &
MI) {
510 return MI.isCopy() ||
512 MI.isExtractSubreg()));
517 static bool isUncoalescableCopy(
const MachineInstr &
MI) {
519 MI.isInsertSubregLike() ||
520 MI.isExtractSubregLike()));
523 MachineInstr &rewriteSource(MachineInstr &CopyLike,
RegSubRegPair Def,
524 RewriteMapTy &RewriteMap);
528 DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
531 void MF_HandleInsertion(MachineInstr &
MI)
override {}
538 unsigned SrcSubReg =
MI.getOperand(1).getSubReg();
539 if (!SrcReg.
isVirtual() && !MRI->isConstantPhysReg(SrcReg))
548 void deleteChangedCopy(MachineInstr &
MI) {
550 if (!getCopySrc(
MI, SrcPair))
553 auto It = CopySrcMIs.find(SrcPair);
554 if (It != CopySrcMIs.end() && It->second == &
MI)
555 CopySrcMIs.erase(It);
558 void MF_HandleRemoval(MachineInstr &
MI)
override { deleteChangedCopy(
MI); }
560 void MF_HandleChangeDesc(MachineInstr &
MI,
const MCInstrDesc &TID)
override {
561 deleteChangedCopy(
MI);
569 PeepholeOptimizerLegacy() : MachineFunctionPass(ID) {}
573 void getAnalysisUsage(AnalysisUsage &AU)
const override {
582 MachineFunctionProperties getRequiredProperties()
const override {
583 return MachineFunctionProperties().setIsSSA();
593class RecurrenceInstr {
595 using IndexPair = std::pair<unsigned, unsigned>;
597 RecurrenceInstr(MachineInstr *MI) : MI(MI) {}
598 RecurrenceInstr(MachineInstr *MI,
unsigned Idx1,
unsigned Idx2)
599 : MI(MI), CommutePair(std::make_pair(Idx1, Idx2)) {}
601 MachineInstr *getMI()
const {
return MI; }
602 std::optional<IndexPair> getCommutePair()
const {
return CommutePair; }
606 std::optional<IndexPair> CommutePair;
612class ValueTrackerResult {
618 const MachineInstr *Inst =
nullptr;
621 ValueTrackerResult() =
default;
623 ValueTrackerResult(
Register Reg,
unsigned SubReg) { addSource(
Reg, SubReg); }
625 bool isValid()
const {
return getNumSources() > 0; }
627 void setInst(
const MachineInstr *
I) { Inst =
I; }
628 const MachineInstr *getInst()
const {
return Inst; }
635 void addSource(
Register SrcReg,
unsigned SrcSubReg) {
639 void setSource(
int Idx,
Register SrcReg,
unsigned SrcSubReg) {
640 assert(Idx < getNumSources() &&
"Reg pair source out of index");
644 int getNumSources()
const {
return RegSrcs.size(); }
649 assert(Idx < getNumSources() &&
"Reg source out of index");
650 return RegSrcs[Idx].Reg;
653 unsigned getSrcSubReg(
int Idx)
const {
654 assert(Idx < getNumSources() &&
"SubReg source out of index");
655 return RegSrcs[Idx].SubReg;
659 if (
Other.getInst() != getInst())
662 if (
Other.getNumSources() != getNumSources())
665 for (
int i = 0, e =
Other.getNumSources(); i != e; ++i)
666 if (
Other.getSrcReg(i) != getSrcReg(i) ||
667 Other.getSrcSubReg(i) != getSrcSubReg(i))
692 const MachineInstr *Def =
nullptr;
704 const MachineRegisterInfo &MRI;
707 const TargetInstrInfo *TII;
710 ValueTrackerResult getNextSourceImpl();
713 ValueTrackerResult getNextSourceFromCopy();
716 ValueTrackerResult getNextSourceFromBitcast();
719 ValueTrackerResult getNextSourceFromRegSequence();
722 ValueTrackerResult getNextSourceFromInsertSubreg();
725 ValueTrackerResult getNextSourceFromExtractSubreg();
728 ValueTrackerResult getNextSourceFromSubregToReg();
731 ValueTrackerResult getNextSourceFromPHI();
743 ValueTracker(
Register Reg,
unsigned DefSubReg,
const MachineRegisterInfo &MRI,
744 const TargetInstrInfo *TII =
nullptr)
745 : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
746 if (!Reg.isPhysical()) {
747 MachineRegisterInfo::def_iterator DI = MRI.def_begin(Reg);
748 if (DI != MRI.def_end()) {
749 Def = DI->getParent();
750 DefIdx = DI.getOperandNo();
760 ValueTrackerResult getNextSource();
765char PeepholeOptimizerLegacy::ID = 0;
770 "Peephole Optimizations",
false,
false)
784bool PeepholeOptimizer::optimizeExtInstr(
789 if (!
TII->isCoalescableExtInstr(
MI, SrcReg, DstReg, SubIdx))
802 DstRC =
TRI->getSubClassWithSubReg(DstRC, SubIdx);
812 TRI->getSubClassWithSubReg(MRI->
getRegClass(SrcReg), SubIdx) !=
nullptr;
818 ReachedBBs.insert(UI.getParent());
826 bool ExtendLife =
true;
828 MachineInstr *UseMI = UseMO.getParent();
832 if (UseMI->isPHI()) {
838 if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx)
858 if (
UseMI->getOpcode() == TargetOpcode::SUBREG_TO_REG)
862 if (UseMBB == &
MBB) {
864 if (!LocalMIs.count(
UseMI))
865 Uses.push_back(&UseMO);
866 }
else if (ReachedBBs.count(UseMBB)) {
869 Uses.push_back(&UseMO);
873 ExtendedUses.push_back(&UseMO);
882 if (ExtendLife && !ExtendedUses.empty())
884 Uses.append(ExtendedUses.begin(), ExtendedUses.end());
889 SmallPtrSet<MachineBasicBlock *, 4> PHIBBs;
894 for (MachineInstr &UI : MRI->use_nodbg_instructions(DstReg))
896 PHIBBs.insert(UI.getParent());
898 const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
899 for (MachineOperand *UseMO : Uses) {
900 MachineInstr *UseMI = UseMO->getParent();
901 MachineBasicBlock *UseMBB = UseMI->getParent();
902 if (PHIBBs.count(UseMBB))
907 MRI->clearKillFlags(DstReg);
908 MRI->constrainRegClass(DstReg, DstRC);
926 RC = MRI->getRegClass(UseMO->getReg());
927 if (UseMO->getSubReg())
928 RC = TRI->getSubRegisterClass(RC, UseMO->getSubReg());
931 Register NewVR = MRI->createVirtualRegister(RC);
932 [[maybe_unused]] auto Copy = BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
933 TII->get(TargetOpcode::COPY), NewVR)
934 .addReg(DstReg, {}, SubIdx);
935 LLVM_DEBUG(dbgs() <<
" Build new copy: " << *Copy
936 <<
" Changing: " << *UseMI);
940 UseMO->setReg(NewVR);
941 LLVM_DEBUG(dbgs() <<
" to: " << *UseMI);
954bool PeepholeOptimizer::optimizeCmpInstr(
960 int64_t CmpMask, CmpValue;
967 if (!
TII->optimizeCompareInstr(
MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI))
976 if (MachineInstr *FlagProducer =
978 MachineInstr *LoadMI = MRI->
getVRegDef(SrcReg);
984 FlagProducer->getIterator()),
985 [](
const MachineInstr &
I) { return I.isLoadFoldBarrier(); }))
986 foldLoadInto(MF, *FlagProducer, SrcReg, LocalMIs);
993bool PeepholeOptimizer::optimizeSelect(
994 MachineInstr &
MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
995 assert(
MI.isSelect() &&
"Should only be called when MI->isSelect() is true");
996 if (!
TII->optimizeSelect(
MI, LocalMIs))
999 MI.eraseFromParent();
1005bool PeepholeOptimizer::optimizeCondBranch(MachineInstr &
MI) {
1006 return TII->optimizeCondBranch(
MI);
1025 RewriteMapTy &RewriteMap) {
1034 unsigned PHICount = 0;
1038 bool FoundSuitable =
false;
1040 bool Aborted =
false;
1049 ValueTracker ValTracker(CurSrcPair.
Reg, CurSrcPair.
SubReg, *MRI,
TII);
1054 ValueTrackerResult Res = ValTracker.getNextSource();
1056 if (!Res.isValid()) {
1062 auto [InsertPt, WasInserted] = RewriteMap.try_emplace(CurSrcPair, Res);
1065 const ValueTrackerResult &CurSrcRes = InsertPt->second;
1067 assert(CurSrcRes == Res &&
"ValueTrackerResult found must match");
1070 if (CurSrcRes.getNumSources() > 1) {
1072 <<
"findNextSource: found PHI cycle, aborting...\n");
1080 unsigned NumSrcs = Res.getNumSources();
1089 for (
unsigned i = 0; i < NumSrcs; ++i)
1094 CurSrcPair = Res.getSrc(0);
1106 if (!
TRI->shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC,
1112 if (PHICount > 0 && CurSrcPair.
SubReg != 0)
1117 if (CurSrcPair.
SubReg != 0) {
1118 SuitablePair = CurSrcPair;
1119 FoundSuitable =
true;
1130 }
while (!SrcToLook.
empty());
1137 CurSrcPair = SuitablePair;
1138 RewriteMap.erase(SuitablePair);
1142 return CurSrcPair.
Reg !=
Reg;
1154 assert(!SrcRegs.
empty() &&
"No sources to create a PHI instruction?");
1159 assert(SrcRegs[0].SubReg == 0 &&
"should not have subreg operand");
1163 TII.get(TargetOpcode::PHI), NewVR);
1165 unsigned MBBOpIdx = 2;
1167 MIB.
addReg(RegPair.Reg, {}, RegPair.SubReg);
1188 const PeepholeOptimizer::RewriteMapTy &RewriteMap,
1189 bool HandleMultipleSources =
true) {
1192 ValueTrackerResult Res = RewriteMap.
lookup(LookupSrc);
1198 unsigned NumSrcs = Res.getNumSources();
1200 LookupSrc.
Reg = Res.getSrcReg(0);
1201 LookupSrc.
SubReg = Res.getSrcSubReg(0);
1206 if (!HandleMultipleSources)
1212 for (
unsigned i = 0; i < NumSrcs; ++i) {
1213 RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i));
1231bool PeepholeOptimizer::optimizeCoalescableCopyImpl(
Rewriter &&CpyRewriter) {
1237 while (CpyRewriter.getNextRewritableSource(TrackPair, Dst)) {
1238 if (Dst.Reg.isPhysical()) {
1249 RewriteMapTy RewriteMap;
1252 if (!findNextSource(DefRC, Dst.SubReg, TrackPair, RewriteMap))
1260 "should not rewrite source to original value");
1270 TRI->getSubClassWithSubReg(RC, NewSrc.
SubReg);
1277 if (CpyRewriter.RewriteCurrentSource(NewSrc.
Reg, NewSrc.
SubReg)) {
1289 NumRewrittenCopies +=
Changed;
1304bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr &
MI) {
1305 assert(isCoalescableCopy(
MI) &&
"Invalid argument");
1306 assert(
MI.getDesc().getNumDefs() == 1 &&
1307 "Coalescer can understand multiple defs?!");
1308 const MachineOperand &MODef =
MI.getOperand(0);
1313 switch (
MI.getOpcode()) {
1314 case TargetOpcode::COPY:
1315 return optimizeCoalescableCopyImpl(CopyRewriter(
MI));
1316 case TargetOpcode::INSERT_SUBREG:
1317 return optimizeCoalescableCopyImpl(InsertSubregRewriter(
MI));
1318 case TargetOpcode::EXTRACT_SUBREG:
1319 return optimizeCoalescableCopyImpl(ExtractSubregRewriter(
MI, *
TII));
1320 case TargetOpcode::REG_SEQUENCE:
1321 return optimizeCoalescableCopyImpl(RegSequenceRewriter(
MI));
1324 if (
MI.isBitcast() ||
MI.isRegSequenceLike() ||
MI.isInsertSubregLike() ||
1325 MI.isExtractSubregLike())
1326 return optimizeCoalescableCopyImpl(UncoalescableRewriter(
MI));
1336MachineInstr &PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike,
1338 RewriteMapTy &RewriteMap) {
1339 assert(!
Def.Reg.isPhysical() &&
"We do not rewrite physical registers");
1351 TRI->getSubClassWithSubReg(NewSrcRC, NewSrc.
SubReg);
1360 MachineInstr *NewCopy =
1362 TII->get(TargetOpcode::COPY), NewVReg)
1394bool PeepholeOptimizer::optimizeUncoalescableCopy(
1395 MachineInstr &
MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
1396 assert(isUncoalescableCopy(
MI) &&
"Invalid argument");
1397 UncoalescableRewriter CpyRewriter(
MI);
1402 RewriteMapTy RewriteMap;
1406 while (CpyRewriter.getNextRewritableSource(Src, Def)) {
1409 if (
Def.Reg.isPhysical())
1419 if (!findNextSource(DefRC,
Def.SubReg, Def, RewriteMap))
1428 MachineInstr &NewCopy = rewriteSource(
MI, Def, RewriteMap);
1429 LocalMIs.
insert(&NewCopy);
1434 MI.eraseFromParent();
1435 ++NumUncoalescableCopies;
1442bool PeepholeOptimizer::isLoadFoldable(
1443 MachineInstr &
MI, SmallSet<Register, 16> &FoldAsLoadDefCandidates) {
1444 if (!
MI.canFoldAsLoad() || !
MI.mayLoad())
1446 const MCInstrDesc &MCID =
MI.getDesc();
1465 SmallPtrSet<MachineInstr *, 16> &LocalMIs) {
1467 MachineInstr *
DefMI =
nullptr;
1468 MachineInstr *CopyMI =
nullptr;
1469 MachineInstr *FoldMI =
TII->optimizeLoadInstr(
MI, MRI,
Reg,
DefMI, CopyMI);
1478 if (
MI.shouldUpdateAdditionalCallInfo())
1480 MI.eraseFromParent();
1487bool PeepholeOptimizer::isMoveImmediate(
1488 MachineInstr &
MI, SmallSet<Register, 4> &ImmDefRegs,
1489 DenseMap<Register, MachineInstr *> &ImmDefMIs) {
1490 const MCInstrDesc &MCID =
MI.getDesc();
1491 if (MCID.
getNumDefs() != 1 || !
MI.getOperand(0).isReg())
1498 if (!
MI.isMoveImmediate() && !
TII->getConstValDefinedInReg(
MI,
Reg, ImmVal))
1509bool PeepholeOptimizer::foldImmediate(
1510 MachineInstr &
MI, SmallSet<Register, 4> &ImmDefRegs,
1511 DenseMap<Register, MachineInstr *> &ImmDefMIs,
bool &
Deleted) {
1513 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1514 MachineOperand &MO =
MI.getOperand(i);
1523 assert(
II != ImmDefMIs.
end() &&
"couldn't find immediate definition");
1524 if (
TII->foldImmediate(
MI, *
II->second,
Reg, MRI)) {
1536 MI.eraseFromParent();
1560bool PeepholeOptimizer::foldRedundantCopy(MachineInstr &
MI) {
1561 assert(
MI.isCopy() &&
"expected a COPY machine instruction");
1564 if (!getCopySrc(
MI, SrcPair))
1571 if (CopySrcMIs.
insert(std::make_pair(SrcPair, &
MI)).second) {
1576 MachineInstr *PrevCopy = CopySrcMIs.
find(SrcPair)->second;
1579 "Unexpected mismatching subreg!");
1597bool PeepholeOptimizer::isNAPhysCopy(
Register Reg) {
1601bool PeepholeOptimizer::foldRedundantNAPhysCopy(
1602 MachineInstr &
MI, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs) {
1603 assert(
MI.isCopy() &&
"expected a COPY machine instruction");
1610 if (isNAPhysCopy(SrcReg) && DstReg.
isVirtual()) {
1614 NAPhysToVirtMIs.
insert({SrcReg, &
MI});
1618 if (!(SrcReg.
isVirtual() && isNAPhysCopy(DstReg)))
1622 auto PrevCopy = NAPhysToVirtMIs.
find(DstReg);
1623 if (PrevCopy == NAPhysToVirtMIs.
end()) {
1626 LLVM_DEBUG(
dbgs() <<
"NAPhysCopy: intervening clobber forbids erasing "
1632 if (PrevDstReg == SrcReg) {
1645 NAPhysToVirtMIs.
erase(PrevCopy);
1654bool PeepholeOptimizer::findTargetRecurrence(
1655 Register Reg,
const SmallSet<Register, 2> &TargetRegs,
1656 RecurrenceCycle &RC) {
1674 unsigned Idx =
MI.findRegisterUseOperandIdx(
Reg,
nullptr);
1678 if (
MI.getDesc().getNumDefs() != 1)
1681 MachineOperand &DefOp =
MI.getOperand(0);
1688 unsigned TiedUseIdx;
1689 if (!
MI.isRegTiedToUseOperand(0, &TiedUseIdx))
1692 if (Idx == TiedUseIdx) {
1693 RC.push_back(RecurrenceInstr(&
MI));
1694 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1698 if (
TII->findCommutedOpIndices(
MI, Idx, CommIdx) && CommIdx == TiedUseIdx) {
1699 RC.push_back(RecurrenceInstr(&
MI, Idx, CommIdx));
1700 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1725bool PeepholeOptimizer::optimizeRecurrence(MachineInstr &
PHI) {
1726 SmallSet<Register, 2> TargetRegs;
1727 for (
unsigned Idx = 1; Idx <
PHI.getNumOperands(); Idx += 2) {
1728 MachineOperand &MO =
PHI.getOperand(Idx);
1735 if (findTargetRecurrence(
PHI.getOperand(0).getReg(), TargetRegs, RC)) {
1739 for (
auto &RI : RC) {
1741 auto CP = RI.getCommutePair();
1744 TII->commuteInstruction(*(RI.getMI()),
false, (*CP).first,
1761 PeepholeOptimizer Impl(DT, MLI);
1771bool PeepholeOptimizerLegacy::runOnMachineFunction(
MachineFunction &MF) {
1775 ? &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()
1777 auto *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1778 PeepholeOptimizer Impl(DT, MLI);
1779 return Impl.run(MF);
1784 LLVM_DEBUG(
dbgs() <<
"********** PEEPHOLE OPTIMIZER **********\n");
1798 bool SeenMoveImm =
false;
1831 if (
MI->isDebugInstr())
1834 if (
MI->isPosition())
1837 if (IsLoopHeader &&
MI->isPHI()) {
1838 if (optimizeRecurrence(*
MI)) {
1844 if (!
MI->isCopy()) {
1845 for (
const MachineOperand &MO :
MI->operands()) {
1849 if (MO.
isDef() && isNAPhysCopy(
Reg)) {
1851 if (Def != NAPhysToVirtMIs.
end()) {
1855 <<
"NAPhysCopy: invalidating because of " << *
MI);
1856 NAPhysToVirtMIs.
erase(Def);
1861 NAPhysToVirtMIs.
remove_if([&](
const auto &RegMI) {
1865 <<
"NAPhysCopy: invalidating because of " << *
MI);
1872 if (
MI->isImplicitDef() ||
MI->isKill())
1875 if (
MI->isInlineAsm() ||
MI->hasUnmodeledSideEffects()) {
1882 NAPhysToVirtMIs.
clear();
1885 if (
MI->isCompare() && optimizeCmpInstr(*
MI, MF, LocalMIs)) {
1890 if ((isUncoalescableCopy(*
MI) &&
1891 optimizeUncoalescableCopy(*
MI, LocalMIs)) ||
1892 (
MI->isSelect() && optimizeSelect(*
MI, LocalMIs))) {
1899 if (
MI->isConditionalBranch() && optimizeCondBranch(*
MI)) {
1904 if (isCoalescableCopy(*
MI) && optimizeCoalescableCopy(*
MI)) {
1910 if (
MI->isCopy() && (foldRedundantCopy(*
MI) ||
1911 foldRedundantNAPhysCopy(*
MI, NAPhysToVirtMIs))) {
1914 MI->eraseFromParent();
1919 if (isMoveImmediate(*
MI, ImmDefRegs, ImmDefMIs)) {
1941 if (!isLoadFoldable(*
MI, FoldAsLoadDefCandidates) &&
1942 !FoldAsLoadDefCandidates.
empty()) {
1949 const MCInstrDesc &MIDesc =
MI->getDesc();
1950 for (
unsigned i = MIDesc.
getNumDefs(); i !=
MI->getNumOperands(); ++i) {
1951 const MachineOperand &MOp =
MI->getOperand(i);
1955 if (FoldAsLoadDefCandidates.
count(FoldAsLoadDefReg)) {
1958 Register FoldedReg = FoldAsLoadDefReg;
1959 if (MachineInstr *FoldMI =
1960 foldLoadInto(MF, *
MI, FoldAsLoadDefReg, LocalMIs)) {
1961 FoldAsLoadDefCandidates.
erase(FoldedReg);
1973 if (
MI->isLoadFoldBarrier()) {
1975 FoldAsLoadDefCandidates.
clear();
1980 MF.resetDelegate(
this);
1984ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
1985 assert(
Def->isCopy() &&
"Invalid definition");
1990 assert(
Def->getNumOperands() -
Def->getNumImplicitOperands() == 2 &&
1991 "Invalid number of operands");
1992 assert(!
Def->hasImplicitDef() &&
"Only implicit uses are allowed");
1993 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"no subregister defs in SSA");
1996 const MachineOperand &Src =
Def->getOperand(1);
1998 return ValueTrackerResult();
2001 unsigned SubReg = Src.getSubReg();
2004 SubReg =
TRI->composeSubRegIndices(SubReg, DefSubReg);
2009 if (!
TRI->isSubRegValidForRegClass(RegRC, SubReg))
2010 return ValueTrackerResult();
2012 if (!
TRI->getSubReg(SrcReg, SubReg))
2013 return ValueTrackerResult();
2017 return ValueTrackerResult(SrcReg, SubReg);
2020ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
2021 assert(
Def->isBitcast() &&
"Invalid definition");
2024 if (
Def->mayRaiseFPException() ||
Def->hasUnmodeledSideEffects())
2025 return ValueTrackerResult();
2028 if (
Def->getDesc().getNumDefs() != 1)
2029 return ValueTrackerResult();
2031 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"no subregister defs in SSA");
2033 unsigned SrcIdx =
Def->getNumOperands();
2034 for (
unsigned OpIdx = DefIdx + 1, EndOpIdx = SrcIdx; OpIdx != EndOpIdx;
2036 const MachineOperand &MO =
Def->getOperand(OpIdx);
2042 assert(!MO.
isDef() &&
"We should have skipped all the definitions by now");
2043 if (SrcIdx != EndOpIdx)
2045 return ValueTrackerResult();
2051 if (SrcIdx >=
Def->getNumOperands())
2052 return ValueTrackerResult();
2054 const MachineOperand &DefOp =
Def->getOperand(DefIdx);
2059 if (
UseMI.isSubregToReg())
2060 return ValueTrackerResult();
2063 const MachineOperand &Src =
Def->getOperand(SrcIdx);
2065 return ValueTrackerResult();
2066 return ValueTrackerResult(Src.getReg(), Src.getSubReg());
2069ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
2070 assert((
Def->isRegSequence() ||
Def->isRegSequenceLike()) &&
2071 "Invalid definition");
2073 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"illegal subregister def");
2076 if (!
TII->getRegSequenceInputs(*Def, DefIdx, RegSeqInputRegs))
2077 return ValueTrackerResult();
2085 if (RegSeqInput.SubIdx == DefSubReg)
2086 return ValueTrackerResult(RegSeqInput.Reg, RegSeqInput.SubReg);
2094 LaneBitmask DefMask =
TRI->getSubRegIndexLaneMask(DefSubReg);
2095 LaneBitmask ThisOpRegMask =
TRI->getSubRegIndexLaneMask(RegSeqInput.SubIdx);
2101 if ((DefMask & ThisOpRegMask) != DefMask)
2104 unsigned ReverseDefCompose =
2105 TRI->reverseComposeSubRegIndices(RegSeqInput.SubIdx, DefSubReg);
2106 if (!ReverseDefCompose)
2109 unsigned ComposedDefInSrcReg1 =
2110 TRI->composeSubRegIndices(RegSeqInput.SubReg, ReverseDefCompose);
2117 if (!
TRI->isSubRegValidForRegClass(SrcRC, ComposedDefInSrcReg1))
2118 return ValueTrackerResult();
2120 return ValueTrackerResult(RegSeqInput.Reg, ComposedDefInSrcReg1);
2126 return ValueTrackerResult();
2129ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
2130 assert((
Def->isInsertSubreg() ||
Def->isInsertSubregLike()) &&
2131 "Invalid definition");
2132 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"no subreg defs in SSA");
2136 if (!
TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg))
2137 return ValueTrackerResult();
2146 if (InsertedReg.
SubIdx == DefSubReg) {
2147 return ValueTrackerResult(InsertedReg.
Reg, InsertedReg.
SubReg);
2152 const MachineOperand &MODef =
Def->getOperand(DefIdx);
2158 return ValueTrackerResult();
2163 if ((
TRI->getSubRegIndexLaneMask(DefSubReg) &
2164 TRI->getSubRegIndexLaneMask(InsertedReg.
SubIdx))
2166 return ValueTrackerResult();
2169 return ValueTrackerResult(
BaseReg.Reg, DefSubReg);
2172ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
2173 assert((
Def->isExtractSubreg() ||
Def->isExtractSubregLike()) &&
2174 "Invalid definition");
2181 return ValueTrackerResult();
2184 if (!
TII->getExtractSubregInputs(*Def, DefIdx, ExtractSubregInputReg))
2185 return ValueTrackerResult();
2189 if (ExtractSubregInputReg.
SubReg)
2190 return ValueTrackerResult();
2192 return ValueTrackerResult(ExtractSubregInputReg.
Reg,
2193 ExtractSubregInputReg.
SubIdx);
2196ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() {
2197 assert(
Def->isSubregToReg() &&
"Invalid definition");
2205 if (DefSubReg !=
Def->getOperand(2).getImm())
2206 return ValueTrackerResult();
2209 if (
Def->getOperand(1).getSubReg())
2210 return ValueTrackerResult();
2212 return ValueTrackerResult(
Def->getOperand(1).getReg(),
2213 Def->getOperand(2).getImm());
2217ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
2218 assert(
Def->isPHI() &&
"Invalid definition");
2219 ValueTrackerResult Res;
2222 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2) {
2223 const MachineOperand &MO =
Def->getOperand(i);
2228 return ValueTrackerResult();
2235ValueTrackerResult ValueTracker::getNextSourceImpl() {
2236 assert(Def &&
"This method needs a valid definition");
2238 assert(((
Def->getOperand(DefIdx).isDef() &&
2239 (DefIdx < Def->
getDesc().getNumDefs() ||
2240 Def->getDesc().isVariadic())) ||
2241 Def->getOperand(DefIdx).isImplicit()) &&
2244 return getNextSourceFromCopy();
2245 if (
Def->isBitcast())
2246 return getNextSourceFromBitcast();
2250 return ValueTrackerResult();
2251 if (
Def->isRegSequence() ||
Def->isRegSequenceLike())
2252 return getNextSourceFromRegSequence();
2253 if (
Def->isInsertSubreg() ||
Def->isInsertSubregLike())
2254 return getNextSourceFromInsertSubreg();
2255 if (
Def->isExtractSubreg() ||
Def->isExtractSubregLike())
2256 return getNextSourceFromExtractSubreg();
2257 if (
Def->isSubregToReg())
2258 return getNextSourceFromSubregToReg();
2260 return getNextSourceFromPHI();
2261 return ValueTrackerResult();
2264ValueTrackerResult ValueTracker::getNextSource() {
2268 return ValueTrackerResult();
2270 ValueTrackerResult Res = getNextSourceImpl();
2271 if (Res.isValid()) {
2275 bool OneRegSrc = Res.getNumSources() == 1;
2277 Reg = Res.getSrcReg(0);
2289 DefSubReg = Res.getSrcSubReg(0);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
A common definition of LaneBitmask for use in TableGen and CodeGen.
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static cl::opt< unsigned > RewritePHILimit("rewrite-phi-limit", cl::Hidden, cl::init(10), cl::desc("Limit the length of PHI chains to lookup"))
static cl::opt< bool > DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), cl::desc("Disable the peephole optimizer"))
static cl::opt< unsigned > MaxRecurrenceChain("recurrence-chain-limit", cl::Hidden, cl::init(3), cl::desc("Maximum length of recurrence chain when evaluating the benefit " "of commuting operands"))
static cl::opt< bool > DisableNAPhysCopyOpt("disable-non-allocatable-phys-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable non-allocatable physical register copy optimization"))
static bool isVirtualRegisterOperand(MachineOperand &MO)
\bried Returns true if MO is a virtual register operand.
static MachineInstr & insertPHI(MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const SmallVectorImpl< RegSubRegPair > &SrcRegs, MachineInstr &OrigPHI)
Insert a PHI instruction with incoming edges SrcRegs that are guaranteed to have the same register cl...
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
static cl::opt< bool > DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable advanced copy optimization"))
Specifiy whether or not the value tracking looks through complex instructions.
TargetInstrInfo::RegSubRegPairAndIdx RegSubRegPairAndIdx
static RegSubRegPair getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII, RegSubRegPair Def, const PeepholeOptimizer::RewriteMapTy &RewriteMap, bool HandleMultipleSources=true)
Given a Def.Reg and Def.SubReg pair, use RewriteMap to find the new source to use for rewrite.
Remove Loads Into Fake Uses
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Virtual Register Rewriter
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
bool remove_if(Predicate Pred)
Remove entries that match the given predicate.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
bool isLoopHeader(const BlockT *BB) const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
An RAII based helper class to modify MachineFunctionProperties when running pass.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
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.
void moveAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
void setDelegate(Delegate *delegate)
Set the delegate.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
LLVM_ABI bool isIdenticalTo(const MachineInstr &Other, MICheckType Check=CheckDefs) const
Return true if this instruction is identical to Other.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool canFoldAsLoad(QueryType Type=IgnoreBundle) const
Return true for instructions that can be folded as memory operands in other instructions.
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
unsigned getOperandNo() const
getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI void markUsesInDebugValueAsUndef(Register Reg) const
markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the specified register as undefined wh...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
def_iterator def_begin(Register RegNo) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
LLVM_ABI bool hasOneNonDBGUser(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
defusechain_iterator< false, true, false, true, false > def_iterator
def_iterator/def_begin/def_end - Walk all defs of the specified register.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
static def_iterator def_end()
const TargetRegisterInfo * getTargetRegisterInfo() 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...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
LLVM_ABI MachineInstr * getOneNonDBGUser(Register RegNo) const
If the register has a single non-Debug instruction using the specified register, returns it; otherwis...
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI char & PeepholeOptimizerLegacyID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MCRegisterClass TargetRegisterClass
A pair composed of a pair of a register and a sub-register index, and another sub-register index.
A pair composed of a register and a sub-register index.