Go to the documentation of this file.
103 #define DEBUG_TYPE "peephole-opt"
108 cl::desc(
"Aggressive extension optimization"));
112 cl::desc(
"Disable the peephole optimizer"));
119 cl::desc(
"Disable advanced copy optimization"));
123 cl::desc(
"Disable non-allocatable physical register copy optimization"));
129 cl::desc(
"Limit the length of PHI chains to lookup"));
135 cl::desc(
"Maximum length of recurrence chain when evaluating the benefit "
136 "of commuting operands"));
139 STATISTIC(NumReuse,
"Number of extension results reused");
140 STATISTIC(NumCmps,
"Number of compares eliminated");
141 STATISTIC(NumImmFold,
"Number of move immediate folded");
142 STATISTIC(NumLoadFold,
"Number of loads folded");
143 STATISTIC(NumSelects,
"Number of selects optimized");
144 STATISTIC(NumUncoalescableCopies,
"Number of uncoalescable copies optimized");
145 STATISTIC(NumRewrittenCopies,
"Number of copies rewritten");
146 STATISTIC(NumNAPhysCopies,
"Number of non-allocatable physical copies removed");
150 class ValueTrackerResult;
151 class RecurrenceInstr;
202 bool findNextSource(
RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
214 RecurrenceCycle &RC);
232 bool foldRedundantNAPhysCopy(
244 (
MI.isRegSequence() ||
MI.isInsertSubreg() ||
245 MI.isExtractSubreg()));
251 return MI.isBitcast() ||
253 (
MI.isRegSequenceLike() ||
MI.isInsertSubregLike() ||
254 MI.isExtractSubregLike()));
267 class RecurrenceInstr {
269 using IndexPair = std::pair<unsigned, unsigned>;
273 :
MI(
MI), CommutePair(
std::make_pair(Idx1, Idx2)) {}
286 class ValueTrackerResult {
295 ValueTrackerResult() =
default;
301 bool isValid()
const {
return getNumSources() > 0; }
311 void addSource(
Register SrcReg,
unsigned SrcSubReg) {
315 void setSource(
int Idx,
Register SrcReg,
unsigned SrcSubReg) {
316 assert(Idx < getNumSources() &&
"Reg pair source out of index");
320 int getNumSources()
const {
return RegSrcs.size(); }
327 assert(Idx < getNumSources() &&
"Reg source out of index");
328 return RegSrcs[Idx].Reg;
331 unsigned getSrcSubReg(
int Idx)
const {
332 assert(Idx < getNumSources() &&
"SubReg source out of index");
333 return RegSrcs[Idx].SubReg;
336 bool operator==(
const ValueTrackerResult &Other)
const {
337 if (
Other.getInst() != getInst())
340 if (
Other.getNumSources() != getNumSources())
343 for (
int i = 0,
e =
Other.getNumSources();
i !=
e; ++
i)
344 if (
Other.getSrcReg(
i) != getSrcReg(
i) ||
345 Other.getSrcSubReg(
i) != getSrcSubReg(
i))
388 ValueTrackerResult getNextSourceImpl();
391 ValueTrackerResult getNextSourceFromCopy();
394 ValueTrackerResult getNextSourceFromBitcast();
397 ValueTrackerResult getNextSourceFromRegSequence();
400 ValueTrackerResult getNextSourceFromInsertSubreg();
403 ValueTrackerResult getNextSourceFromExtractSubreg();
406 ValueTrackerResult getNextSourceFromSubregToReg();
409 ValueTrackerResult getNextSourceFromPHI();
425 if (!
Reg.isPhysical()) {
436 ValueTrackerResult getNextSource();
446 "Peephole Optimizations",
false,
false)
460 bool PeepholeOptimizer::
465 if (!
TII->isCoalescableExtInstr(
MI, SrcReg, DstReg, SubIdx))
494 ReachedBBs.
insert(UI.getParent());
502 bool ExtendLife =
true;
514 if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx)
538 if (UseMBB == &
MBB) {
540 if (!LocalMIs.count(
UseMI))
541 Uses.push_back(&UseMO);
542 }
else if (ReachedBBs.
count(UseMBB)) {
545 Uses.push_back(&UseMO);
549 ExtendedUses.push_back(&UseMO);
558 if (ExtendLife && !ExtendedUses.empty())
560 Uses.append(ExtendedUses.begin(), ExtendedUses.end());
563 bool Changed =
false;
572 PHIBBs.
insert(UI.getParent());
575 for (
unsigned i = 0,
e =
Uses.size();
i !=
e; ++
i) {
579 if (PHIBBs.
count(UseMBB))
607 TII->get(TargetOpcode::COPY), NewVR)
608 .
addReg(DstReg, 0, SubIdx);
629 int64_t CmpMask, CmpValue;
636 if (
TII->optimizeCompareInstr(
MI, SrcReg, SrcReg2, CmpMask, CmpValue,
MRI)) {
649 unsigned FalseOp = 0;
650 bool Optimizable =
false;
652 if (
TII->analyzeSelect(
MI,
Cond, TrueOp, FalseOp, Optimizable))
656 if (!
TII->optimizeSelect(
MI, LocalMIs))
659 MI.eraseFromParent();
666 return TII->optimizeCondBranch(
MI);
680 bool PeepholeOptimizer::findNextSource(
RegSubRegPair RegSubReg,
681 RewriteMapTy &RewriteMap) {
687 if (
Reg.isPhysical())
693 SrcToLook.push_back(CurSrcPair);
695 unsigned PHICount = 0;
707 ValueTrackerResult Res = ValTracker.getNextSource();
713 ValueTrackerResult CurSrcRes = RewriteMap.lookup(CurSrcPair);
714 if (CurSrcRes.isValid()) {
715 assert(CurSrcRes == Res &&
"ValueTrackerResult found must match");
718 if (CurSrcRes.getNumSources() > 1) {
720 <<
"findNextSource: found PHI cycle, aborting...\n");
725 RewriteMap.insert(std::make_pair(CurSrcPair, Res));
729 unsigned NumSrcs = Res.getNumSources();
737 for (
unsigned i = 0;
i < NumSrcs; ++
i)
738 SrcToLook.push_back(Res.getSrc(
i));
742 CurSrcPair = Res.getSrc(0);
758 if (PHICount > 0 && CurSrcPair.
SubReg != 0)
764 }
while (!SrcToLook.empty());
767 return CurSrcPair.
Reg !=
Reg;
779 assert(!SrcRegs.empty() &&
"No sources to create a PHI instruction?");
784 assert(SrcRegs[0].
SubReg == 0 &&
"should not have subreg operand");
788 TII.get(TargetOpcode::PHI), NewVR);
790 unsigned MBBOpIdx = 2;
792 MIB.
addReg(RegPair.Reg, 0, RegPair.SubReg);
810 unsigned CurrentSrcIdx = 0;
845 virtual bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg) = 0;
849 class CopyRewriter :
public Rewriter {
852 assert(
MI.isCopy() &&
"Expected copy instruction");
854 virtual ~CopyRewriter() =
default;
859 if (CurrentSrcIdx > 0)
873 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
874 if (CurrentSrcIdx != 1)
885 class UncoalescableRewriter :
public Rewriter {
890 NumDefs =
MI.getDesc().getNumDefs();
900 if (CurrentSrcIdx == NumDefs)
903 while (CopyLike.getOperand(CurrentSrcIdx).isDead()) {
905 if (CurrentSrcIdx == NumDefs)
918 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
924 class InsertSubregRewriter :
public Rewriter {
927 assert(
MI.isInsertSubreg() &&
"Invalid instruction");
944 if (CurrentSrcIdx == 2)
958 (
unsigned)CopyLike.getOperand(3).getImm());
962 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
963 if (CurrentSrcIdx != 2)
974 class ExtractSubregRewriter :
public Rewriter {
980 assert(
MI.isExtractSubreg() &&
"Invalid instruction");
991 if (CurrentSrcIdx == 1)
1001 CopyLike.getOperand(2).getImm());
1009 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
1011 if (CurrentSrcIdx != 1)
1014 CopyLike.getOperand(CurrentSrcIdx).setReg(NewReg);
1025 CopyLike.removeOperand(2);
1027 CopyLike.setDesc(
TII.get(TargetOpcode::COPY));
1030 CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg);
1036 class RegSequenceRewriter :
public Rewriter {
1039 assert(
MI.isRegSequence() &&
"Invalid instruction");
1063 if (CurrentSrcIdx == 0) {
1068 if (CurrentSrcIdx >= CopyLike.getNumOperands())
1071 const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
1072 Src.Reg = MOInsertedReg.
getReg();
1074 if ((Src.SubReg = MOInsertedReg.
getSubReg()))
1079 Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
1082 Dst.Reg = MODef.
getReg();
1087 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
1090 if ((CurrentSrcIdx & 1) != 1 || CurrentSrcIdx > CopyLike.getNumOperands())
1107 if (
MI.isBitcast() ||
MI.isRegSequenceLike() ||
MI.isInsertSubregLike() ||
1108 MI.isExtractSubregLike())
1109 return new UncoalescableRewriter(
MI);
1111 switch (
MI.getOpcode()) {
1114 case TargetOpcode::COPY:
1115 return new CopyRewriter(
MI);
1116 case TargetOpcode::INSERT_SUBREG:
1117 return new InsertSubregRewriter(
MI);
1118 case TargetOpcode::EXTRACT_SUBREG:
1119 return new ExtractSubregRewriter(
MI,
TII);
1120 case TargetOpcode::REG_SEQUENCE:
1121 return new RegSequenceRewriter(
MI);
1135 bool HandleMultipleSources =
true) {
1138 ValueTrackerResult Res = RewriteMap.
lookup(LookupSrc);
1144 unsigned NumSrcs = Res.getNumSources();
1146 LookupSrc.
Reg = Res.getSrcReg(0);
1147 LookupSrc.
SubReg = Res.getSrcSubReg(0);
1152 if (!HandleMultipleSources)
1158 for (
unsigned i = 0;
i < NumSrcs; ++
i) {
1160 NewPHISrcs.push_back(
1188 bool PeepholeOptimizer::optimizeCoalescableCopy(
MachineInstr &
MI) {
1189 assert(isCoalescableCopy(
MI) &&
"Invalid argument");
1190 assert(
MI.getDesc().getNumDefs() == 1 &&
1191 "Coalescer can understand multiple defs?!");
1197 bool Changed =
false;
1206 while (CpyRewriter->getNextRewritableSource(Src, TrackPair)) {
1208 RewriteMapTy RewriteMap;
1211 if (!findNextSource(TrackPair, RewriteMap))
1218 if (Src.Reg == NewSrc.
Reg || NewSrc.
Reg == 0)
1222 if (CpyRewriter->RewriteCurrentSource(NewSrc.
Reg, NewSrc.
SubReg)) {
1233 NumRewrittenCopies += Changed;
1243 PeepholeOptimizer::rewriteSource(
MachineInstr &CopyLike,
1246 "We do not rewrite physical registers");
1257 TII->get(TargetOpcode::COPY), NewVReg)
1289 bool PeepholeOptimizer::optimizeUncoalescableCopy(
1291 assert(isUncoalescableCopy(
MI) &&
"Invalid argument");
1292 UncoalescableRewriter CpyRewriter(
MI);
1297 RewriteMapTy RewriteMap;
1301 while (CpyRewriter.getNextRewritableSource(Src,
Def)) {
1309 if (!findNextSource(
Def, RewriteMap))
1312 RewritePairs.push_back(
Def);
1319 LocalMIs.
insert(&NewCopy);
1324 MI.eraseFromParent();
1325 ++NumUncoalescableCopies;
1332 bool PeepholeOptimizer::isLoadFoldable(
1334 if (!
MI.canFoldAsLoad() || !
MI.mayLoad())
1344 if (
Reg.isVirtual() && !
MI.getOperand(0).getSubReg() &&
1352 bool PeepholeOptimizer::isMoveImmediate(
1356 if (!
MI.isMoveImmediate())
1361 if (
Reg.isVirtual()) {
1373 bool PeepholeOptimizer::foldImmediate(
1376 for (
unsigned i = 0,
e =
MI.getDesc().getNumOperands();
i !=
e; ++
i) {
1381 if (!
Reg.isVirtual())
1386 assert(II != ImmDefMIs.
end() &&
"couldn't find immediate definition");
1387 if (
TII->FoldImmediate(
MI, *II->second,
Reg,
MRI)) {
1409 bool PeepholeOptimizer::foldRedundantCopy(
1411 assert(
MI.isCopy() &&
"expected a COPY machine instruction");
1414 unsigned SrcSubReg =
MI.getOperand(1).getSubReg();
1424 if (CopyMIs.
insert(std::make_pair(SrcPair, &
MI)).second) {
1432 "Unexpected mismatching subreg!");
1450 bool PeepholeOptimizer::isNAPhysCopy(
Register Reg) {
1454 bool PeepholeOptimizer::foldRedundantNAPhysCopy(
1456 assert(
MI.isCopy() &&
"expected a COPY machine instruction");
1467 NAPhysToVirtMIs.
insert({SrcReg, &
MI});
1471 if (!(SrcReg.
isVirtual() && isNAPhysCopy(DstReg)))
1475 auto PrevCopy = NAPhysToVirtMIs.
find(DstReg);
1476 if (PrevCopy == NAPhysToVirtMIs.
end()) {
1479 LLVM_DEBUG(
dbgs() <<
"NAPhysCopy: intervening clobber forbids erasing "
1485 if (PrevDstReg == SrcReg) {
1498 NAPhysToVirtMIs.
erase(PrevCopy);
1507 bool PeepholeOptimizer::findTargetRecurrence(
1509 RecurrenceCycle &RC) {
1527 unsigned Idx =
MI.findRegisterUseOperandIdx(
Reg);
1531 if (
MI.getDesc().getNumDefs() != 1)
1541 unsigned TiedUseIdx;
1542 if (!
MI.isRegTiedToUseOperand(0, &TiedUseIdx))
1545 if (Idx == TiedUseIdx) {
1546 RC.push_back(RecurrenceInstr(&
MI));
1547 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1551 if (
TII->findCommutedOpIndices(
MI, Idx, CommIdx) && CommIdx == TiedUseIdx) {
1552 RC.push_back(RecurrenceInstr(&
MI, Idx, CommIdx));
1553 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1578 bool PeepholeOptimizer::optimizeRecurrence(
MachineInstr &PHI) {
1586 bool Changed =
false;
1592 for (
auto &RI : RC) {
1594 auto CP = RI.getCommutePair();
1597 TII->commuteInstruction(*(RI.getMI()),
false, (*CP).first,
1611 LLVM_DEBUG(
dbgs() <<
"********** PEEPHOLE OPTIMIZER **********\n");
1620 DT =
Aggressive ? &getAnalysis<MachineDominatorTree>() : nullptr;
1621 MLI = &getAnalysis<MachineLoopInfo>();
1623 bool Changed =
false;
1626 bool SeenMoveImm =
false;
1661 if (
MI->isDebugInstr())
1664 if (
MI->isPosition())
1667 if (IsLoopHeader &&
MI->isPHI()) {
1668 if (optimizeRecurrence(*
MI)) {
1674 if (!
MI->isCopy()) {
1679 if (MO.
isDef() && isNAPhysCopy(
Reg)) {
1681 if (
Def != NAPhysToVirtMIs.
end()) {
1685 <<
"NAPhysCopy: invalidating because of " << *
MI);
1691 for (
auto &RegMI : NAPhysToVirtMIs) {
1695 <<
"NAPhysCopy: invalidating because of " << *
MI);
1696 NAPhysToVirtMIs.erase(
Def);
1703 if (
MI->isImplicitDef() ||
MI->isKill())
1706 if (
MI->isInlineAsm() ||
MI->hasUnmodeledSideEffects()) {
1713 NAPhysToVirtMIs.clear();
1716 if ((isUncoalescableCopy(*
MI) &&
1717 optimizeUncoalescableCopy(*
MI, LocalMIs)) ||
1718 (
MI->isCompare() && optimizeCmpInstr(*
MI)) ||
1731 if (isCoalescableCopy(*
MI) && optimizeCoalescableCopy(*
MI)) {
1737 if (
MI->isCopy() && (foldRedundantCopy(*
MI, CopySrcMIs) ||
1738 foldRedundantNAPhysCopy(*
MI, NAPhysToVirtMIs))) {
1741 MI->eraseFromParent();
1746 if (isMoveImmediate(*
MI, ImmDefRegs, ImmDefMIs)) {
1749 Changed |= optimizeExtInstr(*
MI,
MBB, LocalMIs);
1756 Changed |= foldImmediate(*
MI, ImmDefRegs, ImmDefMIs);
1762 if (!isLoadFoldable(*
MI, FoldAsLoadDefCandidates) &&
1763 !FoldAsLoadDefCandidates.
empty()) {
1771 for (
unsigned i = MIDesc.
getNumDefs();
i !=
MI->getNumOperands();
1777 if (FoldAsLoadDefCandidates.
count(FoldAsLoadDefReg)) {
1782 Register FoldedReg = FoldAsLoadDefReg;
1785 TII->optimizeLoadInstr(*
MI,
MRI, FoldAsLoadDefReg,
DefMI)) {
1794 if (
MI->shouldUpdateCallSiteInfo())
1795 MI->getMF()->moveCallSiteInfo(
MI, FoldMI);
1796 MI->eraseFromParent();
1799 FoldAsLoadDefCandidates.
erase(FoldedReg);
1813 if (
MI->isLoadFoldBarrier()) {
1815 FoldAsLoadDefCandidates.
clear();
1823 ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
1824 assert(
Def->isCopy() &&
"Invalid definition");
1829 assert(
Def->getNumOperands() -
Def->getNumImplicitOperands() == 2 &&
1830 "Invalid number of operands");
1831 assert(!
Def->hasImplicitDef() &&
"Only implicit uses are allowed");
1833 if (
Def->getOperand(DefIdx).getSubReg() != DefSubReg)
1836 return ValueTrackerResult();
1840 return ValueTrackerResult();
1841 return ValueTrackerResult(Src.getReg(), Src.getSubReg());
1844 ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
1845 assert(
Def->isBitcast() &&
"Invalid definition");
1848 if (
Def->mayRaiseFPException() ||
Def->hasUnmodeledSideEffects())
1849 return ValueTrackerResult();
1852 if (
Def->getDesc().getNumDefs() != 1)
1853 return ValueTrackerResult();
1858 return ValueTrackerResult();
1860 unsigned SrcIdx =
Def->getNumOperands();
1861 for (
unsigned OpIdx = DefIdx + 1, EndOpIdx = SrcIdx; OpIdx != EndOpIdx;
1869 assert(!MO.
isDef() &&
"We should have skipped all the definitions by now");
1870 if (SrcIdx != EndOpIdx)
1872 return ValueTrackerResult();
1878 if (SrcIdx >=
Def->getNumOperands())
1879 return ValueTrackerResult();
1884 if (
UseMI.isSubregToReg())
1885 return ValueTrackerResult();
1890 return ValueTrackerResult();
1891 return ValueTrackerResult(Src.getReg(), Src.getSubReg());
1894 ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
1895 assert((
Def->isRegSequence() ||
Def->isRegSequenceLike()) &&
1896 "Invalid definition");
1898 if (
Def->getOperand(DefIdx).getSubReg())
1913 return ValueTrackerResult();
1918 return ValueTrackerResult();
1921 if (!
TII->getRegSequenceInputs(*
Def, DefIdx, RegSeqInputRegs))
1922 return ValueTrackerResult();
1928 if (RegSeqInput.SubIdx == DefSubReg)
1929 return ValueTrackerResult(RegSeqInput.Reg, RegSeqInput.SubReg);
1935 return ValueTrackerResult();
1938 ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
1939 assert((
Def->isInsertSubreg() ||
Def->isInsertSubregLike()) &&
1940 "Invalid definition");
1942 if (
Def->getOperand(DefIdx).getSubReg())
1946 return ValueTrackerResult();
1951 return ValueTrackerResult();
1955 if (!
TII->getInsertSubregInputs(*
Def, DefIdx, BaseReg, InsertedReg))
1956 return ValueTrackerResult();
1965 if (InsertedReg.
SubIdx == DefSubReg) {
1966 return ValueTrackerResult(InsertedReg.
Reg, InsertedReg.
SubReg);
1977 return ValueTrackerResult();
1985 return ValueTrackerResult();
1988 return ValueTrackerResult(BaseReg.
Reg, DefSubReg);
1991 ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
1993 Def->isExtractSubregLike()) &&
"Invalid definition");
2000 return ValueTrackerResult();
2005 return ValueTrackerResult();
2008 if (!
TII->getExtractSubregInputs(*
Def, DefIdx, ExtractSubregInputReg))
2009 return ValueTrackerResult();
2013 if (ExtractSubregInputReg.
SubReg)
2014 return ValueTrackerResult();
2016 return ValueTrackerResult(ExtractSubregInputReg.
Reg,
2017 ExtractSubregInputReg.
SubIdx);
2020 ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() {
2021 assert(
Def->isSubregToReg() &&
"Invalid definition");
2029 if (DefSubReg !=
Def->getOperand(3).getImm())
2030 return ValueTrackerResult();
2033 if (
Def->getOperand(2).getSubReg())
2034 return ValueTrackerResult();
2036 return ValueTrackerResult(
Def->getOperand(2).getReg(),
2037 Def->getOperand(3).getImm());
2041 ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
2042 assert(
Def->isPHI() &&
"Invalid definition");
2043 ValueTrackerResult Res;
2047 if (
Def->getOperand(0).getSubReg() != DefSubReg)
2048 return ValueTrackerResult();
2051 for (
unsigned i = 1,
e =
Def->getNumOperands();
i <
e;
i += 2) {
2057 return ValueTrackerResult();
2064 ValueTrackerResult ValueTracker::getNextSourceImpl() {
2065 assert(
Def &&
"This method needs a valid definition");
2067 assert(((
Def->getOperand(DefIdx).isDef() &&
2068 (DefIdx < Def->
getDesc().getNumDefs() ||
2069 Def->getDesc().isVariadic())) ||
2070 Def->getOperand(DefIdx).isImplicit()) &&
2073 return getNextSourceFromCopy();
2074 if (
Def->isBitcast())
2075 return getNextSourceFromBitcast();
2079 return ValueTrackerResult();
2080 if (
Def->isRegSequence() ||
Def->isRegSequenceLike())
2081 return getNextSourceFromRegSequence();
2082 if (
Def->isInsertSubreg() ||
Def->isInsertSubregLike())
2083 return getNextSourceFromInsertSubreg();
2084 if (
Def->isExtractSubreg() ||
Def->isExtractSubregLike())
2085 return getNextSourceFromExtractSubreg();
2086 if (
Def->isSubregToReg())
2087 return getNextSourceFromSubregToReg();
2089 return getNextSourceFromPHI();
2090 return ValueTrackerResult();
2093 ValueTrackerResult ValueTracker::getNextSource() {
2097 return ValueTrackerResult();
2099 ValueTrackerResult Res = getNextSourceImpl();
2100 if (Res.isValid()) {
2104 bool OneRegSrc = Res.getNumSources() == 1;
2106 Reg = Res.getSrcReg(0);
2118 DefSubReg = Res.getSrcSubReg(0);
virtual const TargetRegisterClass * getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const
Returns the largest legal sub-class of RC that supports the sub-register index Idx.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
void markUsesInDebugValueAsUndef(Register Reg) const
markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the specified register as undefined wh...
def_iterator def_begin(Register RegNo) const
This is an optimization pass for GlobalISel generic memory operations.
const MCInstrDesc & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
MachineInstrBuilder & UseMI
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
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...
char & PeepholeOptimizerID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing optimizeSelect
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
virtual const TargetInstrInfo * getInstrInfo() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A pair composed of a pair of a register and a sub-register index, and another sub-register index.
Reg
All possible values of the reg field in the ModR/M byte.
const TargetRegisterInfo * getTargetRegisterInfo() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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"))
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool erase(const KeyT &Val)
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
LLVM_NODISCARD T pop_back_val()
unsigned const TargetRegisterInfo * TRI
unsigned getOperandNo() const
getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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"))
A pair composed of a register and a sub-register index.
SmallPtrSet< MachineInstr *, 2 > Uses
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void clear(coro::Shape &Shape)
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Virtual Register Rewriter
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
const MachineOperand & getOperand(unsigned i) const
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
void setSubReg(unsigned subReg)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Represent the analysis usage information of a pass.
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
MachineOperand class - Representation of each machine instruction operand.
MachineFunctionProperties & set(Property P)
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...
STATISTIC(NumFunctions, "Total number of functions")
static cl::opt< unsigned > RewritePHILimit("rewrite-phi-limit", cl::Hidden, cl::init(10), cl::desc("Limit the length of PHI chains to lookup"))
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isLoopHeader(const MachineBasicBlock *BB) const
True if the block is a loop header node.
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.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
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.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
static bool isVirtualRegisterOperand(MachineOperand &MO)
\bried Returns true if MO is a virtual register operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
initializer< Ty > init(const Ty &Val)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
iterator find(const_arg_type_t< KeyT > Val)
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
TargetInstrInfo::RegSubRegPair RegSubRegPair
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator==(uint64_t V1, const APInt &V2)
static Rewriter * getCopyRewriter(MachineInstr &MI, const TargetInstrInfo &TII)
Get the appropriated Rewriter for MI.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
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.
static def_iterator def_end()
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
MachineBasicBlock * getMBB() const
SmallVector< MachineOperand, 4 > Cond
void setPreservesCFG()
This function should be called by the pass, iff they do not:
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setIsUndef(bool Val=true)
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const MachineBasicBlock * getParent() const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const
Function & getFunction()
Return the LLVM function that this machine code represents.
void initializePeepholeOptimizerPass(PassRegistry &)
bool hasOneNonDBGUser(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing optimizeCondBranch
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static cl::opt< bool > DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), cl::desc("Disable the peephole optimizer"))
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned getNumOperands() const
Retuns the total number of operands.
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...
INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE, "Peephole Optimizations", false, false) INITIALIZE_PASS_END(PeepholeOptimizer
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
LLVM_NODISCARD bool empty() const
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...
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.
AnalysisUsage & addRequired()
static const unsigned CommuteAnyOperandIndex
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Optional< std::vector< StOtherPiece > > Other
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.