78#define DEBUG_TYPE "machine-cp"
80STATISTIC(NumDeletes,
"Number of dead copies deleted");
81STATISTIC(NumCopyForwards,
"Number of copy uses forwarded");
82STATISTIC(NumCopyBackwardPropagated,
"Number of copy defs backward propagated");
83STATISTIC(SpillageChainsLength,
"Length of spillage chains");
84STATISTIC(NumSpillageChains,
"Number of spillage chains");
86 "Controls which register COPYs are forwarded");
95static std::optional<DestSourcePair> isCopyInstr(
const MachineInstr &
MI,
99 return TII.isCopyInstr(
MI);
102 return std::optional<DestSourcePair>(
125 auto CI =
Copies.find(Unit);
127 CI->second.Avail =
false;
141 std::optional<DestSourcePair> CopyOperands =
142 isCopyInstr(*
MI,
TII, UseCopyInstr);
143 assert(CopyOperands &&
"Expect copy");
145 auto Dest =
TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
146 auto Src =
TRI.regunits(CopyOperands->Source->getReg().asMCReg());
147 RegUnitsToInvalidate.
insert(Dest.begin(), Dest.end());
148 RegUnitsToInvalidate.
insert(Src.begin(), Src.end());
160 for (
MCRegUnit Unit : RegUnitsToInvalidate)
172 markRegsUnavailable(
I->second.DefRegs,
TRI);
176 std::optional<DestSourcePair> CopyOperands =
177 isCopyInstr(*
MI,
TII, UseCopyInstr);
179 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
180 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
182 markRegsUnavailable(Def,
TRI);
197 auto SrcCopy =
Copies.find(SrcUnit);
198 if (SrcCopy !=
Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
201 for (
auto itr = SrcCopy->second.DefRegs.begin();
202 itr != SrcCopy->second.DefRegs.end(); itr++) {
204 SrcCopy->second.DefRegs.erase(itr);
210 if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
228 std::optional<DestSourcePair> CopyOperands =
229 isCopyInstr(*
MI,
TII, UseCopyInstr);
230 assert(CopyOperands &&
"Tracking non-copy?");
232 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
233 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
237 Copies[Unit] = {
MI,
nullptr, {},
true};
242 auto I =
Copies.insert({Unit, {
nullptr,
nullptr, {},
false}});
243 auto &
Copy =
I.first->second;
245 Copy.DefRegs.push_back(Def);
246 Copy.LastSeenUseInCopy =
MI;
250 bool hasAnyCopies() {
256 bool MustBeAvailable =
false) {
257 auto CI =
Copies.find(RegUnit);
260 if (MustBeAvailable && !CI->second.Avail)
262 return CI->second.MI;
267 auto CI =
Copies.find(RegUnit);
270 if (CI->second.DefRegs.size() != 1)
272 MCRegUnit RU = *
TRI.regunits(CI->second.DefRegs[0]).begin();
273 return findCopyForUnit(RU,
TRI,
true);
286 std::optional<DestSourcePair> CopyOperands =
287 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
288 Register AvailSrc = CopyOperands->Source->getReg();
289 Register AvailDef = CopyOperands->Destination->getReg();
290 if (!
TRI.isSubRegisterEq(AvailSrc, Reg))
298 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
311 findCopyForUnit(RU,
TRI,
true);
316 std::optional<DestSourcePair> CopyOperands =
317 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
318 Register AvailSrc = CopyOperands->Source->getReg();
319 Register AvailDef = CopyOperands->Destination->getReg();
320 if (!
TRI.isSubRegisterEq(AvailDef, Reg))
329 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
342 auto CI =
Copies.find(RU);
343 if (CI ==
Copies.end() || !CI->second.Avail)
347 std::optional<DestSourcePair> CopyOperands =
348 isCopyInstr(*DefCopy,
TII, UseCopyInstr);
349 Register Def = CopyOperands->Destination->getReg();
350 if (!
TRI.isSubRegisterEq(Def, Reg))
358 if (MO.clobbersPhysReg(Def)) {
371 auto CI =
Copies.find(RU);
374 return CI->second.LastSeenUseInCopy;
393 MachineCopyPropagation(
bool CopyInstr =
false)
407 MachineFunctionProperties::Property::NoVRegs);
411 typedef enum { DebugUse =
false, RegularUse =
true }
DebugType;
421 bool isForwardableRegClassCopy(
const MachineInstr &Copy,
423 bool isBackwardPropagatableRegClassCopy(
const MachineInstr &Copy,
438 bool Changed =
false;
443char MachineCopyPropagation::ID = 0;
448 "Machine Copy Propagation Pass",
false,
false)
457 if (DT == RegularUse) {
458 LLVM_DEBUG(
dbgs() <<
"MCP: Copy is used - not dead: "; Copy->dump());
459 MaybeDeadCopies.remove(Copy);
461 CopyDbgUsers[Copy].insert(&Reader);
467void MachineCopyPropagation::readSuccessorLiveIns(
469 if (MaybeDeadCopies.empty())
474 for (
const auto &LI : Succ->liveins()) {
477 MaybeDeadCopies.remove(Copy);
493 std::optional<DestSourcePair> CopyOperands =
494 isCopyInstr(PreviousCopy, *
TII, UseCopyInstr);
495 MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
496 MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
497 if (Src == PreviousSrc && Def == PreviousDef)
499 if (!
TRI->isSubRegister(PreviousSrc, Src))
501 unsigned SubIdx =
TRI->getSubRegIndex(PreviousSrc, Src);
502 return SubIdx ==
TRI->getSubRegIndex(PreviousDef, Def);
508bool MachineCopyPropagation::eraseIfRedundant(
MachineInstr &Copy,
512 if (
MRI->isReserved(Src) ||
MRI->isReserved(Def))
517 Tracker.findAvailCopy(Copy, Def, *
TRI, *
TII, UseCopyInstr);
521 auto PrevCopyOperands = isCopyInstr(*PrevCopy, *
TII, UseCopyInstr);
523 if (PrevCopyOperands->Destination->isDead())
532 std::optional<DestSourcePair> CopyOperands =
533 isCopyInstr(Copy, *
TII, UseCopyInstr);
536 Register CopyDef = CopyOperands->Destination->getReg();
537 assert(CopyDef == Src || CopyDef == Def);
540 MI.clearRegisterKills(CopyDef,
TRI);
543 if (!CopyOperands->Source->isUndef()) {
544 PrevCopy->
getOperand(PrevCopyOperands->Source->getOperandNo())
548 Copy.eraseFromParent();
554bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
556 std::optional<DestSourcePair> CopyOperands =
557 isCopyInstr(Copy, *
TII, UseCopyInstr);
558 Register Def = CopyOperands->Destination->getReg();
562 return URC->contains(Def);
572bool MachineCopyPropagation::isForwardableRegClassCopy(
const MachineInstr &Copy,
575 std::optional<DestSourcePair> CopyOperands =
576 isCopyInstr(Copy, *
TII, UseCopyInstr);
577 Register CopySrcReg = CopyOperands->Source->getReg();
583 return URC->contains(CopySrcReg);
585 auto UseICopyOperands = isCopyInstr(UseI, *
TII, UseCopyInstr);
586 if (!UseICopyOperands)
609 Register UseDstReg = UseICopyOperands->Destination->getReg();
611 bool IsCrossClass =
false;
613 if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
615 if (
TRI->getCrossCopyRegClass(RC) != RC) {
627 Register CopyDstReg = CopyOperands->Destination->getReg();
629 if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
630 TRI->getCrossCopyRegClass(RC) != RC)
644bool MachineCopyPropagation::hasImplicitOverlap(
const MachineInstr &
MI,
647 if (&MIUse != &
Use && MIUse.isReg() && MIUse.isImplicit() &&
648 MIUse.isUse() &&
TRI->regsOverlap(
Use.getReg(), MIUse.getReg()))
658bool MachineCopyPropagation::hasOverlappingMultipleDef(
661 if ((&MIDef != &MODef) && MIDef.isReg() &&
662 TRI->regsOverlap(Def, MIDef.getReg()))
672 if (!Tracker.hasAnyCopies())
678 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands(); OpIdx < OpEnd;
700 *
TRI, *
TII, UseCopyInstr);
704 std::optional<DestSourcePair> CopyOperands =
705 isCopyInstr(*Copy, *
TII, UseCopyInstr);
706 Register CopyDstReg = CopyOperands->Destination->getReg();
713 if (MOUse.
getReg() != CopyDstReg) {
714 unsigned SubRegIdx =
TRI->getSubRegIndex(CopyDstReg, MOUse.
getReg());
716 "MI source is not a sub-register of Copy destination");
717 ForwardedReg =
TRI->getSubReg(CopySrcReg, SubRegIdx);
719 LLVM_DEBUG(
dbgs() <<
"MCP: Copy source does not have sub-register "
720 <<
TRI->getSubRegIndexName(SubRegIdx) <<
'\n');
726 if (
MRI->isReserved(CopySrcReg) && !
MRI->isConstantPhysReg(CopySrcReg))
729 if (!isForwardableRegClassCopy(*Copy,
MI, OpIdx))
732 if (hasImplicitOverlap(
MI, MOUse))
738 if (isCopyInstr(
MI, *
TII, UseCopyInstr) &&
739 MI.modifiesRegister(CopySrcReg,
TRI) &&
740 !
MI.definesRegister(CopySrcReg,
nullptr)) {
746 LLVM_DEBUG(
dbgs() <<
"MCP: Skipping forwarding due to debug counter:\n "
753 <<
"\n in " <<
MI <<
" from " << *Copy);
755 MOUse.
setReg(ForwardedReg);
766 KMI.clearRegisterKills(CopySrcReg,
TRI);
779 std::optional<DestSourcePair> CopyOperands =
780 isCopyInstr(
MI, *
TII, UseCopyInstr);
783 Register RegSrc = CopyOperands->Source->getReg();
784 Register RegDef = CopyOperands->Destination->getReg();
786 if (!
TRI->regsOverlap(RegDef, RegSrc)) {
788 "MachineCopyPropagation should be run after register allocation!");
808 if (eraseIfRedundant(
MI, Def, Src) || eraseIfRedundant(
MI, Src, Def))
814 CopyOperands = isCopyInstr(
MI, *
TII, UseCopyInstr);
815 Src = CopyOperands->Source->getReg().asMCReg();
819 ReadRegister(Src,
MI, RegularUse);
821 if (!MO.isReg() || !MO.readsReg())
826 ReadRegister(Reg,
MI, RegularUse);
832 if (!
MRI->isReserved(Def))
833 MaybeDeadCopies.insert(&
MI);
842 Tracker.clobberRegister(Def, *
TRI, *
TII, UseCopyInstr);
844 if (!MO.isReg() || !MO.isDef())
849 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
852 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
860 if (MO.isReg() && MO.isEarlyClobber()) {
866 ReadRegister(Reg,
MI, RegularUse);
867 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
885 "MachineCopyPropagation should be run after register allocation!");
887 if (MO.isDef() && !MO.isEarlyClobber()) {
890 }
else if (MO.readsReg())
891 ReadRegister(
Reg.asMCReg(),
MI, MO.isDebug() ? DebugUse : RegularUse);
900 MaybeDeadCopies.
begin();
901 DI != MaybeDeadCopies.end();) {
903 std::optional<DestSourcePair> CopyOperands =
904 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
905 MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
913 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to regmask clobbering: ";
918 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
922 DI = MaybeDeadCopies.erase(DI);
931 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
934 bool TracksLiveness =
MRI->tracksLiveness();
939 readSuccessorLiveIns(
MBB);
946 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to no live-out succ: ";
949 std::optional<DestSourcePair> CopyOperands =
950 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
953 Register SrcReg = CopyOperands->Source->getReg();
954 Register DestReg = CopyOperands->Destination->getReg();
959 CopyDbgUsers[MaybeDead].
begin(), CopyDbgUsers[MaybeDead].
end());
969 MaybeDeadCopies.clear();
970 CopyDbgUsers.clear();
983 if (
MRI.isReserved(Def) ||
MRI.isReserved(Src))
990 if (!Tracker.hasAnyCopies())
993 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands(); OpIdx != OpEnd;
1016 std::optional<DestSourcePair> CopyOperands =
1017 isCopyInstr(*Copy, *
TII, UseCopyInstr);
1018 Register Def = CopyOperands->Destination->getReg();
1019 Register Src = CopyOperands->Source->getReg();
1021 if (MODef.
getReg() != Src)
1024 if (!isBackwardPropagatableRegClassCopy(*Copy,
MI, OpIdx))
1027 if (hasImplicitOverlap(
MI, MODef))
1030 if (hasOverlappingMultipleDef(
MI, MODef, Def))
1035 <<
MI <<
" from " << *Copy);
1041 MaybeDeadCopies.insert(Copy);
1043 ++NumCopyBackwardPropagated;
1047void MachineCopyPropagation::BackwardCopyPropagateBlock(
1054 std::optional<DestSourcePair> CopyOperands =
1055 isCopyInstr(
MI, *
TII, UseCopyInstr);
1056 if (CopyOperands &&
MI.getNumOperands() == 2) {
1057 Register DefReg = CopyOperands->Destination->getReg();
1058 Register SrcReg = CopyOperands->Source->getReg();
1060 if (!
TRI->regsOverlap(DefReg, SrcReg)) {
1068 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1076 if (MO.isReg() && MO.isEarlyClobber()) {
1080 Tracker.invalidateRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1092 Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
1095 if (MO.readsReg()) {
1100 for (
MCRegUnit Unit :
TRI->regunits(MO.getReg().asMCReg())) {
1101 if (
auto *Copy = Tracker.findCopyDefViaUnit(Unit, *
TRI)) {
1102 CopyDbgUsers[
Copy].insert(&
MI);
1106 Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
1113 for (
auto *Copy : MaybeDeadCopies) {
1114 std::optional<DestSourcePair> CopyOperands =
1115 isCopyInstr(*Copy, *
TII, UseCopyInstr);
1116 Register Src = CopyOperands->Source->getReg();
1117 Register Def = CopyOperands->Destination->getReg();
1119 CopyDbgUsers[Copy].
end());
1121 MRI->updateDbgUsersToReg(Src.asMCReg(),
Def.asMCReg(), MaybeDeadDbgUsers);
1122 Copy->eraseFromParent();
1126 MaybeDeadCopies.clear();
1127 CopyDbgUsers.clear();
1135 auto &SC = SpillChain[Leader];
1136 auto &RC = ReloadChain[Leader];
1137 for (
auto I = SC.rbegin(), E = SC.rend();
I != E; ++
I)
1194 auto TryFoldSpillageCopies =
1197 assert(
SC.size() == RC.size() &&
"Spill-reload should be paired");
1213 if (CopySourceInvalid.
count(Spill))
1217 if (CopySourceInvalid.
count(Reload))
1222 if (RC->contains(Def) && RC->contains(Src))
1232 MO.setReg(
New->getReg());
1236 std::optional<DestSourcePair> InnerMostSpillCopy =
1237 isCopyInstr(*SC[0], *
TII, UseCopyInstr);
1238 std::optional<DestSourcePair> OuterMostSpillCopy =
1239 isCopyInstr(*
SC.back(), *
TII, UseCopyInstr);
1240 std::optional<DestSourcePair> InnerMostReloadCopy =
1241 isCopyInstr(*RC[0], *
TII, UseCopyInstr);
1242 std::optional<DestSourcePair> OuterMostReloadCopy =
1243 isCopyInstr(*RC.back(), *
TII, UseCopyInstr);
1244 if (!CheckCopyConstraint(OuterMostSpillCopy->Source->getReg(),
1245 InnerMostSpillCopy->Source->getReg()) ||
1246 !CheckCopyConstraint(InnerMostReloadCopy->Destination->getReg(),
1247 OuterMostReloadCopy->Destination->getReg()))
1250 SpillageChainsLength +=
SC.size() + RC.size();
1251 NumSpillageChains += 1;
1252 UpdateReg(SC[0], InnerMostSpillCopy->Destination,
1253 OuterMostSpillCopy->Source);
1254 UpdateReg(RC[0], InnerMostReloadCopy->Source,
1255 OuterMostReloadCopy->Destination);
1257 for (
size_t I = 1;
I <
SC.size() - 1; ++
I) {
1258 SC[
I]->eraseFromParent();
1259 RC[
I]->eraseFromParent();
1264 auto IsFoldableCopy = [
this](
const MachineInstr &MaybeCopy) {
1265 if (MaybeCopy.getNumImplicitOperands() > 0)
1267 std::optional<DestSourcePair> CopyOperands =
1268 isCopyInstr(MaybeCopy, *
TII, UseCopyInstr);
1271 Register Src = CopyOperands->Source->getReg();
1272 Register Def = CopyOperands->Destination->getReg();
1273 return Src &&
Def && !
TRI->regsOverlap(Src, Def) &&
1274 CopyOperands->Source->isRenamable() &&
1275 CopyOperands->Destination->isRenamable();
1280 if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
1282 std::optional<DestSourcePair> SpillCopy =
1283 isCopyInstr(Spill, *
TII, UseCopyInstr);
1284 std::optional<DestSourcePair> ReloadCopy =
1285 isCopyInstr(Reload, *
TII, UseCopyInstr);
1286 if (!SpillCopy || !ReloadCopy)
1288 return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
1289 SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
1292 auto IsChainedCopy = [&,
this](
const MachineInstr &Prev,
1294 if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
1296 std::optional<DestSourcePair> PrevCopy =
1297 isCopyInstr(Prev, *
TII, UseCopyInstr);
1298 std::optional<DestSourcePair> CurrentCopy =
1299 isCopyInstr(Current, *
TII, UseCopyInstr);
1300 if (!PrevCopy || !CurrentCopy)
1302 return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
1306 std::optional<DestSourcePair> CopyOperands =
1307 isCopyInstr(
MI, *
TII, UseCopyInstr);
1311 if (!CopyOperands) {
1319 Tracker.findLastSeenUseInCopy(
Reg.asMCReg(), *
TRI);
1325 CopySourceInvalid.
insert(LastUseCopy);
1333 if (Tracker.findLastSeenDefInCopy(
MI,
Reg.asMCReg(), *
TRI, *
TII,
1336 RegsToClobber.
insert(Reg);
1338 for (
Register Reg : RegsToClobber) {
1339 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
1346 Register Src = CopyOperands->Source->getReg();
1347 Register Def = CopyOperands->Destination->getReg();
1349 LLVM_DEBUG(
dbgs() <<
"MCP: Searching paired spill for reload: ");
1352 Tracker.findLastSeenDefInCopy(
MI, Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
1353 bool MaybeSpillIsChained = ChainLeader.
count(MaybeSpill);
1354 if (!MaybeSpillIsChained && MaybeSpill &&
1355 IsSpillReloadPair(*MaybeSpill,
MI)) {
1391 Tracker.findLastSeenUseInCopy(
Def.asMCReg(), *
TRI);
1392 auto Leader = ChainLeader.
find(MaybePrevReload);
1394 if (Leader == ChainLeader.
end() ||
1395 (MaybePrevReload && !IsChainedCopy(*MaybePrevReload,
MI))) {
1398 "SpillChain should not have contained newly found chain");
1400 assert(MaybePrevReload &&
1401 "Found a valid leader through nullptr should not happend");
1404 "Existing chain's length should be larger than zero");
1407 "Newly found paired spill-reload should not belong to any chain "
1409 ChainLeader.
insert({MaybeSpill,
L});
1411 SpillChain[
L].push_back(MaybeSpill);
1412 ReloadChain[
L].push_back(&
MI);
1415 }
else if (MaybeSpill && !MaybeSpillIsChained) {
1432 Tracker.clobberRegister(Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
1436 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
1439 for (
auto I = SpillChain.
begin(), E = SpillChain.
end();
I != E; ++
I) {
1440 auto &
SC =
I->second;
1442 "Reload chain of the same leader should exist");
1443 auto &RC = ReloadChain[
I->first];
1444 TryFoldSpillageCopies(SC, RC);
1447 MaybeDeadCopies.clear();
1448 CopyDbgUsers.clear();
1452bool MachineCopyPropagation::runOnMachineFunction(
MachineFunction &MF) {
1456 bool isSpillageCopyElimEnabled =
false;
1459 isSpillageCopyElimEnabled =
1463 isSpillageCopyElimEnabled =
true;
1466 isSpillageCopyElimEnabled =
false;
1477 if (isSpillageCopyElimEnabled)
1478 EliminateSpillageCopies(
MBB);
1479 BackwardCopyPropagateBlock(
MBB);
1480 ForwardCopyPropagateBlock(
MBB);
1488 return new MachineCopyPropagation(UseCopyInstr);
unsigned const MachineRegisterInfo * MRI
#define LLVM_ATTRIBUTE_UNUSED
static void clear(coro::Shape &Shape)
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, const TargetInstrInfo &TII)
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.
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