68#define DEBUG_TYPE "twoaddressinstruction"
70STATISTIC(NumTwoAddressInstrs,
"Number of two-address instructions");
71STATISTIC(NumCommuted ,
"Number of instructions commuted to coalesce");
72STATISTIC(NumAggrCommuted ,
"Number of instructions aggressively commuted");
73STATISTIC(NumConvertedTo3Addr,
"Number of instructions promoted to 3-address");
74STATISTIC(NumReSchedUps,
"Number of instructions re-scheduled up");
75STATISTIC(NumReSchedDowns,
"Number of instructions re-scheduled down");
80 cl::desc(
"Coalesce copies by rescheduling (default=true)"),
87 cl::desc(
"Maximum number of dataflow edges to traverse when evaluating "
88 "the benefit of commuting operands"));
92class TwoAddressInstructionImpl {
126 bool noUseAfterLastDef(
Register Reg,
unsigned Dist,
unsigned &LastDef);
129 bool &IsSrcPhys,
bool &IsDstPhys)
const;
139 bool &IsDstPhys)
const;
154 unsigned RegBIdx,
unsigned RegCIdx,
unsigned Dist);
171 unsigned SrcIdx,
unsigned DstIdx,
172 unsigned &Dist,
bool shouldOnlyCommute);
187 void processTiedPairs(
MachineInstr *
MI, TiedPairList&,
unsigned &Dist);
189 bool processStatepoint(
MachineInstr *
MI, TiedOperandMap &TiedOperands);
210 TwoAddressInstructionImpl Impl(MF,
this);
214 Impl.setOptLevel(CodeGenOptLevel::None);
238 TwoAddressInstructionImpl Impl(MF, MFAM);
243 bool Changed = Impl.run();
256char TwoAddressInstructionLegacyPass::ID = 0;
261 "Two-Address instruction pass",
false,
false)
266TwoAddressInstructionImpl::TwoAddressInstructionImpl(
268 : MF(&Func),
TII(Func.getSubtarget().getInstrInfo()),
269 TRI(Func.getSubtarget().getRegisterInfo()),
270 InstrItins(Func.getSubtarget().getInstrItineraryData()),
271 MRI(&Func.getRegInfo()),
274 OptLevel(Func.getTarget().getOptLevel()) {
280TwoAddressInstructionImpl::TwoAddressInstructionImpl(
MachineFunction &Func,
282 : MF(&
Func),
TII(
Func.getSubtarget().getInstrInfo()),
283 TRI(
Func.getSubtarget().getRegisterInfo()),
284 InstrItins(
Func.getSubtarget().getInstrItineraryData()),
285 MRI(&
Func.getRegInfo()), OptLevel(
Func.getTarget().getOptLevel()) {
287 LV = LVWrapper ? &LVWrapper->
getLV() :
nullptr;
289 LIS = LISWrapper ? &LISWrapper->
getLIS() :
nullptr;
291 AA = &AAPass->getAAResults();
298TwoAddressInstructionImpl::getSingleDef(
Register Reg,
302 if (
DefMI.getParent() != BB ||
DefMI.isDebugValue())
306 else if (Ret != &
DefMI)
319bool TwoAddressInstructionImpl::isRevCopyChain(
Register FromReg,
Register ToReg,
322 for (
int i = 0; i < Maxlen; i++) {
324 if (!Def || !
Def->isCopy())
327 TmpReg =
Def->getOperand(1).getReg();
339bool TwoAddressInstructionImpl::noUseAfterLastDef(
Register Reg,
unsigned Dist,
342 unsigned LastUse = Dist;
345 if (
MI->getParent() !=
MBB ||
MI->isDebugValue())
348 if (DI == DistanceMap.end())
350 if (MO.isUse() && DI->second < LastUse)
351 LastUse = DI->second;
352 if (MO.isDef() && DI->second > LastDef)
353 LastDef = DI->second;
356 return !(LastUse > LastDef && LastUse < Dist);
364 bool &IsDstPhys)
const {
368 DstReg =
MI.getOperand(0).getReg();
369 SrcReg =
MI.getOperand(1).getReg();
370 }
else if (
MI.isInsertSubreg() ||
MI.isSubregToReg()) {
371 DstReg =
MI.getOperand(0).getReg();
372 SrcReg =
MI.getOperand(2).getReg();
382bool TwoAddressInstructionImpl::isPlainlyKilled(
const MachineInstr *
MI,
390 assert(
I != LR.
end() &&
"Reg must be live-in to use.");
396bool TwoAddressInstructionImpl::isPlainlyKilled(
const MachineInstr *
MI,
404 if (LIS && !LIS->isNotInMIMap(*
MI)) {
406 return isPlainlyKilled(
MI, LIS->getInterval(Reg));
408 if (
MRI->isReserved(Reg))
411 return isPlainlyKilled(MI, LIS->getRegUnit(U));
415 return MI->killsRegister(Reg,
nullptr);
420bool TwoAddressInstructionImpl::isPlainlyKilled(
443 bool allowFalsePositives)
const {
447 if (
Reg.isPhysical() && (allowFalsePositives ||
MRI->hasOneUse(Reg)))
449 if (!isPlainlyKilled(
DefMI, Reg))
451 if (
Reg.isPhysical())
456 if (std::next(Begin) !=
MRI->def_end())
459 bool IsSrcPhys, IsDstPhys;
463 if (!isCopyToReg(*
DefMI, SrcReg, DstReg, IsSrcPhys, IsDstPhys))
472 for (
unsigned i = 0, NumOps =
MI.getNumOperands(); i != NumOps; ++i) {
477 if (
MI.isRegTiedToDefOperand(i, &ti)) {
478 DstReg =
MI.getOperand(ti).getReg();
487MachineInstr *TwoAddressInstructionImpl::findOnlyInterestingUse(
489 bool &IsDstPhys)
const {
493 if (
MI->getParent() !=
MBB)
495 if (isPlainlyKilled(
MI, Reg))
504 if (isCopyToReg(
UseMI, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) {
513 if (
UseMI.isCommutable()) {
516 if (
TII->findCommutedOpIndices(
UseMI, Src1, Src2)) {
532 while (Reg.isVirtual()) {
534 if (SI == RegMap.
end())
538 if (Reg.isPhysical())
544bool TwoAddressInstructionImpl::regsAreCompatible(
Register RegA,
550 return TRI->regsOverlap(RegA, RegB);
554void TwoAddressInstructionImpl::removeMapRegEntry(
558 "removeMapRegEntry must be called with a register or regmask operand.");
561 for (
auto SI : RegMap) {
568 if (
TRI->regsOverlap(ToReg, Reg))
574 for (
auto SrcReg : Srcs)
575 RegMap.erase(SrcReg);
586void TwoAddressInstructionImpl::removeClobberedSrcRegMap(
MachineInstr *
MI) {
599 if (!Dst || Dst.isVirtual())
603 if (regsAreCompatible(Dst,
getMappedReg(Src, SrcRegMap)))
609 removeMapRegEntry(MO, SrcRegMap);
615 if (!Reg ||
Reg.isVirtual())
617 removeMapRegEntry(MO, SrcRegMap);
622bool TwoAddressInstructionImpl::regOverlapsSet(
624 for (
unsigned R : Set)
625 if (
TRI->regsOverlap(R, Reg))
633bool TwoAddressInstructionImpl::isProfitableToCommute(
Register RegA,
638 if (OptLevel == CodeGenOptLevel::None)
659 if (!isPlainlyKilled(
MI, RegC))
676 bool CompB = FromRegB && regsAreCompatible(FromRegB, ToRegA);
677 bool CompC = FromRegC && regsAreCompatible(FromRegC, ToRegA);
683 if ((!FromRegB && CompC) || (FromRegB && !CompB && (!FromRegC || CompC)))
689 if ((!FromRegC && CompB) || (FromRegC && !CompC && (!FromRegB || CompB)))
695 unsigned LastDefC = 0;
696 if (!noUseAfterLastDef(RegC, Dist, LastDefC))
701 unsigned LastDefB = 0;
702 if (!noUseAfterLastDef(RegB, Dist, LastDefB))
728 if (
TII->hasCommutePreference(*
MI, Commute))
733 return LastDefB && LastDefC && LastDefC > LastDefB;
738bool TwoAddressInstructionImpl::commuteInstruction(
MachineInstr *
MI,
743 Register RegC =
MI->getOperand(RegCIdx).getReg();
747 if (NewMI ==
nullptr) {
754 "TargetInstrInfo::commuteInstruction() should not return a new "
755 "instruction unless it was requested.");
760 Register RegA =
MI->getOperand(DstIdx).getReg();
761 SrcRegMap[RegA] = FromRegC;
769bool TwoAddressInstructionImpl::isProfitableToConv3Addr(
Register RegA,
781 return (ToRegA && !regsAreCompatible(FromRegB, ToRegA));
786bool TwoAddressInstructionImpl::convertInstTo3Addr(
798 if (
auto OldInstrNum = mi->peekDebugInstrNum()) {
799 assert(mi->getNumExplicitDefs() == 1);
803 unsigned OldIdx = mi->defs().begin()->getOperandNo();
804 unsigned NewIdx = NewMI->
defs().begin()->getOperandNo();
809 std::make_pair(NewInstrNum, NewIdx));
815 DistanceMap.insert(std::make_pair(&
MI, Dist++));
821 SrcRegMap.erase(RegA);
822 DstRegMap.erase(RegB);
828void TwoAddressInstructionImpl::scanUses(
Register DstReg) {
835 findOnlyInterestingUse(Reg,
MBB, IsCopy, NewReg, IsDstPhys)) {
836 if (IsCopy && !Processed.insert(
UseMI).second)
840 if (DI != DistanceMap.end())
848 SrcRegMap[NewReg] =
Reg;
853 if (!VirtRegPairs.
empty()) {
854 unsigned ToReg = VirtRegPairs.
back();
856 while (!VirtRegPairs.
empty()) {
858 bool isNew = DstRegMap.insert(std::make_pair(FromReg, ToReg)).second;
860 assert(DstRegMap[FromReg] == ToReg &&
"Can't map to two dst registers!");
863 bool isNew = DstRegMap.insert(std::make_pair(DstReg, ToReg)).second;
865 assert(DstRegMap[DstReg] == ToReg &&
"Can't map to two dst registers!");
882 if (Processed.count(
MI))
885 bool IsSrcPhys, IsDstPhys;
887 if (!isCopyToReg(*
MI, SrcReg, DstReg, IsSrcPhys, IsDstPhys))
890 if (IsDstPhys && !IsSrcPhys) {
891 DstRegMap.insert(std::make_pair(SrcReg, DstReg));
892 }
else if (!IsDstPhys && IsSrcPhys) {
893 bool isNew = SrcRegMap.insert(std::make_pair(DstReg, SrcReg)).second;
895 assert(SrcRegMap[DstReg] == SrcReg &&
896 "Can't map to two src physical registers!");
901 Processed.insert(
MI);
907bool TwoAddressInstructionImpl::rescheduleMIBelowKill(
917 if (DI == DistanceMap.end())
925 "Reg should not have empty live interval.");
927 SlotIndex MBBEndIdx = LIS->getMBBEndIdx(
MBB).getPrevSlot();
929 if (
I != LI.
end() &&
I->start < MBBEndIdx)
933 KillMI = LIS->getInstructionFromIndex(
I->end);
935 KillMI = LV->getVarInfo(Reg).findKill(
MBB);
950 bool SeenStore =
true;
951 if (!
MI->isSafeToMove(SeenStore))
970 Uses.push_back(MOReg);
971 if (MOReg != Reg && isPlainlyKilled(MO))
982 if (
End->isCopy() && regOverlapsSet(Defs,
End->getOperand(1).getReg()))
990 unsigned NumVisited = 0;
995 if (OtherMI.isDebugOrPseudoInstr())
1000 if (OtherMI.hasUnmodeledSideEffects() || OtherMI.isCall() ||
1001 OtherMI.isBranch() || OtherMI.isTerminator())
1011 if (regOverlapsSet(
Uses, MOReg))
1014 if (!MO.
isDead() && regOverlapsSet(Defs, MOReg))
1020 if (regOverlapsSet(Defs, MOReg))
1022 bool isKill = isPlainlyKilled(MO);
1023 if (MOReg != Reg && ((isKill && regOverlapsSet(
Uses, MOReg)) ||
1024 regOverlapsSet(Kills, MOReg)))
1027 if (MOReg == Reg && !isKill)
1031 assert((MOReg != Reg || &OtherMI == KillMI) &&
1032 "Found multiple kills of a register in a basic block");
1038 while (Begin !=
MBB->
begin() && std::prev(Begin)->isDebugInstr())
1047 auto CopyMI =
MBBI++;
1049 if (!CopyMI->isDebugOrPseudoInstr())
1050 LIS->handleMove(*CopyMI);
1058 DistanceMap.erase(DI);
1062 LIS->handleMove(*
MI);
1064 LV->removeVirtualRegisterKilled(Reg, *KillMI);
1065 LV->addVirtualRegisterKilled(Reg, *
MI);
1074bool TwoAddressInstructionImpl::isDefTooClose(
Register Reg,
unsigned Dist,
1082 if (DDI == DistanceMap.end())
1084 unsigned DefDist = DDI->second;
1085 assert(Dist > DefDist &&
"Visited def already?");
1095bool TwoAddressInstructionImpl::rescheduleKillAboveMI(
1105 if (DI == DistanceMap.end())
1113 "Reg should not have empty live interval.");
1115 SlotIndex MBBEndIdx = LIS->getMBBEndIdx(
MBB).getPrevSlot();
1117 if (
I != LI.
end() &&
I->start < MBBEndIdx)
1121 KillMI = LIS->getInstructionFromIndex(
I->end);
1123 KillMI = LV->getVarInfo(Reg).findKill(
MBB);
1133 bool SeenStore =
true;
1148 if (isDefTooClose(MOReg, DI->second,
MI))
1150 bool isKill = isPlainlyKilled(MO);
1151 if (MOReg == Reg && !isKill)
1153 Uses.push_back(MOReg);
1154 if (isKill && MOReg != Reg)
1164 unsigned NumVisited = 0;
1168 if (OtherMI.isDebugOrPseudoInstr())
1170 if (NumVisited > 10)
1173 if (OtherMI.hasUnmodeledSideEffects() || OtherMI.isCall() ||
1174 OtherMI.isBranch() || OtherMI.isTerminator())
1185 if (regOverlapsSet(Defs, MOReg))
1189 if (regOverlapsSet(Kills, MOReg))
1192 if (&OtherMI !=
MI && MOReg == Reg && !isPlainlyKilled(MO))
1201 if (regOverlapsSet(
Uses, MOReg))
1203 if (MOReg.
isPhysical() && regOverlapsSet(LiveDefs, MOReg))
1212 while (InsertPos !=
MBB->
begin() && std::prev(InsertPos)->isDebugInstr())
1216 while (std::prev(
From)->isDebugInstr())
1220 nmi = std::prev(InsertPos);
1221 DistanceMap.erase(DI);
1225 LIS->handleMove(*KillMI);
1227 LV->removeVirtualRegisterKilled(Reg, *KillMI);
1228 LV->addVirtualRegisterKilled(Reg, *
MI);
1247bool TwoAddressInstructionImpl::tryInstructionCommute(
MachineInstr *
MI,
1252 if (!
MI->isCommutable())
1255 bool MadeChange =
false;
1256 Register DstOpReg =
MI->getOperand(DstOpIdx).getReg();
1257 Register BaseOpReg =
MI->getOperand(BaseOpIdx).getReg();
1258 unsigned OpsNum =
MI->getDesc().getNumOperands();
1259 unsigned OtherOpIdx =
MI->getDesc().getNumDefs();
1260 for (; OtherOpIdx < OpsNum; OtherOpIdx++) {
1265 if (OtherOpIdx == BaseOpIdx || !
MI->getOperand(OtherOpIdx).isReg() ||
1266 !
TII->findCommutedOpIndices(*
MI, BaseOpIdx, OtherOpIdx))
1269 Register OtherOpReg =
MI->getOperand(OtherOpIdx).getReg();
1270 bool AggressiveCommute =
false;
1274 bool OtherOpKilled = isKilled(*
MI, OtherOpReg,
false);
1275 bool DoCommute = !BaseOpKilled && OtherOpKilled;
1278 isProfitableToCommute(DstOpReg, BaseOpReg, OtherOpReg,
MI, Dist)) {
1280 AggressiveCommute =
true;
1284 if (DoCommute && commuteInstruction(
MI, DstOpIdx, BaseOpIdx, OtherOpIdx,
1288 if (AggressiveCommute)
1295 BaseOpReg = OtherOpReg;
1296 BaseOpKilled = OtherOpKilled;
1299 OpsNum =
MI->getDesc().getNumOperands();
1312bool TwoAddressInstructionImpl::tryInstructionTransform(
1314 unsigned SrcIdx,
unsigned DstIdx,
unsigned &Dist,
bool shouldOnlyCommute) {
1315 if (OptLevel == CodeGenOptLevel::None)
1319 Register regA =
MI.getOperand(DstIdx).getReg();
1320 Register regB =
MI.getOperand(SrcIdx).getReg();
1322 assert(regB.
isVirtual() &&
"cannot make instruction into two-address form");
1323 bool regBKilled = isKilled(
MI, regB,
true);
1328 bool Commuted = tryInstructionCommute(&
MI, DstIdx, SrcIdx, regBKilled, Dist);
1338 if (Commuted && !
MI.isConvertibleTo3Addr())
1341 if (shouldOnlyCommute)
1354 regB =
MI.getOperand(SrcIdx).getReg();
1355 regBKilled = isKilled(
MI, regB,
true);
1358 if (
MI.isConvertibleTo3Addr()) {
1361 if (!regBKilled || isProfitableToConv3Addr(regA, regB)) {
1363 if (convertInstTo3Addr(mi, nmi, regA, regB, Dist)) {
1364 ++NumConvertedTo3Addr;
1389 if (
MI.mayLoad() && !regBKilled) {
1391 unsigned LoadRegIndex;
1393 TII->getOpcodeAfterMemoryUnfold(
MI.getOpcode(),
1403 TRI->getAllocatableClass(
1404 TII->getRegClass(UnfoldMCID, LoadRegIndex,
TRI, *MF));
1407 if (!
TII->unfoldMemoryOperand(*MF,
MI, Reg,
1414 "Unfolded a load into multiple instructions!");
1416 NewMIs[1]->addRegisterKilled(Reg,
TRI);
1422 DistanceMap.insert(std::make_pair(NewMIs[0], Dist++));
1423 DistanceMap.insert(std::make_pair(NewMIs[1], Dist));
1426 <<
"2addr: NEW INST: " << *NewMIs[1]);
1429 unsigned NewDstIdx =
1430 NewMIs[1]->findRegisterDefOperandIdx(regA,
nullptr);
1431 unsigned NewSrcIdx =
1432 NewMIs[1]->findRegisterUseOperandIdx(regB,
nullptr);
1434 bool TransformResult =
1435 tryInstructionTransform(NewMI, mi, NewSrcIdx, NewDstIdx, Dist,
true);
1436 (void)TransformResult;
1437 assert(!TransformResult &&
1438 "tryInstructionTransform() should return false.");
1439 if (NewMIs[1]->getOperand(NewSrcIdx).isKill()) {
1447 if (NewMIs[0]->killsRegister(MO.
getReg(),
nullptr))
1448 LV->replaceKillInstruction(MO.
getReg(),
MI, *NewMIs[0]);
1452 "Kill missing after load unfold!");
1453 LV->replaceKillInstruction(MO.
getReg(),
MI, *NewMIs[1]);
1456 }
else if (LV->removeVirtualRegisterDead(MO.
getReg(),
MI)) {
1457 if (NewMIs[1]->registerDefIsDead(MO.
getReg(),
1459 LV->addVirtualRegisterDead(MO.
getReg(), *NewMIs[1]);
1463 "Dead flag missing after load unfold!");
1464 LV->addVirtualRegisterDead(MO.
getReg(), *NewMIs[0]);
1469 LV->addVirtualRegisterKilled(Reg, *NewMIs[1]);
1479 LIS->RemoveMachineInstrFromMaps(
MI);
1482 MI.eraseFromParent();
1483 DistanceMap.erase(&
MI);
1489 LIS->repairIntervalsInRange(
MBB, Begin,
End, OrigRegs);
1498 NewMIs[0]->eraseFromParent();
1499 NewMIs[1]->eraseFromParent();
1500 DistanceMap.
erase(NewMIs[0]);
1501 DistanceMap.erase(NewMIs[1]);
1514bool TwoAddressInstructionImpl::collectTiedOperands(
1516 bool AnyOps =
false;
1517 unsigned NumOps =
MI->getNumOperands();
1519 for (
unsigned SrcIdx = 0; SrcIdx < NumOps; ++SrcIdx) {
1520 unsigned DstIdx = 0;
1521 if (!
MI->isRegTiedToDefOperand(SrcIdx, &DstIdx))
1529 if (SrcReg == DstReg)
1532 assert(SrcReg && SrcMO.
isUse() &&
"two address instruction invalid");
1539 MRI->constrainRegClass(DstReg, RC);
1546 TiedOperands[SrcReg].push_back(std::make_pair(SrcIdx, DstIdx));
1553void TwoAddressInstructionImpl::processTiedPairs(
MachineInstr *
MI,
1554 TiedPairList &TiedPairs,
1556 bool IsEarlyClobber =
llvm::any_of(TiedPairs, [
MI](
auto const &TP) {
1557 return MI->getOperand(TP.second).isEarlyClobber();
1560 bool RemovedKillFlag =
false;
1561 bool AllUsesCopied =
true;
1562 unsigned LastCopiedReg = 0;
1565 unsigned SubRegB = 0;
1566 for (
auto &TP : TiedPairs) {
1567 unsigned SrcIdx = TP.first;
1568 unsigned DstIdx = TP.second;
1575 RegB =
MI->getOperand(SrcIdx).getReg();
1576 SubRegB =
MI->getOperand(SrcIdx).getSubReg();
1582 AllUsesCopied =
false;
1585 LastCopiedReg = RegA;
1587 assert(RegB.
isVirtual() &&
"cannot make instruction into two-address form");
1593 for (
unsigned i = 0; i !=
MI->getNumOperands(); ++i)
1595 !
MI->getOperand(i).isReg() ||
1596 MI->getOperand(i).getReg() != RegA);
1601 TII->get(TargetOpcode::COPY), RegA);
1604 MIB.
addReg(RegB, 0, SubRegB);
1608 assert(
TRI->getMatchingSuperRegClass(RC,
MRI->getRegClass(RegA),
1610 "tied subregister must be a truncation");
1614 assert(
TRI->getMatchingSuperReg(RegA, SubRegB,
MRI->getRegClass(RegB))
1615 &&
"tied subregister must be a truncation");
1622 DistanceMap.insert(std::make_pair(&*PrevMI, Dist));
1623 DistanceMap[
MI] = ++Dist;
1626 LastCopyIdx = LIS->InsertMachineInstrInMaps(*PrevMI).getRegSlot();
1629 LIS->getInstructionIndex(*MI).getRegSlot(IsEarlyClobber);
1635 VNI = S.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator());
1640 if (
LiveRange *LR = LIS->getCachedRegUnit(Unit)) {
1642 LR->
getNextValue(LastCopyIdx, LIS->getVNInfoAllocator());
1653 "inconsistent operand info for 2-reg pass");
1654 if (isPlainlyKilled(MO)) {
1656 RemovedKillFlag =
true;
1661 MRI->constrainRegClass(RegA, RC);
1669 if (AllUsesCopied) {
1673 if (MO.
getReg() == RegB) {
1674 if (MO.
getSubReg() == SubRegB && !IsEarlyClobber) {
1675 if (isPlainlyKilled(MO)) {
1677 RemovedKillFlag =
true;
1679 MO.
setReg(LastCopiedReg);
1682 RemainingUses |=
TRI->getSubRegIndexLaneMask(MO.
getSubReg());
1688 if (RemovedKillFlag && RemainingUses.
none() && LV &&
1689 LV->getVarInfo(RegB).removeKill(*
MI)) {
1692 LV->addVirtualRegisterKilled(RegB, *PrevMI);
1695 if (RemovedKillFlag && RemainingUses.
none())
1696 SrcRegMap[LastCopiedReg] = RegB;
1705 if ((LaneMask & RemainingUses).any())
1709 S->
end = LastCopyIdx;
1714 bool ShrinkLI =
true;
1716 ShrinkLI &= Shrink(S, S.LaneMask);
1720 }
else if (RemovedKillFlag) {
1726 if (MO.
getReg() == RegB) {
1741bool TwoAddressInstructionImpl::processStatepoint(
1744 bool NeedCopy =
false;
1745 for (
auto &TO : TiedOperands) {
1747 if (TO.second.size() != 1) {
1752 unsigned SrcIdx = TO.second[0].first;
1753 unsigned DstIdx = TO.second[0].second;
1758 assert(RegB ==
MI->getOperand(SrcIdx).getReg());
1769 const auto &UseLI = LIS->getInterval(RegB);
1770 const auto &DefLI = LIS->getInterval(RegA);
1771 if (DefLI.overlaps(UseLI)) {
1773 <<
" UseLI overlaps with DefLI\n");
1777 }
else if (LV && LV->getVarInfo(RegB).findKill(
MI->getParent()) !=
MI) {
1782 <<
" not killed by statepoint\n");
1787 if (!
MRI->constrainRegClass(RegB,
MRI->getRegClass(RegA))) {
1789 <<
" to register class of " <<
printReg(RegA,
TRI, 0)
1794 MRI->replaceRegWith(RegA, RegB);
1805 for (
auto &S :
Other) {
1810 LIS->removeInterval(RegA);
1814 if (
MI->getOperand(SrcIdx).isKill())
1815 LV->removeVirtualRegisterKilled(RegB, *
MI);
1820 for (
auto *KillMI : DstInfo.
Kills)
1821 LV->addVirtualRegisterKilled(RegB, *KillMI,
false);
1828bool TwoAddressInstructionImpl::run() {
1829 bool MadeChange =
false;
1831 LLVM_DEBUG(
dbgs() <<
"********** REWRITING TWO-ADDR INSTRS **********\n");
1839 .
set(MachineFunctionProperties::Property::TiedOpsRewritten);
1841 TiedOperandMap TiedOperands;
1845 DistanceMap.clear();
1853 if (mi->isDebugInstr()) {
1860 if (mi->isRegSequence())
1861 eliminateRegSequence(mi);
1863 DistanceMap.insert(std::make_pair(&*mi, ++Dist));
1869 if (!collectTiedOperands(&*mi, TiedOperands)) {
1870 removeClobberedSrcRegMap(&*mi);
1875 ++NumTwoAddressInstrs;
1882 if (TiedOperands.size() == 1) {
1884 = TiedOperands.
begin()->second;
1885 if (TiedPairs.
size() == 1) {
1886 unsigned SrcIdx = TiedPairs[0].first;
1887 unsigned DstIdx = TiedPairs[0].second;
1888 Register SrcReg = mi->getOperand(SrcIdx).getReg();
1889 Register DstReg = mi->getOperand(DstIdx).getReg();
1890 if (SrcReg != DstReg &&
1891 tryInstructionTransform(mi, nmi, SrcIdx, DstIdx, Dist,
false)) {
1894 TiedOperands.clear();
1895 removeClobberedSrcRegMap(&*mi);
1902 if (mi->getOpcode() == TargetOpcode::STATEPOINT &&
1903 processStatepoint(&*mi, TiedOperands)) {
1904 TiedOperands.clear();
1911 for (
auto &TO : TiedOperands) {
1912 processTiedPairs(&*mi, TO.second, Dist);
1917 if (mi->isInsertSubreg()) {
1920 unsigned SubIdx = mi->getOperand(3).getImm();
1921 mi->removeOperand(3);
1922 assert(mi->getOperand(0).getSubReg() == 0 &&
"Unexpected subreg idx");
1923 mi->getOperand(0).setSubReg(SubIdx);
1924 mi->getOperand(0).setIsUndef(mi->getOperand(1).isUndef());
1925 mi->removeOperand(1);
1926 mi->setDesc(
TII->get(TargetOpcode::COPY));
1937 TRI->getSubRegIndexLaneMask(mi->getOperand(0).getSubReg());
1938 SlotIndex Idx = LIS->getInstructionIndex(*mi).getRegSlot();
1940 if ((S.LaneMask & LaneMask).none()) {
1942 if (mi->getOperand(0).isUndef()) {
1943 S.removeValNo(DefSeg->valno);
1946 S.MergeValueNumberInto(DefSeg->valno, UseSeg->valno);
1952 LIS->shrinkToUses(&LI);
1956 LIS->removeInterval(Reg);
1957 LIS->createAndComputeVirtRegInterval(Reg);
1964 TiedOperands.clear();
1965 removeClobberedSrcRegMap(&*mi);
1983void TwoAddressInstructionImpl::eliminateRegSequence(
1992 for (
unsigned i = 1, e =
MI.getNumOperands(); i < e; i += 2)
1994 if (LIS->hasInterval(DstReg)) {
1995 DefVN = LIS->getInterval(DstReg)
1996 .Query(LIS->getInstructionIndex(
MI))
2002 bool DefEmitted =
false;
2003 for (
unsigned i = 1, e =
MI.getNumOperands(); i < e; i += 2) {
2006 unsigned SubIdx =
MI.getOperand(i+1).getImm();
2009 UndefLanes |=
TRI->getSubRegIndexLaneMask(SubIdx);
2015 bool isKill = UseMO.
isKill();
2017 for (
unsigned j = i + 2;
j <
e;
j += 2)
2018 if (
MI.getOperand(j).getReg() == SrcReg) {
2019 MI.getOperand(j).setIsKill();
2027 TII->get(TargetOpcode::COPY))
2042 LV->replaceKillInstruction(SrcReg,
MI, *CopyMI);
2052 MI.setDesc(
TII->get(TargetOpcode::IMPLICIT_DEF));
2053 for (
int j =
MI.getNumOperands() - 1, ee = 0; j > ee; --j)
2054 MI.removeOperand(j);
2060 if (UndefLanes.
any() && DefVN &&
MRI->shouldTrackSubRegLiveness(DstReg)) {
2061 auto &LI = LIS->getInterval(DstReg);
2071 if ((UndefLanes & LaneMask).
any())
2074 LIS->removeInterval(DstReg);
2076 LIS->RemoveMachineInstrFromMaps(
MI);
2080 MI.eraseFromParent();
2085 LIS->repairIntervalsInRange(
MBB,
MBBI, EndMBBI, OrigRegs);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator MBBI
BlockVerifier::State From
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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
Rewrite Partial Register Uses
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
modulo schedule Modulo Schedule test pass
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet 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)
static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg)
Return true if the specified MI uses the specified register as a two-address use.
static MCRegister getMappedReg(Register Reg, DenseMap< Register, Register > &RegMap)
Return the physical register the specified virtual register might be mapped to.
static cl::opt< bool > EnableRescheduling("twoaddr-reschedule", cl::desc("Coalesce copies by rescheduling (default=true)"), cl::init(true), cl::Hidden)
static cl::opt< unsigned > MaxDataFlowEdge("dataflow-edge-limit", cl::Hidden, cl::init(3), cl::desc("Maximum number of dataflow edges to traverse when evaluating " "the benefit of commuting operands"))
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
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 & addPreservedID(const void *ID)
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Allocate memory in an ever growing pool, as if by bump-pointer.
Represents analyses that only rely on functions' control flow.
iterator find(const_arg_type_t< KeyT > Val)
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
bool hasOptNone() const
Do not optimize this function (-O0).
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
Compute the instruction latency of a given instruction.
Itinerary data supplied by a subtarget to be used by a target.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
This class represents the liveness of a register, stack slot, etc.
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
VNInfo * createValueCopy(const VNInfo *orig, VNInfo::Allocator &VNInfoAllocator)
Create a copy of the given value.
bool hasAtLeastOneValue() const
VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
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.
Wrapper class representing physical registers. Should be passed by value.
An RAII based helper class to modify MachineFunctionProperties when running pass.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Analysis pass which computes a MachineDominatorTree.
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...
MachineFunctionProperties & set(Property P)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
void makeDebugValueSubstitution(DebugInstrOperandPair, DebugInstrOperandPair, unsigned SubReg=0)
Create a substitution between one <instr,operand> value to a different, new value.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
MachineInstrSpan provides an interface to get an iteration range containing the instruction it was in...
Representation of each machine instruction.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
bool isCall(QueryType Type=AnyInBundle) const
bool isSafeToMove(bool &SawStore) const
Return true if it is safe to move this instruction.
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
iterator_range< mop_iterator > operands()
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
unsigned getDebugInstrNum()
Fetch the instruction number of this MachineInstr.
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
unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
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.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
SlotIndex - An opaque wrapper around machine indexes.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
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...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
VNInfo - Value Number Information.
unsigned id
The ID number of this value.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
constexpr bool any(E Val)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
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
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
void initializeTwoAddressInstructionLegacyPassPass(PassRegistry &)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CodeGenOptLevel
Code generation optimization level.
char & TwoAddressInstructionPassID
TwoAddressInstruction - This pass reduces two-address instructions to use two operands.
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
static constexpr LaneBitmask getAll()
constexpr bool none() const
constexpr bool any() const
static constexpr LaneBitmask getNone()
This represents a simple continuous liveness interval for a value.
VarInfo - This represents the regions where a virtual register is live in the program.
std::vector< MachineInstr * > Kills
Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...
SparseBitVector AliveBlocks
AliveBlocks - Set of blocks in which this value is alive completely through.