80#define DEBUG_TYPE "machine-cp"
82STATISTIC(NumDeletes,
"Number of dead copies deleted");
83STATISTIC(NumCopyForwards,
"Number of copy uses forwarded");
84STATISTIC(NumCopyBackwardPropagated,
"Number of copy defs backward propagated");
85STATISTIC(SpillageChainsLength,
"Length of spillage chains");
86STATISTIC(NumSpillageChains,
"Number of spillage chains");
88 "Controls which register COPYs are forwarded");
97static std::optional<DestSourcePair> isCopyInstr(
const MachineInstr &
MI,
101 return TII.isCopyInstr(
MI);
104 return std::optional<DestSourcePair>(
135 BitVector &PreservedRegUnits = It->second;
137 PreservedRegUnits.
resize(
TRI.getNumRegUnits());
138 for (
unsigned SafeReg = 0, E =
TRI.getNumRegs(); SafeReg < E; ++SafeReg)
140 for (
auto SafeUnit :
TRI.regunits(SafeReg))
141 PreservedRegUnits.
set(SafeUnit);
143 return PreservedRegUnits;
154 auto CI =
Copies.find(Unit);
156 CI->second.Avail =
false;
170 std::optional<DestSourcePair> CopyOperands =
171 isCopyInstr(*
MI,
TII, UseCopyInstr);
172 assert(CopyOperands &&
"Expect copy");
174 auto Dest =
TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
175 auto Src =
TRI.regunits(CopyOperands->Source->getReg().asMCReg());
189 for (
MCRegUnit Unit : RegUnitsToInvalidate)
200 markRegsUnavailable(
I->second.DefRegs,
TRI);
204 std::optional<DestSourcePair> CopyOperands =
205 isCopyInstr(*
MI,
TII, UseCopyInstr);
207 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
208 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
210 markRegsUnavailable(Def,
TRI);
225 auto SrcCopy =
Copies.find(SrcUnit);
226 if (SrcCopy !=
Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
229 for (
auto itr = SrcCopy->second.DefRegs.begin();
230 itr != SrcCopy->second.DefRegs.end(); itr++) {
232 SrcCopy->second.DefRegs.erase(itr);
238 if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
256 clobberRegUnit(Unit,
TRI,
TII, UseCopyInstr);
271 std::optional<DestSourcePair> CopyOperands =
272 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
273 Register Src = CopyOperands->Source->getReg();
283 I->second.SrcUsers.insert(&
MI);
294 return I->second.SrcUsers;
300 std::optional<DestSourcePair> CopyOperands =
301 isCopyInstr(*
MI,
TII, UseCopyInstr);
302 assert(CopyOperands &&
"Tracking non-copy?");
304 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
305 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
309 Copies[Unit] = {
MI,
nullptr, {}, {},
true};
316 Copy.DefRegs.push_back(Def);
317 Copy.LastSeenUseInCopy =
MI;
321 bool hasAnyCopies() {
327 bool MustBeAvailable =
false) {
328 auto CI =
Copies.find(RegUnit);
331 if (MustBeAvailable && !CI->second.Avail)
333 return CI->second.MI;
338 auto CI =
Copies.find(RegUnit);
341 if (CI->second.DefRegs.size() != 1)
343 MCRegUnit RU = *
TRI.regunits(CI->second.DefRegs[0]).begin();
344 return findCopyForUnit(RU,
TRI,
true);
357 std::optional<DestSourcePair> CopyOperands =
358 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
359 Register AvailSrc = CopyOperands->Source->getReg();
360 Register AvailDef = CopyOperands->Destination->getReg();
361 if (!
TRI.isSubRegisterEq(AvailSrc, Reg))
369 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
382 findCopyForUnit(RU,
TRI,
true);
387 std::optional<DestSourcePair> CopyOperands =
388 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
389 Register AvailSrc = CopyOperands->Source->getReg();
390 Register AvailDef = CopyOperands->Destination->getReg();
391 if (!
TRI.isSubRegisterEq(AvailDef, Reg))
400 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
413 auto CI =
Copies.find(RU);
414 if (CI ==
Copies.end() || !CI->second.Avail)
418 std::optional<DestSourcePair> CopyOperands =
419 isCopyInstr(*DefCopy,
TII, UseCopyInstr);
420 Register Def = CopyOperands->Destination->getReg();
421 if (!
TRI.isSubRegisterEq(Def, Reg))
429 if (MO.clobbersPhysReg(Def)) {
442 auto CI =
Copies.find(RU);
445 return CI->second.LastSeenUseInCopy;
453class MachineCopyPropagation {
462 MachineCopyPropagation(
bool CopyInstr =
false)
468 typedef enum { DebugUse =
false, RegularUse =
true }
DebugType;
478 bool isForwardableRegClassCopy(
const MachineInstr &Copy,
480 bool isBackwardPropagatableRegClassCopy(
const MachineInstr &Copy,
497 bool Changed =
false;
506 MachineCopyPropagationLegacy(
bool UseCopyInstr =
false)
523char MachineCopyPropagationLegacy::ID = 0;
528 "Machine Copy Propagation Pass",
false,
false)
537 if (DT == RegularUse) {
538 LLVM_DEBUG(
dbgs() <<
"MCP: Copy is used - not dead: "; Copy->dump());
539 MaybeDeadCopies.remove(Copy);
541 CopyDbgUsers[Copy].insert(&Reader);
547void MachineCopyPropagation::readSuccessorLiveIns(
549 if (MaybeDeadCopies.empty())
554 for (
const auto &LI : Succ->liveins()) {
556 auto [Unit,
Mask] = *
U;
557 if ((Mask & LI.LaneMask).any()) {
559 MaybeDeadCopies.remove(Copy);
576 std::optional<DestSourcePair> CopyOperands =
577 isCopyInstr(PreviousCopy, *
TII, UseCopyInstr);
578 MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
579 MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
580 if (Src == PreviousSrc && Def == PreviousDef)
582 if (!
TRI->isSubRegister(PreviousSrc, Src))
584 unsigned SubIdx =
TRI->getSubRegIndex(PreviousSrc, Src);
585 return SubIdx ==
TRI->getSubRegIndex(PreviousDef, Def);
591bool MachineCopyPropagation::eraseIfRedundant(
MachineInstr &Copy,
595 if (
MRI->isReserved(Src) ||
MRI->isReserved(Def))
600 Tracker.findAvailCopy(Copy, Def, *
TRI, *
TII, UseCopyInstr);
604 auto PrevCopyOperands = isCopyInstr(*PrevCopy, *
TII, UseCopyInstr);
606 if (PrevCopyOperands->Destination->isDead())
615 std::optional<DestSourcePair> CopyOperands =
616 isCopyInstr(Copy, *
TII, UseCopyInstr);
619 Register CopyDef = CopyOperands->Destination->getReg();
620 assert(CopyDef == Src || CopyDef == Def);
623 MI.clearRegisterKills(CopyDef,
TRI);
626 if (!CopyOperands->Source->isUndef()) {
627 PrevCopy->
getOperand(PrevCopyOperands->Source->getOperandNo())
631 Copy.eraseFromParent();
637bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
639 std::optional<DestSourcePair> CopyOperands =
640 isCopyInstr(Copy, *
TII, UseCopyInstr);
641 Register Def = CopyOperands->Destination->getReg();
645 return URC->contains(Def);
655bool MachineCopyPropagation::isForwardableRegClassCopy(
const MachineInstr &Copy,
658 std::optional<DestSourcePair> CopyOperands =
659 isCopyInstr(Copy, *
TII, UseCopyInstr);
660 Register CopySrcReg = CopyOperands->Source->getReg();
666 return URC->contains(CopySrcReg);
668 auto UseICopyOperands = isCopyInstr(UseI, *
TII, UseCopyInstr);
669 if (!UseICopyOperands)
692 Register UseDstReg = UseICopyOperands->Destination->getReg();
694 bool IsCrossClass =
false;
696 if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
698 if (
TRI->getCrossCopyRegClass(RC) != RC) {
710 Register CopyDstReg = CopyOperands->Destination->getReg();
712 if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
713 TRI->getCrossCopyRegClass(RC) != RC)
727bool MachineCopyPropagation::hasImplicitOverlap(
const MachineInstr &
MI,
730 if (&MIUse != &
Use && MIUse.isReg() && MIUse.isImplicit() &&
731 MIUse.isUse() &&
TRI->regsOverlap(
Use.getReg(), MIUse.getReg()))
741bool MachineCopyPropagation::hasOverlappingMultipleDef(
744 if ((&MIDef != &MODef) && MIDef.isReg() &&
745 TRI->regsOverlap(Def, MIDef.getReg()))
754bool MachineCopyPropagation::canUpdateSrcUsers(
const MachineInstr &Copy,
756 assert(CopySrc.
isReg() &&
"Expected a register operand");
757 for (
auto *SrcUser : Tracker.getSrcUsers(CopySrc.
getReg(), *
TRI)) {
758 if (hasImplicitOverlap(*SrcUser, CopySrc))
762 if (!MO.isReg() || !MO.isUse() || MO.getReg() != CopySrc.
getReg())
764 if (MO.isTied() || !MO.isRenamable() ||
765 !isBackwardPropagatableRegClassCopy(Copy, *SrcUser,
776 if (!Tracker.hasAnyCopies())
782 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands();
OpIdx < OpEnd;
804 *
TRI, *
TII, UseCopyInstr);
808 std::optional<DestSourcePair> CopyOperands =
809 isCopyInstr(*Copy, *
TII, UseCopyInstr);
810 Register CopyDstReg = CopyOperands->Destination->getReg();
817 if (MOUse.
getReg() != CopyDstReg) {
818 unsigned SubRegIdx =
TRI->getSubRegIndex(CopyDstReg, MOUse.
getReg());
820 "MI source is not a sub-register of Copy destination");
821 ForwardedReg =
TRI->getSubReg(CopySrcReg, SubRegIdx);
823 LLVM_DEBUG(
dbgs() <<
"MCP: Copy source does not have sub-register "
824 <<
TRI->getSubRegIndexName(SubRegIdx) <<
'\n');
830 if (
MRI->isReserved(CopySrcReg) && !
MRI->isConstantPhysReg(CopySrcReg))
833 if (!isForwardableRegClassCopy(*Copy,
MI,
OpIdx))
836 if (hasImplicitOverlap(
MI, MOUse))
842 if (isCopyInstr(
MI, *
TII, UseCopyInstr) &&
843 MI.modifiesRegister(CopySrcReg,
TRI) &&
844 !
MI.definesRegister(CopySrcReg,
nullptr)) {
850 LLVM_DEBUG(
dbgs() <<
"MCP: Skipping forwarding due to debug counter:\n "
857 <<
"\n in " <<
MI <<
" from " << *Copy);
859 MOUse.
setReg(ForwardedReg);
870 KMI.clearRegisterKills(CopySrcReg,
TRI);
883 std::optional<DestSourcePair> CopyOperands =
884 isCopyInstr(
MI, *
TII, UseCopyInstr);
886 Register RegSrc = CopyOperands->Source->getReg();
887 Register RegDef = CopyOperands->Destination->getReg();
888 if (!
TRI->regsOverlap(RegDef, RegSrc)) {
890 "MachineCopyPropagation should be run after register allocation!");
910 if (eraseIfRedundant(
MI, Def, Src) || eraseIfRedundant(
MI, Src, Def))
917 if (MO.isReg() && MO.isEarlyClobber()) {
923 ReadRegister(Reg,
MI, RegularUse);
924 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
931 if (
TII->simplifyInstruction(
MI)) {
936 CopyOperands = isCopyInstr(
MI, *
TII, UseCopyInstr);
938 Register RegSrc = CopyOperands->Source->getReg();
939 Register RegDef = CopyOperands->Destination->getReg();
944 if (RegSrc == RegDef && !
MRI->isReserved(RegSrc)) {
945 MI.eraseFromParent();
951 if (!
TRI->regsOverlap(RegDef, RegSrc)) {
954 if (!
MRI->isReserved(Def))
955 MaybeDeadCopies.insert(&
MI);
971 "MachineCopyPropagation should be run after register allocation!");
973 if (MO.isDef() && !MO.isEarlyClobber()) {
975 if (!
MRI->isConstantPhysReg(Reg)) {
979 }
else if (MO.readsReg())
980 ReadRegister(
Reg.asMCReg(),
MI, MO.isDebug() ? DebugUse : RegularUse);
988 Tracker.getPreservedRegUnits(*RegMask, *
TRI);
992 MaybeDeadCopies.
begin();
993 DI != MaybeDeadCopies.end();) {
995 std::optional<DestSourcePair> CopyOperands =
996 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
997 MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
1007 bool MIRefedinCopyInfo =
false;
1008 for (
unsigned RegUnit :
TRI->regunits(Reg)) {
1009 if (!PreservedRegUnits.
test(RegUnit))
1010 Tracker.clobberRegUnit(RegUnit, *
TRI, *
TII, UseCopyInstr);
1012 if (MaybeDead == Tracker.findCopyForUnit(RegUnit, *
TRI)) {
1013 MIRefedinCopyInfo =
true;
1020 DI = MaybeDeadCopies.erase(DI);
1023 if (MIRefedinCopyInfo)
1026 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to regmask clobbering: "
1037 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1040 Register RegSrc = CopyOperands->Source->getReg();
1041 Register RegDef = CopyOperands->Destination->getReg();
1042 if (!
TRI->regsOverlap(RegDef, RegSrc)) {
1043 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1048 bool TracksLiveness =
MRI->tracksLiveness();
1053 readSuccessorLiveIns(
MBB);
1060 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to no live-out succ: ";
1063 std::optional<DestSourcePair> CopyOperands =
1064 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
1067 Register SrcReg = CopyOperands->Source->getReg();
1068 Register DestReg = CopyOperands->Destination->getReg();
1072 const auto &DbgUsers = CopyDbgUsers[MaybeDead];
1084 MaybeDeadCopies.clear();
1085 CopyDbgUsers.clear();
1097 if (
MRI.isReserved(Def) ||
MRI.isReserved(Src))
1104 if (!Tracker.hasAnyCopies())
1107 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands();
OpIdx != OpEnd;
1130 std::optional<DestSourcePair> CopyOperands =
1131 isCopyInstr(*Copy, *
TII, UseCopyInstr);
1132 Register Def = CopyOperands->Destination->getReg();
1133 Register Src = CopyOperands->Source->getReg();
1135 if (MODef.
getReg() != Src)
1138 if (!isBackwardPropagatableRegClassCopy(*Copy,
MI,
OpIdx))
1141 if (hasImplicitOverlap(
MI, MODef))
1144 if (hasOverlappingMultipleDef(
MI, MODef, Def))
1147 if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
1152 <<
MI <<
" from " << *Copy);
1157 for (
auto *SrcUser : Tracker.getSrcUsers(Src, *
TRI)) {
1159 if (!MO.isReg() || !MO.isUse() || MO.getReg() != Src)
1162 MO.setIsRenamable(CopyOperands->Destination->isRenamable());
1167 MaybeDeadCopies.insert(Copy);
1169 ++NumCopyBackwardPropagated;
1173void MachineCopyPropagation::BackwardCopyPropagateBlock(
1180 std::optional<DestSourcePair> CopyOperands =
1181 isCopyInstr(
MI, *
TII, UseCopyInstr);
1182 if (CopyOperands &&
MI.getNumImplicitOperands() == 0) {
1183 Register DefReg = CopyOperands->Destination->getReg();
1184 Register SrcReg = CopyOperands->Source->getReg();
1186 if (!
TRI->regsOverlap(DefReg, SrcReg)) {
1194 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1202 if (MO.isReg() && MO.isEarlyClobber()) {
1206 Tracker.invalidateRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1218 Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
1221 if (MO.readsReg()) {
1226 for (
MCRegUnit Unit :
TRI->regunits(MO.getReg().asMCReg())) {
1227 if (
auto *Copy = Tracker.findCopyDefViaUnit(Unit, *
TRI)) {
1228 CopyDbgUsers[
Copy].insert(&
MI);
1231 }
else if (!Tracker.trackSrcUsers(MO.getReg().asMCReg(),
MI, *
TRI, *
TII,
1234 Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
1241 for (
auto *Copy : MaybeDeadCopies) {
1242 std::optional<DestSourcePair> CopyOperands =
1243 isCopyInstr(*Copy, *
TII, UseCopyInstr);
1244 Register Src = CopyOperands->Source->getReg();
1245 Register Def = CopyOperands->Destination->getReg();
1246 const auto &DbgUsers = CopyDbgUsers[
Copy];
1250 MRI->updateDbgUsersToReg(Src.asMCReg(),
Def.asMCReg(), MaybeDeadDbgUsers);
1251 Copy->eraseFromParent();
1255 MaybeDeadCopies.clear();
1256 CopyDbgUsers.clear();
1264 auto &SC = SpillChain[Leader];
1265 auto &RC = ReloadChain[Leader];
1266 for (
auto I = SC.rbegin(), E = SC.rend();
I != E; ++
I)
1323 auto TryFoldSpillageCopies =
1326 assert(SC.
size() == RC.size() &&
"Spill-reload should be paired");
1342 if (CopySourceInvalid.
count(Spill))
1346 if (CopySourceInvalid.
count(Reload))
1351 if (RC->contains(Def) && RC->contains(Src))
1361 MO.setReg(
New->getReg());
1365 std::optional<DestSourcePair> InnerMostSpillCopy =
1366 isCopyInstr(*SC[0], *
TII, UseCopyInstr);
1367 std::optional<DestSourcePair> OuterMostSpillCopy =
1368 isCopyInstr(*SC.
back(), *
TII, UseCopyInstr);
1369 std::optional<DestSourcePair> InnerMostReloadCopy =
1370 isCopyInstr(*RC[0], *
TII, UseCopyInstr);
1371 std::optional<DestSourcePair> OuterMostReloadCopy =
1372 isCopyInstr(*RC.back(), *
TII, UseCopyInstr);
1373 if (!CheckCopyConstraint(OuterMostSpillCopy->Source->getReg(),
1374 InnerMostSpillCopy->Source->getReg()) ||
1375 !CheckCopyConstraint(InnerMostReloadCopy->Destination->getReg(),
1376 OuterMostReloadCopy->Destination->getReg()))
1379 SpillageChainsLength += SC.
size() + RC.size();
1380 NumSpillageChains += 1;
1381 UpdateReg(SC[0], InnerMostSpillCopy->Destination,
1382 OuterMostSpillCopy->Source);
1383 UpdateReg(RC[0], InnerMostReloadCopy->Source,
1384 OuterMostReloadCopy->Destination);
1386 for (
size_t I = 1;
I < SC.
size() - 1; ++
I) {
1387 SC[
I]->eraseFromParent();
1388 RC[
I]->eraseFromParent();
1393 auto IsFoldableCopy = [
this](
const MachineInstr &MaybeCopy) {
1394 if (MaybeCopy.getNumImplicitOperands() > 0)
1396 std::optional<DestSourcePair> CopyOperands =
1397 isCopyInstr(MaybeCopy, *
TII, UseCopyInstr);
1400 Register Src = CopyOperands->Source->getReg();
1401 Register Def = CopyOperands->Destination->getReg();
1402 return Src &&
Def && !
TRI->regsOverlap(Src, Def) &&
1403 CopyOperands->Source->isRenamable() &&
1404 CopyOperands->Destination->isRenamable();
1409 if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
1411 std::optional<DestSourcePair> SpillCopy =
1412 isCopyInstr(Spill, *
TII, UseCopyInstr);
1413 std::optional<DestSourcePair> ReloadCopy =
1414 isCopyInstr(Reload, *
TII, UseCopyInstr);
1415 if (!SpillCopy || !ReloadCopy)
1417 return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
1418 SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
1421 auto IsChainedCopy = [&,
this](
const MachineInstr &Prev,
1423 if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
1425 std::optional<DestSourcePair> PrevCopy =
1426 isCopyInstr(Prev, *
TII, UseCopyInstr);
1427 std::optional<DestSourcePair> CurrentCopy =
1428 isCopyInstr(Current, *
TII, UseCopyInstr);
1429 if (!PrevCopy || !CurrentCopy)
1431 return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
1435 std::optional<DestSourcePair> CopyOperands =
1436 isCopyInstr(
MI, *
TII, UseCopyInstr);
1440 if (!CopyOperands) {
1448 Tracker.findLastSeenUseInCopy(
Reg.asMCReg(), *
TRI);
1454 CopySourceInvalid.
insert(LastUseCopy);
1462 if (Tracker.findLastSeenDefInCopy(
MI,
Reg.asMCReg(), *
TRI, *
TII,
1465 RegsToClobber.
insert(Reg);
1467 for (
Register Reg : RegsToClobber) {
1468 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1475 Register Src = CopyOperands->Source->getReg();
1476 Register Def = CopyOperands->Destination->getReg();
1478 LLVM_DEBUG(
dbgs() <<
"MCP: Searching paired spill for reload: ");
1481 Tracker.findLastSeenDefInCopy(
MI, Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
1482 bool MaybeSpillIsChained = ChainLeader.
count(MaybeSpill);
1483 if (!MaybeSpillIsChained && MaybeSpill &&
1484 IsSpillReloadPair(*MaybeSpill,
MI)) {
1520 Tracker.findLastSeenUseInCopy(
Def.asMCReg(), *
TRI);
1521 auto Leader = ChainLeader.
find(MaybePrevReload);
1523 if (Leader == ChainLeader.
end() ||
1524 (MaybePrevReload && !IsChainedCopy(*MaybePrevReload,
MI))) {
1527 "SpillChain should not have contained newly found chain");
1529 assert(MaybePrevReload &&
1530 "Found a valid leader through nullptr should not happend");
1533 "Existing chain's length should be larger than zero");
1536 "Newly found paired spill-reload should not belong to any chain "
1538 ChainLeader.
insert({MaybeSpill,
L});
1540 SpillChain[
L].push_back(MaybeSpill);
1541 ReloadChain[
L].push_back(&
MI);
1544 }
else if (MaybeSpill && !MaybeSpillIsChained) {
1561 Tracker.clobberRegister(Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
1565 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1568 for (
auto I = SpillChain.
begin(), E = SpillChain.
end();
I != E; ++
I) {
1569 auto &SC =
I->second;
1571 "Reload chain of the same leader should exist");
1572 auto &RC = ReloadChain[
I->first];
1573 TryFoldSpillageCopies(SC, RC);
1576 MaybeDeadCopies.clear();
1577 CopyDbgUsers.clear();
1581bool MachineCopyPropagationLegacy::runOnMachineFunction(
MachineFunction &MF) {
1585 return MachineCopyPropagation(UseCopyInstr).run(MF);
1592 if (!MachineCopyPropagation(UseCopyInstr).
run(MF))
1600 bool isSpillageCopyElimEnabled =
false;
1603 isSpillageCopyElimEnabled =
1607 isSpillageCopyElimEnabled =
true;
1610 isSpillageCopyElimEnabled =
false;
1621 if (isSpillageCopyElimEnabled)
1622 EliminateSpillageCopies(
MBB);
1623 BackwardCopyPropagateBlock(
MBB);
1624 ForwardCopyPropagateBlock(
MBB);
1632 return new MachineCopyPropagationLegacy(UseCopyInstr);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ATTRIBUTE_UNUSED
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static cl::opt< cl::boolOrDefault > EnableSpillageCopyElimination("enable-spill-copy-elim", cl::Hidden)
static void LLVM_ATTRIBUTE_UNUSED printSpillReloadChain(DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &SpillChain, DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &ReloadChain, MachineInstr *Leader)
static bool isBackwardPropagatableCopy(const DestSourcePair &CopyOperands, const MachineRegisterInfo &MRI)
static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src, MCRegister Def, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, bool UseCopyInstr)
Return true if PreviousCopy did copy register Src to register Def.
static cl::opt< bool > MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false), cl::Hidden)
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
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)
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Represents analyses that only rely on functions' control flow.
static bool shouldExecute(unsigned CounterName)
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
MCRegUnitMaskIterator enumerates a list of register units and their associated lane masks for Reg.
Wrapper class representing physical registers. Should be passed by value.
An RAII based helper class to modify MachineFunctionProperties when running pass.
iterator_range< succ_iterator > successors()
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
LLVM_ABI bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
iterator begin()
Get an iterator to the beginning of the SetVector.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void insert_range(Range &&R)
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool enableSpillageCopyElimination() const
Enable spillage copy elimination in MachineCopyPropagation pass.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
LLVM_ABI 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.
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
const MachineOperand * Source
const MachineOperand * Destination