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 Def.getOperand(0).getSubReg();
1275void InlineSpiller::insertSpill(
Register NewVReg,
1279 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1294 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1308 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1309 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1313void InlineSpiller::spillAroundUses(
Register Reg) {
1320 if (
MI.isDebugValue()) {
1329 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1330 "instruction that isn't a DBG_VALUE");
1333 if (SnippetCopies.count(&
MI))
1337 if (coalesceStackAccess(&
MI,
Reg))
1353 if (SibReg && isSibling(SibReg)) {
1355 if (isRegToSpill(SibReg)) {
1357 SnippetCopies.insert(&
MI);
1361 if (hoistSpillInsideBB(OldLI,
MI)) {
1363 MI.getOperand(0).setIsDead();
1364 DeadDefs.push_back(&
MI);
1370 eliminateRedundantSpills(SibLI, SibLI.
getVNInfoAt(Idx));
1376 if (foldMemoryOperand(
Ops))
1384 insertReload(NewVReg, Idx, &
MI);
1387 bool hasLiveDef =
false;
1388 for (
const auto &OpPair :
Ops) {
1399 insertSpill(NewVReg, &
MI);
1404void InlineSpiller::spillAll() {
1407 StackSlot = VRM.assignVirt2StackSlot(Original);
1408 StackInt = &LSS.getOrCreateInterval(StackSlot,
MRI.
getRegClass(Original));
1409 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1411 StackInt = &LSS.getInterval(StackSlot);
1413 if (Original != Edit->getReg())
1414 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1416 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1420 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1424 spillAroundUses(
Reg);
1428 VRM.assignVirt2StackSlot(
Reg, StackSlot);
1432 if (!DeadDefs.empty()) {
1433 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1434 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1441 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1444 MI.eraseFromBundle();
1450 Edit->eraseVirtReg(
Reg);
1459 Original = VRM.getOriginal(edit.
getReg());
1460 StackSlot = VRM.getStackSlot(Original);
1465 <<
':' << edit.
getParent() <<
"\nFrom original "
1468 "Attempting to spill already spilled value.");
1469 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1471 collectRegsToSpill();
1475 if (!RegsToSpill.empty())
1478 Edit->calculateRegClassAndHint(MF, VRAI);
1482void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1485void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1492 auto [Place,
Inserted] = StackSlotToOrigLI.try_emplace(StackSlot);
1494 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1496 Place->second = std::move(LI);
1500 VNInfo *OrigVNI = Place->second->getVNInfoAt(
Idx.getRegSlot());
1501 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1502 MergeableSpills[MIdx].insert(&Spill);
1507bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1509 auto It = StackSlotToOrigLI.find(StackSlot);
1510 if (It == StackSlotToOrigLI.end())
1513 VNInfo *OrigVNI = It->second->getVNInfoAt(
Idx.getRegSlot());
1514 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1515 return MergeableSpills[MIdx].erase(&Spill);
1525 if (Idx < OrigVNI.
def) {
1528 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1535 for (
const Register &SibReg : Siblings) {
1543 return SR.getVNInfoAt(Idx) != nullptr;
1554void HoistSpillHelper::rmRedundantSpills(
1561 for (
auto *
const CurrentSpill : Spills) {
1568 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1569 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1571 SpillBBToSpill[MDT.getNode(
Block)] = SpillToKeep;
1573 SpillBBToSpill[MDT.getNode(
Block)] = CurrentSpill;
1576 for (
auto *
const SpillToRm : SpillsToRm)
1577 Spills.erase(SpillToRm);
1586void HoistSpillHelper::getVisitOrders(
1610 for (
auto *
const Spill : Spills) {
1614 while (Node != RootIDomNode) {
1617 if (Node != MDT[
Block] && SpillBBToSpill[Node]) {
1618 SpillToRm = SpillBBToSpill[MDT[
Block]];
1623 }
else if (WorkSet.
count(Node)) {
1626 NodesOnPath.
insert(Node);
1641 NodesOnPath.
clear();
1651 if (WorkSet.
count(Child))
1654 }
while (idx != Orders.
size());
1656 "Orders have different size with WorkSet");
1661 for (; RIt != Orders.
rend(); RIt++)
1662 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1670void HoistSpillHelper::runHoistSpills(
1686 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1689 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1696 using NodesCostPair =
1697 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1705 for (; RIt != Orders.
rend(); RIt++) {
1709 if (
auto It = SpillsToKeep.
find(*RIt);
1710 It != SpillsToKeep.
end() && !It->second) {
1711 auto &SIt = SpillsInSubTreeMap[*RIt];
1714 SIt.second = MBFI.getBlockFreq(
Block);
1721 if (!SpillsInSubTreeMap.
contains(Child))
1729 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1730 auto ChildIt = SpillsInSubTreeMap.
find(Child);
1731 SubTreeCost += ChildIt->second.second;
1732 auto BI = ChildIt->second.first.begin();
1733 auto EI = ChildIt->second.first.end();
1734 SpillsInSubTree.insert(BI, EI);
1735 SpillsInSubTreeMap.
erase(ChildIt);
1738 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1740 if (SpillsInSubTree.empty())
1745 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1753 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1755 for (auto *const SpillBB : SpillsInSubTree) {
1758 if (auto It = SpillsToKeep.find(SpillBB);
1759 It != SpillsToKeep.end() && !It->second) {
1760 MachineInstr *SpillToRm = SpillBBToSpill[SpillBB];
1761 SpillsToRm.push_back(SpillToRm);
1764 SpillsToKeep.erase(SpillBB);
1768 SpillsToKeep[*RIt] = LiveReg;
1770 dbgs() <<
"spills in BB: ";
1771 for (
const auto Rspill : SpillsInSubTree)
1772 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1773 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1776 SpillsInSubTree.clear();
1777 SpillsInSubTree.insert(*RIt);
1778 SubTreeCost = MBFI.getBlockFreq(
Block);
1783 for (
const auto &Ent : SpillsToKeep) {
1785 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1805void HoistSpillHelper::hoistAllSpills() {
1813 Virt2SiblingsMap[Original].insert(
Reg);
1817 for (
auto &Ent : MergeableSpills) {
1818 int Slot = Ent.first.first;
1820 VNInfo *OrigVNI = Ent.first.second;
1822 if (Ent.second.empty())
1826 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1827 <<
"Equal spills in BB: ";
1828 for (
const auto spill : EqValSpills)
1829 dbgs() << spill->getParent()->getNumber() <<
" ";
1838 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1841 dbgs() <<
"Finally inserted spills in BB: ";
1842 for (
const auto &Ispill : SpillsToIns)
1843 dbgs() << Ispill.first->getNumber() <<
" ";
1844 dbgs() <<
"\nFinally removed spills in BB: ";
1845 for (
const auto Rspill : SpillsToRm)
1846 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1852 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1854 StackIntvl.getValNumInfo(0));
1857 for (
auto const &Insert : SpillsToIns) {
1871 NumSpills -= SpillsToRm.size();
1872 for (
auto *
const RMEnt : SpillsToRm) {
1873 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1874 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1877 RMEnt->removeOperand(i - 1);
1880 Edit.eliminateDeadDefs(SpillsToRm, {});
1885 for (
auto &[VReg, PhysReg] : PendingReassignments) {
1887 "Pending reassignment without matrix or live interval");
1890 PendingReassignments.clear();
1897void HoistSpillHelper::LRE_WillShrinkVirtReg(
Register VirtReg) {
1903 Matrix->unassign(LI,
true);
1904 PendingReassignments[VirtReg] = PhysReg;
1910bool HoistSpillHelper::LRE_CanEraseVirtReg(
Register VirtReg) {
1911 PendingReassignments.erase(VirtReg);
1912 if (
Matrix && VRM.hasPhys(VirtReg)) {
1914 Matrix->unassign(LI,
true);
1926 auto PendingIt = PendingReassignments.find(Old);
1927 if (PendingIt != PendingReassignments.end()) {
1931 "Pending reassignment without matrix or live interval");
1933 PendingReassignments.erase(PendingIt);
1938 }
else if (VRM.hasPhys(Old)) {
1944 Matrix->unassign(LI,
true);
1945 Matrix->assign(LI, PhysReg);
1949 VRM.assignVirt2Phys(New, PhysReg);
1952 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1956 if (VRM.hasShape(Old))
1957 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)
Check if Def fully defines a VReg 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...
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.