47#include "llvm/Config/llvm-config.h"
62#define DEBUG_TYPE "regalloc"
64STATISTIC(NumSpilledRanges,
"Number of spilled live ranges");
65STATISTIC(NumSnippets,
"Number of spilled snippets");
67STATISTIC(NumSpillsRemoved,
"Number of spills removed");
69STATISTIC(NumReloadsRemoved,
"Number of reloads removed");
70STATISTIC(NumFolded,
"Number of folded stack accesses");
72STATISTIC(NumRemats,
"Number of rematerialized defs for spilling");
77 cl::desc(
"Restrict remat for statepoint operands"));
103 using MergeableSpillsMap =
105 MergeableSpillsMap MergeableSpills;
115 void rmRedundantSpills(
135 : MF(mf), LIS(Analyses.LIS), LSS(Analyses.LSS), MDT(Analyses.MDT),
136 VRM(vrm),
MRI(mf.getRegInfo()),
TII(*mf.getSubtarget().getInstrInfo()),
137 TRI(*mf.getSubtarget().getRegisterInfo()), MBFI(Analyses.MBFI),
138 Matrix(matrix), IPA(LIS, mf.getNumBlockIDs()) {}
140 void addToMergeableSpills(MachineInstr &Spill,
int StackSlot,
142 bool rmFromMergeableSpills(MachineInstr &Spill,
int StackSlot);
143 void hoistAllSpills();
144 void LRE_WillShrinkVirtReg(
Register)
override;
145 bool LRE_CanEraseVirtReg(
Register)
override;
151 DenseMap<Register, MCRegister> PendingReassignments;
154class InlineSpiller :
public Spiller {
159 MachineRegisterInfo &MRI;
160 const TargetInstrInfo &TII;
161 const TargetRegisterInfo &TRI;
162 LiveRegMatrix *Matrix =
nullptr;
165 LiveRangeEdit *Edit =
nullptr;
166 LiveInterval *StackInt =
nullptr;
169 AllocationOrder *Order =
nullptr;
181 SmallPtrSet<MachineInstr*, 8> SnippetCopies;
184 SmallPtrSet<VNInfo*, 8> UsedValues;
187 SmallVector<MachineInstr*, 8> DeadDefs;
190 HoistSpillHelper HSpiller;
193 VirtRegAuxInfo &VRAI;
195 ~InlineSpiller()
override =
default;
198 InlineSpiller(
const Spiller::RequiredAnalyses &Analyses,
MachineFunction &MF,
199 VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix)
200 : MF(MF), LIS(Analyses.LIS), LSS(Analyses.LSS), VRM(VRM),
201 MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
202 TRI(*MF.getSubtarget().getRegisterInfo()), Matrix(Matrix),
203 HSpiller(Analyses, MF, VRM, Matrix), VRAI(VRAI) {}
205 void spill(LiveRangeEdit &, AllocationOrder *Order =
nullptr)
override;
208 void postOptimization()
override;
211 bool isSnippet(
const LiveInterval &SnipLI);
212 void collectRegsToSpill();
217 bool hoistSpillInsideBB(LiveInterval &SpillLI, MachineInstr &CopyMI);
218 void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI);
220 void markValueUsed(LiveInterval *, VNInfo *);
221 bool hasPhysRegAvailable(
const MachineInstr &
MI);
222 bool reMaterializeFor(LiveInterval &, MachineInstr &
MI);
223 void reMaterializeAll();
226 bool foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>,
227 MachineInstr *LoadMI =
nullptr);
239void Spiller::anchor() {}
245 return new InlineSpiller(Analyses, MF, VRM, VRAI,
Matrix);
264 if (!
TII.isCopyInstr(
MI))
287 "expected to see first instruction in bundle");
291 while (
I->isBundledWithSucc()) {
293 auto CopyInst =
TII.isCopyInstr(
MI);
319 if (MO.getReg().isVirtual())
326bool InlineSpiller::isSnippet(
const LiveInterval &SnipLI) {
340 if (!LIS.intervalIsInOneMBB(SnipLI))
346 for (
auto *VNI : SnipLI.
vnis()) {
348 if (
MI->getOpcode() == TargetOpcode::STATEPOINT)
389void InlineSpiller::collectRegsToSpill() {
393 RegsToSpill.assign(1,
Reg);
394 SnippetCopies.clear();
395 RegsReplaced.clear();
404 if (!isSibling(SnipReg))
407 if (!isSnippet(SnipLI))
409 SnippetCopies.insert(&
MI);
410 if (isRegToSpill(SnipReg))
412 RegsToSpill.push_back(SnipReg);
441bool InlineSpiller::hoistSpillInsideBB(
LiveInterval &SpillLI,
446 assert(VNI && VNI->
def ==
Idx.getRegSlot() &&
"Not defined by copy");
463 assert(
DefMI &&
"Defining instruction disappeared");
477 ? LIS.getMBBEndIdx(
MBB)
478 : LIS.getInstructionIndex(*MII).getBaseIndex();
481 VRM.getPhys(SrcReg)))
488 assert(StackInt &&
"No stack slot assigned yet.");
491 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
493 << *StackInt <<
'\n');
497 eliminateRedundantSpills(SrcLI, SrcVNI);
503 LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
520 if (MIS.begin() == MII)
521 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
529 assert(VNI &&
"Missing value");
531 WorkList.
push_back(std::make_pair(&SLI, VNI));
532 assert(StackInt &&
"No stack slot assigned yet.");
539 << VNI->
def <<
" in " << *LI <<
'\n');
542 if (isRegToSpill(
Reg))
546 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
547 LLVM_DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
552 if (!
MI.mayStore() && !
TII.isCopyInstr(
MI))
560 if (isSibling(DstReg)) {
563 assert(DstVNI &&
"Missing defined value");
564 assert(DstVNI->
def ==
Idx.getRegSlot() &&
"Wrong copy def slot");
566 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
576 MI.setDesc(
TII.get(TargetOpcode::KILL));
577 DeadDefs.push_back(&
MI);
579 if (HSpiller.rmFromMergeableSpills(
MI, StackSlot))
583 }
while (!WorkList.
empty());
594 WorkList.
push_back(std::make_pair(LI, VNI));
597 if (!UsedValues.insert(VNI).second)
605 WorkList.
push_back(std::make_pair(LI, PVNI));
612 if (!SnippetCopies.count(
MI))
614 LiveInterval &SnipLI = LIS.getInterval(
MI->getOperand(1).getReg());
615 assert(isRegToSpill(SnipLI.
reg()) &&
"Unexpected register in copy");
617 assert(SnipVNI &&
"Snippet undefined before copy");
618 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
619 }
while (!WorkList.
empty());
641 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
647 EndIdx =
MI.getNumOperands();
648 Idx < EndIdx; ++Idx) {
666 if (!
Matrix->checkInterference(PrevIdx, UseIdx, PhysReg))
692 if (MO.getReg() == VirtReg.
reg())
700 if (SnippetCopies.count(&
MI)) {
701 LLVM_DEBUG(
dbgs() <<
"\tskipping remat snippet copy for " << UseIdx <<
'\t'
708 assert(OrigVNI &&
"corrupted sub-interval");
726 CurDef = LIS.getInstructionFromIndex(CurVNI->
def);
743 if (CurDef &&
TII.isReMaterializable(*CurDef)) {
745 LLVM_DEBUG(
dbgs() <<
"\tFound remat possibility through COPY chain: "
749 markValueUsed(&VirtReg, ParentVNI);
750 LLVM_DEBUG(
dbgs() <<
"\tcannot remat missing def for " << UseIdx <<
'\t'
758 if (!Edit->canRematerializeAt(RM, UseIdx)) {
759 markValueUsed(&VirtReg, ParentVNI);
767 markValueUsed(&VirtReg, ParentVNI);
774 if (
RM.OrigMI->canFoldAsLoad() &&
775 (
RM.OrigMI->mayLoad() || !hasPhysRegAvailable(
MI)) &&
776 foldMemoryOperand(
Ops,
RM.OrigMI)) {
777 Edit->markRematerialized(
RM.ParentVNI);
785 markValueUsed(&VirtReg, ParentVNI);
791 Register NewVReg = Edit->createFrom(Original);
801 if (SR.liveAt(UseIdx))
802 UsedLanes |= SR.LaneMask;
806 SlotIndex DefIdx = Edit->rematerializeAt(*
MI.getParent(),
MI, NewVReg, RM,
807 TRI,
false, 0,
nullptr, UsedLanes);
811 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
812 NewMI->setDebugLoc(
MI.getDebugLoc());
816 << *LIS.getInstructionFromIndex(DefIdx));
819 for (
const auto &OpPair :
Ops) {
832void InlineSpiller::reMaterializeAll() {
836 bool anyRemat =
false;
841 if (
MI.isDebugValue())
844 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
845 "instruction that isn't a DBG_VALUE");
847 anyRemat |= reMaterializeFor(LI,
MI);
861 if (!
MI->allDefsAreDead())
864 DeadDefs.push_back(
MI);
868 if (
MI->isBundledWithSucc() && !
MI->isBundledWithPred()) {
870 EndIt =
MI->getParent()->instr_end();
873 bool OnlyDeadCopies =
true;
875 It != EndIt && It->isBundledWithPred(); ++It) {
877 auto DestSrc =
TII.isCopyInstr(*It);
878 bool IsCopyToDeadReg =
879 DestSrc && DestSrc->Destination->getReg() ==
Reg;
880 if (!IsCopyToDeadReg) {
881 OnlyDeadCopies =
false;
885 if (OnlyDeadCopies) {
887 It != EndIt && It->isBundledWithPred(); ++It) {
888 It->addRegisterDead(
Reg, &
TRI);
890 DeadDefs.push_back(&*It);
899 if (DeadDefs.empty())
901 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
902 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
910 unsigned ResultPos = 0;
913 Edit->eraseVirtReg(
Reg);
914 RegsReplaced.push_back(
Reg);
920 "Empty and not used live-range?!");
922 RegsToSpill[ResultPos++] =
Reg;
924 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
926 <<
" registers to spill after remat.\n");
937 bool IsLoad = InstrReg.
isValid();
942 if (InstrReg !=
Reg || FI != StackSlot)
946 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
949 LIS.RemoveMachineInstrFromMaps(*
MI);
950 MI->eraseFromParent();
963#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
969 const char *
const header,
971 char NextLine =
'\n';
972 char SlotIndent =
'\t';
974 if (std::next(
B) ==
E) {
979 dbgs() <<
'\t' << header <<
": " << NextLine;
990 Idx = Idx.getRegSlot(
true);
993 dbgs() << SlotIndent << Idx <<
'\t' << *
I;
1005foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>
Ops,
1011 if (
Ops.back().first !=
MI ||
MI->isBundled())
1014 bool WasCopy =
TII.isCopyInstr(*MI).has_value();
1023 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
1027 bool SpillSubRegs =
TII.isSubregFoldable() ||
1028 MI->getOpcode() == TargetOpcode::STATEPOINT ||
1029 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
1030 MI->getOpcode() == TargetOpcode::STACKMAP;
1035 for (
const auto &OpPair :
Ops) {
1036 unsigned Idx = OpPair.second;
1037 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
1054 if (LoadMI && MO.
isDef())
1057 if (UntieRegs || !
MI->isRegTiedToDefOperand(Idx))
1063 if (FoldOps.
empty())
1070 for (
unsigned Idx : FoldOps) {
1074 unsigned Tied =
MI->findTiedOperandIdx(Idx);
1081 MI->untieRegOperand(Idx);
1087 ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, CopyMI, &LIS, &VRM)
1088 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, CopyMI, &LIS, &VRM);
1091 for (
auto Tied : TiedOps)
1092 MI->tieOperands(Tied.first, Tied.second);
1118 HSpiller.rmFromMergeableSpills(*
MI, FI))
1134 bool NeedMatrixReassign =
1137 if (NeedMatrixReassign) {
1138 PhysReg = VRM.getPhys(CopyDstReg);
1145 if (NeedMatrixReassign)
1146 Matrix->assign(LI, PhysReg);
1148 Register OrigReg = VRM.getOriginal(CopyDstReg);
1149 if (OrigReg != CopyDstReg) {
1164 if (
MI->isCandidateForAdditionalCallInfo())
1165 MI->getMF()->moveAdditionalCallInfo(
MI, FoldMI);
1172 if (
MI->peekDebugInstrNum() &&
Ops[0].second == 0) {
1174 auto MakeSubstitution = [
this,FoldMI,
MI,&
Ops]() {
1176 unsigned OldOperandNum =
Ops[0].second;
1178 unsigned OldNum =
MI->getDebugInstrNum();
1179 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1184 if (
Ops.size() == 1 && Op0.
isDef()) {
1186 }
else if (
Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
1187 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
1190 }
else if (
MI->peekDebugInstrNum()) {
1196 MF.substituteDebugValuesForInst(*
MI, *FoldMI,
Ops[0].second);
1199 MI->eraseFromParent();
1202 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
1204 if (&
MI != FoldMI && &
MI != CopyMI)
1209 if (
R.isVirtual()) {
1224 if (MO.
getReg() == ImpReg)
1233 else if (
Ops.front().second == 0) {
1238 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1239 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1245void InlineSpiller::insertReload(
Register NewVReg,
1265 if (!Def.isImplicitDef())
1271 return MO.getReg() == Reg && MO.readsReg();
1276void InlineSpiller::insertSpill(
Register NewVReg,
1280 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1295 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1309 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1310 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1314void InlineSpiller::spillAroundUses(
Register Reg) {
1321 if (
MI.isDebugValue()) {
1330 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1331 "instruction that isn't a DBG_VALUE");
1334 if (SnippetCopies.count(&
MI))
1338 if (coalesceStackAccess(&
MI,
Reg))
1354 if (SibReg && isSibling(SibReg)) {
1356 if (isRegToSpill(SibReg)) {
1358 SnippetCopies.insert(&
MI);
1362 if (hoistSpillInsideBB(OldLI,
MI)) {
1364 MI.getOperand(0).setIsDead();
1365 DeadDefs.push_back(&
MI);
1371 eliminateRedundantSpills(SibLI, SibLI.
getVNInfoAt(Idx));
1377 if (foldMemoryOperand(
Ops))
1385 insertReload(NewVReg, Idx, &
MI);
1388 bool hasLiveDef =
false;
1389 for (
const auto &OpPair :
Ops) {
1400 insertSpill(NewVReg, &
MI);
1405void InlineSpiller::spillAll() {
1408 StackSlot = VRM.assignVirt2StackSlot(Original);
1409 StackInt = &LSS.getOrCreateInterval(StackSlot,
MRI.
getRegClass(Original));
1410 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1412 StackInt = &LSS.getInterval(StackSlot);
1414 if (Original != Edit->getReg())
1415 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1417 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1421 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1425 spillAroundUses(
Reg);
1429 VRM.assignVirt2StackSlot(
Reg, StackSlot);
1433 if (!DeadDefs.empty()) {
1434 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1435 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1442 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1445 MI.eraseFromBundle();
1451 Edit->eraseVirtReg(
Reg);
1460 Original = VRM.getOriginal(edit.
getReg());
1461 StackSlot = VRM.getStackSlot(Original);
1466 <<
':' << edit.
getParent() <<
"\nFrom original "
1469 "Attempting to spill already spilled value.");
1470 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1472 collectRegsToSpill();
1476 if (!RegsToSpill.empty())
1479 Edit->calculateRegClassAndHint(MF, VRAI);
1483void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1486void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1493 auto [Place,
Inserted] = StackSlotToOrigLI.try_emplace(StackSlot);
1495 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1497 Place->second = std::move(LI);
1501 VNInfo *OrigVNI = Place->second->getVNInfoAt(
Idx.getRegSlot());
1502 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1503 MergeableSpills[MIdx].insert(&Spill);
1508bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1510 auto It = StackSlotToOrigLI.find(StackSlot);
1511 if (It == StackSlotToOrigLI.end())
1514 VNInfo *OrigVNI = It->second->getVNInfoAt(
Idx.getRegSlot());
1515 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1516 return MergeableSpills[MIdx].erase(&Spill);
1526 if (Idx < OrigVNI.
def) {
1529 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1536 for (
const Register &SibReg : Siblings) {
1544 return SR.getVNInfoAt(Idx) != nullptr;
1555void HoistSpillHelper::rmRedundantSpills(
1562 for (
auto *
const CurrentSpill : Spills) {
1569 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1570 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1572 SpillBBToSpill[MDT.getNode(
Block)] = SpillToKeep;
1574 SpillBBToSpill[MDT.getNode(
Block)] = CurrentSpill;
1577 for (
auto *
const SpillToRm : SpillsToRm)
1578 Spills.erase(SpillToRm);
1587void HoistSpillHelper::getVisitOrders(
1611 for (
auto *
const Spill : Spills) {
1615 while (Node != RootIDomNode) {
1618 if (Node != MDT[
Block] && SpillBBToSpill[Node]) {
1619 SpillToRm = SpillBBToSpill[MDT[
Block]];
1624 }
else if (WorkSet.
count(Node)) {
1627 NodesOnPath.
insert(Node);
1642 NodesOnPath.
clear();
1652 if (WorkSet.
count(Child))
1655 }
while (idx != Orders.
size());
1657 "Orders have different size with WorkSet");
1662 for (; RIt != Orders.
rend(); RIt++)
1663 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1671void HoistSpillHelper::runHoistSpills(
1687 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1690 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1697 using NodesCostPair =
1698 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1706 for (; RIt != Orders.
rend(); RIt++) {
1710 if (
auto It = SpillsToKeep.
find(*RIt);
1711 It != SpillsToKeep.
end() && !It->second) {
1712 auto &SIt = SpillsInSubTreeMap[*RIt];
1715 SIt.second = MBFI.getBlockFreq(
Block);
1722 if (!SpillsInSubTreeMap.
contains(Child))
1730 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1731 auto ChildIt = SpillsInSubTreeMap.
find(Child);
1732 SubTreeCost += ChildIt->second.second;
1733 auto BI = ChildIt->second.first.begin();
1734 auto EI = ChildIt->second.first.end();
1735 SpillsInSubTree.insert(BI, EI);
1736 SpillsInSubTreeMap.
erase(ChildIt);
1739 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1741 if (SpillsInSubTree.empty())
1746 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1754 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1756 for (auto *const SpillBB : SpillsInSubTree) {
1759 if (auto It = SpillsToKeep.find(SpillBB);
1760 It != SpillsToKeep.end() && !It->second) {
1761 MachineInstr *SpillToRm = SpillBBToSpill[SpillBB];
1762 SpillsToRm.push_back(SpillToRm);
1765 SpillsToKeep.erase(SpillBB);
1769 SpillsToKeep[*RIt] = LiveReg;
1771 dbgs() <<
"spills in BB: ";
1772 for (
const auto Rspill : SpillsInSubTree)
1773 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1774 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1777 SpillsInSubTree.clear();
1778 SpillsInSubTree.insert(*RIt);
1779 SubTreeCost = MBFI.getBlockFreq(
Block);
1784 for (
const auto &Ent : SpillsToKeep) {
1786 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1806void HoistSpillHelper::hoistAllSpills() {
1814 Virt2SiblingsMap[Original].insert(
Reg);
1818 for (
auto &Ent : MergeableSpills) {
1819 int Slot = Ent.first.first;
1821 VNInfo *OrigVNI = Ent.first.second;
1823 if (Ent.second.empty())
1827 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1828 <<
"Equal spills in BB: ";
1829 for (
const auto spill : EqValSpills)
1830 dbgs() << spill->getParent()->getNumber() <<
" ";
1839 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1842 dbgs() <<
"Finally inserted spills in BB: ";
1843 for (
const auto &Ispill : SpillsToIns)
1844 dbgs() << Ispill.first->getNumber() <<
" ";
1845 dbgs() <<
"\nFinally removed spills in BB: ";
1846 for (
const auto Rspill : SpillsToRm)
1847 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1853 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1855 StackIntvl.getValNumInfo(0));
1858 for (
auto const &Insert : SpillsToIns) {
1872 NumSpills -= SpillsToRm.size();
1873 for (
auto *
const RMEnt : SpillsToRm) {
1874 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1875 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1878 RMEnt->removeOperand(i - 1);
1881 Edit.eliminateDeadDefs(SpillsToRm, {});
1886 for (
auto &[VReg, PhysReg] : PendingReassignments) {
1888 "Pending reassignment without matrix or live interval");
1891 PendingReassignments.clear();
1898void HoistSpillHelper::LRE_WillShrinkVirtReg(
Register VirtReg) {
1904 Matrix->unassign(LI,
true);
1905 PendingReassignments[VirtReg] = PhysReg;
1911bool HoistSpillHelper::LRE_CanEraseVirtReg(
Register VirtReg) {
1912 PendingReassignments.erase(VirtReg);
1913 if (
Matrix && VRM.hasPhys(VirtReg)) {
1915 Matrix->unassign(LI,
true);
1927 auto PendingIt = PendingReassignments.find(Old);
1928 if (PendingIt != PendingReassignments.end()) {
1932 "Pending reassignment without matrix or live interval");
1934 PendingReassignments.erase(PendingIt);
1939 }
else if (VRM.hasPhys(Old)) {
1945 Matrix->unassign(LI,
true);
1946 Matrix->assign(LI, PhysReg);
1950 VRM.assignVirt2Phys(New, PhysReg);
1953 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1957 if (VRM.hasShape(Old))
1958 VRM.assignVirt2Shape(New, VRM.getShape(Old));
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static LLVM_DUMP_METHOD void dumpMachineInstrRangeWithSlotIndex(MachineBasicBlock::iterator B, MachineBasicBlock::iterator E, LiveIntervals const &LIS, const char *const header, Register VReg=Register())
static Register isCopyOfBundle(const MachineInstr &FirstMI, Register Reg, const TargetInstrInfo &TII)
Check for a copy bundle as formed by SplitKit.
static bool isRealSpill(const MachineInstr &Def, Register Reg)
Check if Def defines Reg with an undefined value.
static cl::opt< bool > RestrictStatepointRemat("restrict-statepoint-remat", cl::init(false), cl::Hidden, cl::desc("Restrict remat for statepoint operands"))
static Register isCopyOf(const MachineInstr &MI, Register Reg, const TargetInstrInfo &TII)
isFullCopyOf - If MI is a COPY to or from Reg, return the other register, otherwise return 0.
static void getVDefInterval(const MachineInstr &MI, LiveIntervals &LIS)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
Promote Memory to Register
MachineRegisterInfo & MRI
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
Determines the latest safe point in a block in which we can insert a split, spill or other instructio...
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool isSpillable() const
isSpillable - Can this interval be spilled?
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
bool hasInterval(Register Reg) const
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
VNInfo::Allocator & getVNInfoAllocator()
LiveInterval & getInterval(Register Reg)
void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B, MachineBasicBlock::iterator E)
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
Result of a LiveRange query.
SlotIndex endPoint() const
Return the end point of the last live range segment to interact with the instruction,...
bool isKill() const
Return true if the live-in value is killed by this instruction.
Callback methods for LiveRangeEdit owners.
const LiveInterval & getParent() const
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
LLVM_ABI void MergeValueInAsValue(const LiveRange &RHS, const VNInfo *RHSValNo, VNInfo *LHSValNo)
MergeValueInAsValue - Merge all of the segments of a specific val# in RHS into this live range as the...
iterator_range< vni_iterator > vnis()
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
LLVM_ABI std::pair< VNInfo *, bool > extendInBlock(ArrayRef< SlotIndex > Undefs, SlotIndex StartIdx, SlotIndex Kill)
Attempt to extend a value defined after StartIdx to include Use.
unsigned getNumValNums() const
VNInfo * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
void assign(const LiveRange &Other, BumpPtrAllocator &Allocator)
Copies values numbers and live segments from Other into this range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Wrapper class representing physical registers. Should be passed by value.
MIBundleOperands - Iterate over all operands in a bundle of machine instructions.
LLVM_ABI iterator SkipPHIsLabelsAndDebug(iterator I, Register Reg=Register(), bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
Instructions::iterator instr_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
static const unsigned int DebugOperandMemNumber
A reserved operand number representing the instructions memory operand, for instructions that have a ...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
MachineInstrSpan provides an interface to get an iteration range containing the instruction it was in...
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
bool isBundledWithPred() const
Return true if this instruction is part of a bundle, and it is not the first instruction in the bundl...
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
bool isBundledWithSucc() const
Return true if this instruction is part of a bundle, and it is not the last instruction in the bundle...
LLVM_ABI unsigned getDebugInstrNum()
Fetch the instruction number of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
bool isBundled() const
Return true if this instruction part of a bundle.
LLVM_ABI bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
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.
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< reg_bundle_iterator > reg_bundles(Register Reg) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
reg_bundle_nodbg_iterator reg_bundle_nodbg_begin(Register RegNo) const
defusechain_instr_iterator< true, true, true, false > reg_bundle_nodbg_iterator
reg_bundle_nodbg_iterator/reg_bundle_nodbg_begin/reg_bundle_nodbg_end - Walk all defs and uses of the...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
iterator_range< use_bundle_nodbg_iterator > use_nodbg_bundles(Register Reg) const
bool def_empty(Register RegNo) const
def_empty - Return true if there are no instructions defining the specified register (it may be live-...
bool reg_nodbg_empty(Register RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions.
static reg_bundle_nodbg_iterator reg_bundle_nodbg_end()
iterator_range< reg_instr_iterator > reg_instructions(Register Reg) const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
This class implements a map that also provides access to all stored values in a deterministic order.
Wrapper class representing virtual and physical registers.
constexpr bool isStack() const
Return true if this is a stack slot.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
LLVM_ABI void removeSingleMachineInstrFromMaps(MachineInstr &MI)
Removes a single machine instruction MI from the mapping.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
reverse_iterator rbegin()
std::reverse_iterator< iterator > reverse_iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level Statepoint operands.
LLVM_ABI bool isFoldableReg(Register Reg) const
Return true if Reg is used only in operands which can be folded to stack usage.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VNInfo - Value Number Information.
bool isUnused() const
Returns true if this value is unused.
unsigned id
The ID number of this value.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
Calculate auxiliary information for a virtual register such as its spill weight and allocation hint.
static constexpr int NO_STACK_SLOT
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI PhysRegInfo AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg, const TargetRegisterInfo *TRI)
AnalyzePhysRegInBundle - Analyze how the current instruction or bundle uses a physical register.
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix=nullptr)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI VirtRegInfo AnalyzeVirtRegInBundle(MachineInstr &MI, Register Reg, SmallVectorImpl< std::pair< MachineInstr *, unsigned > > *Ops=nullptr)
AnalyzeVirtRegInBundle - Analyze how the current instruction or bundle uses a virtual register.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool canGuaranteeAssignmentAfterRemat(Register VReg, const MachineInstr &MI)
Return whether we can guarantee physical register assignment if VReg's value is rematerialized immedi...
LLVM_ABI MachineInstr * buildDbgValueForSpill(MachineBasicBlock &BB, MachineBasicBlock::iterator I, const MachineInstr &Orig, int FrameIndex, Register SpillReg)
Clone a DBG_VALUE whose value has been spilled to FrameIndex.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
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.
static constexpr LaneBitmask getAll()
static constexpr LaneBitmask getNone()
Remat - Information needed to rematerialize at a specific location.
This represents a simple continuous liveness interval for a value.
Information about how a physical register Reg is used by a set of operands.
bool FullyDefined
Reg or a super-register is defined.
VirtRegInfo - Information about a virtual register used by a set of operands.
bool Reads
Reads - One of the operands read the virtual register.
bool Tied
Tied - Uses and defs must use the same register.
bool Writes
Writes - One of the operands writes the virtual register.