100 using namespace llvm;
104 #define DEBUG_TYPE "peephole-opt" 109 cl::desc(
"Aggressive extension optimization"));
113 cl::desc(
"Disable the peephole optimizer"));
120 cl::desc(
"Disable advanced copy optimization"));
124 cl::desc(
"Disable non-allocatable physical register copy optimization"));
130 cl::desc(
"Limit the length of PHI chains to lookup"));
136 cl::desc(
"Maximum length of recurrence chain when evaluating the benefit " 137 "of commuting operands"));
140 STATISTIC(NumReuse,
"Number of extension results reused");
141 STATISTIC(NumCmps,
"Number of compares eliminated");
142 STATISTIC(NumImmFold,
"Number of move immediate folded");
143 STATISTIC(NumLoadFold,
"Number of loads folded");
144 STATISTIC(NumSelects,
"Number of selects optimized");
145 STATISTIC(NumUncoalescableCopies,
"Number of uncoalescable copies optimized");
146 STATISTIC(NumRewrittenCopies,
"Number of copies rewritten");
147 STATISTIC(NumNAPhysCopies,
"Number of non-allocatable physical copies removed");
151 class ValueTrackerResult;
152 class RecurrenceInstr;
198 bool findNextSource(
RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
209 bool findTargetRecurrence(
unsigned Reg,
211 RecurrenceCycle &RC);
222 bool isNAPhysCopy(
unsigned Reg);
264 class RecurrenceInstr {
266 using IndexPair = std::pair<unsigned, unsigned>;
269 RecurrenceInstr(
MachineInstr *MI,
unsigned Idx1,
unsigned Idx2)
270 : MI(MI), CommutePair(
std::make_pair(Idx1, Idx2)) {}
283 class ValueTrackerResult {
292 ValueTrackerResult() =
default;
294 ValueTrackerResult(
unsigned Reg,
unsigned SubReg) {
295 addSource(Reg, SubReg);
298 bool isValid()
const {
return getNumSources() > 0; }
308 void addSource(
unsigned SrcReg,
unsigned SrcSubReg) {
312 void setSource(
int Idx,
unsigned SrcReg,
unsigned SrcSubReg) {
313 assert(Idx < getNumSources() &&
"Reg pair source out of index");
317 int getNumSources()
const {
return RegSrcs.
size(); }
323 unsigned getSrcReg(
int Idx)
const {
324 assert(Idx < getNumSources() &&
"Reg source out of index");
325 return RegSrcs[Idx].Reg;
328 unsigned getSrcSubReg(
int Idx)
const {
329 assert(Idx < getNumSources() &&
"SubReg source out of index");
330 return RegSrcs[Idx].SubReg;
333 bool operator==(
const ValueTrackerResult &Other) {
334 if (Other.getInst() != getInst())
337 if (Other.getNumSources() != getNumSources())
340 for (
int i = 0, e = Other.getNumSources(); i != e; ++i)
341 if (Other.getSrcReg(i) != getSrcReg(i) ||
342 Other.getSrcSubReg(i) != getSrcSubReg(i))
385 ValueTrackerResult getNextSourceImpl();
388 ValueTrackerResult getNextSourceFromCopy();
391 ValueTrackerResult getNextSourceFromBitcast();
394 ValueTrackerResult getNextSourceFromRegSequence();
397 ValueTrackerResult getNextSourceFromInsertSubreg();
400 ValueTrackerResult getNextSourceFromExtractSubreg();
403 ValueTrackerResult getNextSourceFromSubregToReg();
406 ValueTrackerResult getNextSourceFromPHI();
418 ValueTracker(
unsigned Reg,
unsigned DefSubReg,
421 : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
433 ValueTrackerResult getNextSource();
443 "Peephole Optimizations",
false,
false)
457 bool PeepholeOptimizer::
460 unsigned SrcReg, DstReg, SubIdx;
491 ReachedBBs.
insert(UI.getParent());
499 bool ExtendLife =
true;
505 if (UseMI->
isPHI()) {
511 if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx)
531 if (UseMI->
getOpcode() == TargetOpcode::SUBREG_TO_REG)
535 if (UseMBB == &MBB) {
537 if (!LocalMIs.count(UseMI))
539 }
else if (ReachedBBs.
count(UseMBB)) {
555 if (ExtendLife && !ExtendedUses.
empty())
560 bool Changed =
false;
569 PHIBBs.
insert(UI.getParent());
572 for (
unsigned i = 0, e = Uses.
size(); i != e; ++i) {
576 if (PHIBBs.
count(UseMBB))
587 TII->
get(TargetOpcode::COPY), NewVR)
588 .addReg(DstReg, 0, SubIdx);
607 bool PeepholeOptimizer::optimizeCmpInstr(
MachineInstr &MI) {
610 unsigned SrcReg, SrcReg2;
611 int CmpMask, CmpValue;
612 if (!TII->
analyzeCompare(MI, SrcReg, SrcReg2, CmpMask, CmpValue) ||
627 bool PeepholeOptimizer::optimizeSelect(
MachineInstr &MI,
630 unsigned FalseOp = 0;
631 bool Optimizable =
false;
633 if (TII->
analyzeSelect(MI, Cond, TrueOp, FalseOp, Optimizable))
645 bool PeepholeOptimizer::optimizeCondBranch(
MachineInstr &MI) {
660 bool PeepholeOptimizer::findNextSource(
RegSubRegPair RegSubReg,
661 RewriteMapTy &RewriteMap) {
666 unsigned Reg = RegSubReg.
Reg;
675 unsigned PHICount = 0;
682 ValueTracker ValTracker(CurSrcPair.
Reg, CurSrcPair.
SubReg, *MRI, TII);
687 ValueTrackerResult Res = ValTracker.getNextSource();
693 ValueTrackerResult CurSrcRes = RewriteMap.lookup(CurSrcPair);
694 if (CurSrcRes.isValid()) {
695 assert(CurSrcRes == Res &&
"ValueTrackerResult found must match");
698 if (CurSrcRes.getNumSources() > 1) {
700 <<
"findNextSource: found PHI cycle, aborting...\n");
705 RewriteMap.insert(std::make_pair(CurSrcPair, Res));
709 unsigned NumSrcs = Res.getNumSources();
717 for (
unsigned i = 0; i < NumSrcs; ++i)
722 CurSrcPair = Res.getSrc(0);
738 if (PHICount > 0 && CurSrcPair.
SubReg != 0)
744 }
while (!SrcToLook.
empty());
747 return CurSrcPair.
Reg !=
Reg;
759 assert(!SrcRegs.
empty() &&
"No sources to create a PHI instruction?");
764 assert(SrcRegs[0].
SubReg == 0 &&
"should not have subreg operand");
768 TII.
get(TargetOpcode::PHI), NewVR);
770 unsigned MBBOpIdx = 2;
772 MIB.
addReg(RegPair.Reg, 0, RegPair.SubReg);
790 unsigned CurrentSrcIdx = 0;
825 virtual bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg) = 0;
829 class CopyRewriter :
public Rewriter {
834 virtual ~CopyRewriter() =
default;
839 if (CurrentSrcIdx > 0)
853 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
854 if (CurrentSrcIdx != 1)
865 class UncoalescableRewriter :
public Rewriter {
880 if (CurrentSrcIdx == NumDefs)
883 while (CopyLike.getOperand(CurrentSrcIdx).isDead()) {
885 if (CurrentSrcIdx == NumDefs)
898 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
904 class InsertSubregRewriter :
public Rewriter {
924 if (CurrentSrcIdx == 2)
934 if (MODef.getSubReg())
938 (
unsigned)CopyLike.getOperand(3).getImm());
942 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
943 if (CurrentSrcIdx != 2)
954 class ExtractSubregRewriter :
public Rewriter {
971 if (CurrentSrcIdx == 1)
981 CopyLike.getOperand(2).getImm());
989 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
991 if (CurrentSrcIdx != 1)
994 CopyLike.getOperand(CurrentSrcIdx).setReg(NewReg);
1005 CopyLike.RemoveOperand(2);
1007 CopyLike.setDesc(TII.
get(TargetOpcode::COPY));
1010 CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg);
1016 class RegSequenceRewriter :
public Rewriter {
1043 if (CurrentSrcIdx == 0) {
1048 if (CurrentSrcIdx >= CopyLike.getNumOperands())
1051 const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
1059 Dst.
SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
1067 bool RewriteCurrentSource(
unsigned NewReg,
unsigned NewSubReg)
override {
1070 if ((CurrentSrcIdx & 1) != 1 || CurrentSrcIdx > CopyLike.getNumOperands())
1089 return new UncoalescableRewriter(MI);
1094 case TargetOpcode::COPY:
1095 return new CopyRewriter(MI);
1096 case TargetOpcode::INSERT_SUBREG:
1097 return new InsertSubregRewriter(MI);
1098 case TargetOpcode::EXTRACT_SUBREG:
1099 return new ExtractSubregRewriter(MI, TII);
1100 case TargetOpcode::REG_SEQUENCE:
1101 return new RegSequenceRewriter(MI);
1115 bool HandleMultipleSources =
true) {
1118 ValueTrackerResult Res = RewriteMap.
lookup(LookupSrc);
1124 unsigned NumSrcs = Res.getNumSources();
1126 LookupSrc.
Reg = Res.getSrcReg(0);
1127 LookupSrc.
SubReg = Res.getSrcSubReg(0);
1132 if (!HandleMultipleSources)
1138 for (
unsigned i = 0; i < NumSrcs; ++i) {
1139 RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i));
1141 getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
1168 bool PeepholeOptimizer::optimizeCoalescableCopy(
MachineInstr &MI) {
1169 assert(isCoalescableCopy(MI) &&
"Invalid argument");
1171 "Coalescer can understand multiple defs?!");
1177 bool Changed =
false;
1186 while (CpyRewriter->getNextRewritableSource(Src, TrackPair)) {
1188 RewriteMapTy RewriteMap;
1191 if (!findNextSource(TrackPair, RewriteMap))
1198 if (Src.
Reg == NewSrc.
Reg || NewSrc.
Reg == 0)
1202 if (CpyRewriter->RewriteCurrentSource(NewSrc.
Reg, NewSrc.
SubReg)) {
1213 NumRewrittenCopies += Changed;
1223 PeepholeOptimizer::rewriteSource(
MachineInstr &CopyLike,
1226 "We do not rewrite physical registers");
1237 TII->
get(TargetOpcode::COPY), NewVReg)
1269 bool PeepholeOptimizer::optimizeUncoalescableCopy(
1271 assert(isUncoalescableCopy(MI) &&
"Invalid argument");
1272 UncoalescableRewriter CpyRewriter(MI);
1277 RewriteMapTy RewriteMap;
1281 while (CpyRewriter.getNextRewritableSource(Src, Def)) {
1289 if (!findNextSource(Def, RewriteMap))
1298 MachineInstr &NewCopy = rewriteSource(MI, Def, RewriteMap);
1299 LocalMIs.
insert(&NewCopy);
1304 ++NumUncoalescableCopies;
1311 bool PeepholeOptimizer::isLoadFoldable(
1326 FoldAsLoadDefCandidates.
insert(Reg);
1332 bool PeepholeOptimizer::isMoveImmediate(
1342 ImmDefMIs.
insert(std::make_pair(Reg, &MI));
1353 bool PeepholeOptimizer::foldImmediate(
MachineInstr &MI,
1363 unsigned Reg = MO.
getReg();
1366 if (ImmDefRegs.
count(Reg) == 0)
1369 assert(II != ImmDefMIs.
end() &&
"couldn't find immediate definition");
1392 bool PeepholeOptimizer::foldRedundantCopy(
MachineInstr &MI,
1395 assert(MI.
isCopy() &&
"expected a COPY machine instruction");
1405 if (CopySrcRegs.
insert(SrcReg).second) {
1407 CopyMIs.
insert(std::make_pair(SrcReg, &MI));
1417 if (SrcSubReg != PrevSrcSubReg)
1436 bool PeepholeOptimizer::isNAPhysCopy(
unsigned Reg) {
1441 bool PeepholeOptimizer::foldRedundantNAPhysCopy(
1443 assert(MI.
isCopy() &&
"expected a COPY machine instruction");
1454 NAPhysToVirtMIs.
insert({SrcReg, &MI});
1462 auto PrevCopy = NAPhysToVirtMIs.
find(DstReg);
1463 if (PrevCopy == NAPhysToVirtMIs.
end()) {
1466 LLVM_DEBUG(
dbgs() <<
"NAPhysCopy: intervening clobber forbids erasing " 1471 unsigned PrevDstReg = PrevCopy->second->getOperand(0).getReg();
1472 if (PrevDstReg == SrcReg) {
1485 NAPhysToVirtMIs.
erase(PrevCopy);
1496 bool PeepholeOptimizer::findTargetRecurrence(
1498 RecurrenceCycle &RC) {
1500 if (TargetRegs.
count(Reg))
1530 unsigned TiedUseIdx;
1534 if (Idx == TiedUseIdx) {
1535 RC.push_back(RecurrenceInstr(&MI));
1536 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1541 RC.push_back(RecurrenceInstr(&MI, Idx, CommIdx));
1542 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1567 bool PeepholeOptimizer::optimizeRecurrence(
MachineInstr &PHI) {
1575 bool Changed =
false;
1581 for (
auto &RI : RC) {
1583 auto CP = RI.getCommutePair();
1600 LLVM_DEBUG(
dbgs() <<
"********** PEEPHOLE OPTIMIZER **********\n");
1609 DT =
Aggressive ? &getAnalysis<MachineDominatorTree>() :
nullptr;
1610 MLI = &getAnalysis<MachineLoopInfo>();
1612 bool Changed =
false;
1615 bool SeenMoveImm =
false;
1639 bool IsLoopHeader = MLI->isLoopHeader(&MBB);
1655 if (IsLoopHeader && MI->
isPHI()) {
1656 if (optimizeRecurrence(*MI)) {
1666 unsigned Reg = MO.getReg();
1667 if (MO.isDef() && isNAPhysCopy(Reg)) {
1668 const auto &Def = NAPhysToVirtMIs.
find(Reg);
1669 if (Def != NAPhysToVirtMIs.
end()) {
1673 <<
"NAPhysCopy: invalidating because of " << *MI);
1674 NAPhysToVirtMIs.
erase(Def);
1677 }
else if (MO.isRegMask()) {
1678 const uint32_t *RegMask = MO.getRegMask();
1679 for (
auto &RegMI : NAPhysToVirtMIs) {
1680 unsigned Def = RegMI.first;
1683 <<
"NAPhysCopy: invalidating because of " << *MI);
1684 NAPhysToVirtMIs.erase(Def);
1701 NAPhysToVirtMIs.
clear();
1704 if ((isUncoalescableCopy(*MI) &&
1705 optimizeUncoalescableCopy(*MI, LocalMIs)) ||
1706 (MI->
isCompare() && optimizeCmpInstr(*MI)) ||
1707 (MI->
isSelect() && optimizeSelect(*MI, LocalMIs))) {
1719 if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(*MI)) {
1726 (foldRedundantCopy(*MI, CopySrcRegs, CopySrcMIs) ||
1727 foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
1734 if (isMoveImmediate(*MI, ImmDefRegs, ImmDefMIs)) {
1737 Changed |= optimizeExtInstr(*MI, MBB, LocalMIs);
1744 Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs);
1750 if (!isLoadFoldable(*MI, FoldAsLoadDefCandidates) &&
1751 !FoldAsLoadDefCandidates.
empty()) {
1764 unsigned FoldAsLoadDefReg = MOp.
getReg();
1765 if (FoldAsLoadDefCandidates.
count(FoldAsLoadDefReg)) {
1770 unsigned FoldedReg = FoldAsLoadDefReg;
1779 LocalMIs.
erase(DefMI);
1784 FoldAsLoadDefCandidates.
erase(FoldedReg);
1799 LLVM_DEBUG(
dbgs() <<
"Encountered load fold barrier on " << *MI);
1800 FoldAsLoadDefCandidates.
clear();
1808 ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
1809 assert(Def->isCopy() &&
"Invalid definition");
1812 assert(Def->getNumOperands() == 2 &&
"Invalid number of operands");
1814 if (Def->getOperand(DefIdx).getSubReg() != DefSubReg)
1817 return ValueTrackerResult();
1821 return ValueTrackerResult();
1825 ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
1826 assert(Def->isBitcast() &&
"Invalid definition");
1829 if (Def->hasUnmodeledSideEffects())
1830 return ValueTrackerResult();
1833 if (Def->getDesc().getNumDefs() != 1)
1834 return ValueTrackerResult();
1839 return ValueTrackerResult();
1841 unsigned SrcIdx = Def->getNumOperands();
1842 for (
unsigned OpIdx = DefIdx + 1, EndOpIdx = SrcIdx; OpIdx != EndOpIdx;
1850 assert(!MO.
isDef() &&
"We should have skipped all the definitions by now");
1851 if (SrcIdx != EndOpIdx)
1853 return ValueTrackerResult();
1860 if (
UseMI.isSubregToReg())
1861 return ValueTrackerResult();
1866 return ValueTrackerResult();
1870 ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
1871 assert((Def->isRegSequence() || Def->isRegSequenceLike()) &&
1872 "Invalid definition");
1874 if (Def->getOperand(DefIdx).getSubReg())
1889 return ValueTrackerResult();
1894 return ValueTrackerResult();
1898 return ValueTrackerResult();
1904 if (RegSeqInput.SubIdx == DefSubReg) {
1905 if (RegSeqInput.SubReg)
1907 return ValueTrackerResult();
1909 return ValueTrackerResult(RegSeqInput.Reg, RegSeqInput.SubReg);
1916 return ValueTrackerResult();
1919 ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
1920 assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) &&
1921 "Invalid definition");
1923 if (Def->getOperand(DefIdx).getSubReg())
1927 return ValueTrackerResult();
1932 return ValueTrackerResult();
1937 return ValueTrackerResult();
1946 if (InsertedReg.
SubIdx == DefSubReg) {
1947 return ValueTrackerResult(InsertedReg.
Reg, InsertedReg.
SubReg);
1958 return ValueTrackerResult();
1966 return ValueTrackerResult();
1969 return ValueTrackerResult(BaseReg.
Reg, DefSubReg);
1972 ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
1973 assert((Def->isExtractSubreg() ||
1974 Def->isExtractSubregLike()) &&
"Invalid definition");
1981 return ValueTrackerResult();
1986 return ValueTrackerResult();
1990 return ValueTrackerResult();
1994 if (ExtractSubregInputReg.
SubReg)
1995 return ValueTrackerResult();
1997 return ValueTrackerResult(ExtractSubregInputReg.
Reg,
1998 ExtractSubregInputReg.
SubIdx);
2001 ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() {
2002 assert(Def->isSubregToReg() &&
"Invalid definition");
2010 if (DefSubReg != Def->getOperand(3).getImm())
2011 return ValueTrackerResult();
2014 if (Def->getOperand(2).getSubReg())
2015 return ValueTrackerResult();
2017 return ValueTrackerResult(Def->getOperand(2).getReg(),
2018 Def->getOperand(3).getImm());
2022 ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
2023 assert(Def->isPHI() &&
"Invalid definition");
2024 ValueTrackerResult Res;
2028 if (Def->getOperand(0).getSubReg() != DefSubReg)
2029 return ValueTrackerResult();
2032 for (
unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2) {
2038 return ValueTrackerResult();
2045 ValueTrackerResult ValueTracker::getNextSourceImpl() {
2046 assert(Def &&
"This method needs a valid definition");
2048 assert(((Def->getOperand(DefIdx).isDef() &&
2049 (DefIdx < Def->getDesc().getNumDefs() ||
2050 Def->getDesc().isVariadic())) ||
2051 Def->getOperand(DefIdx).isImplicit()) &&
2054 return getNextSourceFromCopy();
2055 if (Def->isBitcast())
2056 return getNextSourceFromBitcast();
2060 return ValueTrackerResult();
2061 if (Def->isRegSequence() || Def->isRegSequenceLike())
2062 return getNextSourceFromRegSequence();
2063 if (Def->isInsertSubreg() || Def->isInsertSubregLike())
2064 return getNextSourceFromInsertSubreg();
2065 if (Def->isExtractSubreg() || Def->isExtractSubregLike())
2066 return getNextSourceFromExtractSubreg();
2067 if (Def->isSubregToReg())
2068 return getNextSourceFromSubregToReg();
2070 return getNextSourceFromPHI();
2071 return ValueTrackerResult();
2074 ValueTrackerResult ValueTracker::getNextSource() {
2078 return ValueTrackerResult();
2080 ValueTrackerResult Res = getNextSourceImpl();
2081 if (Res.isValid()) {
2085 bool OneRegSrc = Res.getNumSources() == 1;
2087 Reg = Res.getSrcReg(0);
2099 DefSubReg = Res.getSrcSubReg(0);
A common definition of LaneBitmask for use in TableGen and CodeGen.
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.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
bool isAllocatable(unsigned PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
This class represents lattice values for constants.
virtual bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int Mask, int Value, const MachineRegisterInfo *MRI) const
See if the comparison instruction can be converted into something more efficient. ...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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"))
bool isExtractSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic EXTRACT_SUBREG instructions...
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
iterator_range< use_nodbg_iterator > use_nodbg_operands(unsigned Reg) const
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
virtual bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const
Analyze the given select instruction, returning true if it cannot be understood.
MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const
This method commutes the operands of the given machine instruction MI.
unsigned getSubReg() const
bool isRegSequence() const
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
bool isMoveImmediate(QueryType Type=IgnoreBundle) const
Return true if this instruction is a move immediate (including conditional moves) instruction...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool isBitcast(QueryType Type=IgnoreBundle) const
Return true if this instruction is a bitcast instruction.
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...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
LLVM_NODISCARD bool empty() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
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 ...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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.
def_iterator def_begin(unsigned RegNo) const
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"))
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
void initializePeepholeOptimizerPass(PassRegistry &)
virtual const TargetInstrInfo * getInstrInfo() const
TargetInstrInfo::RegSubRegPairAndIdx RegSubRegPairAndIdx
virtual MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr *> &NewMIs, bool PreferFalse=false) const
Given a select instruction that was understood by analyzeSelect and returned Optimizable = true...
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...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
TargetInstrInfo - Interface to description of machine instruction set.
iterator find(const_arg_type_t< KeyT > Val)
TargetInstrInfo::RegSubRegPair RegSubRegPair
static const unsigned CommuteAnyOperandIndex
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)
static bool isVirtualRegisterOperand(MachineOperand &MO)
Returns true if MO is a virtual register operand.
const TargetRegisterInfo * getTargetRegisterInfo() const
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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 isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
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...
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...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Represent the analysis usage information of a pass.
bool isSelect(QueryType Type=IgnoreBundle) const
Return true if this instruction is a select instruction.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
static Rewriter * getCopyRewriter(MachineInstr &MI, const TargetInstrInfo &TII)
Get the appropriated Rewriter for MI.
bool isInsertSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic INSERT_SUBREG instructions...
bool isImplicitDef() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isDebugInstr() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
virtual bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
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...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
virtual bool optimizeCondBranch(MachineInstr &MI) const
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...
bool isInsertSubreg() const
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
A pair composed of a register and a sub-register index.
MachineInstrBuilder MachineInstrBuilder & DefMI
LLVM_NODISCARD T pop_back_val()
virtual bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg, unsigned &SubIdx) const
Return true if the instruction is a "coalescable" extension instruction.
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
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.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
virtual bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction...
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.
char & PeepholeOptimizerID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE, "Peephole Optimizations", false, false) INITIALIZE_PASS_END(PeepholeOptimizer
static void clear(coro::Shape &Shape)
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Virtual Register Rewriter
bool isRegSequenceLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic REG_SEQUENCE instructions.
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()
unsigned getOperandNo() const
getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const
LLVM_NODISCARD bool empty() const
bool canFoldAsLoad(QueryType Type=IgnoreBundle) const
Return true for instructions that can be folded as memory operands in other instructions.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static cl::opt< bool > DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), cl::desc("Disable the peephole optimizer"))
void setReg(unsigned Reg)
Change the register this operand corresponds to.
void setSubReg(unsigned subReg)
void markUsesInDebugValueAsUndef(unsigned Reg) const
markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the specified register as undefined wh...
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.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isLoadFoldBarrier() const
Returns true if it is illegal to fold a load across this instruction.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx=nullptr) const
Given the index of a register def operand, check if the register def is tied to a source operand...
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...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static def_iterator def_end()
use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
bool operator==(uint64_t V1, const APInt &V2)
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
bool getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const
Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.
const MachineOperand & getOperand(unsigned i) const
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(unsigned Reg) const
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
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.
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 isExtractSubreg() const
int findRegisterUseOperandIdx(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a use of the specific register or -1 if it is not found...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
A pair composed of a pair of a register and a sub-register index, and another sub-register index...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.