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 {
188 HoistSpillHelper HSpiller;
193 ~InlineSpiller()
override =
default;
202 MRI(MF.getRegInfo()),
TII(*MF.getSubtarget().getInstrInfo()),
203 TRI(*MF.getSubtarget().getRegisterInfo()),
205 HSpiller(
Pass, MF, VRM), VRAI(VRAI) {}
212 void collectRegsToSpill();
223 void reMaterializeAll();
226 bool foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>,
239void Spiller::anchor() {}
244 return new InlineSpiller(
Pass, MF, VRM, VRAI);
263 if (!
TII.isCopyInstr(
MI))
286 "expected to see first instruction in bundle");
290 while (
I->isBundledWithSucc()) {
292 auto CopyInst =
TII.isCopyInstr(
MI);
318 if (MO.getReg().isVirtual())
325bool InlineSpiller::isSnippet(
const LiveInterval &SnipLI) {
339 if (!LIS.intervalIsInOneMBB(SnipLI))
345 for (
auto *VNI : SnipLI.
vnis()) {
347 if (
MI->getOpcode() == TargetOpcode::STATEPOINT)
357 RI =
MRI.reg_bundle_nodbg_begin(SnipLI.
reg()),
358 E =
MRI.reg_bundle_nodbg_end();
388void InlineSpiller::collectRegsToSpill() {
392 RegsToSpill.assign(1, Reg);
393 SnippetCopies.clear();
402 if (!isSibling(SnipReg))
405 if (!isSnippet(SnipLI))
407 SnippetCopies.insert(&
MI);
408 if (isRegToSpill(SnipReg))
410 RegsToSpill.push_back(SnipReg);
416bool InlineSpiller::isSibling(
Register Reg) {
417 return Reg.isVirtual() && VRM.getOriginal(Reg) == Original;
439bool InlineSpiller::hoistSpillInsideBB(
LiveInterval &SpillLI,
444 assert(VNI && VNI->
def ==
Idx.getRegSlot() &&
"Not defined by copy");
458 assert(StackInt &&
"No stack slot assigned yet.");
461 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
463 << *StackInt <<
'\n');
467 eliminateRedundantSpills(SrcLI, SrcVNI);
475 assert(
DefMI &&
"Defining instruction disappeared");
483 LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
492 if (MIS.begin() == MII)
493 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
509 if (SubLI.LaneMask == SR.LaneMask) {
510 if (SubVNI != SubLI.getVNInfoAt(
Idx))
512 }
else if ((SubLI.LaneMask & SR.LaneMask).any()) {
526 assert(VNI &&
"Missing value");
528 WorkList.
push_back(std::make_pair(&SLI, VNI));
529 assert(StackInt &&
"No stack slot assigned yet.");
536 << VNI->
def <<
" in " << *LI <<
'\n');
539 if (isRegToSpill(Reg))
543 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
544 LLVM_DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
549 if (!
MI.mayStore() && !
TII.isCopyInstr(
MI))
563 if (isSibling(DstReg)) {
566 assert(DstVNI &&
"Missing defined value");
567 assert(DstVNI->
def ==
Idx.getRegSlot() &&
"Wrong copy def slot");
569 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
579 MI.setDesc(
TII.get(TargetOpcode::KILL));
580 DeadDefs.push_back(&
MI);
582 if (HSpiller.rmFromMergeableSpills(
MI, StackSlot))
586 }
while (!WorkList.
empty());
597 WorkList.
push_back(std::make_pair(LI, VNI));
600 if (!UsedValues.insert(VNI).second)
608 WorkList.
push_back(std::make_pair(LI, PVNI));
615 if (!SnippetCopies.count(
MI))
617 LiveInterval &SnipLI = LIS.getInterval(
MI->getOperand(1).getReg());
618 assert(isRegToSpill(SnipLI.
reg()) &&
"Unexpected register in copy");
620 assert(SnipVNI &&
"Snippet undefined before copy");
621 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
622 }
while (!WorkList.
empty());
625bool InlineSpiller::canGuaranteeAssignmentAfterRemat(
Register VReg,
644 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
650 EndIdx =
MI.getNumOperands();
680 if (SnippetCopies.count(&
MI))
686 RM.OrigMI = LIS.getInstructionFromIndex(OrigVNI->
def);
688 if (!Edit->canRematerializeAt(RM, OrigVNI, UseIdx,
false)) {
689 markValueUsed(&VirtReg, ParentVNI);
697 markValueUsed(&VirtReg, ParentVNI);
704 if (
RM.OrigMI->canFoldAsLoad() &&
705 foldMemoryOperand(Ops,
RM.OrigMI)) {
706 Edit->markRematerialized(
RM.ParentVNI);
713 if (!canGuaranteeAssignmentAfterRemat(VirtReg.
reg(),
MI)) {
714 markValueUsed(&VirtReg, ParentVNI);
720 Register NewVReg = Edit->createFrom(Original);
724 Edit->rematerializeAt(*
MI.getParent(),
MI, NewVReg, RM,
TRI);
728 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
729 NewMI->setDebugLoc(
MI.getDebugLoc());
733 << *LIS.getInstructionFromIndex(DefIdx));
736 for (
const auto &OpPair : Ops) {
751void InlineSpiller::reMaterializeAll() {
752 if (!Edit->anyRematerializable())
758 bool anyRemat =
false;
763 if (
MI.isDebugValue())
766 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
767 "instruction that isn't a DBG_VALUE");
769 anyRemat |= reMaterializeFor(LI,
MI);
782 MI->addRegisterDead(Reg, &
TRI);
783 if (!
MI->allDefsAreDead())
786 DeadDefs.push_back(
MI);
792 if (DeadDefs.empty())
794 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
795 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
803 unsigned ResultPos = 0;
805 if (
MRI.reg_nodbg_empty(Reg)) {
806 Edit->eraseVirtReg(Reg);
810 assert(LIS.hasInterval(Reg) &&
811 (!LIS.getInterval(Reg).empty() || !
MRI.reg_nodbg_empty(Reg)) &&
812 "Empty and not used live-range?!");
814 RegsToSpill[ResultPos++] =
Reg;
816 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
818 <<
" registers to spill after remat.\n");
829 bool IsLoad = InstrReg;
834 if (InstrReg != Reg || FI != StackSlot)
838 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
841 LIS.RemoveMachineInstrFromMaps(*
MI);
842 MI->eraseFromParent();
855#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
861 const char *
const header,
863 char NextLine =
'\n';
864 char SlotIndent =
'\t';
866 if (std::next(
B) ==
E) {
871 dbgs() <<
'\t' << header <<
": " << NextLine;
882 Idx =
Idx.getRegSlot(
true);
885 dbgs() << SlotIndent <<
Idx <<
'\t' << *
I;
897foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
903 if (Ops.back().first !=
MI ||
MI->isBundled())
906 bool WasCopy =
TII.isCopyInstr(*MI).has_value();
915 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
919 bool SpillSubRegs =
TII.isSubregFoldable() ||
920 MI->getOpcode() == TargetOpcode::STATEPOINT ||
921 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
922 MI->getOpcode() == TargetOpcode::STACKMAP;
927 for (
const auto &OpPair : Ops) {
928 unsigned Idx = OpPair.second;
929 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
946 if (LoadMI && MO.
isDef())
949 if (UntieRegs || !
MI->isRegTiedToDefOperand(
Idx))
962 for (
unsigned Idx : FoldOps) {
966 unsigned Tied =
MI->findTiedOperandIdx(
Idx);
973 MI->untieRegOperand(
Idx);
977 LoadMI ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, &LIS)
978 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, &LIS, &VRM);
981 for (
auto Tied : TiedOps)
982 MI->tieOperands(Tied.first, Tied.second);
991 if (!Reg ||
Reg.isVirtual() ||
MRI.isReserved(Reg)) {
1008 HSpiller.rmFromMergeableSpills(*
MI, FI))
1012 if (
MI->isCandidateForCallSiteEntry())
1013 MI->getMF()->moveCallSiteInfo(
MI, FoldMI);
1020 if (
MI->peekDebugInstrNum() && Ops[0].second == 0) {
1022 auto MakeSubstitution = [
this,FoldMI,
MI,&Ops]() {
1024 unsigned OldOperandNum = Ops[0].second;
1026 unsigned OldNum =
MI->getDebugInstrNum();
1027 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1032 if (Ops.size() == 1 && Op0.
isDef()) {
1034 }
else if (Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
1035 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
1038 }
else if (
MI->peekDebugInstrNum()) {
1044 MF.substituteDebugValuesForInst(*
MI, *FoldMI, Ops[0].second);
1047 MI->eraseFromParent();
1050 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
1062 if (MO.
getReg() == ImpReg)
1071 else if (Ops.front().second == 0) {
1076 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1077 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1083void InlineSpiller::insertReload(
Register NewVReg,
1103 if (!Def.isImplicitDef())
1105 assert(Def.getNumOperands() == 1 &&
1106 "Implicit def with more than one definition");
1110 return Def.getOperand(0).getSubReg();
1114void InlineSpiller::insertSpill(
Register NewVReg,
bool isKill,
1118 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1133 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1147 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1148 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1152void InlineSpiller::spillAroundUses(
Register Reg) {
1159 if (
MI.isDebugValue()) {
1168 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1169 "instruction that isn't a DBG_VALUE");
1172 if (SnippetCopies.count(&
MI))
1176 if (coalesceStackAccess(&
MI, Reg))
1192 if (SibReg && isSibling(SibReg)) {
1194 if (isRegToSpill(SibReg)) {
1196 SnippetCopies.insert(&
MI);
1200 if (hoistSpillInsideBB(OldLI,
MI)) {
1202 MI.getOperand(0).setIsDead();
1203 DeadDefs.push_back(&
MI);
1215 if (foldMemoryOperand(Ops))
1220 Register NewVReg = Edit->createFrom(Reg);
1223 insertReload(NewVReg,
Idx, &
MI);
1226 bool hasLiveDef =
false;
1227 for (
const auto &OpPair : Ops) {
1231 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
1243 insertSpill(NewVReg,
true, &
MI);
1248void InlineSpiller::spillAll() {
1251 StackSlot = VRM.assignVirt2StackSlot(Original);
1252 StackInt = &LSS.getOrCreateInterval(StackSlot,
MRI.getRegClass(Original));
1253 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1255 StackInt = &LSS.getInterval(StackSlot);
1257 if (Original != Edit->getReg())
1258 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1260 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1262 StackInt->MergeSegmentsInAsValue(LIS.
getInterval(Reg),
1264 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1268 spillAroundUses(Reg);
1271 if (!DeadDefs.empty()) {
1272 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1273 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1280 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1283 MI.eraseFromBundle();
1289 Edit->eraseVirtReg(Reg);
1296 "Trying to spill a stack slot.");
1298 Original = VRM.getOriginal(edit.
getReg());
1299 StackSlot = VRM.getStackSlot(Original);
1304 <<
':' << edit.
getParent() <<
"\nFrom original "
1307 "Attempting to spill already spilled value.");
1308 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1310 collectRegsToSpill();
1314 if (!RegsToSpill.empty())
1317 Edit->calculateRegClassAndHint(MF, VRAI);
1321void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1324void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1325 unsigned Original) {
1330 if (!StackSlotToOrigLI.contains(StackSlot)) {
1331 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1332 LI->
assign(OrigLI, Allocator);
1333 StackSlotToOrigLI[StackSlot] = std::move(LI);
1336 VNInfo *OrigVNI = StackSlotToOrigLI[StackSlot]->getVNInfoAt(
Idx.getRegSlot());
1337 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1338 MergeableSpills[MIdx].insert(&Spill);
1343bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1345 auto It = StackSlotToOrigLI.find(StackSlot);
1346 if (It == StackSlotToOrigLI.end())
1349 VNInfo *OrigVNI = It->second->getVNInfoAt(
Idx.getRegSlot());
1350 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1351 return MergeableSpills[MIdx].erase(&Spill);
1364 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1371 for (
const Register &SibReg : Siblings) {
1384void HoistSpillHelper::rmRedundantSpills(
1391 for (
auto *
const CurrentSpill : Spills) {
1398 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1399 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1401 SpillBBToSpill[MDT.getBase().getNode(
Block)] = SpillToKeep;
1403 SpillBBToSpill[MDT.getBase().getNode(
Block)] = CurrentSpill;
1406 for (
auto *
const SpillToRm : SpillsToRm)
1407 Spills.
erase(SpillToRm);
1416void HoistSpillHelper::getVisitOrders(
1440 for (
auto *
const Spill : Spills) {
1444 while (
Node != RootIDomNode) {
1448 SpillToRm = SpillBBToSpill[MDT[
Block]];
1468 SpillsToKeep[MDT[
Block]] = 0;
1471 NodesOnPath.
clear();
1477 Orders.
push_back(MDT.getBase().getNode(Root));
1481 if (WorkSet.
count(Child))
1484 }
while (idx != Orders.
size());
1486 "Orders have different size with WorkSet");
1491 for (; RIt != Orders.
rend(); RIt++)
1492 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1500void HoistSpillHelper::runHoistSpills(
1516 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1519 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1526 using NodesCostPair =
1527 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1535 for (; RIt != Orders.
rend(); RIt++) {
1539 if (SpillsToKeep.
contains(*RIt) && !SpillsToKeep[*RIt]) {
1540 SpillsInSubTreeMap[*RIt].first.
insert(*RIt);
1542 SpillsInSubTreeMap[*RIt].second = MBFI.getBlockFreq(
Block);
1549 if (!SpillsInSubTreeMap.
contains(Child))
1557 SpillsInSubTreeMap[*RIt].first;
1559 SubTreeCost += SpillsInSubTreeMap[Child].second;
1560 auto BI = SpillsInSubTreeMap[Child].first.
begin();
1561 auto EI = SpillsInSubTreeMap[Child].first.
end();
1562 SpillsInSubTree.
insert(BI, EI);
1563 SpillsInSubTreeMap.
erase(Child);
1567 SpillsInSubTreeMap[*RIt].first;
1570 if (SpillsInSubTree.
empty())
1575 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1583 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1585 for (
auto *
const SpillBB : SpillsInSubTree) {
1588 if (SpillsToKeep.
contains(SpillBB) && !SpillsToKeep[SpillBB]) {
1593 SpillsToKeep.
erase(SpillBB);
1597 SpillsToKeep[*RIt] = LiveReg;
1599 dbgs() <<
"spills in BB: ";
1600 for (
const auto Rspill : SpillsInSubTree)
1601 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1602 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1605 SpillsInSubTree.clear();
1606 SpillsInSubTree.insert(*RIt);
1607 SubTreeCost = MBFI.getBlockFreq(
Block);
1612 for (
const auto &Ent : SpillsToKeep) {
1614 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1634void HoistSpillHelper::hoistAllSpills() {
1638 for (
unsigned i = 0, e =
MRI.getNumVirtRegs(); i != e; ++i) {
1640 Register Original = VRM.getPreSplitReg(Reg);
1641 if (!
MRI.def_empty(Reg))
1642 Virt2SiblingsMap[Original].insert(Reg);
1646 for (
auto &Ent : MergeableSpills) {
1647 int Slot = Ent.first.first;
1649 VNInfo *OrigVNI = Ent.first.second;
1651 if (Ent.second.empty())
1655 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1656 <<
"Equal spills in BB: ";
1657 for (
const auto spill : EqValSpills)
1658 dbgs() << spill->getParent()->getNumber() <<
" ";
1667 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1670 dbgs() <<
"Finally inserted spills in BB: ";
1671 for (
const auto &Ispill : SpillsToIns)
1672 dbgs() << Ispill.first->getNumber() <<
" ";
1673 dbgs() <<
"\nFinally removed spills in BB: ";
1674 for (
const auto Rspill : SpillsToRm)
1675 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1681 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1683 StackIntvl.getValNumInfo(0));
1686 for (
auto const &Insert : SpillsToIns) {
1700 NumSpills -= SpillsToRm.size();
1701 for (
auto *
const RMEnt : SpillsToRm) {
1702 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1703 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1706 RMEnt->removeOperand(i - 1);
1709 Edit.eliminateDeadDefs(SpillsToRm, std::nullopt);
1716 if (VRM.hasPhys(Old))
1717 VRM.assignVirt2Phys(New, VRM.getPhys(Old));
1719 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1722 if (VRM.hasShape(Old))
1723 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 bool allSubRangeValNoSame(const LiveInterval &LI, const LiveInterval &SLI, const MachineInstr &MI, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, SlotIndex Idx)
Check if all subranges in LI and SLI have the same value number at Idx.
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 > 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 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)
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?
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)
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.
bool isBundledWithPred() const
Return true if this instruction is part of a bundle, and it is not the first instruction in the bundl...
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...
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.
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 constexpr bool isStackSlot(unsigned Reg)
isStackSlot - Sometimes it is useful the be able to store a non-negative frame index in a variable th...
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
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.
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.
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.
Iterator for intrusive lists based on ilist_node.
self_iterator getIterator()
#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.