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(
137 VRM(vrm),
MRI(mf.getRegInfo()),
TII(*mf.getSubtarget().getInstrInfo()),
138 TRI(*mf.getSubtarget().getRegisterInfo()),
141 IPA(LIS, mf.getNumBlockIDs()) {}
143 void addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
145 bool rmFromMergeableSpills(
MachineInstr &Spill,
int StackSlot);
146 void hoistAllSpills();
150class InlineSpiller :
public Spiller {
182 HoistSpillHelper HSpiller;
187 ~InlineSpiller()
override =
default;
195 VRM(VRM),
MRI(MF.getRegInfo()),
TII(*MF.getSubtarget().getInstrInfo()),
196 TRI(*MF.getSubtarget().getRegisterInfo()),
199 HSpiller(
Pass, MF, VRM), VRAI(VRAI) {}
206 void collectRegsToSpill();
217 void reMaterializeAll();
220 bool foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>>,
233void Spiller::anchor() {}
238 return new InlineSpiller(
Pass, MF, VRM, VRAI);
257 if (!
TII.isCopyInstr(
MI))
280 "expected to see first instruction in bundle");
284 while (
I->isBundledWithSucc()) {
286 auto CopyInst =
TII.isCopyInstr(
MI);
312 if (MO.getReg().isVirtual())
319bool InlineSpiller::isSnippet(
const LiveInterval &SnipLI) {
333 if (!LIS.intervalIsInOneMBB(SnipLI))
339 for (
auto *VNI : SnipLI.
vnis()) {
341 if (
MI->getOpcode() == TargetOpcode::STATEPOINT)
351 RI =
MRI.reg_bundle_nodbg_begin(SnipLI.
reg()),
352 E =
MRI.reg_bundle_nodbg_end();
382void InlineSpiller::collectRegsToSpill() {
386 RegsToSpill.assign(1, Reg);
387 SnippetCopies.clear();
396 if (!isSibling(SnipReg))
399 if (!isSnippet(SnipLI))
401 SnippetCopies.insert(&
MI);
402 if (isRegToSpill(SnipReg))
404 RegsToSpill.push_back(SnipReg);
410bool InlineSpiller::isSibling(
Register Reg) {
411 return Reg.isVirtual() && VRM.getOriginal(Reg) == Original;
433bool InlineSpiller::hoistSpillInsideBB(
LiveInterval &SpillLI,
438 assert(VNI && VNI->
def ==
Idx.getRegSlot() &&
"Not defined by copy");
452 assert(StackInt &&
"No stack slot assigned yet.");
455 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
457 << *StackInt <<
'\n');
461 eliminateRedundantSpills(SrcLI, SrcVNI);
469 assert(
DefMI &&
"Defining instruction disappeared");
477 LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
486 if (MIS.begin() == MII)
487 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
495 assert(VNI &&
"Missing value");
497 WorkList.
push_back(std::make_pair(&SLI, VNI));
498 assert(StackInt &&
"No stack slot assigned yet.");
505 << VNI->
def <<
" in " << *LI <<
'\n');
508 if (isRegToSpill(Reg))
512 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
513 LLVM_DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
518 if (!
MI.mayStore() && !
TII.isCopyInstr(
MI))
526 if (isSibling(DstReg)) {
529 assert(DstVNI &&
"Missing defined value");
530 assert(DstVNI->
def ==
Idx.getRegSlot() &&
"Wrong copy def slot");
532 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
542 MI.setDesc(
TII.get(TargetOpcode::KILL));
543 DeadDefs.push_back(&
MI);
545 if (HSpiller.rmFromMergeableSpills(
MI, StackSlot))
549 }
while (!WorkList.
empty());
560 WorkList.
push_back(std::make_pair(LI, VNI));
563 if (!UsedValues.insert(VNI).second)
571 WorkList.
push_back(std::make_pair(LI, PVNI));
578 if (!SnippetCopies.count(
MI))
580 LiveInterval &SnipLI = LIS.getInterval(
MI->getOperand(1).getReg());
581 assert(isRegToSpill(SnipLI.
reg()) &&
"Unexpected register in copy");
583 assert(SnipVNI &&
"Snippet undefined before copy");
584 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
585 }
while (!WorkList.
empty());
588bool InlineSpiller::canGuaranteeAssignmentAfterRemat(
Register VReg,
607 if (
MI.getOpcode() != TargetOpcode::STATEPOINT)
613 EndIdx =
MI.getNumOperands();
643 if (SnippetCopies.count(&
MI))
649 RM.OrigMI = LIS.getInstructionFromIndex(OrigVNI->
def);
651 if (!Edit->canRematerializeAt(RM, OrigVNI, UseIdx,
false)) {
652 markValueUsed(&VirtReg, ParentVNI);
660 markValueUsed(&VirtReg, ParentVNI);
667 if (
RM.OrigMI->canFoldAsLoad() &&
668 foldMemoryOperand(Ops,
RM.OrigMI)) {
669 Edit->markRematerialized(
RM.ParentVNI);
676 if (!canGuaranteeAssignmentAfterRemat(VirtReg.
reg(),
MI)) {
677 markValueUsed(&VirtReg, ParentVNI);
683 Register NewVReg = Edit->createFrom(Original);
687 Edit->rematerializeAt(*
MI.getParent(),
MI, NewVReg, RM,
TRI);
691 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
692 NewMI->setDebugLoc(
MI.getDebugLoc());
696 << *LIS.getInstructionFromIndex(DefIdx));
699 for (
const auto &OpPair : Ops) {
714void InlineSpiller::reMaterializeAll() {
715 if (!Edit->anyRematerializable())
721 bool anyRemat =
false;
726 if (
MI.isDebugValue())
729 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
730 "instruction that isn't a DBG_VALUE");
732 anyRemat |= reMaterializeFor(LI,
MI);
745 MI->addRegisterDead(Reg, &
TRI);
746 if (!
MI->allDefsAreDead())
749 DeadDefs.push_back(
MI);
753 if (
MI->isBundledWithSucc() && !
MI->isBundledWithPred()) {
755 EndIt =
MI->getParent()->instr_end();
758 bool OnlyDeadCopies =
true;
760 It != EndIt && It->isBundledWithPred(); ++It) {
762 auto DestSrc =
TII.isCopyInstr(*It);
763 bool IsCopyToDeadReg =
764 DestSrc && DestSrc->Destination->getReg() ==
Reg;
765 if (!IsCopyToDeadReg) {
766 OnlyDeadCopies =
false;
770 if (OnlyDeadCopies) {
772 It != EndIt && It->isBundledWithPred(); ++It) {
773 It->addRegisterDead(Reg, &
TRI);
775 DeadDefs.push_back(&*It);
784 if (DeadDefs.empty())
786 LLVM_DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
787 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
795 unsigned ResultPos = 0;
797 if (
MRI.reg_nodbg_empty(Reg)) {
798 Edit->eraseVirtReg(Reg);
802 assert(LIS.hasInterval(Reg) &&
803 (!LIS.getInterval(Reg).empty() || !
MRI.reg_nodbg_empty(Reg)) &&
804 "Empty and not used live-range?!");
806 RegsToSpill[ResultPos++] =
Reg;
808 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
810 <<
" registers to spill after remat.\n");
821 bool IsLoad = InstrReg;
826 if (InstrReg != Reg || FI != StackSlot)
830 HSpiller.rmFromMergeableSpills(*
MI, StackSlot);
833 LIS.RemoveMachineInstrFromMaps(*
MI);
834 MI->eraseFromParent();
847#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
853 const char *
const header,
855 char NextLine =
'\n';
856 char SlotIndent =
'\t';
858 if (std::next(
B) == E) {
863 dbgs() <<
'\t' << header <<
": " << NextLine;
874 Idx =
Idx.getRegSlot(
true);
877 dbgs() << SlotIndent <<
Idx <<
'\t' << *
I;
889foldMemoryOperand(
ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
895 if (Ops.back().first !=
MI ||
MI->isBundled())
898 bool WasCopy =
TII.isCopyInstr(*MI).has_value();
907 bool UntieRegs =
MI->getOpcode() == TargetOpcode::STATEPOINT;
911 bool SpillSubRegs =
TII.isSubregFoldable() ||
912 MI->getOpcode() == TargetOpcode::STATEPOINT ||
913 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
914 MI->getOpcode() == TargetOpcode::STACKMAP;
919 for (
const auto &OpPair : Ops) {
920 unsigned Idx = OpPair.second;
921 assert(
MI == OpPair.first &&
"Instruction conflict during operand folding");
938 if (LoadMI && MO.
isDef())
941 if (UntieRegs || !
MI->isRegTiedToDefOperand(
Idx))
954 for (
unsigned Idx : FoldOps) {
958 unsigned Tied =
MI->findTiedOperandIdx(
Idx);
965 MI->untieRegOperand(
Idx);
969 LoadMI ?
TII.foldMemoryOperand(*
MI, FoldOps, *LoadMI, &LIS)
970 :
TII.foldMemoryOperand(*
MI, FoldOps, StackSlot, &LIS, &VRM);
973 for (
auto Tied : TiedOps)
974 MI->tieOperands(Tied.first, Tied.second);
983 if (!Reg ||
Reg.isVirtual() ||
MRI.isReserved(Reg)) {
1000 HSpiller.rmFromMergeableSpills(*
MI, FI))
1004 if (
MI->isCandidateForCallSiteEntry())
1005 MI->getMF()->moveCallSiteInfo(
MI, FoldMI);
1012 if (
MI->peekDebugInstrNum() && Ops[0].second == 0) {
1014 auto MakeSubstitution = [
this,FoldMI,
MI,&Ops]() {
1016 unsigned OldOperandNum = Ops[0].second;
1018 unsigned OldNum =
MI->getDebugInstrNum();
1019 MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1024 if (Ops.size() == 1 && Op0.
isDef()) {
1026 }
else if (Ops.size() == 2 && Op0.
isDef() &&
MI->getOperand(1).isTied() &&
1027 Op0.
getReg() ==
MI->getOperand(1).getReg()) {
1030 }
else if (
MI->peekDebugInstrNum()) {
1036 MF.substituteDebugValuesForInst(*
MI, *FoldMI, Ops[0].second);
1039 MI->eraseFromParent();
1042 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
1054 if (MO.
getReg() == ImpReg)
1063 else if (Ops.front().second == 0) {
1068 if (std::distance(MIS.begin(), MIS.end()) <= 1)
1069 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
1075void InlineSpiller::insertReload(
Register NewVReg,
1095 if (!Def.isImplicitDef())
1101 return Def.getOperand(0).getSubReg();
1105void InlineSpiller::insertSpill(
Register NewVReg,
bool isKill,
1109 assert(!
MI->isTerminator() &&
"Inserting a spill after a terminator");
1124 BuildMI(
MBB, SpillBefore,
MI->getDebugLoc(),
TII.get(TargetOpcode::KILL))
1138 if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
1139 HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
1143void InlineSpiller::spillAroundUses(
Register Reg) {
1150 if (
MI.isDebugValue()) {
1159 assert(!
MI.isDebugInstr() &&
"Did not expect to find a use in debug "
1160 "instruction that isn't a DBG_VALUE");
1163 if (SnippetCopies.count(&
MI))
1167 if (coalesceStackAccess(&
MI, Reg))
1183 if (SibReg && isSibling(SibReg)) {
1185 if (isRegToSpill(SibReg)) {
1187 SnippetCopies.insert(&
MI);
1191 if (hoistSpillInsideBB(OldLI,
MI)) {
1193 MI.getOperand(0).setIsDead();
1194 DeadDefs.push_back(&
MI);
1206 if (foldMemoryOperand(Ops))
1211 Register NewVReg = Edit->createFrom(Reg);
1214 insertReload(NewVReg,
Idx, &
MI);
1217 bool hasLiveDef =
false;
1218 for (
const auto &OpPair : Ops) {
1222 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
1234 insertSpill(NewVReg,
true, &
MI);
1239void InlineSpiller::spillAll() {
1242 StackSlot = VRM.assignVirt2StackSlot(Original);
1243 StackInt = &LSS.getOrCreateInterval(StackSlot,
MRI.getRegClass(Original));
1244 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
1246 StackInt = &LSS.getInterval(StackSlot);
1248 if (Original != Edit->getReg())
1249 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
1251 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
1253 StackInt->MergeSegmentsInAsValue(LIS.
getInterval(Reg),
1255 LLVM_DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1259 spillAroundUses(Reg);
1262 if (!DeadDefs.empty()) {
1263 LLVM_DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1264 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
1271 assert(SnippetCopies.count(&
MI) &&
"Remaining use wasn't a snippet copy");
1274 MI.eraseFromBundle();
1280 Edit->eraseVirtReg(Reg);
1287 "Trying to spill a stack slot.");
1289 Original = VRM.getOriginal(edit.
getReg());
1290 StackSlot = VRM.getStackSlot(Original);
1295 <<
':' << edit.
getParent() <<
"\nFrom original "
1298 "Attempting to spill already spilled value.");
1299 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1301 collectRegsToSpill();
1305 if (!RegsToSpill.empty())
1308 Edit->calculateRegClassAndHint(MF, VRAI);
1312void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1315void HoistSpillHelper::addToMergeableSpills(
MachineInstr &Spill,
int StackSlot,
1316 unsigned Original) {
1321 if (!StackSlotToOrigLI.contains(StackSlot)) {
1322 auto LI = std::make_unique<LiveInterval>(OrigLI.
reg(), OrigLI.
weight());
1323 LI->
assign(OrigLI, Allocator);
1324 StackSlotToOrigLI[StackSlot] = std::move(LI);
1327 VNInfo *OrigVNI = StackSlotToOrigLI[StackSlot]->getVNInfoAt(
Idx.getRegSlot());
1328 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1329 MergeableSpills[MIdx].insert(&Spill);
1334bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1336 auto It = StackSlotToOrigLI.find(StackSlot);
1337 if (It == StackSlotToOrigLI.end())
1340 VNInfo *OrigVNI = It->second->getVNInfoAt(
Idx.getRegSlot());
1341 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1342 return MergeableSpills[MIdx].erase(&Spill);
1355 LLVM_DEBUG(
dbgs() <<
"can't spill in root block - def after LIP\n");
1362 for (
const Register &SibReg : Siblings) {
1375void HoistSpillHelper::rmRedundantSpills(
1382 for (
auto *
const CurrentSpill : Spills) {
1389 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1390 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1392 SpillBBToSpill[MDT.getNode(
Block)] = SpillToKeep;
1394 SpillBBToSpill[MDT.getNode(
Block)] = CurrentSpill;
1397 for (
auto *
const SpillToRm : SpillsToRm)
1398 Spills.
erase(SpillToRm);
1407void HoistSpillHelper::getVisitOrders(
1431 for (
auto *
const Spill : Spills) {
1435 while (
Node != RootIDomNode) {
1439 SpillToRm = SpillBBToSpill[MDT[
Block]];
1459 SpillsToKeep[MDT[
Block]] = 0;
1462 NodesOnPath.
clear();
1472 if (WorkSet.
count(Child))
1475 }
while (idx != Orders.
size());
1477 "Orders have different size with WorkSet");
1482 for (; RIt != Orders.
rend(); RIt++)
1483 LLVM_DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1491void HoistSpillHelper::runHoistSpills(
1507 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1510 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1517 using NodesCostPair =
1518 std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>;
1526 for (; RIt != Orders.
rend(); RIt++) {
1530 if (SpillsToKeep.
contains(*RIt) && !SpillsToKeep[*RIt]) {
1531 SpillsInSubTreeMap[*RIt].first.
insert(*RIt);
1533 SpillsInSubTreeMap[*RIt].second = MBFI.getBlockFreq(
Block);
1540 if (!SpillsInSubTreeMap.
contains(Child))
1548 SpillsInSubTreeMap[*RIt].first;
1550 SubTreeCost += SpillsInSubTreeMap[Child].second;
1551 auto BI = SpillsInSubTreeMap[Child].first.
begin();
1552 auto EI = SpillsInSubTreeMap[Child].first.
end();
1553 SpillsInSubTree.
insert(BI, EI);
1554 SpillsInSubTreeMap.
erase(Child);
1558 SpillsInSubTreeMap[*RIt].first;
1561 if (SpillsInSubTree.
empty())
1566 if (!isSpillCandBB(OrigLI, OrigVNI, *
Block, LiveReg))
1574 if (SubTreeCost > MBFI.getBlockFreq(
Block) * MarginProb) {
1576 for (
auto *
const SpillBB : SpillsInSubTree) {
1579 if (SpillsToKeep.
contains(SpillBB) && !SpillsToKeep[SpillBB]) {
1584 SpillsToKeep.
erase(SpillBB);
1588 SpillsToKeep[*RIt] = LiveReg;
1590 dbgs() <<
"spills in BB: ";
1591 for (
const auto Rspill : SpillsInSubTree)
1592 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1593 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1596 SpillsInSubTree.clear();
1597 SpillsInSubTree.insert(*RIt);
1598 SubTreeCost = MBFI.getBlockFreq(
Block);
1603 for (
const auto &Ent : SpillsToKeep) {
1605 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1625void HoistSpillHelper::hoistAllSpills() {
1629 for (
unsigned i = 0, e =
MRI.getNumVirtRegs(); i != e; ++i) {
1631 Register Original = VRM.getPreSplitReg(Reg);
1632 if (!
MRI.def_empty(Reg))
1633 Virt2SiblingsMap[Original].insert(Reg);
1637 for (
auto &Ent : MergeableSpills) {
1638 int Slot = Ent.first.first;
1640 VNInfo *OrigVNI = Ent.first.second;
1642 if (Ent.second.empty())
1646 dbgs() <<
"\nFor Slot" <<
Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1647 <<
"Equal spills in BB: ";
1648 for (
const auto spill : EqValSpills)
1649 dbgs() << spill->getParent()->getNumber() <<
" ";
1658 runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1661 dbgs() <<
"Finally inserted spills in BB: ";
1662 for (
const auto &Ispill : SpillsToIns)
1663 dbgs() << Ispill.first->getNumber() <<
" ";
1664 dbgs() <<
"\nFinally removed spills in BB: ";
1665 for (
const auto Rspill : SpillsToRm)
1666 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1672 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1674 StackIntvl.getValNumInfo(0));
1677 for (
auto const &Insert : SpillsToIns) {
1691 NumSpills -= SpillsToRm.size();
1692 for (
auto *
const RMEnt : SpillsToRm) {
1693 RMEnt->setDesc(
TII.get(TargetOpcode::KILL));
1694 for (
unsigned i = RMEnt->getNumOperands(); i; --i) {
1697 RMEnt->removeOperand(i - 1);
1700 Edit.eliminateDeadDefs(SpillsToRm, std::nullopt);
1707 if (VRM.hasPhys(Old))
1708 VRM.assignVirt2Phys(New, VRM.getPhys(Old));
1710 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
1713 if (VRM.hasShape(Old))
1714 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")
#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 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)
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.
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, const TargetRegisterInfo *TRI, Register VReg) 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...
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)
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, 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
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...
Analysis pass which computes a MachineDominatorTree.
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 to be able to store a non-negative frame index in a variable tha...
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.
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.