97 #define DEBUG_TYPE "peephole-opt"
102 cl::desc(
"Aggressive extension optimization"));
106 cl::desc(
"Disable the peephole optimizer"));
110 cl::desc(
"Disable advanced copy optimization"));
114 cl::desc(
"Disable non-allocatable physical register copy optimization"));
120 cl::desc(
"Limit the length of PHI chains to lookup"));
122 STATISTIC(NumReuse,
"Number of extension results reused");
123 STATISTIC(NumCmps,
"Number of compares eliminated");
124 STATISTIC(NumImmFold,
"Number of move immediate folded");
125 STATISTIC(NumLoadFold,
"Number of loads folded");
126 STATISTIC(NumSelects,
"Number of selects optimized");
127 STATISTIC(NumUncoalescableCopies,
"Number of uncoalescable copies optimized");
128 STATISTIC(NumRewrittenCopies,
"Number of copies rewritten");
129 STATISTIC(NumNAPhysCopies,
"Number of non-allocatable physical copies removed");
133 class ValueTrackerResult;
173 bool findNextSource(
unsigned Reg,
unsigned SubReg,
174 RewriteMapTy &RewriteMap);
191 bool isNAPhysCopy(
unsigned Reg);
198 bool foldRedundantNAPhysCopy(
228 class ValueTrackerResult {
237 ValueTrackerResult() : Inst(nullptr) {}
238 ValueTrackerResult(
unsigned Reg,
unsigned SubReg) : Inst(nullptr) {
239 addSource(Reg, SubReg);
242 bool isValid()
const {
return getNumSources() > 0; }
252 void addSource(
unsigned SrcReg,
unsigned SrcSubReg) {
256 void setSource(
int Idx,
unsigned SrcReg,
unsigned SrcSubReg) {
257 assert(Idx < getNumSources() &&
"Reg pair source out of index");
261 int getNumSources()
const {
return RegSrcs.size(); }
263 unsigned getSrcReg(
int Idx)
const {
264 assert(Idx < getNumSources() &&
"Reg source out of index");
265 return RegSrcs[Idx].Reg;
268 unsigned getSrcSubReg(
int Idx)
const {
269 assert(Idx < getNumSources() &&
"SubReg source out of index");
270 return RegSrcs[Idx].SubReg;
273 bool operator==(
const ValueTrackerResult &Other) {
274 if (Other.getInst() != getInst())
277 if (Other.getNumSources() != getNumSources())
280 for (
int i = 0, e = Other.getNumSources();
i != e; ++
i)
281 if (Other.getSrcReg(
i) != getSrcReg(
i) ||
282 Other.getSrcSubReg(
i) != getSrcSubReg(
i))
321 bool UseAdvancedTracking;
330 ValueTrackerResult getNextSourceImpl();
332 ValueTrackerResult getNextSourceFromCopy();
334 ValueTrackerResult getNextSourceFromBitcast();
337 ValueTrackerResult getNextSourceFromRegSequence();
340 ValueTrackerResult getNextSourceFromInsertSubreg();
343 ValueTrackerResult getNextSourceFromExtractSubreg();
346 ValueTrackerResult getNextSourceFromSubregToReg();
348 ValueTrackerResult getNextSourceFromPHI();
363 ValueTracker(
unsigned Reg,
unsigned DefSubReg,
365 bool UseAdvancedTracking =
false,
367 :
Def(nullptr), DefIdx(0), DefSubReg(DefSubReg), Reg(Reg),
368 UseAdvancedTracking(UseAdvancedTracking), MRI(MRI),
TII(
TII) {
382 ValueTracker(
const MachineInstr &MI,
unsigned DefIdx,
unsigned DefSubReg,
384 bool UseAdvancedTracking =
false,
386 :
Def(&MI), DefIdx(DefIdx), DefSubReg(DefSubReg),
387 UseAdvancedTracking(UseAdvancedTracking), MRI(MRI),
TII(
TII) {
389 Def->getOperand(DefIdx).isReg() &&
"Invalid definition");
390 Reg =
Def->getOperand(DefIdx).getReg();
398 ValueTrackerResult getNextSource();
413 "Peephole Optimizations",
false,
false)
426 bool PeepholeOptimizer::
429 unsigned SrcReg, DstReg, SubIdx;
430 if (!
TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx))
444 DstRC = TRI->getSubClassWithSubReg(DstRC, SubIdx);
454 TRI->getSubClassWithSubReg(MRI->
getRegClass(SrcReg), SubIdx) !=
nullptr;
460 ReachedBBs.
insert(UI.getParent());
468 bool ExtendLife =
true;
474 if (UseMI->
isPHI()) {
480 if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx)
500 if (UseMI->
getOpcode() == TargetOpcode::SUBREG_TO_REG)
506 if (!LocalMIs.count(UseMI))
508 }
else if (ReachedBBs.
count(UseMBB)) {
512 }
else if (
Aggressive && DT->dominates(MBB, UseMBB)) {
524 if (ExtendLife && !ExtendedUses.
empty())
529 bool Changed =
false;
538 PHIBBs.
insert(UI.getParent());
541 for (
unsigned i = 0, e = Uses.
size();
i != e; ++
i) {
545 if (PHIBBs.
count(UseMBB))
556 TII->get(TargetOpcode::COPY), NewVR)
557 .addReg(DstReg, 0, SubIdx);
576 bool PeepholeOptimizer::optimizeCmpInstr(
MachineInstr *MI,
580 unsigned SrcReg, SrcReg2;
581 int CmpMask, CmpValue;
588 if (
TII->optimizeCompareInstr(*MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) {
597 bool PeepholeOptimizer::optimizeSelect(
MachineInstr *MI,
600 unsigned FalseOp = 0;
601 bool Optimizable =
false;
603 if (
TII->analyzeSelect(*MI, Cond, TrueOp, FalseOp, Optimizable))
607 if (!
TII->optimizeSelect(*MI, LocalMIs))
616 bool PeepholeOptimizer::optimizeCondBranch(
MachineInstr *MI) {
617 return TII->optimizeCondBranch(*MI);
631 bool PeepholeOptimizer::findNextSource(
unsigned Reg,
unsigned SubReg,
632 RewriteMapTy &RewriteMap) {
645 unsigned PHICount = 0;
653 ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI,
655 ValueTrackerResult Res;
656 bool ShouldRewrite =
false;
661 Res = ValTracker.getNextSource();
666 ValueTrackerResult CurSrcRes = RewriteMap.lookup(CurSrcPair);
667 if (CurSrcRes.isValid()) {
668 assert(CurSrcRes == Res &&
"ValueTrackerResult found must match");
671 if (CurSrcRes.getNumSources() > 1) {
672 DEBUG(
dbgs() <<
"findNextSource: found PHI cycle, aborting...\n");
677 RewriteMap.insert(std::make_pair(CurSrcPair, Res));
681 unsigned NumSrcs = Res.getNumSources();
684 for (
unsigned i = 0;
i < NumSrcs; ++
i)
686 Res.getSrcReg(
i), Res.getSrcSubReg(
i)));
690 CurSrcPair.Reg = Res.getSrcReg(0);
691 CurSrcPair.SubReg = Res.getSrcSubReg(0);
700 ShouldRewrite = TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC,
702 }
while (!ShouldRewrite);
715 DEBUG(
dbgs() <<
"findNextSource: PHI limit reached\n");
720 return CurSrcPair.Reg !=
Reg;
732 assert(!SrcRegs.
empty() &&
"No sources to create a PHI instruction?");
738 TII->
get(TargetOpcode::PHI), NewVR);
740 unsigned MBBOpIdx = 2;
741 for (
auto RegPair : SrcRegs) {
742 MIB.
addReg(RegPair.Reg, 0, RegPair.SubReg);
762 unsigned CurrentSrcIdx;
765 CopyRewriter(
MachineInstr &MI) : CopyLike(MI), CurrentSrcIdx(0) {}
767 virtual ~CopyRewriter() {}
794 virtual bool getNextRewritableSource(
unsigned &SrcReg,
unsigned &SrcSubReg,
796 unsigned &TrackSubReg) {
800 if (!CopyLike.isCopy() || CurrentSrcIdx == 1)
811 TrackReg = MODef.
getReg();
819 virtual bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg) {
820 if (!CopyLike.isCopy() || CurrentSrcIdx != 1)
838 bool HandleMultipleSources =
true) {
841 ValueTrackerResult Res = RewriteMap.
lookup(LookupSrc);
847 unsigned NumSrcs = Res.getNumSources();
849 LookupSrc.Reg = Res.getSrcReg(0);
850 LookupSrc.SubReg = Res.getSrcSubReg(0);
855 if (!HandleMultipleSources)
861 for (
unsigned i = 0;
i < NumSrcs; ++
i) {
863 Res.getSrcSubReg(
i));
865 getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
872 DEBUG(
dbgs() <<
" Replacing: " << *OrigPHI);
896 class UncoalescableRewriter :
public CopyRewriter {
906 : CopyRewriter(MI), TII(TII), MRI(MRI) {
915 bool getNextRewritableSource(
unsigned &SrcReg,
unsigned &SrcSubReg,
917 unsigned &TrackSubReg)
override {
919 if (CurrentSrcIdx == NumDefs)
922 while (CopyLike.getOperand(CurrentSrcIdx).isDead()) {
924 if (CurrentSrcIdx == NumDefs)
930 TrackReg = MODef.
getReg();
946 "We do not rewrite physical registers");
950 getNewSource(&MRI, &TII, Def, RewriteMap);
957 BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(),
958 TII.
get(TargetOpcode::COPY), NewVR)
966 DEBUG(
dbgs() <<
" Replacing: " << CopyLike);
980 class InsertSubregRewriter :
public CopyRewriter {
982 InsertSubregRewriter(
MachineInstr &MI) : CopyRewriter(MI) {
997 bool getNextRewritableSource(
unsigned &SrcReg,
unsigned &SrcSubReg,
999 unsigned &TrackSubReg)
override {
1001 if (CurrentSrcIdx == 2)
1006 SrcReg = MOInsertedReg.
getReg();
1012 TrackReg = MODef.
getReg();
1016 TrackSubReg = (
unsigned)CopyLike.getOperand(3).getImm();
1020 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
1021 if (CurrentSrcIdx != 2)
1032 class ExtractSubregRewriter :
public CopyRewriter {
1037 : CopyRewriter(MI), TII(TII) {
1046 bool getNextRewritableSource(
unsigned &SrcReg,
unsigned &SrcSubReg,
1048 unsigned &TrackSubReg)
override {
1050 if (CurrentSrcIdx == 1)
1055 SrcReg = MOExtractedReg.
getReg();
1060 SrcSubReg = CopyLike.getOperand(2).getImm();
1064 TrackReg = MODef.
getReg();
1069 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
1071 if (CurrentSrcIdx != 1)
1074 CopyLike.getOperand(CurrentSrcIdx).setReg(NewReg);
1085 CopyLike.RemoveOperand(2);
1087 CopyLike.setDesc(TII.
get(TargetOpcode::COPY));
1090 CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg);
1096 class RegSequenceRewriter :
public CopyRewriter {
1098 RegSequenceRewriter(
MachineInstr &MI) : CopyRewriter(MI) {
1118 bool getNextRewritableSource(
unsigned &SrcReg,
unsigned &SrcSubReg,
1120 unsigned &TrackSubReg)
override {
1124 if (CurrentSrcIdx == 0) {
1129 if (CurrentSrcIdx >= CopyLike.getNumOperands())
1132 const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
1133 SrcReg = MOInsertedReg.
getReg();
1135 if ((SrcSubReg = MOInsertedReg.
getSubReg()))
1140 TrackSubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
1143 TrackReg = MODef.
getReg();
1148 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
1151 if ((CurrentSrcIdx & 1) != 1 || CurrentSrcIdx > CopyLike.getNumOperands())
1172 return new UncoalescableRewriter(MI, TII, MRI);
1177 case TargetOpcode::COPY:
1178 return new CopyRewriter(MI);
1179 case TargetOpcode::INSERT_SUBREG:
1180 return new InsertSubregRewriter(MI);
1181 case TargetOpcode::EXTRACT_SUBREG:
1182 return new ExtractSubregRewriter(MI, TII);
1183 case TargetOpcode::REG_SEQUENCE:
1184 return new RegSequenceRewriter(MI);
1201 bool PeepholeOptimizer::optimizeCoalescableCopy(
MachineInstr *MI) {
1202 assert(MI && isCoalescableCopy(*MI) &&
"Invalid argument");
1204 "Coalescer can understand multiple defs?!");
1210 bool Changed =
false;
1212 std::unique_ptr<CopyRewriter> CpyRewriter(
getCopyRewriter(*MI, *TII, *MRI));
1217 unsigned SrcReg, SrcSubReg, TrackReg, TrackSubReg;
1218 while (CpyRewriter->getNextRewritableSource(SrcReg, SrcSubReg, TrackReg,
1221 RewriteMapTy RewriteMap;
1224 if (!findNextSource(TrackReg, TrackSubReg, RewriteMap))
1231 MRI, TII, TrackPair, RewriteMap,
false );
1232 if (SrcReg == NewSrc.
Reg || NewSrc.
Reg == 0)
1236 if (CpyRewriter->RewriteCurrentSource(NewSrc.
Reg, NewSrc.
SubReg)) {
1247 NumRewrittenCopies += Changed;
1262 bool PeepholeOptimizer::optimizeUncoalescableCopy(
1264 assert(MI && isUncoalescableCopy(*MI) &&
"Invalid argument");
1269 std::unique_ptr<CopyRewriter> CpyRewriter(
getCopyRewriter(*MI, *TII, *MRI));
1277 RewriteMapTy RewriteMap;
1278 unsigned Reg,
SubReg, CopyDefReg, CopyDefSubReg;
1279 while (CpyRewriter->getNextRewritableSource(Reg, SubReg, CopyDefReg,
1289 if (!findNextSource(Def.
Reg, Def.
SubReg, RewriteMap))
1296 for (
const auto &Def : RewritePairs) {
1298 MachineInstr *NewCopy = CpyRewriter->RewriteSource(Def, RewriteMap);
1299 assert(NewCopy &&
"Should be able to always generate a new copy");
1300 LocalMIs.
insert(NewCopy);
1305 ++NumUncoalescableCopies;
1312 bool PeepholeOptimizer::isLoadFoldable(
1327 FoldAsLoadDefCandidates.
insert(Reg);
1333 bool PeepholeOptimizer::isMoveImmediate(
1343 ImmDefMIs.
insert(std::make_pair(Reg, MI));
1354 bool PeepholeOptimizer::foldImmediate(
1364 unsigned Reg = MO.
getReg();
1367 if (ImmDefRegs.
count(Reg) == 0)
1370 assert(II != ImmDefMIs.
end() &&
"couldn't find immediate definition");
1393 bool PeepholeOptimizer::foldRedundantCopy(
1396 assert(MI->
isCopy() &&
"expected a COPY machine instruction");
1406 if (CopySrcRegs.
insert(SrcReg).second) {
1408 CopyMIs.
insert(std::make_pair(SrcReg, MI));
1418 if (SrcSubReg != PrevSrcSubReg)
1437 bool PeepholeOptimizer::isNAPhysCopy(
unsigned Reg) {
1442 bool PeepholeOptimizer::foldRedundantNAPhysCopy(
1444 assert(MI->
isCopy() &&
"expected a COPY machine instruction");
1455 NAPhysToVirtMIs.
insert({SrcReg, MI});
1463 auto PrevCopy = NAPhysToVirtMIs.
find(DstReg);
1464 if (PrevCopy == NAPhysToVirtMIs.
end()) {
1467 DEBUG(
dbgs() <<
"NAPhysCopy: intervening clobber forbids erasing " << *MI
1473 if (PrevDstReg == SrcReg) {
1476 DEBUG(
dbgs() <<
"NAPhysCopy: erasing " << *MI <<
'\n');
1485 DEBUG(
dbgs() <<
"NAPhysCopy: missed opportunity " << *MI <<
'\n');
1486 NAPhysToVirtMIs.
erase(PrevCopy);
1494 DEBUG(
dbgs() <<
"********** PEEPHOLE OPTIMIZER **********\n");
1503 DT =
Aggressive ? &getAnalysis<MachineDominatorTree>() :
nullptr;
1505 bool Changed =
false;
1508 bool SeenMoveImm =
false;
1550 unsigned Reg =
Op.getReg();
1551 if (
Op.isDef() && isNAPhysCopy(Reg)) {
1552 const auto &Def = NAPhysToVirtMIs.
find(Reg);
1553 if (Def != NAPhysToVirtMIs.
end()) {
1556 DEBUG(
dbgs() <<
"NAPhysCopy: invalidating because of " << *MI
1558 NAPhysToVirtMIs.
erase(Def);
1561 }
else if (
Op.isRegMask()) {
1563 for (
auto &RegMI : NAPhysToVirtMIs) {
1564 unsigned Def = RegMI.first;
1566 DEBUG(
dbgs() <<
"NAPhysCopy: invalidating because of " << *MI
1568 NAPhysToVirtMIs.erase(Def);
1583 DEBUG(
dbgs() <<
"NAPhysCopy: blowing away all info due to " << *MI
1585 NAPhysToVirtMIs.clear();
1588 if ((isUncoalescableCopy(*MI) &&
1589 optimizeUncoalescableCopy(MI, LocalMIs)) ||
1590 (MI->
isCompare() && optimizeCmpInstr(MI, &MBB)) ||
1591 (MI->
isSelect() && optimizeSelect(MI, LocalMIs))) {
1603 if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(MI)) {
1610 (foldRedundantCopy(MI, CopySrcRegs, CopySrcMIs) ||
1611 foldRedundantNAPhysCopy(MI, NAPhysToVirtMIs))) {
1618 if (isMoveImmediate(MI, ImmDefRegs, ImmDefMIs)) {
1621 Changed |= optimizeExtInstr(MI, &MBB, LocalMIs);
1628 Changed |= foldImmediate(MI, &MBB, ImmDefRegs, ImmDefMIs);
1634 if (!isLoadFoldable(MI, FoldAsLoadDefCandidates) &&
1635 !FoldAsLoadDefCandidates.
empty()) {
1648 unsigned FoldAsLoadDefReg = MOp.
getReg();
1649 if (FoldAsLoadDefCandidates.
count(FoldAsLoadDefReg)) {
1654 unsigned FoldedReg = FoldAsLoadDefReg;
1663 LocalMIs.
erase(DefMI);
1668 FoldAsLoadDefCandidates.
erase(FoldedReg);
1683 DEBUG(
dbgs() <<
"Encountered load fold barrier on " << *MI <<
"\n");
1684 FoldAsLoadDefCandidates.
clear();
1693 ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
1694 assert(Def->isCopy() &&
"Invalid definition");
1697 assert(Def->getNumOperands() == 2 &&
"Invalid number of operands");
1699 if (Def->getOperand(DefIdx).getSubReg() != DefSubReg)
1702 return ValueTrackerResult();
1708 ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
1709 assert(Def->isBitcast() &&
"Invalid definition");
1712 if (Def->hasUnmodeledSideEffects())
1713 return ValueTrackerResult();
1716 if (Def->getDesc().getNumDefs() != 1)
1717 return ValueTrackerResult();
1722 return ValueTrackerResult();
1724 unsigned SrcIdx = Def->getNumOperands();
1725 for (
unsigned OpIdx = DefIdx + 1, EndOpIdx = SrcIdx; OpIdx != EndOpIdx;
1733 assert(!MO.
isDef() &&
"We should have skipped all the definitions by now");
1734 if (SrcIdx != EndOpIdx)
1736 return ValueTrackerResult();
1743 if (
UseMI.isSubregToReg())
1744 return ValueTrackerResult();
1751 ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
1752 assert((Def->isRegSequence() || Def->isRegSequenceLike()) &&
1753 "Invalid definition");
1755 if (Def->getOperand(DefIdx).getSubReg())
1770 return ValueTrackerResult();
1775 return ValueTrackerResult();
1779 return ValueTrackerResult();
1784 for (
auto &RegSeqInput : RegSeqInputRegs) {
1785 if (RegSeqInput.SubIdx == DefSubReg) {
1786 if (RegSeqInput.SubReg)
1788 return ValueTrackerResult();
1790 return ValueTrackerResult(RegSeqInput.Reg, RegSeqInput.SubReg);
1797 return ValueTrackerResult();
1800 ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
1801 assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) &&
1802 "Invalid definition");
1804 if (Def->getOperand(DefIdx).getSubReg())
1808 return ValueTrackerResult();
1813 return ValueTrackerResult();
1818 return ValueTrackerResult();
1827 if (InsertedReg.
SubIdx == DefSubReg) {
1828 return ValueTrackerResult(InsertedReg.
Reg, InsertedReg.
SubReg);
1839 return ValueTrackerResult();
1847 return ValueTrackerResult();
1850 return ValueTrackerResult(BaseReg.
Reg, DefSubReg);
1853 ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
1854 assert((Def->isExtractSubreg() ||
1855 Def->isExtractSubregLike()) &&
"Invalid definition");
1862 return ValueTrackerResult();
1867 return ValueTrackerResult();
1871 return ValueTrackerResult();
1875 if (ExtractSubregInputReg.
SubReg)
1876 return ValueTrackerResult();
1878 return ValueTrackerResult(ExtractSubregInputReg.
Reg,
1879 ExtractSubregInputReg.
SubIdx);
1882 ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() {
1883 assert(Def->isSubregToReg() &&
"Invalid definition");
1891 if (DefSubReg != Def->getOperand(3).getImm())
1892 return ValueTrackerResult();
1895 if (Def->getOperand(2).getSubReg())
1896 return ValueTrackerResult();
1898 return ValueTrackerResult(Def->getOperand(2).getReg(),
1899 Def->getOperand(3).getImm());
1903 ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
1904 assert(Def->isPHI() &&
"Invalid definition");
1905 ValueTrackerResult Res;
1909 if (Def->getOperand(0).getSubReg() != DefSubReg)
1910 return ValueTrackerResult();
1913 for (
unsigned i = 1, e = Def->getNumOperands();
i < e;
i += 2) {
1914 auto &MO = Def->getOperand(
i);
1922 ValueTrackerResult ValueTracker::getNextSourceImpl() {
1923 assert(Def &&
"This method needs a valid definition");
1925 assert(((Def->getOperand(DefIdx).isDef() &&
1926 (DefIdx < Def->getDesc().getNumDefs() ||
1927 Def->getDesc().isVariadic())) ||
1928 Def->getOperand(DefIdx).isImplicit()) &&
1931 return getNextSourceFromCopy();
1932 if (Def->isBitcast())
1933 return getNextSourceFromBitcast();
1936 if (!UseAdvancedTracking)
1937 return ValueTrackerResult();
1938 if (Def->isRegSequence() || Def->isRegSequenceLike())
1939 return getNextSourceFromRegSequence();
1940 if (Def->isInsertSubreg() || Def->isInsertSubregLike())
1941 return getNextSourceFromInsertSubreg();
1942 if (Def->isExtractSubreg() || Def->isExtractSubregLike())
1943 return getNextSourceFromExtractSubreg();
1944 if (Def->isSubregToReg())
1945 return getNextSourceFromSubregToReg();
1947 return getNextSourceFromPHI();
1948 return ValueTrackerResult();
1951 ValueTrackerResult ValueTracker::getNextSource() {
1955 return ValueTrackerResult();
1957 ValueTrackerResult Res = getNextSourceImpl();
1958 if (Res.isValid()) {
1962 bool OneRegSrc = Res.getNumSources() == 1;
1964 Reg = Res.getSrcReg(0);
1974 DefSubReg = Res.getSrcSubReg(0);
void push_back(const T &Elt)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isLoadFoldBarrier() const
Returns true if it is illegal to fold a load across this instruction.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
MachineBasicBlock * getMBB() const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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"))
Describe properties that are true of each instruction in the target description file.
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
bool getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const
Build the equivalent inputs of a REG_SEQUENCE for the given MI and DefIdx.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool canFoldAsLoad(QueryType Type=IgnoreBundle) const
Return true for instructions that can be folded as memory operands in other instructions.
bool isConditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
iterator_range< mop_iterator > operands()
bool isExtractSubreg() const
void markUsesInDebugValueAsUndef(unsigned Reg) const
markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the specified register as undefined wh...
bool isSelect(QueryType Type=IgnoreBundle) const
Return true if this instruction is a select instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
LLVM_NODISCARD bool empty() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
const TargetRegisterInfo * getTargetRegisterInfo() const
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
static MachineInstr * insertPHI(MachineRegisterInfo *MRI, const TargetInstrInfo *TII, const SmallVectorImpl< TargetInstrInfo::RegSubRegPair > &SrcRegs, MachineInstr *OrigPHI)
Insert a PHI instruction with incoming edges SrcRegs that are guaranteed to have the same register cl...
LLVM_NODISCARD bool empty() const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void initializePeepholeOptimizerPass(PassRegistry &)
bool isBitcast(QueryType Type=IgnoreBundle) const
Return true if this instruction is a bitcast instruction.
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
bool getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const
Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
bool isImplicitDef() const
bool isInsertSubreg() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
unsigned const MachineRegisterInfo * MRI
iterator_range< use_nodbg_iterator > use_nodbg_operands(unsigned Reg) const
static cl::opt< unsigned > RewritePHILimit("rewrite-phi-limit", cl::Hidden, cl::init(10), cl::desc("Limit the length of PHI chains to lookup"))
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
MachineInstrBuilder & UseMI
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
unsigned getOperandNo() const
getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
unsigned getSubReg() const
virtual MachineInstr * optimizeLoadInstr(MachineInstr &MI, const MachineRegisterInfo *MRI, unsigned &FoldAsLoadDefReg, MachineInstr *&DefMI) const
Try to remove the load by folding it to a register operand at the use.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
bool isInsertSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic INSERT_SUBREG instructions...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool getInsertSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const
Build the equivalent inputs of a INSERT_SUBREG for the given MI and DefIdx.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
A pair composed of a register and a sub-register index.
INITIALIZE_PASS(HexagonGenMux,"hexagon-mux","Hexagon generate mux instructions", false, false) void HexagonGenMux I isValid()
LLVM_NODISCARD T pop_back_val()
bool isAllocatable(unsigned PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
char & PeepholeOptimizerID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
bool isExtractSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic EXTRACT_SUBREG instructions...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
static void clear(coro::Shape &Shape)
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
def_iterator def_begin(unsigned RegNo) const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(unsigned Reg) const
static cl::opt< bool > DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), cl::desc("Disable the peephole optimizer"))
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
void setSubReg(unsigned subReg)
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
iterator find(const KeyT &Val)
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg, MachineRegisterInfo *MRI) const
'Reg' is known to be defined by a move immediate instruction, try to fold the immediate into the use ...
bool operator==(uint64_t V1, const APInt &V2)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE,"Peephole Optimizations", false, false) INITIALIZE_PASS_END(PeepholeOptimizer
bool isRegSequence() const
bool isMoveImmediate(QueryType Type=IgnoreBundle) const
Return true if this instruction is a move immediate (including conditional moves) instruction...
bool isRegSequenceLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic REG_SEQUENCE instructions.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static cl::opt< bool > DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable advanced copy optimization"))
static CopyRewriter * getCopyRewriter(MachineInstr &MI, const TargetInstrInfo &TII, MachineRegisterInfo &MRI)
Get the appropriated CopyRewriter for MI.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
A pair composed of a pair of a register and a sub-register index, and another sub-register index...