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>(
126 auto CI =
Copies.find(Unit);
128 CI->second.Avail =
false;
142 std::optional<DestSourcePair> CopyOperands =
143 isCopyInstr(*
MI,
TII, UseCopyInstr);
144 assert(CopyOperands &&
"Expect copy");
146 auto Dest =
TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
147 auto Src =
TRI.regunits(CopyOperands->Source->getReg().asMCReg());
148 RegUnitsToInvalidate.
insert(Dest.begin(), Dest.end());
149 RegUnitsToInvalidate.
insert(Src.begin(), Src.end());
161 for (
MCRegUnit Unit : RegUnitsToInvalidate)
173 markRegsUnavailable(
I->second.DefRegs,
TRI);
177 std::optional<DestSourcePair> CopyOperands =
178 isCopyInstr(*
MI,
TII, UseCopyInstr);
180 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
181 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
183 markRegsUnavailable(Def,
TRI);
198 auto SrcCopy =
Copies.find(SrcUnit);
199 if (SrcCopy !=
Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
202 for (
auto itr = SrcCopy->second.DefRegs.begin();
203 itr != SrcCopy->second.DefRegs.end(); itr++) {
205 SrcCopy->second.DefRegs.erase(itr);
211 if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
229 std::optional<DestSourcePair> CopyOperands =
230 isCopyInstr(*
MI,
TII, UseCopyInstr);
231 assert(CopyOperands &&
"Tracking non-copy?");
233 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
234 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
238 Copies[Unit] = {
MI,
nullptr, {},
true};
243 auto I =
Copies.insert({Unit, {
nullptr,
nullptr, {},
false}});
244 auto &
Copy =
I.first->second;
246 Copy.DefRegs.push_back(Def);
247 Copy.LastSeenUseInCopy =
MI;
251 bool hasAnyCopies() {
257 bool MustBeAvailable =
false) {
258 auto CI =
Copies.find(RegUnit);
261 if (MustBeAvailable && !CI->second.Avail)
263 return CI->second.MI;
268 auto CI =
Copies.find(RegUnit);
271 if (CI->second.DefRegs.size() != 1)
273 MCRegUnit RU = *
TRI.regunits(CI->second.DefRegs[0]).begin();
274 return findCopyForUnit(RU,
TRI,
true);
287 std::optional<DestSourcePair> CopyOperands =
288 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
289 Register AvailSrc = CopyOperands->Source->getReg();
290 Register AvailDef = CopyOperands->Destination->getReg();
291 if (!
TRI.isSubRegisterEq(AvailSrc, Reg))
299 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
312 findCopyForUnit(RU,
TRI,
true);
317 std::optional<DestSourcePair> CopyOperands =
318 isCopyInstr(*AvailCopy,
TII, UseCopyInstr);
319 Register AvailSrc = CopyOperands->Source->getReg();
320 Register AvailDef = CopyOperands->Destination->getReg();
321 if (!
TRI.isSubRegisterEq(AvailDef, Reg))
330 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
343 auto CI =
Copies.find(RU);
344 if (CI ==
Copies.end() || !CI->second.Avail)
348 std::optional<DestSourcePair> CopyOperands =
349 isCopyInstr(*DefCopy,
TII, UseCopyInstr);
350 Register Def = CopyOperands->Destination->getReg();
351 if (!
TRI.isSubRegisterEq(Def, Reg))
359 if (MO.clobbersPhysReg(Def)) {
372 auto CI =
Copies.find(RU);
375 return CI->second.LastSeenUseInCopy;
394 MachineCopyPropagation(
bool CopyInstr =
false)
408 MachineFunctionProperties::Property::NoVRegs);
412 typedef enum { DebugUse =
false, RegularUse =
true }
DebugType;
422 bool isForwardableRegClassCopy(
const MachineInstr &Copy,
424 bool isBackwardPropagatableRegClassCopy(
const MachineInstr &Copy,
439 bool Changed =
false;
444char MachineCopyPropagation::ID = 0;
449 "Machine Copy Propagation Pass",
false,
false)
458 if (DT == RegularUse) {
459 LLVM_DEBUG(
dbgs() <<
"MCP: Copy is used - not dead: "; Copy->dump());
460 MaybeDeadCopies.remove(Copy);
462 CopyDbgUsers[Copy].insert(&Reader);
468void MachineCopyPropagation::readSuccessorLiveIns(
470 if (MaybeDeadCopies.empty())
475 for (
const auto &LI : Succ->liveins()) {
478 MaybeDeadCopies.remove(Copy);
494 std::optional<DestSourcePair> CopyOperands =
495 isCopyInstr(PreviousCopy, *
TII, UseCopyInstr);
496 MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
497 MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
498 if (Src == PreviousSrc && Def == PreviousDef)
500 if (!
TRI->isSubRegister(PreviousSrc, Src))
502 unsigned SubIdx =
TRI->getSubRegIndex(PreviousSrc, Src);
503 return SubIdx ==
TRI->getSubRegIndex(PreviousDef, Def);
509bool MachineCopyPropagation::eraseIfRedundant(
MachineInstr &Copy,
513 if (
MRI->isReserved(Src) ||
MRI->isReserved(Def))
518 Tracker.findAvailCopy(Copy, Def, *
TRI, *
TII, UseCopyInstr);
522 auto PrevCopyOperands = isCopyInstr(*PrevCopy, *
TII, UseCopyInstr);
524 if (PrevCopyOperands->Destination->isDead())
533 std::optional<DestSourcePair> CopyOperands =
534 isCopyInstr(Copy, *
TII, UseCopyInstr);
537 Register CopyDef = CopyOperands->Destination->getReg();
538 assert(CopyDef == Src || CopyDef == Def);
541 MI.clearRegisterKills(CopyDef,
TRI);
544 if (!CopyOperands->Source->isUndef()) {
545 PrevCopy->
getOperand(PrevCopyOperands->Source->getOperandNo())
549 Copy.eraseFromParent();
555bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
557 std::optional<DestSourcePair> CopyOperands =
558 isCopyInstr(Copy, *
TII, UseCopyInstr);
559 Register Def = CopyOperands->Destination->getReg();
563 return URC->contains(Def);
573bool MachineCopyPropagation::isForwardableRegClassCopy(
const MachineInstr &Copy,
576 std::optional<DestSourcePair> CopyOperands =
577 isCopyInstr(Copy, *
TII, UseCopyInstr);
578 Register CopySrcReg = CopyOperands->Source->getReg();
584 return URC->contains(CopySrcReg);
586 auto UseICopyOperands = isCopyInstr(UseI, *
TII, UseCopyInstr);
587 if (!UseICopyOperands)
610 Register UseDstReg = UseICopyOperands->Destination->getReg();
612 bool IsCrossClass =
false;
614 if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
616 if (
TRI->getCrossCopyRegClass(RC) != RC) {
628 Register CopyDstReg = CopyOperands->Destination->getReg();
630 if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
631 TRI->getCrossCopyRegClass(RC) != RC)
645bool MachineCopyPropagation::hasImplicitOverlap(
const MachineInstr &
MI,
648 if (&MIUse != &
Use && MIUse.isReg() && MIUse.isImplicit() &&
649 MIUse.isUse() &&
TRI->regsOverlap(
Use.getReg(), MIUse.getReg()))
659bool MachineCopyPropagation::hasOverlappingMultipleDef(
662 if ((&MIDef != &MODef) && MIDef.isReg() &&
663 TRI->regsOverlap(Def, MIDef.getReg()))
673 if (!Tracker.hasAnyCopies())
679 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands(); OpIdx < OpEnd;
701 *
TRI, *
TII, UseCopyInstr);
705 std::optional<DestSourcePair> CopyOperands =
706 isCopyInstr(*Copy, *
TII, UseCopyInstr);
707 Register CopyDstReg = CopyOperands->Destination->getReg();
714 if (MOUse.
getReg() != CopyDstReg) {
715 unsigned SubRegIdx =
TRI->getSubRegIndex(CopyDstReg, MOUse.
getReg());
717 "MI source is not a sub-register of Copy destination");
718 ForwardedReg =
TRI->getSubReg(CopySrcReg, SubRegIdx);
720 LLVM_DEBUG(
dbgs() <<
"MCP: Copy source does not have sub-register "
721 <<
TRI->getSubRegIndexName(SubRegIdx) <<
'\n');
727 if (
MRI->isReserved(CopySrcReg) && !
MRI->isConstantPhysReg(CopySrcReg))
730 if (!isForwardableRegClassCopy(*Copy,
MI, OpIdx))
733 if (hasImplicitOverlap(
MI, MOUse))
739 if (isCopyInstr(
MI, *
TII, UseCopyInstr) &&
740 MI.modifiesRegister(CopySrcReg,
TRI) &&
741 !
MI.definesRegister(CopySrcReg,
nullptr)) {
747 LLVM_DEBUG(
dbgs() <<
"MCP: Skipping forwarding due to debug counter:\n "
754 <<
"\n in " <<
MI <<
" from " << *Copy);
756 MOUse.
setReg(ForwardedReg);
767 KMI.clearRegisterKills(CopySrcReg,
TRI);
780 std::optional<DestSourcePair> CopyOperands =
781 isCopyInstr(
MI, *
TII, UseCopyInstr);
784 Register RegSrc = CopyOperands->Source->getReg();
785 Register RegDef = CopyOperands->Destination->getReg();
787 if (!
TRI->regsOverlap(RegDef, RegSrc)) {
789 "MachineCopyPropagation should be run after register allocation!");
809 if (eraseIfRedundant(
MI, Def, Src) || eraseIfRedundant(
MI, Src, Def))
815 CopyOperands = isCopyInstr(
MI, *
TII, UseCopyInstr);
816 Src = CopyOperands->Source->getReg().asMCReg();
820 ReadRegister(Src,
MI, RegularUse);
822 if (!MO.isReg() || !MO.readsReg())
827 ReadRegister(Reg,
MI, RegularUse);
833 if (!
MRI->isReserved(Def))
834 MaybeDeadCopies.insert(&
MI);
843 Tracker.clobberRegister(Def, *
TRI, *
TII, UseCopyInstr);
845 if (!MO.isReg() || !MO.isDef())
850 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
853 Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
861 if (MO.isReg() && MO.isEarlyClobber()) {
867 ReadRegister(Reg,
MI, RegularUse);
868 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
886 "MachineCopyPropagation should be run after register allocation!");
888 if (MO.isDef() && !MO.isEarlyClobber()) {
891 }
else if (MO.readsReg())
892 ReadRegister(
Reg.asMCReg(),
MI, MO.isDebug() ? DebugUse : RegularUse);
901 MaybeDeadCopies.
begin();
902 DI != MaybeDeadCopies.end();) {
904 std::optional<DestSourcePair> CopyOperands =
905 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
906 MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
914 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to regmask clobbering: ";
919 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
923 DI = MaybeDeadCopies.erase(DI);
932 Tracker.clobberRegister(Reg, *
TRI, *
TII, UseCopyInstr);
935 bool TracksLiveness =
MRI->tracksLiveness();
940 readSuccessorLiveIns(
MBB);
947 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to no live-out succ: ";
950 std::optional<DestSourcePair> CopyOperands =
951 isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
954 Register SrcReg = CopyOperands->Source->getReg();
955 Register DestReg = CopyOperands->Destination->getReg();
960 CopyDbgUsers[MaybeDead].
begin(), CopyDbgUsers[MaybeDead].
end());
970 MaybeDeadCopies.clear();
971 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)
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