79#define DEBUG_TYPE "machine-cp"
81STATISTIC(NumDeletes,
"Number of dead copies deleted");
82STATISTIC(NumCopyForwards,
"Number of copy uses forwarded");
83STATISTIC(NumCopyBackwardPropagated,
"Number of copy defs backward propagated");
84STATISTIC(SpillageChainsLength,
"Length of spillage chains");
85STATISTIC(NumSpillageChains,
"Number of spillage chains");
87 "Controls which register COPYs are forwarded");
96static std::optional<DestSourcePair> isCopyInstr(
const MachineInstr &
MI,
100 return TII.isCopyInstr(
MI);
103 return std::optional<DestSourcePair>(
128 auto CI =
Copies.find(Unit);
130 CI->second.Avail =
false;
144 std::optional<DestSourcePair> CopyOperands =
145 isCopyInstr(*
MI,
TII, UseCopyInstr);
146 assert(CopyOperands &&
"Expect copy");
148 auto Dest =
TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
149 auto Src =
TRI.regunits(CopyOperands->Source->getReg().asMCReg());
150 RegUnitsToInvalidate.
insert(Dest.begin(), Dest.end());
151 RegUnitsToInvalidate.
insert(Src.begin(), Src.end());
163 for (
MCRegUnit Unit : RegUnitsToInvalidate)
175 markRegsUnavailable(
I->second.DefRegs,
TRI);
179 std::optional<DestSourcePair> CopyOperands =
180 isCopyInstr(*
MI,
TII, UseCopyInstr);
182 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
183 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
185 markRegsUnavailable(Def,
TRI);
200 auto SrcCopy =
Copies.find(SrcUnit);
201 if (SrcCopy !=
Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
204 for (
auto itr = SrcCopy->second.DefRegs.begin();
205 itr != SrcCopy->second.DefRegs.end(); itr++) {
207 SrcCopy->second.DefRegs.erase(itr);
213 if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
239 std::optional<DestSourcePair> CopyOperands =
240 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
241 Register Src = CopyOperands->Source->getReg();
251 I->second.SrcUsers.insert(&
MI);
262 return I->second.SrcUsers;
268 std::optional<DestSourcePair> CopyOperands =
269 isCopyInstr(*
MI,
TII, UseCopyInstr);
270 assert(CopyOperands &&
"Tracking non-copy?");
272 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
273 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
277 Copies[Unit] = {
MI,
nullptr, {}, {},
true};
284 Copy.DefRegs.push_back(Def);
285 Copy.LastSeenUseInCopy =
MI;
289 bool hasAnyCopies() {
295 bool MustBeAvailable =
false) {
296 auto CI =
Copies.find(RegUnit);
299 if (MustBeAvailable && !CI->second.Avail)
301 return CI->second.MI;
306 auto CI =
Copies.find(RegUnit);
309 if (CI->second.DefRegs.size() != 1)
311 MCRegUnit RU = *
TRI.regunits(CI->second.DefRegs[0]).begin();
312 return findCopyForUnit(RU,
TRI,
true);
325 std::optional<DestSourcePair> CopyOperands =
326 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
327 Register AvailSrc = CopyOperands->Source->getReg();
328 Register AvailDef = CopyOperands->Destination->getReg();
329 if (!
TRI.isSubRegisterEq(AvailSrc, Reg))
337 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
350 findCopyForUnit(RU,
TRI,
true);
355 std::optional<DestSourcePair> CopyOperands =
356 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
357 Register AvailSrc = CopyOperands->Source->getReg();
358 Register AvailDef = CopyOperands->Destination->getReg();
359 if (!
TRI.isSubRegisterEq(AvailDef, Reg))
368 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
381 auto CI =
Copies.find(RU);
382 if (CI ==
Copies.end() || !CI->second.Avail)
386 std::optional<DestSourcePair> CopyOperands =
387 isCopyInstr(*DefCopy,
TII, UseCopyInstr);
388 Register Def = CopyOperands->Destination->getReg();
389 if (!
TRI.isSubRegisterEq(Def, Reg))
397 if (MO.clobbersPhysReg(Def)) {
410 auto CI =
Copies.find(RU);
413 return CI->second.LastSeenUseInCopy;
432 MachineCopyPropagation(
bool CopyInstr =
false)
446 MachineFunctionProperties::Property::NoVRegs);
450 typedef enum { DebugUse =
false, RegularUse =
true }
DebugType;
460 bool isForwardableRegClassCopy(
const MachineInstr &Copy,
462 bool isBackwardPropagatableRegClassCopy(
const MachineInstr &Copy,
479 bool Changed =
false;
484char MachineCopyPropagation::ID = 0;
489 "Machine Copy Propagation Pass",
false,
false)
498 if (DT == RegularUse) {
499 LLVM_DEBUG(
dbgs() <<
"MCP: Copy is used - not dead: "; Copy->dump());
500 MaybeDeadCopies.remove(Copy);
502 CopyDbgUsers[Copy].insert(&Reader);
508void MachineCopyPropagation::readSuccessorLiveIns(
510 if (MaybeDeadCopies.empty())
515 for (
const auto &LI : Succ->liveins()) {
518 MaybeDeadCopies.remove(Copy);
534 std::optional<DestSourcePair> CopyOperands =
535 isCopyInstr(PreviousCopy, *
TII, UseCopyInstr);
536 MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
537 MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
538 if (Src == PreviousSrc && Def == PreviousDef)
540 if (!
TRI->isSubRegister(PreviousSrc, Src))
542 unsigned SubIdx =
TRI->getSubRegIndex(PreviousSrc, Src);
543 return SubIdx ==
TRI->getSubRegIndex(PreviousDef, Def);
549bool MachineCopyPropagation::eraseIfRedundant(
MachineInstr &Copy,
553 if (
MRI->isReserved(Src) ||
MRI->isReserved(Def))
558 Tracker.findAvailCopy(Copy, Def, *
TRI, *
TII, UseCopyInstr);
562 auto PrevCopyOperands = isCopyInstr(*PrevCopy, *
TII, UseCopyInstr);
564 if (PrevCopyOperands->Destination->isDead())
573 std::optional<DestSourcePair> CopyOperands =
574 isCopyInstr(Copy, *
TII, UseCopyInstr);
577 Register CopyDef = CopyOperands->Destination->getReg();
578 assert(CopyDef == Src || CopyDef == Def);
581 MI.clearRegisterKills(CopyDef,
TRI);
584 if (!CopyOperands->Source->isUndef()) {
585 PrevCopy->
getOperand(PrevCopyOperands->Source->getOperandNo())
589 Copy.eraseFromParent();
595bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
597 std::optional<DestSourcePair> CopyOperands =
598 isCopyInstr(Copy, *
TII, UseCopyInstr);
599 Register Def = CopyOperands->Destination->getReg();
603 return URC->contains(Def);
613bool MachineCopyPropagation::isForwardableRegClassCopy(
const MachineInstr &Copy,
616 std::optional<DestSourcePair> CopyOperands =
617 isCopyInstr(Copy, *
TII, UseCopyInstr);
618 Register CopySrcReg = CopyOperands->Source->getReg();
624 return URC->contains(CopySrcReg);
626 auto UseICopyOperands = isCopyInstr(UseI, *
TII, UseCopyInstr);
627 if (!UseICopyOperands)
650 Register UseDstReg = UseICopyOperands->Destination->getReg();
652 bool IsCrossClass =
false;
654 if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
656 if (
TRI->getCrossCopyRegClass(RC) != RC) {
668 Register CopyDstReg = CopyOperands->Destination->getReg();
670 if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
671 TRI->getCrossCopyRegClass(RC) != RC)
685bool MachineCopyPropagation::hasImplicitOverlap(
const MachineInstr &
MI,
688 if (&MIUse != &
Use && MIUse.isReg() && MIUse.isImplicit() &&
689 MIUse.isUse() &&
TRI->regsOverlap(
Use.getReg(), MIUse.getReg()))
699bool MachineCopyPropagation::hasOverlappingMultipleDef(
702 if ((&MIDef != &MODef) && MIDef.isReg() &&
703 TRI->regsOverlap(Def, MIDef.getReg()))
712bool MachineCopyPropagation::canUpdateSrcUsers(
const MachineInstr &Copy,
714 assert(CopySrc.
isReg() &&
"Expected a register operand");
715 for (
auto *SrcUser : Tracker.getSrcUsers(CopySrc.
getReg(), *
TRI)) {
716 if (hasImplicitOverlap(*SrcUser, CopySrc))
720 if (!MO.isReg() || !MO.isUse() || MO.getReg() != CopySrc.
getReg())
722 if (MO.isTied() || !MO.isRenamable() ||
723 !isBackwardPropagatableRegClassCopy(Copy, *SrcUser,
734 if (!Tracker.hasAnyCopies())
740 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands(); OpIdx < OpEnd;
762 *
TRI, *
TII, UseCopyInstr);
766 std::optional<DestSourcePair> CopyOperands =
767 isCopyInstr(*Copy, *
TII, UseCopyInstr);
768 Register CopyDstReg = CopyOperands->Destination->getReg();
775 if (MOUse.
getReg() != CopyDstReg) {
776 unsigned SubRegIdx =
TRI->getSubRegIndex(CopyDstReg, MOUse.
getReg());
778 "MI source is not a sub-register of Copy destination");
779 ForwardedReg =
TRI->getSubReg(CopySrcReg, SubRegIdx);
781 LLVM_DEBUG(
dbgs() <<
"MCP: Copy source does not have sub-register "
782 <<
TRI->getSubRegIndexName(SubRegIdx) <<
'\n');
788 if (
MRI->isReserved(CopySrcReg) && !
MRI->isConstantPhysReg(CopySrcReg))
791 if (!isForwardableRegClassCopy(*Copy,
MI, OpIdx))
794 if (hasImplicitOverlap(
MI, MOUse))
800 if (isCopyInstr(
MI, *
TII, UseCopyInstr) &&
801 MI.modifiesRegister(CopySrcReg,
TRI) &&
802 !
MI.definesRegister(CopySrcReg,
nullptr)) {
808 LLVM_DEBUG(
dbgs() <<
"MCP: Skipping forwarding due to debug counter:\n "
815 <<
"\n in " <<
MI <<
" from " << *Copy);
817 MOUse.
setReg(ForwardedReg);
828 KMI.clearRegisterKills(CopySrcReg,
TRI);
841 std::optional<DestSourcePair> CopyOperands =
842 isCopyInstr(
MI, *
TII, UseCopyInstr);
845 Register RegSrc = CopyOperands->Source->getReg();
846 Register RegDef = CopyOperands->Destination->getReg();
848 if (!
TRI->regsOverlap(RegDef, RegSrc)) {
850 "MachineCopyPropagation should be run after register allocation!");
870 if (eraseIfRedundant(
MI, Def, Src) || eraseIfRedundant(
MI, Src, Def))
876 CopyOperands = isCopyInstr(
MI, *
TII, UseCopyInstr);
877 Src = CopyOperands->Source->getReg().asMCReg();
881 ReadRegister(Src,
MI, RegularUse);
883 if (!MO.isReg() || !MO.readsReg())
888 ReadRegister(Reg,
MI, RegularUse);
894 if (!
MRI->isReserved(Def))
895 MaybeDeadCopies.insert(&
MI);
904 Tracker.clobberRegister(Def, *
TRI, *
TII, UseCopyInstr);
906 if (!MO.isReg() || !MO.isDef())
911 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
914 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
922 if (MO.isReg() && MO.isEarlyClobber()) {
928 ReadRegister(Reg,
MI, RegularUse);
929 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
947 "MachineCopyPropagation should be run after register allocation!");
949 if (MO.isDef() && !MO.isEarlyClobber()) {
951 if (!
MRI->isConstantPhysReg(Reg)) {
955 }
else if (MO.readsReg())
956 ReadRegister(
Reg.asMCReg(),
MI, MO.isDebug() ? DebugUse : RegularUse);
965 MaybeDeadCopies.
begin();
966 DI != MaybeDeadCopies.end();) {
968 std::optional<DestSourcePair> CopyOperands =
969 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
970 MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
978 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to regmask clobbering: ";
983 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
987 DI = MaybeDeadCopies.erase(DI);
996 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
999 bool TracksLiveness =
MRI->tracksLiveness();
1004 readSuccessorLiveIns(
MBB);
1011 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to no live-out succ: ";
1014 std::optional<DestSourcePair> CopyOperands =
1015 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
1018 Register SrcReg = CopyOperands->Source->getReg();
1019 Register DestReg = CopyOperands->Destination->getReg();
1024 CopyDbgUsers[MaybeDead].
begin(), CopyDbgUsers[MaybeDead].
end());
1034 MaybeDeadCopies.clear();
1035 CopyDbgUsers.clear();
1047 if (
MRI.isReserved(Def) ||
MRI.isReserved(Src))
1054 if (!Tracker.hasAnyCopies())
1057 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands(); OpIdx != OpEnd;
1080 std::optional<DestSourcePair> CopyOperands =
1081 isCopyInstr(*Copy, *
TII, UseCopyInstr);
1082 Register Def = CopyOperands->Destination->getReg();
1083 Register Src = CopyOperands->Source->getReg();
1085 if (MODef.
getReg() != Src)
1088 if (!isBackwardPropagatableRegClassCopy(*Copy,
MI, OpIdx))
1091 if (hasImplicitOverlap(
MI, MODef))
1094 if (hasOverlappingMultipleDef(
MI, MODef, Def))
1097 if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
1102 <<
MI <<
" from " << *Copy);
1107 for (
auto *SrcUser : Tracker.getSrcUsers(Src, *
TRI)) {
1109 if (!MO.isReg() || !MO.isUse() || MO.getReg() != Src)
1112 MO.setIsRenamable(CopyOperands->Destination->isRenamable());
1117 MaybeDeadCopies.insert(Copy);
1119 ++NumCopyBackwardPropagated;
1123void MachineCopyPropagation::BackwardCopyPropagateBlock(
1130 std::optional<DestSourcePair> CopyOperands =
1131 isCopyInstr(
MI, *
TII, UseCopyInstr);
1133 Register DefReg = CopyOperands->Destination->getReg();
1134 Register SrcReg = CopyOperands->Source->getReg();
1136 if (!
TRI->regsOverlap(DefReg, SrcReg)) {
1144 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1152 if (MO.isReg() && MO.isEarlyClobber()) {
1156 Tracker.invalidateRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1168 Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
1171 if (MO.readsReg()) {
1176 for (
MCRegUnit Unit :
TRI->regunits(MO.getReg().asMCReg())) {
1177 if (
auto *Copy = Tracker.findCopyDefViaUnit(Unit, *
TRI)) {
1178 CopyDbgUsers[
Copy].insert(&
MI);
1181 }
else if (!Tracker.trackSrcUsers(MO.getReg().asMCReg(),
MI, *
TRI, *
TII,
1184 Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
1191 for (
auto *Copy : MaybeDeadCopies) {
1192 std::optional<DestSourcePair> CopyOperands =
1193 isCopyInstr(*Copy, *
TII, UseCopyInstr);
1194 Register Src = CopyOperands->Source->getReg();
1195 Register Def = CopyOperands->Destination->getReg();
1197 CopyDbgUsers[Copy].
end());
1199 MRI->updateDbgUsersToReg(Src.asMCReg(),
Def.asMCReg(), MaybeDeadDbgUsers);
1200 Copy->eraseFromParent();
1204 MaybeDeadCopies.clear();
1205 CopyDbgUsers.clear();
1213 auto &SC = SpillChain[Leader];
1214 auto &RC = ReloadChain[Leader];
1215 for (
auto I = SC.rbegin(), E = SC.rend();
I != E; ++
I)
1272 auto TryFoldSpillageCopies =
1275 assert(
SC.size() == RC.size() &&
"Spill-reload should be paired");
1291 if (CopySourceInvalid.
count(Spill))
1295 if (CopySourceInvalid.
count(Reload))
1300 if (RC->contains(Def) && RC->contains(Src))
1310 MO.setReg(
New->getReg());
1314 std::optional<DestSourcePair> InnerMostSpillCopy =
1315 isCopyInstr(*SC[0], *
TII, UseCopyInstr);
1316 std::optional<DestSourcePair> OuterMostSpillCopy =
1317 isCopyInstr(*
SC.back(), *
TII, UseCopyInstr);
1318 std::optional<DestSourcePair> InnerMostReloadCopy =
1319 isCopyInstr(*RC[0], *
TII, UseCopyInstr);
1320 std::optional<DestSourcePair> OuterMostReloadCopy =
1321 isCopyInstr(*RC.back(), *
TII, UseCopyInstr);
1322 if (!CheckCopyConstraint(OuterMostSpillCopy->Source->getReg(),
1323 InnerMostSpillCopy->Source->getReg()) ||
1324 !CheckCopyConstraint(InnerMostReloadCopy->Destination->getReg(),
1325 OuterMostReloadCopy->Destination->getReg()))
1328 SpillageChainsLength +=
SC.size() + RC.size();
1329 NumSpillageChains += 1;
1330 UpdateReg(SC[0], InnerMostSpillCopy->Destination,
1331 OuterMostSpillCopy->Source);
1332 UpdateReg(RC[0], InnerMostReloadCopy->Source,
1333 OuterMostReloadCopy->Destination);
1335 for (
size_t I = 1;
I <
SC.size() - 1; ++
I) {
1336 SC[
I]->eraseFromParent();
1337 RC[
I]->eraseFromParent();
1342 auto IsFoldableCopy = [
this](
const MachineInstr &MaybeCopy) {
1343 if (MaybeCopy.getNumImplicitOperands() > 0)
1345 std::optional<DestSourcePair> CopyOperands =
1346 isCopyInstr(MaybeCopy, *
TII, UseCopyInstr);
1349 Register Src = CopyOperands->Source->getReg();
1350 Register Def = CopyOperands->Destination->getReg();
1351 return Src &&
Def && !
TRI->regsOverlap(Src, Def) &&
1352 CopyOperands->Source->isRenamable() &&
1353 CopyOperands->Destination->isRenamable();
1358 if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
1360 std::optional<DestSourcePair> SpillCopy =
1361 isCopyInstr(Spill, *
TII, UseCopyInstr);
1362 std::optional<DestSourcePair> ReloadCopy =
1363 isCopyInstr(Reload, *
TII, UseCopyInstr);
1364 if (!SpillCopy || !ReloadCopy)
1366 return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
1367 SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
1370 auto IsChainedCopy = [&,
this](
const MachineInstr &Prev,
1372 if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
1374 std::optional<DestSourcePair> PrevCopy =
1375 isCopyInstr(Prev, *
TII, UseCopyInstr);
1376 std::optional<DestSourcePair> CurrentCopy =
1377 isCopyInstr(Current, *
TII, UseCopyInstr);
1378 if (!PrevCopy || !CurrentCopy)
1380 return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
1384 std::optional<DestSourcePair> CopyOperands =
1385 isCopyInstr(
MI, *
TII, UseCopyInstr);
1389 if (!CopyOperands) {
1397 Tracker.findLastSeenUseInCopy(
Reg.asMCReg(), *
TRI);
1403 CopySourceInvalid.
insert(LastUseCopy);
1411 if (Tracker.findLastSeenDefInCopy(
MI,
Reg.asMCReg(), *
TRI, *
TII,
1414 RegsToClobber.
insert(Reg);
1416 for (
Register Reg : RegsToClobber) {
1417 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1424 Register Src = CopyOperands->Source->getReg();
1425 Register Def = CopyOperands->Destination->getReg();
1427 LLVM_DEBUG(
dbgs() <<
"MCP: Searching paired spill for reload: ");
1430 Tracker.findLastSeenDefInCopy(
MI, Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
1431 bool MaybeSpillIsChained = ChainLeader.
count(MaybeSpill);
1432 if (!MaybeSpillIsChained && MaybeSpill &&
1433 IsSpillReloadPair(*MaybeSpill,
MI)) {
1469 Tracker.findLastSeenUseInCopy(
Def.asMCReg(), *
TRI);
1470 auto Leader = ChainLeader.
find(MaybePrevReload);
1472 if (Leader == ChainLeader.
end() ||
1473 (MaybePrevReload && !IsChainedCopy(*MaybePrevReload,
MI))) {
1476 "SpillChain should not have contained newly found chain");
1478 assert(MaybePrevReload &&
1479 "Found a valid leader through nullptr should not happend");
1482 "Existing chain's length should be larger than zero");
1485 "Newly found paired spill-reload should not belong to any chain "
1487 ChainLeader.
insert({MaybeSpill,
L});
1489 SpillChain[
L].push_back(MaybeSpill);
1490 ReloadChain[
L].push_back(&
MI);
1493 }
else if (MaybeSpill && !MaybeSpillIsChained) {
1510 Tracker.clobberRegister(Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
1514 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1517 for (
auto I = SpillChain.
begin(), E = SpillChain.
end();
I != E; ++
I) {
1518 auto &
SC =
I->second;
1520 "Reload chain of the same leader should exist");
1521 auto &RC = ReloadChain[
I->first];
1522 TryFoldSpillageCopies(SC, RC);
1525 MaybeDeadCopies.clear();
1526 CopyDbgUsers.clear();
1530bool MachineCopyPropagation::runOnMachineFunction(
MachineFunction &MF) {
1534 bool isSpillageCopyElimEnabled =
false;
1537 isSpillageCopyElimEnabled =
1541 isSpillageCopyElimEnabled =
true;
1544 isSpillageCopyElimEnabled =
false;
1555 if (isSpillageCopyElimEnabled)
1556 EliminateSpillageCopies(
MBB);
1557 BackwardCopyPropagateBlock(
MBB);
1558 ForwardCopyPropagateBlock(
MBB);
1566 return new MachineCopyPropagation(UseCopyInstr);
unsigned const MachineRegisterInfo * MRI
#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)
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Represent the analysis usage information of a pass.
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),...
static bool shouldExecute(unsigned CounterName)
iterator find(const_arg_type_t< KeyT > Val)
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.
Wrapper class representing physical registers. Should be passed by value.
iterator_range< succ_iterator > successors()
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
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.
MachineFunctionProperties & set(Property P)
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.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
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.
void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
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.
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...
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...
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 const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual bool enableSpillageCopyElimination() const
Enable spillage copy elimination in MachineCopyPropagation pass.
virtual const TargetInstrInfo * getInstrInfo() const
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const_iterator end(StringRef path)
Get end iterator over path.
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...
auto reverse(ContainerTy &&C)
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.
MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
void initializeMachineCopyPropagationPass(PassRegistry &)
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.
char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
const MachineOperand * Source
const MachineOperand * Destination