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);
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);
502 MRI.getRegClass(SrcReg),
Register());
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");
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());
622bool InlineSpiller::canGuaranteeAssignmentAfterRemat(
Register VReg,
641 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
647 EndIdx =
MI.getNumOperands();
648 Idx < EndIdx; ++Idx) {
666 if (!
Matrix->checkInterference(PrevIdx, UseIdx, PhysReg))
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);
784 if (!canGuaranteeAssignmentAfterRemat(VirtReg.
reg(),
MI)) {
785 markValueUsed(&VirtReg, ParentVNI);
791 Register NewVReg = Edit->createFrom(Original);
794 MRI.constrainRegClass(NewVReg, MRI.getRegClass(VirtReg.
reg()));
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) {
834void InlineSpiller::reMaterializeAll() {
838 bool anyRemat =
false;
843 if (
MI.isDebugValue())
846 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
847 "instruction that isn't a DBG_VALUE");
849 anyRemat |= reMaterializeFor(LI,
MI);
863 if (!
MI->allDefsAreDead())
866 DeadDefs.push_back(
MI);
870 if (
MI->isBundledWithSucc() && !
MI->isBundledWithPred()) {
872 EndIt =
MI->getParent()->instr_end();
875 bool OnlyDeadCopies =
true;
877 It != EndIt && It->isBundledWithPred(); ++It) {
879 auto DestSrc =
TII.isCopyInstr(*It);
880 bool IsCopyToDeadReg =
881 DestSrc && DestSrc->Destination->getReg() ==
Reg;
882 if (!IsCopyToDeadReg) {
883 OnlyDeadCopies =
false;
887 if (OnlyDeadCopies) {
889 It != EndIt && It->isBundledWithPred(); ++It) {
890 It->addRegisterDead(
Reg, &
TRI);
892 DeadDefs.push_back(&*It);
901 if (DeadDefs.empty())
903 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
904 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
912 unsigned ResultPos = 0;
914 if (MRI.reg_nodbg_empty(
Reg)) {
915 Edit->eraseVirtReg(
Reg);
916 RegsReplaced.push_back(
Reg);
921 (!LIS.getInterval(
Reg).empty() || !MRI.reg_nodbg_empty(
Reg)) &&
922 "Empty and not used live-range?!");
924 RegsToSpill[ResultPos++] =
Reg;
926 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
928 <<
" registers to spill after remat.\n");
939 bool IsLoad = InstrReg.
isValid();
944 if (InstrReg !=
Reg || FI != StackSlot)
948 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
951 LIS.RemoveMachineInstrFromMaps(*
MI);
952 MI->eraseFromParent();
965#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
971 const char *
const header,
973 char NextLine =
'\n';
974 char SlotIndent =
'\t';
976 if (std::next(
B) ==
E) {
981 dbgs() <<
'\t' << header <<
": " << NextLine;
995 dbgs() << SlotIndent << Idx <<
'\t' << *
I;
1007foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>
Ops,
1013 if (
Ops.back().first !=
MI ||
MI->isBundled())
1016 bool WasCopy =
TII.isCopyInstr(*MI).has_value();
1025 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
1029 bool SpillSubRegs =
TII.isSubregFoldable() ||
1030 MI->getOpcode() == TargetOpcode::STATEPOINT ||
1031 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
1032 MI->getOpcode() == TargetOpcode::STACKMAP;
1037 for (
const auto &OpPair :
Ops) {
1038 unsigned Idx = OpPair.second;
1039 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
1056 if (LoadMI && MO.
isDef())
1059 if (UntieRegs || !
MI->isRegTiedToDefOperand(Idx))
1065 if (FoldOps.
empty())
1072 for (
unsigned Idx : FoldOps) {
1076 unsigned Tied =
MI->findTiedOperandIdx(Idx);
1083 MI->untieRegOperand(Idx);
1089 ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, CopyMI, &LIS, &VRM)
1090 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, CopyMI, &LIS, &VRM);
1093 for (
auto Tied : TiedOps)
1094 MI->tieOperands(Tied.first, Tied.second);
1120 HSpiller.rmFromMergeableSpills(*
MI, FI))
1136 bool NeedMatrixReassign =
1139 if (NeedMatrixReassign) {
1140 PhysReg = VRM.getPhys(CopyDstReg);
1147 if (NeedMatrixReassign)
1148 Matrix->assign(LI, PhysReg);
1150 Register OrigReg = VRM.getOriginal(CopyDstReg);
1151 if (OrigReg != CopyDstReg) {
1166 if (
MI->isCandidateForAdditionalCallInfo())
1167 MI->getMF()->moveAdditionalCallInfo(
MI, FoldMI);
1174 if (
MI->peekDebugInstrNum() &&
Ops[0].second == 0) {
1176 auto MakeSubstitution = [
this,FoldMI,
MI,&
Ops]() {
1178 unsigned OldOperandNum =
Ops[0].second;
1180 unsigned OldNum =
MI->getDebugInstrNum();
1181 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1186 if (
Ops.size() == 1 && Op0.
isDef()) {
1188 }
else if (
Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
1189 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
1192 }
else if (
MI->peekDebugInstrNum()) {
1198 MF.substituteDebugValuesForInst(*
MI, *FoldMI,
Ops[0].second);
1201 MI->eraseFromParent();
1204 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
1206 if (&
MI != FoldMI && &
MI != CopyMI)
1211 if (
R.isVirtual()) {
1215 assert(MRI.isReserved(R) &&
"Unexpected PhysReg in source operand!");
1226 if (MO.
getReg() == ImpReg)
1235 else if (
Ops.front().second == 0) {
1240 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1241 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1247void InlineSpiller::insertReload(
Register NewVReg,
1254 MRI.getRegClass(NewVReg),
Register());
1267 if (!Def.isImplicitDef())
1273 return Def.getOperand(0).getSubReg();
1277void InlineSpiller::insertSpill(
Register NewVReg,
bool isKill,
1281 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1290 MRI.getRegClass(NewVReg),
Register());
1296 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1310 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1311 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1315void InlineSpiller::spillAroundUses(
Register Reg) {
1322 if (
MI.isDebugValue()) {
1331 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1332 "instruction that isn't a DBG_VALUE");
1335 if (SnippetCopies.count(&
MI))
1339 if (coalesceStackAccess(&
MI,
Reg))
1355 if (SibReg && isSibling(SibReg)) {
1357 if (isRegToSpill(SibReg)) {
1359 SnippetCopies.insert(&
MI);
1363 if (hoistSpillInsideBB(OldLI,
MI)) {
1365 MI.getOperand(0).setIsDead();
1366 DeadDefs.push_back(&
MI);
1372 eliminateRedundantSpills(SibLI, SibLI.
getVNInfoAt(Idx));
1378 if (foldMemoryOperand(
Ops))
1386 insertReload(NewVReg, Idx, &
MI);
1389 bool hasLiveDef =
false;
1390 for (
const auto &OpPair :
Ops) {
1394 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
1406 insertSpill(NewVReg,
true, &
MI);
1411void InlineSpiller::spillAll() {
1414 StackSlot = VRM.assignVirt2StackSlot(Original);
1415 StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
1416 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1418 StackInt = &LSS.getInterval(StackSlot);
1420 if (Original != Edit->getReg())
1421 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1423 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1427 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1431 spillAroundUses(
Reg);
1435 VRM.assignVirt2StackSlot(
Reg, StackSlot);
1439 if (!DeadDefs.empty()) {
1440 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1441 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1448 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1451 MI.eraseFromBundle();
1457 Edit->eraseVirtReg(
Reg);
1466 Original = VRM.getOriginal(edit.
getReg());
1467 StackSlot = VRM.getStackSlot(Original);
1471 <<
TRI.getRegClassName(MRI.getRegClass(edit.
getReg()))
1472 <<
':' << edit.
getParent() <<
"\nFrom original "
1475 "Attempting to spill already spilled value.");
1476 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1478 collectRegsToSpill();
1482 if (!RegsToSpill.empty())
1485 Edit->calculateRegClassAndHint(MF, VRAI);
1489void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1492void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1499 auto [Place,
Inserted] = StackSlotToOrigLI.try_emplace(StackSlot);
1501 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1503 Place->second = std::move(LI);
1508 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1509 MergeableSpills[MIdx].insert(&Spill);
1514bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1516 auto It = StackSlotToOrigLI.find(StackSlot);
1517 if (It == StackSlotToOrigLI.end())
1521 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1522 return MergeableSpills[MIdx].erase(&Spill);
1529 SlotIndex Idx = IPA.getLastInsertPoint(OrigLI, BB);
1532 if (Idx < OrigVNI.
def) {
1535 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1542 for (
const Register &SibReg : Siblings) {
1550 return SR.getVNInfoAt(Idx) != nullptr;
1561void HoistSpillHelper::rmRedundantSpills(
1568 for (
auto *
const CurrentSpill : Spills) {
1575 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1576 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1578 SpillBBToSpill[MDT.getNode(
Block)] = SpillToKeep;
1580 SpillBBToSpill[MDT.getNode(
Block)] = CurrentSpill;
1583 for (
auto *
const SpillToRm : SpillsToRm)
1584 Spills.erase(SpillToRm);
1593void HoistSpillHelper::getVisitOrders(
1617 for (
auto *
const Spill : Spills) {
1621 while (Node != RootIDomNode) {
1624 if (Node != MDT[
Block] && SpillBBToSpill[Node]) {
1625 SpillToRm = SpillBBToSpill[MDT[
Block]];
1630 }
else if (WorkSet.
count(Node)) {
1633 NodesOnPath.
insert(Node);
1648 NodesOnPath.
clear();
1658 if (WorkSet.
count(Child))
1661 }
while (idx != Orders.
size());
1663 "Orders have different size with WorkSet");
1668 for (; RIt != Orders.
rend(); RIt++)
1669 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1677void HoistSpillHelper::runHoistSpills(
1693 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1696 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1703 using NodesCostPair =
1704 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1712 for (; RIt != Orders.
rend(); RIt++) {
1716 if (
auto It = SpillsToKeep.
find(*RIt);
1717 It != SpillsToKeep.
end() && !It->second) {
1718 auto &SIt = SpillsInSubTreeMap[*RIt];
1721 SIt.second = MBFI.getBlockFreq(
Block);
1728 if (!SpillsInSubTreeMap.
contains(Child))
1736 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1737 auto ChildIt = SpillsInSubTreeMap.
find(Child);
1738 SubTreeCost += ChildIt->second.second;
1739 auto BI = ChildIt->second.first.begin();
1740 auto EI = ChildIt->second.first.end();
1741 SpillsInSubTree.insert(BI, EI);
1742 SpillsInSubTreeMap.
erase(ChildIt);
1745 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1747 if (SpillsInSubTree.empty())
1752 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1760 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1762 for (auto *const SpillBB : SpillsInSubTree) {
1765 if (auto It = SpillsToKeep.find(SpillBB);
1766 It != SpillsToKeep.end() && !It->second) {
1767 MachineInstr *SpillToRm = SpillBBToSpill[SpillBB];
1768 SpillsToRm.push_back(SpillToRm);
1771 SpillsToKeep.erase(SpillBB);
1775 SpillsToKeep[*RIt] = LiveReg;
1777 dbgs() <<
"spills in BB: ";
1778 for (
const auto Rspill : SpillsInSubTree)
1779 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1780 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1783 SpillsInSubTree.clear();
1784 SpillsInSubTree.insert(*RIt);
1785 SubTreeCost = MBFI.getBlockFreq(
Block);
1790 for (
const auto &Ent : SpillsToKeep) {
1792 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1812void HoistSpillHelper::hoistAllSpills() {
1816 for (
unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
1819 if (!MRI.def_empty(
Reg) && Original.
isValid())
1820 Virt2SiblingsMap[Original].insert(
Reg);
1824 for (
auto &Ent : MergeableSpills) {
1825 int Slot = Ent.first.first;
1827 VNInfo *OrigVNI = Ent.first.second;
1829 if (Ent.second.empty())
1833 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1834 <<
"Equal spills in BB: ";
1835 for (
const auto spill : EqValSpills)
1836 dbgs() << spill->getParent()->getNumber() <<
" ";
1845 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1848 dbgs() <<
"Finally inserted spills in BB: ";
1849 for (
const auto &Ispill : SpillsToIns)
1850 dbgs() << Ispill.first->getNumber() <<
" ";
1851 dbgs() <<
"\nFinally removed spills in BB: ";
1852 for (
const auto Rspill : SpillsToRm)
1853 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1859 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1861 StackIntvl.getValNumInfo(0));
1864 for (
auto const &Insert : SpillsToIns) {
1870 MRI.getRegClass(LiveReg),
Register());
1878 NumSpills -= SpillsToRm.size();
1879 for (
auto *
const RMEnt : SpillsToRm) {
1880 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1881 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1884 RMEnt->removeOperand(i - 1);
1887 Edit.eliminateDeadDefs(SpillsToRm, {});
1892 for (
auto &[VReg, PhysReg] : PendingReassignments) {
1894 "Pending reassignment without matrix or live interval");
1897 PendingReassignments.clear();
1904void HoistSpillHelper::LRE_WillShrinkVirtReg(
Register VirtReg) {
1910 Matrix->unassign(LI,
true);
1911 PendingReassignments[VirtReg] = PhysReg;
1917bool HoistSpillHelper::LRE_CanEraseVirtReg(
Register VirtReg) {
1918 PendingReassignments.erase(VirtReg);
1919 if (
Matrix && VRM.hasPhys(VirtReg)) {
1921 Matrix->unassign(LI,
true);
1933 auto PendingIt = PendingReassignments.find(Old);
1934 if (PendingIt != PendingReassignments.end()) {
1938 "Pending reassignment without matrix or live interval");
1940 PendingReassignments.erase(PendingIt);
1945 }
else if (VRM.hasPhys(Old)) {
1951 Matrix->unassign(LI,
true);
1952 Matrix->assign(LI, PhysReg);
1956 VRM.assignVirt2Phys(New, PhysReg);
1959 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1963 if (VRM.hasShape(Old))
1964 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.
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
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.