46#include "llvm/Config/llvm-config.h"
61#define DEBUG_TYPE "regalloc"
63STATISTIC(NumSpilledRanges,
"Number of spilled live ranges");
64STATISTIC(NumSnippets,
"Number of spilled snippets");
66STATISTIC(NumSpillsRemoved,
"Number of spills removed");
68STATISTIC(NumReloadsRemoved,
"Number of reloads removed");
69STATISTIC(NumFolded,
"Number of folded stack accesses");
71STATISTIC(NumRemats,
"Number of rematerialized defs for spilling");
76 cl::desc(
"Restrict remat for statepoint operands"));
102 using MergeableSpillsMap =
104 MergeableSpillsMap MergeableSpills;
114 void rmRedundantSpills(
134 : MF(mf), LIS(Analyses.LIS), LSS(Analyses.LSS), MDT(Analyses.MDT),
135 VRM(vrm), MRI(mf.getRegInfo()),
TII(*mf.getSubtarget().getInstrInfo()),
136 TRI(*mf.getSubtarget().getRegisterInfo()), MBFI(Analyses.MBFI),
137 Matrix(matrix), IPA(LIS, mf.getNumBlockIDs()) {}
139 void addToMergeableSpills(MachineInstr &Spill,
int StackSlot,
141 bool rmFromMergeableSpills(MachineInstr &Spill,
int StackSlot);
142 void hoistAllSpills();
143 void LRE_WillShrinkVirtReg(
Register)
override;
144 bool LRE_CanEraseVirtReg(
Register)
override;
150 DenseMap<Register, MCRegister> PendingReassignments;
153class InlineSpiller :
public Spiller {
158 MachineRegisterInfo &MRI;
159 const TargetInstrInfo &TII;
160 const TargetRegisterInfo &TRI;
161 LiveRegMatrix *Matrix =
nullptr;
164 LiveRangeEdit *Edit =
nullptr;
165 LiveInterval *StackInt =
nullptr;
168 AllocationOrder *Order =
nullptr;
180 SmallPtrSet<MachineInstr*, 8> SnippetCopies;
183 SmallPtrSet<VNInfo*, 8> UsedValues;
186 SmallVector<MachineInstr*, 8> DeadDefs;
189 HoistSpillHelper HSpiller;
192 VirtRegAuxInfo &VRAI;
194 ~InlineSpiller()
override =
default;
197 InlineSpiller(
const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF,
198 VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix)
199 : MF(MF), LIS(Analyses.LIS), LSS(Analyses.LSS), VRM(VRM),
200 MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
201 TRI(*MF.getSubtarget().getRegisterInfo()), Matrix(Matrix),
202 HSpiller(Analyses, MF, VRM, Matrix), VRAI(VRAI) {}
204 void spill(LiveRangeEdit &, AllocationOrder *Order =
nullptr)
override;
207 void postOptimization()
override;
210 bool isSnippet(
const LiveInterval &SnipLI);
211 void collectRegsToSpill();
216 bool hoistSpillInsideBB(LiveInterval &SpillLI, MachineInstr &CopyMI);
217 void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI);
219 void markValueUsed(LiveInterval*, VNInfo*);
220 bool canGuaranteeAssignmentAfterRemat(
Register VReg, MachineInstr &
MI);
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)
358 RI = MRI.reg_bundle_nodbg_begin(SnipLI.
reg()),
359 E = MRI.reg_bundle_nodbg_end();
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,
443 SlotIndex Idx = LIS.getInstructionIndex(CopyMI);
460 assert(StackInt &&
"No stack slot assigned yet.");
463 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
465 << *StackInt <<
'\n');
469 eliminateRedundantSpills(SrcLI, SrcVNI);
477 assert(
DefMI &&
"Defining instruction disappeared");
484 MRI.getRegClass(SrcReg),
Register());
485 LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
502 if (MIS.begin() == MII)
503 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
511 assert(VNI &&
"Missing value");
513 WorkList.
push_back(std::make_pair(&SLI, VNI));
514 assert(StackInt &&
"No stack slot assigned yet.");
521 << VNI->
def <<
" in " << *LI <<
'\n');
524 if (isRegToSpill(
Reg))
528 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
529 LLVM_DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
534 if (!
MI.mayStore() && !
TII.isCopyInstr(
MI))
542 if (isSibling(DstReg)) {
545 assert(DstVNI &&
"Missing defined value");
548 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
558 MI.setDesc(
TII.get(TargetOpcode::KILL));
559 DeadDefs.push_back(&
MI);
561 if (HSpiller.rmFromMergeableSpills(
MI, StackSlot))
565 }
while (!WorkList.
empty());
576 WorkList.
push_back(std::make_pair(LI, VNI));
579 if (!UsedValues.insert(VNI).second)
587 WorkList.
push_back(std::make_pair(LI, PVNI));
594 if (!SnippetCopies.count(
MI))
596 LiveInterval &SnipLI = LIS.getInterval(
MI->getOperand(1).getReg());
597 assert(isRegToSpill(SnipLI.
reg()) &&
"Unexpected register in copy");
599 assert(SnipVNI &&
"Snippet undefined before copy");
600 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
601 }
while (!WorkList.
empty());
604bool InlineSpiller::canGuaranteeAssignmentAfterRemat(
Register VReg,
623 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
629 EndIdx =
MI.getNumOperands();
630 Idx < EndIdx; ++Idx) {
648 if (!
Matrix->checkInterference(PrevIdx, UseIdx, PhysReg))
682 if (SnippetCopies.count(&
MI)) {
683 LLVM_DEBUG(
dbgs() <<
"\tskipping remat snippet copy for " << UseIdx <<
'\t'
690 assert(OrigVNI &&
"corrupted sub-interval");
708 CurDef = LIS.getInstructionFromIndex(CurVNI->
def);
725 if (CurDef &&
TII.isReMaterializable(*CurDef)) {
727 LLVM_DEBUG(
dbgs() <<
"\tFound remat possibility through COPY chain: "
731 markValueUsed(&VirtReg, ParentVNI);
732 LLVM_DEBUG(
dbgs() <<
"\tcannot remat missing def for " << UseIdx <<
'\t'
740 if (!Edit->canRematerializeAt(RM, UseIdx)) {
741 markValueUsed(&VirtReg, ParentVNI);
749 markValueUsed(&VirtReg, ParentVNI);
756 if (
RM.OrigMI->canFoldAsLoad() &&
757 (
RM.OrigMI->mayLoad() || !hasPhysRegAvailable(
MI)) &&
758 foldMemoryOperand(
Ops,
RM.OrigMI)) {
759 Edit->markRematerialized(
RM.ParentVNI);
766 if (!canGuaranteeAssignmentAfterRemat(VirtReg.
reg(),
MI)) {
767 markValueUsed(&VirtReg, ParentVNI);
773 Register NewVReg = Edit->createFrom(Original);
776 MRI.constrainRegClass(NewVReg, MRI.getRegClass(VirtReg.
reg()));
783 if (SR.liveAt(UseIdx))
784 UsedLanes |= SR.LaneMask;
788 SlotIndex DefIdx = Edit->rematerializeAt(*
MI.getParent(),
MI, NewVReg, RM,
789 TRI,
false, 0,
nullptr, UsedLanes);
793 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
794 NewMI->setDebugLoc(
MI.getDebugLoc());
798 << *LIS.getInstructionFromIndex(DefIdx));
801 for (
const auto &OpPair :
Ops) {
816void InlineSpiller::reMaterializeAll() {
820 bool anyRemat =
false;
825 if (
MI.isDebugValue())
828 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
829 "instruction that isn't a DBG_VALUE");
831 anyRemat |= reMaterializeFor(LI,
MI);
845 if (!
MI->allDefsAreDead())
848 DeadDefs.push_back(
MI);
852 if (
MI->isBundledWithSucc() && !
MI->isBundledWithPred()) {
854 EndIt =
MI->getParent()->instr_end();
857 bool OnlyDeadCopies =
true;
859 It != EndIt && It->isBundledWithPred(); ++It) {
861 auto DestSrc =
TII.isCopyInstr(*It);
862 bool IsCopyToDeadReg =
863 DestSrc && DestSrc->Destination->getReg() ==
Reg;
864 if (!IsCopyToDeadReg) {
865 OnlyDeadCopies =
false;
869 if (OnlyDeadCopies) {
871 It != EndIt && It->isBundledWithPred(); ++It) {
872 It->addRegisterDead(
Reg, &
TRI);
874 DeadDefs.push_back(&*It);
883 if (DeadDefs.empty())
885 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
886 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
894 unsigned ResultPos = 0;
896 if (MRI.reg_nodbg_empty(
Reg)) {
897 Edit->eraseVirtReg(
Reg);
898 RegsReplaced.push_back(
Reg);
903 (!LIS.getInterval(
Reg).empty() || !MRI.reg_nodbg_empty(
Reg)) &&
904 "Empty and not used live-range?!");
906 RegsToSpill[ResultPos++] =
Reg;
908 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
910 <<
" registers to spill after remat.\n");
921 bool IsLoad = InstrReg.
isValid();
926 if (InstrReg !=
Reg || FI != StackSlot)
930 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
933 LIS.RemoveMachineInstrFromMaps(*
MI);
934 MI->eraseFromParent();
947#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
953 const char *
const header,
955 char NextLine =
'\n';
956 char SlotIndent =
'\t';
958 if (std::next(
B) ==
E) {
963 dbgs() <<
'\t' << header <<
": " << NextLine;
977 dbgs() << SlotIndent << Idx <<
'\t' << *
I;
989foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>
Ops,
995 if (
Ops.back().first !=
MI ||
MI->isBundled())
998 bool WasCopy =
TII.isCopyInstr(*MI).has_value();
1007 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
1011 bool SpillSubRegs =
TII.isSubregFoldable() ||
1012 MI->getOpcode() == TargetOpcode::STATEPOINT ||
1013 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
1014 MI->getOpcode() == TargetOpcode::STACKMAP;
1019 for (
const auto &OpPair :
Ops) {
1020 unsigned Idx = OpPair.second;
1021 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
1038 if (LoadMI && MO.
isDef())
1041 if (UntieRegs || !
MI->isRegTiedToDefOperand(Idx))
1047 if (FoldOps.
empty())
1054 for (
unsigned Idx : FoldOps) {
1058 unsigned Tied =
MI->findTiedOperandIdx(Idx);
1065 MI->untieRegOperand(Idx);
1071 ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, CopyMI, &LIS, &VRM)
1072 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, CopyMI, &LIS, &VRM);
1075 for (
auto Tied : TiedOps)
1076 MI->tieOperands(Tied.first, Tied.second);
1102 HSpiller.rmFromMergeableSpills(*
MI, FI))
1118 bool NeedMatrixReassign =
1121 if (NeedMatrixReassign) {
1122 PhysReg = VRM.getPhys(CopyDstReg);
1129 if (NeedMatrixReassign)
1130 Matrix->assign(LI, PhysReg);
1132 Register OrigReg = VRM.getOriginal(CopyDstReg);
1133 if (OrigReg != CopyDstReg) {
1148 if (
MI->isCandidateForAdditionalCallInfo())
1149 MI->getMF()->moveAdditionalCallInfo(
MI, FoldMI);
1156 if (
MI->peekDebugInstrNum() &&
Ops[0].second == 0) {
1158 auto MakeSubstitution = [
this,FoldMI,
MI,&
Ops]() {
1160 unsigned OldOperandNum =
Ops[0].second;
1162 unsigned OldNum =
MI->getDebugInstrNum();
1163 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1168 if (
Ops.size() == 1 && Op0.
isDef()) {
1170 }
else if (
Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
1171 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
1174 }
else if (
MI->peekDebugInstrNum()) {
1180 MF.substituteDebugValuesForInst(*
MI, *FoldMI,
Ops[0].second);
1183 MI->eraseFromParent();
1186 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
1188 if (&
MI != FoldMI && &
MI != CopyMI)
1193 if (
R.isVirtual()) {
1197 assert(MRI.isReserved(R) &&
"Unexpected PhysReg in source operand!");
1208 if (MO.
getReg() == ImpReg)
1217 else if (
Ops.front().second == 0) {
1222 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1223 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1229void InlineSpiller::insertReload(
Register NewVReg,
1236 MRI.getRegClass(NewVReg),
Register());
1249 if (!Def.isImplicitDef())
1255 return Def.getOperand(0).getSubReg();
1259void InlineSpiller::insertSpill(
Register NewVReg,
bool isKill,
1263 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1272 MRI.getRegClass(NewVReg),
Register());
1278 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1292 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1293 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1297void InlineSpiller::spillAroundUses(
Register Reg) {
1304 if (
MI.isDebugValue()) {
1313 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1314 "instruction that isn't a DBG_VALUE");
1317 if (SnippetCopies.count(&
MI))
1321 if (coalesceStackAccess(&
MI,
Reg))
1337 if (SibReg && isSibling(SibReg)) {
1339 if (isRegToSpill(SibReg)) {
1341 SnippetCopies.insert(&
MI);
1345 if (hoistSpillInsideBB(OldLI,
MI)) {
1347 MI.getOperand(0).setIsDead();
1348 DeadDefs.push_back(&
MI);
1354 eliminateRedundantSpills(SibLI, SibLI.
getVNInfoAt(Idx));
1360 if (foldMemoryOperand(
Ops))
1368 insertReload(NewVReg, Idx, &
MI);
1371 bool hasLiveDef =
false;
1372 for (
const auto &OpPair :
Ops) {
1376 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
1388 insertSpill(NewVReg,
true, &
MI);
1393void InlineSpiller::spillAll() {
1396 StackSlot = VRM.assignVirt2StackSlot(Original);
1397 StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
1398 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1400 StackInt = &LSS.getInterval(StackSlot);
1402 if (Original != Edit->getReg())
1403 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1405 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1409 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1413 spillAroundUses(
Reg);
1417 VRM.assignVirt2StackSlot(
Reg, StackSlot);
1421 if (!DeadDefs.empty()) {
1422 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1423 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1430 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1433 MI.eraseFromBundle();
1439 Edit->eraseVirtReg(
Reg);
1448 Original = VRM.getOriginal(edit.
getReg());
1449 StackSlot = VRM.getStackSlot(Original);
1453 <<
TRI.getRegClassName(MRI.getRegClass(edit.
getReg()))
1454 <<
':' << edit.
getParent() <<
"\nFrom original "
1457 "Attempting to spill already spilled value.");
1458 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1460 collectRegsToSpill();
1464 if (!RegsToSpill.empty())
1467 Edit->calculateRegClassAndHint(MF, VRAI);
1471void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1474void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1481 auto [Place,
Inserted] = StackSlotToOrigLI.try_emplace(StackSlot);
1483 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1485 Place->second = std::move(LI);
1490 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1491 MergeableSpills[MIdx].insert(&Spill);
1496bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1498 auto It = StackSlotToOrigLI.find(StackSlot);
1499 if (It == StackSlotToOrigLI.end())
1503 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1504 return MergeableSpills[MIdx].erase(&Spill);
1511 SlotIndex Idx = IPA.getLastInsertPoint(OrigLI, BB);
1514 if (Idx < OrigVNI.
def) {
1517 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1524 for (
const Register &SibReg : Siblings) {
1532 return SR.getVNInfoAt(Idx) != nullptr;
1543void HoistSpillHelper::rmRedundantSpills(
1550 for (
auto *
const CurrentSpill : Spills) {
1557 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1558 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1560 SpillBBToSpill[MDT.getNode(
Block)] = SpillToKeep;
1562 SpillBBToSpill[MDT.getNode(
Block)] = CurrentSpill;
1565 for (
auto *
const SpillToRm : SpillsToRm)
1566 Spills.erase(SpillToRm);
1575void HoistSpillHelper::getVisitOrders(
1599 for (
auto *
const Spill : Spills) {
1603 while (Node != RootIDomNode) {
1606 if (Node != MDT[
Block] && SpillBBToSpill[Node]) {
1607 SpillToRm = SpillBBToSpill[MDT[
Block]];
1612 }
else if (WorkSet.
count(Node)) {
1615 NodesOnPath.
insert(Node);
1630 NodesOnPath.
clear();
1640 if (WorkSet.
count(Child))
1643 }
while (idx != Orders.
size());
1645 "Orders have different size with WorkSet");
1650 for (; RIt != Orders.
rend(); RIt++)
1651 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1659void HoistSpillHelper::runHoistSpills(
1675 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1678 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1685 using NodesCostPair =
1686 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1694 for (; RIt != Orders.
rend(); RIt++) {
1698 if (
auto It = SpillsToKeep.
find(*RIt);
1699 It != SpillsToKeep.
end() && !It->second) {
1700 auto &SIt = SpillsInSubTreeMap[*RIt];
1703 SIt.second = MBFI.getBlockFreq(
Block);
1710 if (!SpillsInSubTreeMap.
contains(Child))
1718 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1719 auto ChildIt = SpillsInSubTreeMap.
find(Child);
1720 SubTreeCost += ChildIt->second.second;
1721 auto BI = ChildIt->second.first.begin();
1722 auto EI = ChildIt->second.first.end();
1723 SpillsInSubTree.insert(BI, EI);
1724 SpillsInSubTreeMap.
erase(ChildIt);
1727 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1729 if (SpillsInSubTree.empty())
1734 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1742 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1744 for (auto *const SpillBB : SpillsInSubTree) {
1747 if (auto It = SpillsToKeep.find(SpillBB);
1748 It != SpillsToKeep.end() && !It->second) {
1749 MachineInstr *SpillToRm = SpillBBToSpill[SpillBB];
1750 SpillsToRm.push_back(SpillToRm);
1753 SpillsToKeep.erase(SpillBB);
1757 SpillsToKeep[*RIt] = LiveReg;
1759 dbgs() <<
"spills in BB: ";
1760 for (
const auto Rspill : SpillsInSubTree)
1761 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1762 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1765 SpillsInSubTree.clear();
1766 SpillsInSubTree.insert(*RIt);
1767 SubTreeCost = MBFI.getBlockFreq(
Block);
1772 for (
const auto &Ent : SpillsToKeep) {
1774 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1794void HoistSpillHelper::hoistAllSpills() {
1798 for (
unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
1801 if (!MRI.def_empty(
Reg) && Original.
isValid())
1802 Virt2SiblingsMap[Original].insert(
Reg);
1806 for (
auto &Ent : MergeableSpills) {
1807 int Slot = Ent.first.first;
1809 VNInfo *OrigVNI = Ent.first.second;
1811 if (Ent.second.empty())
1815 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1816 <<
"Equal spills in BB: ";
1817 for (
const auto spill : EqValSpills)
1818 dbgs() << spill->getParent()->getNumber() <<
" ";
1827 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1830 dbgs() <<
"Finally inserted spills in BB: ";
1831 for (
const auto &Ispill : SpillsToIns)
1832 dbgs() << Ispill.first->getNumber() <<
" ";
1833 dbgs() <<
"\nFinally removed spills in BB: ";
1834 for (
const auto Rspill : SpillsToRm)
1835 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1841 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1843 StackIntvl.getValNumInfo(0));
1846 for (
auto const &Insert : SpillsToIns) {
1852 MRI.getRegClass(LiveReg),
Register());
1860 NumSpills -= SpillsToRm.size();
1861 for (
auto *
const RMEnt : SpillsToRm) {
1862 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1863 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1866 RMEnt->removeOperand(i - 1);
1869 Edit.eliminateDeadDefs(SpillsToRm, {});
1874 for (
auto &[VReg, PhysReg] : PendingReassignments) {
1876 "Pending reassignment without matrix or live interval");
1879 PendingReassignments.clear();
1886void HoistSpillHelper::LRE_WillShrinkVirtReg(
Register VirtReg) {
1892 Matrix->unassign(LI,
true);
1893 PendingReassignments[VirtReg] = PhysReg;
1899bool HoistSpillHelper::LRE_CanEraseVirtReg(
Register VirtReg) {
1900 PendingReassignments.erase(VirtReg);
1901 if (
Matrix && VRM.hasPhys(VirtReg)) {
1903 Matrix->unassign(LI,
true);
1915 auto PendingIt = PendingReassignments.find(Old);
1916 if (PendingIt != PendingReassignments.end()) {
1920 "Pending reassignment without matrix or live interval");
1922 PendingReassignments.erase(PendingIt);
1927 }
else if (VRM.hasPhys(Old)) {
1933 Matrix->unassign(LI,
true);
1934 Matrix->assign(LI, PhysReg);
1938 VRM.assignVirt2Phys(New, PhysReg);
1941 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1945 if (VRM.hasShape(Old))
1946 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
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),...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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.
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
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.
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.
void setIsKill(bool Val=true)
void setIsUndef(bool Val=true)
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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...
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.
constexpr RegState getKillRegState(bool B)
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 >
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.