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 bool LRE_CanEraseVirtReg(
Register)
override;
147class InlineSpiller :
public Spiller {
152 MachineRegisterInfo &MRI;
153 const TargetInstrInfo &TII;
154 const TargetRegisterInfo &TRI;
155 LiveRegMatrix *Matrix =
nullptr;
158 LiveRangeEdit *Edit =
nullptr;
159 LiveInterval *StackInt =
nullptr;
162 AllocationOrder *Order =
nullptr;
174 SmallPtrSet<MachineInstr*, 8> SnippetCopies;
177 SmallPtrSet<VNInfo*, 8> UsedValues;
180 SmallVector<MachineInstr*, 8> DeadDefs;
183 HoistSpillHelper HSpiller;
186 VirtRegAuxInfo &VRAI;
188 ~InlineSpiller()
override =
default;
191 InlineSpiller(
const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF,
192 VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix)
193 : MF(MF), LIS(Analyses.LIS), LSS(Analyses.LSS), VRM(VRM),
194 MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
195 TRI(*MF.getSubtarget().getRegisterInfo()), Matrix(Matrix),
196 HSpiller(Analyses, MF, VRM, Matrix), VRAI(VRAI) {}
198 void spill(LiveRangeEdit &, AllocationOrder *Order =
nullptr)
override;
201 void postOptimization()
override;
204 bool isSnippet(
const LiveInterval &SnipLI);
205 void collectRegsToSpill();
210 bool hoistSpillInsideBB(LiveInterval &SpillLI, MachineInstr &CopyMI);
211 void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI);
213 void markValueUsed(LiveInterval*, VNInfo*);
214 bool canGuaranteeAssignmentAfterRemat(
Register VReg, MachineInstr &
MI);
215 bool hasPhysRegAvailable(
const MachineInstr &
MI);
216 bool reMaterializeFor(LiveInterval &, MachineInstr &
MI);
217 void reMaterializeAll();
220 bool foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>,
221 MachineInstr *LoadMI =
nullptr);
233void Spiller::anchor() {}
239 return new InlineSpiller(Analyses, MF, VRM, VRAI,
Matrix);
258 if (!
TII.isCopyInstr(
MI))
281 "expected to see first instruction in bundle");
285 while (
I->isBundledWithSucc()) {
287 auto CopyInst =
TII.isCopyInstr(
MI);
313 if (MO.getReg().isVirtual())
320bool InlineSpiller::isSnippet(
const LiveInterval &SnipLI) {
334 if (!LIS.intervalIsInOneMBB(SnipLI))
340 for (
auto *VNI : SnipLI.
vnis()) {
342 if (
MI->getOpcode() == TargetOpcode::STATEPOINT)
352 RI = MRI.reg_bundle_nodbg_begin(SnipLI.
reg()),
353 E = MRI.reg_bundle_nodbg_end();
383void InlineSpiller::collectRegsToSpill() {
387 RegsToSpill.assign(1,
Reg);
388 SnippetCopies.clear();
389 RegsReplaced.clear();
398 if (!isSibling(SnipReg))
401 if (!isSnippet(SnipLI))
403 SnippetCopies.insert(&
MI);
404 if (isRegToSpill(SnipReg))
406 RegsToSpill.push_back(SnipReg);
435bool InlineSpiller::hoistSpillInsideBB(
LiveInterval &SpillLI,
437 SlotIndex Idx = LIS.getInstructionIndex(CopyMI);
454 assert(StackInt &&
"No stack slot assigned yet.");
457 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
459 << *StackInt <<
'\n');
463 eliminateRedundantSpills(SrcLI, SrcVNI);
471 assert(
DefMI &&
"Defining instruction disappeared");
478 MRI.getRegClass(SrcReg),
Register());
479 LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
496 if (MIS.begin() == MII)
497 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
505 assert(VNI &&
"Missing value");
507 WorkList.
push_back(std::make_pair(&SLI, VNI));
508 assert(StackInt &&
"No stack slot assigned yet.");
515 << VNI->
def <<
" in " << *LI <<
'\n');
518 if (isRegToSpill(
Reg))
522 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
523 LLVM_DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
528 if (!
MI.mayStore() && !
TII.isCopyInstr(
MI))
536 if (isSibling(DstReg)) {
539 assert(DstVNI &&
"Missing defined value");
542 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
552 MI.setDesc(
TII.get(TargetOpcode::KILL));
553 DeadDefs.push_back(&
MI);
555 if (HSpiller.rmFromMergeableSpills(
MI, StackSlot))
559 }
while (!WorkList.
empty());
570 WorkList.
push_back(std::make_pair(LI, VNI));
573 if (!UsedValues.insert(VNI).second)
581 WorkList.
push_back(std::make_pair(LI, PVNI));
588 if (!SnippetCopies.count(
MI))
590 LiveInterval &SnipLI = LIS.getInterval(
MI->getOperand(1).getReg());
591 assert(isRegToSpill(SnipLI.
reg()) &&
"Unexpected register in copy");
593 assert(SnipVNI &&
"Snippet undefined before copy");
594 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
595 }
while (!WorkList.
empty());
598bool InlineSpiller::canGuaranteeAssignmentAfterRemat(
Register VReg,
617 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
623 EndIdx =
MI.getNumOperands();
624 Idx < EndIdx; ++Idx) {
642 if (!
Matrix->checkInterference(PrevIdx, UseIdx, PhysReg))
676 if (SnippetCopies.count(&
MI)) {
677 LLVM_DEBUG(
dbgs() <<
"\tskipping remat snippet copy for " << UseIdx <<
'\t'
684 assert(OrigVNI &&
"corrupted sub-interval");
691 markValueUsed(&VirtReg, ParentVNI);
692 LLVM_DEBUG(
dbgs() <<
"\tcannot remat missing def for " << UseIdx <<
'\t'
699 if (!Edit->canRematerializeAt(RM, UseIdx)) {
700 markValueUsed(&VirtReg, ParentVNI);
708 markValueUsed(&VirtReg, ParentVNI);
715 if (
RM.OrigMI->canFoldAsLoad() &&
716 (
RM.OrigMI->mayLoad() || !hasPhysRegAvailable(
MI)) &&
717 foldMemoryOperand(
Ops,
RM.OrigMI)) {
718 Edit->markRematerialized(
RM.ParentVNI);
725 if (!canGuaranteeAssignmentAfterRemat(VirtReg.
reg(),
MI)) {
726 markValueUsed(&VirtReg, ParentVNI);
732 Register NewVReg = Edit->createFrom(Original);
735 MRI.constrainRegClass(NewVReg, MRI.getRegClass(VirtReg.
reg()));
742 if (SR.liveAt(UseIdx))
743 UsedLanes |= SR.LaneMask;
747 SlotIndex DefIdx = Edit->rematerializeAt(*
MI.getParent(),
MI, NewVReg, RM,
748 TRI,
false, 0,
nullptr, UsedLanes);
752 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
753 NewMI->setDebugLoc(
MI.getDebugLoc());
757 << *LIS.getInstructionFromIndex(DefIdx));
760 for (
const auto &OpPair :
Ops) {
775void InlineSpiller::reMaterializeAll() {
779 bool anyRemat =
false;
784 if (
MI.isDebugValue())
787 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
788 "instruction that isn't a DBG_VALUE");
790 anyRemat |= reMaterializeFor(LI,
MI);
804 if (!
MI->allDefsAreDead())
807 DeadDefs.push_back(
MI);
811 if (
MI->isBundledWithSucc() && !
MI->isBundledWithPred()) {
813 EndIt =
MI->getParent()->instr_end();
816 bool OnlyDeadCopies =
true;
818 It != EndIt && It->isBundledWithPred(); ++It) {
820 auto DestSrc =
TII.isCopyInstr(*It);
821 bool IsCopyToDeadReg =
822 DestSrc && DestSrc->Destination->getReg() ==
Reg;
823 if (!IsCopyToDeadReg) {
824 OnlyDeadCopies =
false;
828 if (OnlyDeadCopies) {
830 It != EndIt && It->isBundledWithPred(); ++It) {
831 It->addRegisterDead(
Reg, &
TRI);
833 DeadDefs.push_back(&*It);
842 if (DeadDefs.empty())
844 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
845 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
853 unsigned ResultPos = 0;
855 if (MRI.reg_nodbg_empty(
Reg)) {
856 Edit->eraseVirtReg(
Reg);
857 RegsReplaced.push_back(
Reg);
862 (!LIS.getInterval(
Reg).empty() || !MRI.reg_nodbg_empty(
Reg)) &&
863 "Empty and not used live-range?!");
865 RegsToSpill[ResultPos++] =
Reg;
867 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
869 <<
" registers to spill after remat.\n");
880 bool IsLoad = InstrReg.
isValid();
885 if (InstrReg !=
Reg || FI != StackSlot)
889 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
892 LIS.RemoveMachineInstrFromMaps(*
MI);
893 MI->eraseFromParent();
906#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
912 const char *
const header,
914 char NextLine =
'\n';
915 char SlotIndent =
'\t';
917 if (std::next(
B) ==
E) {
922 dbgs() <<
'\t' << header <<
": " << NextLine;
936 dbgs() << SlotIndent << Idx <<
'\t' << *
I;
948foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>
Ops,
954 if (
Ops.back().first !=
MI ||
MI->isBundled())
957 bool WasCopy =
TII.isCopyInstr(*MI).has_value();
966 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
970 bool SpillSubRegs =
TII.isSubregFoldable() ||
971 MI->getOpcode() == TargetOpcode::STATEPOINT ||
972 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
973 MI->getOpcode() == TargetOpcode::STACKMAP;
978 for (
const auto &OpPair :
Ops) {
979 unsigned Idx = OpPair.second;
980 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
997 if (LoadMI && MO.
isDef())
1000 if (UntieRegs || !
MI->isRegTiedToDefOperand(Idx))
1006 if (FoldOps.
empty())
1013 for (
unsigned Idx : FoldOps) {
1017 unsigned Tied =
MI->findTiedOperandIdx(Idx);
1024 MI->untieRegOperand(Idx);
1030 ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, CopyMI, &LIS)
1031 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, CopyMI, &LIS, &VRM);
1034 for (
auto Tied : TiedOps)
1035 MI->tieOperands(Tied.first, Tied.second);
1061 HSpiller.rmFromMergeableSpills(*
MI, FI))
1073 if (
MI->isCandidateForAdditionalCallInfo())
1074 MI->getMF()->moveAdditionalCallInfo(
MI, FoldMI);
1081 if (
MI->peekDebugInstrNum() &&
Ops[0].second == 0) {
1083 auto MakeSubstitution = [
this,FoldMI,
MI,&
Ops]() {
1085 unsigned OldOperandNum =
Ops[0].second;
1087 unsigned OldNum =
MI->getDebugInstrNum();
1088 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1093 if (
Ops.size() == 1 && Op0.
isDef()) {
1095 }
else if (
Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
1096 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
1099 }
else if (
MI->peekDebugInstrNum()) {
1105 MF.substituteDebugValuesForInst(*
MI, *FoldMI,
Ops[0].second);
1108 MI->eraseFromParent();
1111 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
1113 if (&
MI != FoldMI && &
MI != CopyMI)
1118 if (
R.isVirtual()) {
1122 assert(MRI.isReserved(R) &&
"Unexpected PhysReg in source operand!");
1133 if (MO.
getReg() == ImpReg)
1142 else if (
Ops.front().second == 0) {
1147 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1148 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1154void InlineSpiller::insertReload(
Register NewVReg,
1161 MRI.getRegClass(NewVReg),
Register());
1174 if (!Def.isImplicitDef())
1180 return Def.getOperand(0).getSubReg();
1184void InlineSpiller::insertSpill(
Register NewVReg,
bool isKill,
1188 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1197 MRI.getRegClass(NewVReg),
Register());
1203 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1217 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1218 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1222void InlineSpiller::spillAroundUses(
Register Reg) {
1229 if (
MI.isDebugValue()) {
1238 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1239 "instruction that isn't a DBG_VALUE");
1242 if (SnippetCopies.count(&
MI))
1246 if (coalesceStackAccess(&
MI,
Reg))
1262 if (SibReg && isSibling(SibReg)) {
1264 if (isRegToSpill(SibReg)) {
1266 SnippetCopies.insert(&
MI);
1270 if (hoistSpillInsideBB(OldLI,
MI)) {
1272 MI.getOperand(0).setIsDead();
1273 DeadDefs.push_back(&
MI);
1279 eliminateRedundantSpills(SibLI, SibLI.
getVNInfoAt(Idx));
1285 if (foldMemoryOperand(
Ops))
1293 insertReload(NewVReg, Idx, &
MI);
1296 bool hasLiveDef =
false;
1297 for (
const auto &OpPair :
Ops) {
1301 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
1313 insertSpill(NewVReg,
true, &
MI);
1318void InlineSpiller::spillAll() {
1321 StackSlot = VRM.assignVirt2StackSlot(Original);
1322 StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
1323 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1325 StackInt = &LSS.getInterval(StackSlot);
1327 if (Original != Edit->getReg())
1328 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1330 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1334 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1338 spillAroundUses(
Reg);
1342 VRM.assignVirt2StackSlot(
Reg, StackSlot);
1346 if (!DeadDefs.empty()) {
1347 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1348 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1355 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1358 MI.eraseFromBundle();
1364 Edit->eraseVirtReg(
Reg);
1373 Original = VRM.getOriginal(edit.
getReg());
1374 StackSlot = VRM.getStackSlot(Original);
1378 <<
TRI.getRegClassName(MRI.getRegClass(edit.
getReg()))
1379 <<
':' << edit.
getParent() <<
"\nFrom original "
1382 "Attempting to spill already spilled value.");
1383 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1385 collectRegsToSpill();
1389 if (!RegsToSpill.empty())
1392 Edit->calculateRegClassAndHint(MF, VRAI);
1396void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1399void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1406 auto [Place,
Inserted] = StackSlotToOrigLI.try_emplace(StackSlot);
1408 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1410 Place->second = std::move(LI);
1415 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1416 MergeableSpills[MIdx].insert(&Spill);
1421bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1423 auto It = StackSlotToOrigLI.find(StackSlot);
1424 if (It == StackSlotToOrigLI.end())
1428 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1429 return MergeableSpills[MIdx].erase(&Spill);
1436 SlotIndex Idx = IPA.getLastInsertPoint(OrigLI, BB);
1439 if (Idx < OrigVNI.
def) {
1442 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1449 for (
const Register &SibReg : Siblings) {
1457 return SR.getVNInfoAt(Idx) != nullptr;
1468void HoistSpillHelper::rmRedundantSpills(
1475 for (
auto *
const CurrentSpill : Spills) {
1482 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1483 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1485 SpillBBToSpill[MDT.getNode(
Block)] = SpillToKeep;
1487 SpillBBToSpill[MDT.getNode(
Block)] = CurrentSpill;
1490 for (
auto *
const SpillToRm : SpillsToRm)
1491 Spills.erase(SpillToRm);
1500void HoistSpillHelper::getVisitOrders(
1524 for (
auto *
const Spill : Spills) {
1528 while (Node != RootIDomNode) {
1531 if (Node != MDT[
Block] && SpillBBToSpill[Node]) {
1532 SpillToRm = SpillBBToSpill[MDT[
Block]];
1537 }
else if (WorkSet.
count(Node)) {
1540 NodesOnPath.
insert(Node);
1555 NodesOnPath.
clear();
1565 if (WorkSet.
count(Child))
1568 }
while (idx != Orders.
size());
1570 "Orders have different size with WorkSet");
1575 for (; RIt != Orders.
rend(); RIt++)
1576 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1584void HoistSpillHelper::runHoistSpills(
1600 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1603 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1610 using NodesCostPair =
1611 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1619 for (; RIt != Orders.
rend(); RIt++) {
1623 if (
auto It = SpillsToKeep.
find(*RIt);
1624 It != SpillsToKeep.
end() && !It->second) {
1625 auto &SIt = SpillsInSubTreeMap[*RIt];
1628 SIt.second = MBFI.getBlockFreq(
Block);
1635 if (!SpillsInSubTreeMap.
contains(Child))
1643 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1644 auto ChildIt = SpillsInSubTreeMap.
find(Child);
1645 SubTreeCost += ChildIt->second.second;
1646 auto BI = ChildIt->second.first.begin();
1647 auto EI = ChildIt->second.first.end();
1648 SpillsInSubTree.insert(BI, EI);
1649 SpillsInSubTreeMap.
erase(ChildIt);
1652 auto &[SpillsInSubTree, SubTreeCost] = SpillsInSubTreeMap[*RIt];
1654 if (SpillsInSubTree.empty())
1659 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1667 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1669 for (auto *const SpillBB : SpillsInSubTree) {
1672 if (auto It = SpillsToKeep.find(SpillBB);
1673 It != SpillsToKeep.end() && !It->second) {
1674 MachineInstr *SpillToRm = SpillBBToSpill[SpillBB];
1675 SpillsToRm.push_back(SpillToRm);
1678 SpillsToKeep.erase(SpillBB);
1682 SpillsToKeep[*RIt] = LiveReg;
1684 dbgs() <<
"spills in BB: ";
1685 for (
const auto Rspill : SpillsInSubTree)
1686 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1687 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1690 SpillsInSubTree.clear();
1691 SpillsInSubTree.insert(*RIt);
1692 SubTreeCost = MBFI.getBlockFreq(
Block);
1697 for (
const auto &Ent : SpillsToKeep) {
1699 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1719void HoistSpillHelper::hoistAllSpills() {
1723 for (
unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
1726 if (!MRI.def_empty(
Reg) && Original.
isValid())
1727 Virt2SiblingsMap[Original].insert(
Reg);
1731 for (
auto &Ent : MergeableSpills) {
1732 int Slot = Ent.first.first;
1734 VNInfo *OrigVNI = Ent.first.second;
1736 if (Ent.second.empty())
1740 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1741 <<
"Equal spills in BB: ";
1742 for (
const auto spill : EqValSpills)
1743 dbgs() << spill->getParent()->getNumber() <<
" ";
1752 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1755 dbgs() <<
"Finally inserted spills in BB: ";
1756 for (
const auto &Ispill : SpillsToIns)
1757 dbgs() << Ispill.first->getNumber() <<
" ";
1758 dbgs() <<
"\nFinally removed spills in BB: ";
1759 for (
const auto Rspill : SpillsToRm)
1760 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1766 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1768 StackIntvl.getValNumInfo(0));
1771 for (
auto const &Insert : SpillsToIns) {
1777 MRI.getRegClass(LiveReg),
Register());
1785 NumSpills -= SpillsToRm.size();
1786 for (
auto *
const RMEnt : SpillsToRm) {
1787 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1788 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1791 RMEnt->removeOperand(i - 1);
1794 Edit.eliminateDeadDefs(SpillsToRm, {});
1801bool HoistSpillHelper::LRE_CanEraseVirtReg(
Register VirtReg) {
1802 if (
Matrix && VRM.hasPhys(VirtReg)) {
1804 Matrix->unassign(LI,
true);
1812 if (VRM.hasPhys(Old))
1813 VRM.assignVirt2Phys(New, VRM.getPhys(Old));
1815 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1818 if (VRM.hasShape(Old))
1819 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)
ArrayRef - 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()
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.
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.
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.
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...
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...
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.