47#include "llvm/Config/llvm-config.h"
63#define DEBUG_TYPE "regalloc"
65STATISTIC(NumSpilledRanges,
"Number of spilled live ranges");
66STATISTIC(NumSnippets,
"Number of spilled snippets");
68STATISTIC(NumSpillsRemoved,
"Number of spills removed");
70STATISTIC(NumReloadsRemoved,
"Number of reloads removed");
71STATISTIC(NumFolded,
"Number of folded stack accesses");
73STATISTIC(NumRemats,
"Number of rematerialized defs for spilling");
76 cl::desc(
"Disable inline spill hoisting"));
80 cl::desc(
"Restrict remat for statepoint operands"));
107 using MergeableSpillsMap =
109 MergeableSpillsMap MergeableSpills;
119 void rmRedundantSpills(
143 MRI(mf.getRegInfo()),
TII(*mf.getSubtarget().getInstrInfo()),
144 TRI(*mf.getSubtarget().getRegisterInfo()),
146 IPA(LIS, mf.getNumBlockIDs()) {}
148 void addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
150 bool rmFromMergeableSpills(
MachineInstr &Spill,
int StackSlot);
151 void hoistAllSpills();
155class InlineSpiller :
public Spiller {
187 HoistSpillHelper HSpiller;
192 ~InlineSpiller()
override =
default;
201 MRI(MF.getRegInfo()),
TII(*MF.getSubtarget().getInstrInfo()),
202 TRI(*MF.getSubtarget().getRegisterInfo()),
204 HSpiller(
Pass, MF, VRM), VRAI(VRAI) {}
211 void collectRegsToSpill();
222 void reMaterializeAll();
225 bool foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>,
238void Spiller::anchor() {}
243 return new InlineSpiller(
Pass, MF, VRM, VRAI);
261 if (!
MI.isFullCopy())
263 if (
MI.getOperand(0).getReg() == Reg)
264 return MI.getOperand(1).getReg();
265 if (
MI.getOperand(1).getReg() == Reg)
266 return MI.getOperand(0).getReg();
272 if (MO.isReg() && MO.isDef() && MO.getReg().isVirtual())
279bool InlineSpiller::isSnippet(
const LiveInterval &SnipLI) {
293 if (!LIS.intervalIsInOneMBB(SnipLI))
299 for (
auto *VNI : SnipLI.
vnis()) {
301 if (
MI->getOpcode() == TargetOpcode::STATEPOINT)
311 RI =
MRI.reg_instr_nodbg_begin(SnipLI.
reg()),
312 E =
MRI.reg_instr_nodbg_end();
342void InlineSpiller::collectRegsToSpill() {
346 RegsToSpill.assign(1, Reg);
347 SnippetCopies.clear();
357 if (!isSibling(SnipReg))
360 if (!isSnippet(SnipLI))
362 SnippetCopies.insert(&
MI);
363 if (isRegToSpill(SnipReg))
365 RegsToSpill.push_back(SnipReg);
371bool InlineSpiller::isSibling(
Register Reg) {
372 return Reg.isVirtual() && VRM.getOriginal(Reg) == Original;
394bool InlineSpiller::hoistSpillInsideBB(
LiveInterval &SpillLI,
399 assert(VNI && VNI->
def ==
Idx.getRegSlot() &&
"Not defined by copy");
413 assert(StackInt &&
"No stack slot assigned yet.");
416 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
418 << *StackInt <<
'\n');
422 eliminateRedundantSpills(SrcLI, SrcVNI);
430 assert(
DefMI &&
"Defining instruction disappeared");
438 LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
447 if (MIS.begin() == MII)
448 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
456 assert(VNI &&
"Missing value");
458 WorkList.
push_back(std::make_pair(&SLI, VNI));
459 assert(StackInt &&
"No stack slot assigned yet.");
466 << VNI->
def <<
" in " << *LI <<
'\n');
469 if (isRegToSpill(Reg))
473 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
474 LLVM_DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
479 if (!
MI.isCopy() && !
MI.mayStore())
487 if (isSibling(DstReg)) {
490 assert(DstVNI &&
"Missing defined value");
491 assert(DstVNI->
def ==
Idx.getRegSlot() &&
"Wrong copy def slot");
492 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
502 MI.setDesc(
TII.get(TargetOpcode::KILL));
503 DeadDefs.push_back(&
MI);
505 if (HSpiller.rmFromMergeableSpills(
MI, StackSlot))
509 }
while (!WorkList.
empty());
520 WorkList.
push_back(std::make_pair(LI, VNI));
523 if (!UsedValues.insert(VNI).second)
531 WorkList.
push_back(std::make_pair(LI, PVNI));
538 if (!SnippetCopies.count(
MI))
540 LiveInterval &SnipLI = LIS.getInterval(
MI->getOperand(1).getReg());
541 assert(isRegToSpill(SnipLI.
reg()) &&
"Unexpected register in copy");
543 assert(SnipVNI &&
"Snippet undefined before copy");
544 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
545 }
while (!WorkList.
empty());
548bool InlineSpiller::canGuaranteeAssignmentAfterRemat(
Register VReg,
567 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
573 EndIdx =
MI.getNumOperands();
603 if (SnippetCopies.count(&
MI))
609 RM.OrigMI = LIS.getInstructionFromIndex(OrigVNI->
def);
611 if (!Edit->canRematerializeAt(RM, OrigVNI, UseIdx,
false)) {
612 markValueUsed(&VirtReg, ParentVNI);
620 markValueUsed(&VirtReg, ParentVNI);
627 if (
RM.OrigMI->canFoldAsLoad() &&
628 foldMemoryOperand(Ops,
RM.OrigMI)) {
629 Edit->markRematerialized(
RM.ParentVNI);
636 if (!canGuaranteeAssignmentAfterRemat(VirtReg.
reg(),
MI)) {
637 markValueUsed(&VirtReg, ParentVNI);
643 Register NewVReg = Edit->createFrom(Original);
647 Edit->rematerializeAt(*
MI.getParent(),
MI, NewVReg, RM,
TRI);
651 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
652 NewMI->setDebugLoc(
MI.getDebugLoc());
656 << *LIS.getInstructionFromIndex(DefIdx));
659 for (
const auto &OpPair : Ops) {
674void InlineSpiller::reMaterializeAll() {
675 if (!Edit->anyRematerializable())
681 bool anyRemat =
false;
686 if (
MI.isDebugValue())
689 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
690 "instruction that isn't a DBG_VALUE");
692 anyRemat |= reMaterializeFor(LI,
MI);
705 MI->addRegisterDead(Reg, &
TRI);
706 if (!
MI->allDefsAreDead())
709 DeadDefs.push_back(
MI);
715 if (DeadDefs.empty())
717 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
718 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
726 unsigned ResultPos = 0;
728 if (
MRI.reg_nodbg_empty(Reg)) {
729 Edit->eraseVirtReg(Reg);
733 assert(LIS.hasInterval(Reg) &&
734 (!LIS.getInterval(Reg).empty() || !
MRI.reg_nodbg_empty(Reg)) &&
735 "Empty and not used live-range?!");
737 RegsToSpill[ResultPos++] =
Reg;
739 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
741 <<
" registers to spill after remat.\n");
752 bool IsLoad = InstrReg;
757 if (InstrReg != Reg || FI != StackSlot)
761 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
764 LIS.RemoveMachineInstrFromMaps(*
MI);
765 MI->eraseFromParent();
778#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
784 const char *
const header,
786 char NextLine =
'\n';
787 char SlotIndent =
'\t';
789 if (std::next(
B) ==
E) {
794 dbgs() <<
'\t' << header <<
": " << NextLine;
805 Idx =
Idx.getRegSlot(
true);
808 dbgs() << SlotIndent <<
Idx <<
'\t' << *
I;
820foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
826 if (Ops.back().first !=
MI ||
MI->isBundled())
829 bool WasCopy =
MI->isCopy();
838 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
842 bool SpillSubRegs =
TII.isSubregFoldable() ||
843 MI->getOpcode() == TargetOpcode::STATEPOINT ||
844 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
845 MI->getOpcode() == TargetOpcode::STACKMAP;
850 for (
const auto &OpPair : Ops) {
851 unsigned Idx = OpPair.second;
852 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
869 if (LoadMI && MO.
isDef())
872 if (UntieRegs || !
MI->isRegTiedToDefOperand(
Idx))
885 for (
unsigned Idx : FoldOps) {
889 unsigned Tied =
MI->findTiedOperandIdx(
Idx);
896 MI->untieRegOperand(
Idx);
900 LoadMI ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, &LIS)
901 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, &LIS, &VRM);
904 for (
auto Tied : TiedOps)
905 MI->tieOperands(Tied.first, Tied.second);
914 if (!Reg ||
Reg.isVirtual() ||
MRI.isReserved(Reg)) {
931 HSpiller.rmFromMergeableSpills(*
MI, FI))
935 if (
MI->isCandidateForCallSiteEntry())
936 MI->getMF()->moveCallSiteInfo(
MI, FoldMI);
943 if (
MI->peekDebugInstrNum() && Ops[0].second == 0) {
945 auto MakeSubstitution = [
this,FoldMI,
MI,&Ops]() {
947 unsigned OldOperandNum = Ops[0].second;
949 unsigned OldNum =
MI->getDebugInstrNum();
950 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
955 if (Ops.size() == 1 && Op0.
isDef()) {
957 }
else if (Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
958 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
961 }
else if (
MI->peekDebugInstrNum()) {
967 MF.substituteDebugValuesForInst(*
MI, *FoldMI, Ops[0].second);
970 MI->eraseFromParent();
973 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
985 if (MO.
getReg() == ImpReg)
994 else if (Ops.front().second == 0) {
999 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1000 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1006void InlineSpiller::insertReload(
Register NewVReg,
1026 if (!Def.isImplicitDef())
1028 assert(Def.getNumOperands() == 1 &&
1029 "Implicit def with more than one definition");
1033 return Def.getOperand(0).getSubReg();
1037void InlineSpiller::insertSpill(
Register NewVReg,
bool isKill,
1041 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1056 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1070 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1071 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1075void InlineSpiller::spillAroundUses(
Register Reg) {
1082 if (
MI.isDebugValue()) {
1091 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1092 "instruction that isn't a DBG_VALUE");
1095 if (SnippetCopies.count(&
MI))
1099 if (coalesceStackAccess(&
MI, Reg))
1115 if (SibReg && isSibling(SibReg)) {
1117 if (isRegToSpill(SibReg)) {
1119 SnippetCopies.insert(&
MI);
1123 if (hoistSpillInsideBB(OldLI,
MI)) {
1125 MI.getOperand(0).setIsDead();
1126 DeadDefs.push_back(&
MI);
1138 if (foldMemoryOperand(Ops))
1143 Register NewVReg = Edit->createFrom(Reg);
1146 insertReload(NewVReg,
Idx, &
MI);
1149 bool hasLiveDef =
false;
1150 for (
const auto &OpPair : Ops) {
1154 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
1166 insertSpill(NewVReg,
true, &
MI);
1171void InlineSpiller::spillAll() {
1174 StackSlot = VRM.assignVirt2StackSlot(Original);
1175 StackInt = &LSS.getOrCreateInterval(StackSlot,
MRI.getRegClass(Original));
1176 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1178 StackInt = &LSS.getInterval(StackSlot);
1180 if (Original != Edit->getReg())
1181 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1183 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1185 StackInt->MergeSegmentsInAsValue(LIS.
getInterval(Reg),
1187 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1191 spillAroundUses(Reg);
1194 if (!DeadDefs.empty()) {
1195 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1196 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1203 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1206 MI.eraseFromParent();
1212 Edit->eraseVirtReg(Reg);
1219 "Trying to spill a stack slot.");
1221 Original = VRM.getOriginal(edit.
getReg());
1222 StackSlot = VRM.getStackSlot(Original);
1227 <<
':' << edit.
getParent() <<
"\nFrom original "
1230 "Attempting to spill already spilled value.");
1231 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1233 collectRegsToSpill();
1237 if (!RegsToSpill.empty())
1240 Edit->calculateRegClassAndHint(MF, VRAI);
1244void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1247void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1248 unsigned Original) {
1253 if (!StackSlotToOrigLI.contains(StackSlot)) {
1254 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1255 LI->
assign(OrigLI, Allocator);
1256 StackSlotToOrigLI[StackSlot] = std::move(LI);
1259 VNInfo *OrigVNI = StackSlotToOrigLI[StackSlot]->getVNInfoAt(
Idx.getRegSlot());
1260 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1261 MergeableSpills[MIdx].insert(&Spill);
1266bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1268 auto It = StackSlotToOrigLI.find(StackSlot);
1269 if (It == StackSlotToOrigLI.end())
1272 VNInfo *OrigVNI = It->second->getVNInfoAt(
Idx.getRegSlot());
1273 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1274 return MergeableSpills[MIdx].erase(&Spill);
1287 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1294 for (
const Register &SibReg : Siblings) {
1307void HoistSpillHelper::rmRedundantSpills(
1314 for (
auto *
const CurrentSpill : Spills) {
1321 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1322 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1324 SpillBBToSpill[MDT.getBase().getNode(
Block)] = SpillToKeep;
1326 SpillBBToSpill[MDT.getBase().getNode(
Block)] = CurrentSpill;
1329 for (
auto *
const SpillToRm : SpillsToRm)
1330 Spills.
erase(SpillToRm);
1339void HoistSpillHelper::getVisitOrders(
1363 for (
auto *
const Spill : Spills) {
1367 while (
Node != RootIDomNode) {
1371 SpillToRm = SpillBBToSpill[MDT[
Block]];
1391 SpillsToKeep[MDT[
Block]] = 0;
1394 NodesOnPath.
clear();
1400 Orders.
push_back(MDT.getBase().getNode(Root));
1404 if (WorkSet.
count(Child))
1407 }
while (idx != Orders.
size());
1409 "Orders have different size with WorkSet");
1414 for (; RIt != Orders.
rend(); RIt++)
1415 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1423void HoistSpillHelper::runHoistSpills(
1439 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1442 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1449 using NodesCostPair =
1450 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1458 for (; RIt != Orders.
rend(); RIt++) {
1462 if (SpillsToKeep.
contains(*RIt) && !SpillsToKeep[*RIt]) {
1463 SpillsInSubTreeMap[*RIt].first.
insert(*RIt);
1465 SpillsInSubTreeMap[*RIt].second = MBFI.getBlockFreq(
Block);
1472 if (!SpillsInSubTreeMap.
contains(Child))
1480 SpillsInSubTreeMap[*RIt].first;
1482 SubTreeCost += SpillsInSubTreeMap[Child].second;
1483 auto BI = SpillsInSubTreeMap[Child].first.
begin();
1484 auto EI = SpillsInSubTreeMap[Child].first.
end();
1485 SpillsInSubTree.
insert(BI, EI);
1486 SpillsInSubTreeMap.
erase(Child);
1490 SpillsInSubTreeMap[*RIt].first;
1493 if (SpillsInSubTree.
empty())
1498 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1506 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1508 for (
auto *
const SpillBB : SpillsInSubTree) {
1511 if (SpillsToKeep.
contains(SpillBB) && !SpillsToKeep[SpillBB]) {
1516 SpillsToKeep.
erase(SpillBB);
1520 SpillsToKeep[*RIt] = LiveReg;
1522 dbgs() <<
"spills in BB: ";
1523 for (
const auto Rspill : SpillsInSubTree)
1524 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1525 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1528 SpillsInSubTree.clear();
1529 SpillsInSubTree.insert(*RIt);
1530 SubTreeCost = MBFI.getBlockFreq(
Block);
1535 for (
const auto &Ent : SpillsToKeep) {
1537 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1557void HoistSpillHelper::hoistAllSpills() {
1561 for (
unsigned i = 0, e =
MRI.getNumVirtRegs(); i != e; ++i) {
1563 Register Original = VRM.getPreSplitReg(Reg);
1564 if (!
MRI.def_empty(Reg))
1565 Virt2SiblingsMap[Original].insert(Reg);
1569 for (
auto &Ent : MergeableSpills) {
1570 int Slot = Ent.first.first;
1572 VNInfo *OrigVNI = Ent.first.second;
1574 if (Ent.second.empty())
1578 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1579 <<
"Equal spills in BB: ";
1580 for (
const auto spill : EqValSpills)
1581 dbgs() << spill->getParent()->getNumber() <<
" ";
1590 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1593 dbgs() <<
"Finally inserted spills in BB: ";
1594 for (
const auto &Ispill : SpillsToIns)
1595 dbgs() << Ispill.first->getNumber() <<
" ";
1596 dbgs() <<
"\nFinally removed spills in BB: ";
1597 for (
const auto Rspill : SpillsToRm)
1598 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1604 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1606 StackIntvl.getValNumInfo(0));
1609 for (
auto const &Insert : SpillsToIns) {
1623 NumSpills -= SpillsToRm.size();
1624 for (
auto *
const RMEnt : SpillsToRm) {
1625 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1626 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1629 RMEnt->removeOperand(i - 1);
1632 Edit.eliminateDeadDefs(SpillsToRm, std::nullopt);
1639 if (VRM.hasPhys(Old))
1640 VRM.assignVirt2Phys(New, VRM.getPhys(Old));
1642 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1645 if (VRM.hasShape(Old))
1646 VRM.assignVirt2Shape(New, VRM.getShape(Old));
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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 isFullCopyOf(const MachineInstr &MI, Register Reg)
isFullCopyOf - If MI is a COPY to or from Reg, return the other register, otherwise return 0.
static bool isRealSpill(const MachineInstr &Def)
Check if Def fully defines a VReg with an undefined value.
static cl::opt< bool > DisableHoisting("disable-spill-hoist", cl::Hidden, cl::desc("Disable inline spill hoisting"))
static cl::opt< bool > RestrictStatepointRemat("restrict-statepoint-remat", cl::init(false), cl::Hidden, cl::desc("Restrict remat for statepoint operands"))
static void getVDefInterval(const MachineInstr &MI, LiveIntervals &LIS)
unsigned const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
modulo schedule Modulo Schedule test pass
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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),...
Allocate memory in an ever growing pool, as if by bump-pointer.
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)
Base class for the actual dominator tree node.
iterator_range< iterator > children()
DomTreeNodeBase * getIDom() const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Store the specified register of the given register class to the specified stack frame index.
unsigned 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...
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Load the specified register of the given register class from the specified stack frame index.
Determines the latest safe point in a block in which we can insert a split, spill or other instructio...
LiveInterval - This class represents the liveness of a register, or stack slot.
bool isSpillable() const
isSpillable - Can this interval be spilled?
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
VNInfo::Allocator & getVNInfoAllocator()
LiveInterval & getInterval(Register Reg)
void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B, MachineBasicBlock::iterator E)
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.
virtual void LRE_DidCloneVirtReg(Register New, Register Old)
Called after cloning a virtual register.
const LiveInterval & getParent() const
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
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 necessarilly including Idx,...
unsigned getNumValNums() const
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.
iterator SkipPHIsLabelsAndDebug(iterator I, bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< pred_iterator > predecessors()
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
static const unsigned int DebugOperandMemNumber
A reserved operand number representing the instructions memory operand, for instructions that have a ...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, 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.
void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
unsigned getDebugInstrNum()
Fetch the instruction number of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
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.
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.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
Pass interface - Implemented by all 'passes'.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
static bool isStackSlot(unsigned Reg)
isStackSlot - Sometimes it is useful the be able to store a non-negative frame index in a variable th...
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 getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
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()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual void spill(LiveRangeEdit &LRE)=0
spill - Spill the LRE.getParent() live interval.
virtual void postOptimization()
MI-level Statepoint operands.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
Spiller * createInlineSpiller(MachineFunctionPass &Pass, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
unsigned getKillRegState(bool B)
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.
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.
Remat - Information needed to rematerialize at a specific location.
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.