103#define DEBUG_TYPE "peephole-opt"
107 cl::desc(
"Aggressive extension optimization"));
111 cl::desc(
"Disable the peephole optimizer"));
118 cl::desc(
"Disable advanced copy optimization"));
122 cl::desc(
"Disable non-allocatable physical register copy optimization"));
128 cl::desc(
"Limit the length of PHI chains to lookup"));
134 cl::desc(
"Maximum length of recurrence chain when evaluating the benefit "
135 "of commuting operands"));
137STATISTIC(NumReuse,
"Number of extension results reused");
139STATISTIC(NumImmFold,
"Number of move immediate folded");
142STATISTIC(NumUncoalescableCopies,
"Number of uncoalescable copies optimized");
143STATISTIC(NumRewrittenCopies,
"Number of copies rewritten");
144STATISTIC(NumNAPhysCopies,
"Number of non-allocatable physical copies removed");
148class ValueTrackerResult;
149class RecurrenceInstr;
155 int CurrentSrcIdx = 0;
158 virtual ~Rewriter() =
default;
190 virtual bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg) = 0;
194class CopyRewriter :
public Rewriter {
197 assert(
MI.isCopy() &&
"Expected copy instruction");
199 virtual ~CopyRewriter() =
default;
203 if (++CurrentSrcIdx > 1)
215 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
225class UncoalescableRewriter :
public Rewriter {
230 NumDefs =
MI.getDesc().getNumDefs();
240 if (CurrentSrcIdx == NumDefs)
243 while (CopyLike.getOperand(CurrentSrcIdx).isDead()) {
245 if (CurrentSrcIdx == NumDefs)
258 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
264class InsertSubregRewriter :
public Rewriter {
267 assert(
MI.isInsertSubreg() &&
"Invalid instruction");
284 if (CurrentSrcIdx == 2)
298 (
unsigned)CopyLike.getOperand(3).getImm());
302 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
303 if (CurrentSrcIdx != 2)
314class ExtractSubregRewriter :
public Rewriter {
320 assert(
MI.isExtractSubreg() &&
"Invalid instruction");
331 if (CurrentSrcIdx == 1)
349 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
351 if (CurrentSrcIdx != 1)
354 CopyLike.getOperand(CurrentSrcIdx).setReg(NewReg);
365 CopyLike.removeOperand(2);
367 CopyLike.setDesc(
TII.get(TargetOpcode::COPY));
370 CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg);
376class RegSequenceRewriter :
public Rewriter {
379 assert(
MI.isRegSequence() &&
"Invalid instruction");
403 if (
static_cast<unsigned>(CurrentSrcIdx) >= CopyLike.getNumOperands())
406 const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
407 Src.Reg = MOInsertedReg.
getReg();
412 Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
416 assert(MODef.
getSubReg() == 0 &&
"cannot have subregister def in SSA");
420 bool RewriteCurrentSource(
Register NewReg,
unsigned NewSubReg)
override {
437 : DT(DT), MLI(MLI) {}
454 bool optimizeCoalescableCopyImpl(Rewriter &&CpyRewriter);
471 bool findTargetRecurrence(
Register Reg,
473 RecurrenceCycle &RC);
502 return MI.isCopy() ||
504 MI.isExtractSubreg()));
511 MI.isInsertSubregLike() ||
512 MI.isExtractSubregLike()));
516 RewriteMapTy &RewriteMap);
530 unsigned SrcSubReg =
MI.getOperand(1).getSubReg();
531 if (!SrcReg.
isVirtual() && !
MRI->isConstantPhysReg(SrcReg))
542 if (!getCopySrc(
MI, SrcPair))
545 auto It = CopySrcMIs.
find(SrcPair);
546 if (It != CopySrcMIs.
end() && It->second == &
MI)
547 CopySrcMIs.
erase(It);
553 deleteChangedCopy(
MI);
589class RecurrenceInstr {
591 using IndexPair = std::pair<unsigned, unsigned>;
594 RecurrenceInstr(
MachineInstr *MI,
unsigned Idx1,
unsigned Idx2)
595 :
MI(
MI), CommutePair(
std::make_pair(Idx1, Idx2)) {}
598 std::optional<IndexPair> getCommutePair()
const {
return CommutePair; }
602 std::optional<IndexPair> CommutePair;
608class ValueTrackerResult {
617 ValueTrackerResult() =
default;
621 bool isValid()
const {
return getNumSources() > 0; }
631 void addSource(
Register SrcReg,
unsigned SrcSubReg) {
635 void setSource(
int Idx,
Register SrcReg,
unsigned SrcSubReg) {
636 assert(
Idx < getNumSources() &&
"Reg pair source out of index");
640 int getNumSources()
const {
return RegSrcs.
size(); }
645 assert(
Idx < getNumSources() &&
"Reg source out of index");
646 return RegSrcs[
Idx].Reg;
649 unsigned getSrcSubReg(
int Idx)
const {
650 assert(
Idx < getNumSources() &&
"SubReg source out of index");
651 return RegSrcs[
Idx].SubReg;
655 if (
Other.getInst() != getInst())
658 if (
Other.getNumSources() != getNumSources())
661 for (
int i = 0, e =
Other.getNumSources(); i != e; ++i)
662 if (
Other.getSrcReg(i) != getSrcReg(i) ||
663 Other.getSrcSubReg(i) != getSrcSubReg(i))
706 ValueTrackerResult getNextSourceImpl();
709 ValueTrackerResult getNextSourceFromCopy();
712 ValueTrackerResult getNextSourceFromBitcast();
715 ValueTrackerResult getNextSourceFromRegSequence();
718 ValueTrackerResult getNextSourceFromInsertSubreg();
721 ValueTrackerResult getNextSourceFromExtractSubreg();
724 ValueTrackerResult getNextSourceFromSubregToReg();
727 ValueTrackerResult getNextSourceFromPHI();
742 if (!
Reg.isPhysical()) {
743 Def =
MRI.getVRegDef(Reg);
744 DefIdx =
MRI.def_begin(Reg).getOperandNo();
753 ValueTrackerResult getNextSource();
758char PeepholeOptimizerLegacy::ID = 0;
763 "Peephole Optimizations",
false,
false)
777bool PeepholeOptimizer::optimizeExtInstr(
782 if (!
TII->isCoalescableExtInstr(
MI, SrcReg, DstReg, SubIdx))
788 if (
MRI->hasOneNonDBGUse(SrcReg))
795 DstRC =
TRI->getSubClassWithSubReg(DstRC, SubIdx);
805 TRI->getSubClassWithSubReg(
MRI->getRegClass(SrcReg), SubIdx) !=
nullptr;
811 ReachedBBs.
insert(UI.getParent());
819 bool ExtendLife =
true;
831 if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx)
855 if (UseMBB == &
MBB) {
857 if (!LocalMIs.count(
UseMI))
858 Uses.push_back(&UseMO);
859 }
else if (ReachedBBs.
count(UseMBB)) {
862 Uses.push_back(&UseMO);
875 if (ExtendLife && !ExtendedUses.
empty())
880 bool Changed =
false;
889 PHIBBs.
insert(UI.getParent());
895 if (PHIBBs.
count(UseMBB))
900 MRI->clearKillFlags(DstReg);
901 MRI->constrainRegClass(DstReg, DstRC);
923 TII->get(TargetOpcode::COPY), NewVR)
924 .
addReg(DstReg, 0, SubIdx);
928 UseMO->setReg(NewVR);
945 int64_t CmpMask, CmpValue;
952 if (
TII->optimizeCompareInstr(
MI, SrcReg, SrcReg2, CmpMask, CmpValue,
MRI)) {
962bool PeepholeOptimizer::optimizeSelect(
965 unsigned FalseOp = 0;
966 bool Optimizable =
false;
968 if (
TII->analyzeSelect(
MI,
Cond, TrueOp, FalseOp, Optimizable))
972 if (!
TII->optimizeSelect(
MI, LocalMIs))
975 MI.eraseFromParent();
982 return TII->optimizeCondBranch(
MI);
1001 RewriteMapTy &RewriteMap) {
1011 unsigned PHICount = 0;
1018 ValueTracker ValTracker(CurSrcPair.
Reg, CurSrcPair.
SubReg, *
MRI,
TII);
1023 ValueTrackerResult Res = ValTracker.getNextSource();
1029 auto [InsertPt, WasInserted] = RewriteMap.try_emplace(CurSrcPair, Res);
1032 const ValueTrackerResult &CurSrcRes = InsertPt->second;
1034 assert(CurSrcRes == Res &&
"ValueTrackerResult found must match");
1037 if (CurSrcRes.getNumSources() > 1) {
1039 <<
"findNextSource: found PHI cycle, aborting...\n");
1047 unsigned NumSrcs = Res.getNumSources();
1055 for (
unsigned i = 0; i < NumSrcs; ++i)
1060 CurSrcPair = Res.getSrc(0);
1070 if (!
TRI->shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC,
1076 if (PHICount > 0 && CurSrcPair.
SubReg != 0)
1082 }
while (!SrcToLook.
empty());
1085 return CurSrcPair.
Reg !=
Reg;
1097 assert(!SrcRegs.
empty() &&
"No sources to create a PHI instruction?");
1102 assert(SrcRegs[0].
SubReg == 0 &&
"should not have subreg operand");
1103 Register NewVR =
MRI.createVirtualRegister(NewRC);
1106 TII.get(TargetOpcode::PHI), NewVR);
1108 unsigned MBBOpIdx = 2;
1110 MIB.
addReg(RegPair.Reg, 0, RegPair.SubReg);
1115 MRI.clearKillFlags(RegPair.Reg);
1132 bool HandleMultipleSources =
true) {
1135 ValueTrackerResult Res = RewriteMap.
lookup(LookupSrc);
1141 unsigned NumSrcs = Res.getNumSources();
1143 LookupSrc.
Reg = Res.getSrcReg(0);
1144 LookupSrc.
SubReg = Res.getSrcSubReg(0);
1149 if (!HandleMultipleSources)
1155 for (
unsigned i = 0; i < NumSrcs; ++i) {
1156 RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i));
1174bool PeepholeOptimizer::optimizeCoalescableCopyImpl(Rewriter &&CpyRewriter) {
1175 bool Changed =
false;
1180 while (CpyRewriter.getNextRewritableSource(TrackPair, Dst)) {
1181 if (Dst.Reg.isPhysical()) {
1192 RewriteMapTy RewriteMap;
1195 if (!findNextSource(DefRC, Dst.SubReg, TrackPair, RewriteMap))
1203 "should not rewrite source to original value");
1208 if (CpyRewriter.RewriteCurrentSource(NewSrc.
Reg, NewSrc.
SubReg)) {
1210 MRI->clearKillFlags(NewSrc.
Reg);
1220 NumRewrittenCopies += Changed;
1235bool PeepholeOptimizer::optimizeCoalescableCopy(
MachineInstr &
MI) {
1236 assert(isCoalescableCopy(
MI) &&
"Invalid argument");
1237 assert(
MI.getDesc().getNumDefs() == 1 &&
1238 "Coalescer can understand multiple defs?!");
1244 switch (
MI.getOpcode()) {
1245 case TargetOpcode::COPY:
1246 return optimizeCoalescableCopyImpl(CopyRewriter(
MI));
1247 case TargetOpcode::INSERT_SUBREG:
1248 return optimizeCoalescableCopyImpl(InsertSubregRewriter(
MI));
1249 case TargetOpcode::EXTRACT_SUBREG:
1250 return optimizeCoalescableCopyImpl(ExtractSubregRewriter(
MI, *
TII));
1251 case TargetOpcode::REG_SEQUENCE:
1252 return optimizeCoalescableCopyImpl(RegSequenceRewriter(
MI));
1255 if (
MI.isBitcast() ||
MI.isRegSequenceLike() ||
MI.isInsertSubregLike() ||
1256 MI.isExtractSubregLike())
1257 return optimizeCoalescableCopyImpl(UncoalescableRewriter(
MI));
1269 RewriteMapTy &RewriteMap) {
1270 assert(!
Def.Reg.isPhysical() &&
"We do not rewrite physical registers");
1277 Register NewVReg =
MRI->createVirtualRegister(DefRC);
1281 TII->get(TargetOpcode::COPY), NewVReg)
1292 MRI->replaceRegWith(
Def.Reg, NewVReg);
1293 MRI->clearKillFlags(NewVReg);
1297 MRI->clearKillFlags(NewSrc.
Reg);
1313bool PeepholeOptimizer::optimizeUncoalescableCopy(
1315 assert(isUncoalescableCopy(
MI) &&
"Invalid argument");
1316 UncoalescableRewriter CpyRewriter(
MI);
1321 RewriteMapTy RewriteMap;
1325 while (CpyRewriter.getNextRewritableSource(Src, Def)) {
1328 if (
Def.Reg.isPhysical())
1338 if (!findNextSource(DefRC,
Def.SubReg, Def, RewriteMap))
1348 LocalMIs.
insert(&NewCopy);
1353 MI.eraseFromParent();
1354 ++NumUncoalescableCopies;
1361bool PeepholeOptimizer::isLoadFoldable(
1363 if (!
MI.canFoldAsLoad() || !
MI.mayLoad())
1373 if (
Reg.isVirtual() && !
MI.getOperand(0).getSubReg() &&
1374 MRI->hasOneNonDBGUser(Reg)) {
1375 FoldAsLoadDefCandidates.
insert(Reg);
1381bool PeepholeOptimizer::isMoveImmediate(
1385 if (MCID.
getNumDefs() != 1 || !
MI.getOperand(0).isReg())
1388 if (!
Reg.isVirtual())
1392 if (!
MI.isMoveImmediate() && !
TII->getConstValDefinedInReg(
MI, Reg, ImmVal))
1395 ImmDefMIs.
insert(std::make_pair(Reg, &
MI));
1403bool PeepholeOptimizer::foldImmediate(
1407 for (
unsigned i = 0, e =
MI.getDesc().getNumOperands(); i != e; ++i) {
1412 if (!
Reg.isVirtual())
1414 if (ImmDefRegs.
count(Reg) == 0)
1417 assert(
II != ImmDefMIs.
end() &&
"couldn't find immediate definition");
1418 if (
TII->foldImmediate(
MI, *
II->second, Reg,
MRI)) {
1423 if (
MRI->getVRegDef(Reg) &&
1427 MRI->getRegClass(DstReg) ==
MRI->getRegClass(Reg)) {
1428 MRI->replaceRegWith(DstReg, Reg);
1429 MI.eraseFromParent();
1454 assert(
MI.isCopy() &&
"expected a COPY machine instruction");
1457 if (!getCopySrc(
MI, SrcPair))
1464 if (CopySrcMIs.
insert(std::make_pair(SrcPair, &
MI)).second) {
1472 "Unexpected mismatching subreg!");
1480 if (
MRI->getRegClass(DstReg) !=
MRI->getRegClass(PrevDstReg))
1483 MRI->replaceRegWith(DstReg, PrevDstReg);
1486 MRI->clearKillFlags(PrevDstReg);
1490bool PeepholeOptimizer::isNAPhysCopy(
Register Reg) {
1491 return Reg.isPhysical() && !
MRI->isAllocatable(Reg);
1494bool PeepholeOptimizer::foldRedundantNAPhysCopy(
1496 assert(
MI.isCopy() &&
"expected a COPY machine instruction");
1503 if (isNAPhysCopy(SrcReg) && DstReg.
isVirtual()) {
1507 NAPhysToVirtMIs.
insert({SrcReg, &
MI});
1511 if (!(SrcReg.
isVirtual() && isNAPhysCopy(DstReg)))
1515 auto PrevCopy = NAPhysToVirtMIs.
find(DstReg);
1516 if (PrevCopy == NAPhysToVirtMIs.
end()) {
1519 LLVM_DEBUG(
dbgs() <<
"NAPhysCopy: intervening clobber forbids erasing "
1525 if (PrevDstReg == SrcReg) {
1538 NAPhysToVirtMIs.
erase(PrevCopy);
1547bool PeepholeOptimizer::findTargetRecurrence(
1549 RecurrenceCycle &RC) {
1551 if (TargetRegs.
count(Reg))
1559 if (!
MRI->hasOneNonDBGUse(Reg))
1567 unsigned Idx =
MI.findRegisterUseOperandIdx(Reg,
nullptr);
1571 if (
MI.getDesc().getNumDefs() != 1)
1581 unsigned TiedUseIdx;
1582 if (!
MI.isRegTiedToUseOperand(0, &TiedUseIdx))
1585 if (
Idx == TiedUseIdx) {
1586 RC.push_back(RecurrenceInstr(&
MI));
1587 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1591 if (
TII->findCommutedOpIndices(
MI,
Idx, CommIdx) && CommIdx == TiedUseIdx) {
1592 RC.push_back(RecurrenceInstr(&
MI,
Idx, CommIdx));
1593 return findTargetRecurrence(DefOp.
getReg(), TargetRegs, RC);
1620 for (
unsigned Idx = 1;
Idx <
PHI.getNumOperands();
Idx += 2) {
1626 bool Changed =
false;
1628 if (findTargetRecurrence(
PHI.getOperand(0).getReg(), TargetRegs, RC)) {
1632 for (
auto &RI : RC) {
1634 auto CP = RI.getCommutePair();
1637 TII->commuteInstruction(*(RI.getMI()),
false, (*CP).first,
1654 PeepholeOptimizer Impl(DT, MLI);
1655 bool Changed = Impl.run(MF);
1666bool PeepholeOptimizerLegacy::runOnMachineFunction(
MachineFunction &MF) {
1670 ? &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()
1672 auto *MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1673 PeepholeOptimizer Impl(DT, MLI);
1674 return Impl.run(MF);
1679 LLVM_DEBUG(
dbgs() <<
"********** PEEPHOLE OPTIMIZER **********\n");
1690 bool Changed =
false;
1693 bool SeenMoveImm =
false;
1726 if (
MI->isDebugInstr())
1729 if (
MI->isPosition())
1732 if (IsLoopHeader &&
MI->isPHI()) {
1733 if (optimizeRecurrence(*
MI)) {
1739 if (!
MI->isCopy()) {
1744 if (MO.
isDef() && isNAPhysCopy(Reg)) {
1745 const auto &
Def = NAPhysToVirtMIs.
find(Reg);
1746 if (Def != NAPhysToVirtMIs.
end()) {
1750 <<
"NAPhysCopy: invalidating because of " << *
MI);
1751 NAPhysToVirtMIs.
erase(Def);
1756 for (
auto &RegMI : NAPhysToVirtMIs) {
1760 <<
"NAPhysCopy: invalidating because of " << *
MI);
1761 NAPhysToVirtMIs.erase(Def);
1768 if (
MI->isImplicitDef() ||
MI->isKill())
1771 if (
MI->isInlineAsm() ||
MI->hasUnmodeledSideEffects()) {
1778 NAPhysToVirtMIs.clear();
1781 if ((isUncoalescableCopy(*
MI) &&
1782 optimizeUncoalescableCopy(*
MI, LocalMIs)) ||
1783 (
MI->isCompare() && optimizeCmpInstr(*
MI)) ||
1784 (
MI->isSelect() && optimizeSelect(*
MI, LocalMIs))) {
1791 if (
MI->isConditionalBranch() && optimizeCondBranch(*
MI)) {
1796 if (isCoalescableCopy(*
MI) && optimizeCoalescableCopy(*
MI)) {
1802 if (
MI->isCopy() && (foldRedundantCopy(*
MI) ||
1803 foldRedundantNAPhysCopy(*
MI, NAPhysToVirtMIs))) {
1806 MI->eraseFromParent();
1811 if (isMoveImmediate(*
MI, ImmDefRegs, ImmDefMIs)) {
1814 Changed |= optimizeExtInstr(*
MI,
MBB, LocalMIs);
1822 Changed |= foldImmediate(*
MI, ImmDefRegs, ImmDefMIs,
Deleted);
1833 if (!isLoadFoldable(*
MI, FoldAsLoadDefCandidates) &&
1834 !FoldAsLoadDefCandidates.
empty()) {
1842 for (
unsigned i = MIDesc.
getNumDefs(); i !=
MI->getNumOperands(); ++i) {
1847 if (FoldAsLoadDefCandidates.
count(FoldAsLoadDefReg)) {
1852 Register FoldedReg = FoldAsLoadDefReg;
1855 TII->optimizeLoadInstr(*
MI,
MRI, FoldAsLoadDefReg,
DefMI)) {
1864 if (
MI->shouldUpdateAdditionalCallInfo())
1865 MI->getMF()->moveAdditionalCallInfo(
MI, FoldMI);
1866 MI->eraseFromParent();
1868 MRI->markUsesInDebugValueAsUndef(FoldedReg);
1869 FoldAsLoadDefCandidates.
erase(FoldedReg);
1883 if (
MI->isLoadFoldBarrier()) {
1885 FoldAsLoadDefCandidates.
clear();
1890 MF.resetDelegate(
this);
1894ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
1895 assert(
Def->isCopy() &&
"Invalid definition");
1900 assert(
Def->getNumOperands() -
Def->getNumImplicitOperands() == 2 &&
1901 "Invalid number of operands");
1902 assert(!
Def->hasImplicitDef() &&
"Only implicit uses are allowed");
1903 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"no subregister defs in SSA");
1908 return ValueTrackerResult();
1909 return ValueTrackerResult(Src.getReg(), Src.getSubReg());
1912ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
1913 assert(
Def->isBitcast() &&
"Invalid definition");
1916 if (
Def->mayRaiseFPException() ||
Def->hasUnmodeledSideEffects())
1917 return ValueTrackerResult();
1920 if (
Def->getDesc().getNumDefs() != 1)
1921 return ValueTrackerResult();
1923 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"no subregister defs in SSA");
1925 unsigned SrcIdx =
Def->getNumOperands();
1926 for (
unsigned OpIdx = DefIdx + 1, EndOpIdx = SrcIdx;
OpIdx != EndOpIdx;
1934 assert(!MO.
isDef() &&
"We should have skipped all the definitions by now");
1935 if (SrcIdx != EndOpIdx)
1937 return ValueTrackerResult();
1943 if (SrcIdx >=
Def->getNumOperands())
1944 return ValueTrackerResult();
1951 if (
UseMI.isSubregToReg())
1952 return ValueTrackerResult();
1957 return ValueTrackerResult();
1958 return ValueTrackerResult(Src.getReg(), Src.getSubReg());
1961ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
1962 assert((
Def->isRegSequence() ||
Def->isRegSequenceLike()) &&
1963 "Invalid definition");
1965 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"illegal subregister def");
1968 if (!
TII->getRegSequenceInputs(*Def, DefIdx, RegSeqInputRegs))
1969 return ValueTrackerResult();
1977 if (RegSeqInput.SubIdx == DefSubReg)
1978 return ValueTrackerResult(RegSeqInput.Reg, RegSeqInput.SubReg);
1987 LaneBitmask ThisOpRegMask =
TRI->getSubRegIndexLaneMask(RegSeqInput.SubIdx);
1993 if ((DefMask & ThisOpRegMask) != DefMask)
1996 unsigned ReverseDefCompose =
1997 TRI->reverseComposeSubRegIndices(RegSeqInput.SubIdx, DefSubReg);
1998 if (!ReverseDefCompose)
2001 unsigned ComposedDefInSrcReg1 =
2002 TRI->composeSubRegIndices(RegSeqInput.SubReg, ReverseDefCompose);
2010 TRI->getSubClassWithSubReg(SrcRC, ComposedDefInSrcReg1);
2011 if (SrcRC != SrcWithSubRC)
2012 return ValueTrackerResult();
2014 return ValueTrackerResult(RegSeqInput.Reg, ComposedDefInSrcReg1);
2020 return ValueTrackerResult();
2023ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
2024 assert((
Def->isInsertSubreg() ||
Def->isInsertSubregLike()) &&
2025 "Invalid definition");
2026 assert(!
Def->getOperand(DefIdx).getSubReg() &&
"no subreg defs in SSA");
2030 if (!
TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg))
2031 return ValueTrackerResult();
2040 if (InsertedReg.
SubIdx == DefSubReg) {
2041 return ValueTrackerResult(InsertedReg.
Reg, InsertedReg.
SubReg);
2052 return ValueTrackerResult();
2057 if ((
TRI->getSubRegIndexLaneMask(DefSubReg) &
2058 TRI->getSubRegIndexLaneMask(InsertedReg.
SubIdx))
2060 return ValueTrackerResult();
2063 return ValueTrackerResult(
BaseReg.Reg, DefSubReg);
2066ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
2067 assert((
Def->isExtractSubreg() ||
Def->isExtractSubregLike()) &&
2068 "Invalid definition");
2075 return ValueTrackerResult();
2078 if (!
TII->getExtractSubregInputs(*Def, DefIdx, ExtractSubregInputReg))
2079 return ValueTrackerResult();
2083 if (ExtractSubregInputReg.
SubReg)
2084 return ValueTrackerResult();
2086 return ValueTrackerResult(ExtractSubregInputReg.
Reg,
2087 ExtractSubregInputReg.
SubIdx);
2090ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() {
2091 assert(
Def->isSubregToReg() &&
"Invalid definition");
2099 if (DefSubReg !=
Def->getOperand(3).getImm())
2100 return ValueTrackerResult();
2103 if (
Def->getOperand(2).getSubReg())
2104 return ValueTrackerResult();
2106 return ValueTrackerResult(
Def->getOperand(2).getReg(),
2107 Def->getOperand(3).getImm());
2111ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
2112 assert(
Def->isPHI() &&
"Invalid definition");
2113 ValueTrackerResult Res;
2116 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2) {
2122 return ValueTrackerResult();
2129ValueTrackerResult ValueTracker::getNextSourceImpl() {
2130 assert(Def &&
"This method needs a valid definition");
2132 assert(((
Def->getOperand(DefIdx).isDef() &&
2133 (DefIdx < Def->
getDesc().getNumDefs() ||
2134 Def->getDesc().isVariadic())) ||
2135 Def->getOperand(DefIdx).isImplicit()) &&
2138 return getNextSourceFromCopy();
2139 if (
Def->isBitcast())
2140 return getNextSourceFromBitcast();
2144 return ValueTrackerResult();
2145 if (
Def->isRegSequence() ||
Def->isRegSequenceLike())
2146 return getNextSourceFromRegSequence();
2147 if (
Def->isInsertSubreg() ||
Def->isInsertSubregLike())
2148 return getNextSourceFromInsertSubreg();
2149 if (
Def->isExtractSubreg() ||
Def->isExtractSubregLike())
2150 return getNextSourceFromExtractSubreg();
2151 if (
Def->isSubregToReg())
2152 return getNextSourceFromSubregToReg();
2154 return getNextSourceFromPHI();
2155 return ValueTrackerResult();
2158ValueTrackerResult ValueTracker::getNextSource() {
2162 return ValueTrackerResult();
2164 ValueTrackerResult Res = getNextSourceImpl();
2165 if (Res.isValid()) {
2169 bool OneRegSrc = Res.getNumSources() == 1;
2171 Reg = Res.getSrcReg(0);
2178 if (!
Reg.isPhysical() && OneRegSrc) {
2180 if (DI !=
MRI.def_end()) {
2183 DefSubReg = Res.getSrcSubReg(0);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
std::optional< std::vector< StOtherPiece > > Other
const HexagonInstrInfo * TII
A common definition of LaneBitmask for use in TableGen and CodeGen.
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
TargetInstrInfo::RegSubRegPair RegSubRegPair
static cl::opt< unsigned > RewritePHILimit("rewrite-phi-limit", cl::Hidden, cl::init(10), cl::desc("Limit the length of PHI chains to lookup"))
static cl::opt< bool > DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), cl::desc("Disable the peephole optimizer"))
static cl::opt< unsigned > MaxRecurrenceChain("recurrence-chain-limit", cl::Hidden, cl::init(3), cl::desc("Maximum length of recurrence chain when evaluating the benefit " "of commuting operands"))
static cl::opt< bool > DisableNAPhysCopyOpt("disable-non-allocatable-phys-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable non-allocatable physical register copy optimization"))
static bool isVirtualRegisterOperand(MachineOperand &MO)
\bried Returns true if MO is a virtual register operand.
static MachineInstr & insertPHI(MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const SmallVectorImpl< RegSubRegPair > &SrcRegs, MachineInstr &OrigPHI)
Insert a PHI instruction with incoming edges SrcRegs that are guaranteed to have the same register cl...
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
static cl::opt< bool > DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable advanced copy optimization"))
Specifiy whether or not the value tracking looks through complex instructions.
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.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Virtual Register Rewriter
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
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...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
bool isLoopHeader(const BlockT *BB) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
An RAII based helper class to modify MachineFunctionProperties when running pass.
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
virtual void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID)
Callback before changing MCInstrDesc.
virtual void MF_HandleRemoval(MachineInstr &MI)=0
Callback before a removal. This should not modify the MI directly.
virtual void MF_HandleInsertion(MachineInstr &MI)=0
Callback after an insertion. This should not modify the MI directly.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
void setDelegate(Delegate *delegate)
Set the delegate.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
unsigned getOperandNo() const
getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
std::pair< unsigned, unsigned > IndexPair
The pair of an instruction index and a operand index.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI char & PeepholeOptimizerLegacyID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void initializePeepholeOptimizerLegacyPass(PassRegistry &)
Implement std::hash so that hash_code can be used in STL containers.
A pair composed of a pair of a register and a sub-register index, and another sub-register index.
A pair composed of a register and a sub-register index.