79#define DEBUG_TYPE "regalloc"
81STATISTIC(NumGlobalSplits,
"Number of split global live ranges");
82STATISTIC(NumLocalSplits,
"Number of split local live ranges");
83STATISTIC(NumEvicted,
"Number of interferences evicted");
87 cl::desc(
"Spill mode for splitting live ranges"),
95 cl::desc(
"Last chance recoloring max depth"),
100 cl::desc(
"Last chance recoloring maximum number of considered"
101 " interference at a time"),
106 cl::desc(
"Exhaustive Search for registers bypassing the depth "
107 "and interference cutoffs of last chance recoloring"),
112 cl::desc(
"Instead of spilling a variable right away, defer the actual "
113 "code insertion to the end of the allocation. That way the "
114 "allocator might still find a suitable coloring for this "
115 "variable because of other evicted variables."),
121 cl::desc(
"Cost for first time use of callee-saved register."),
125 "grow-region-complexity-budget",
126 cl::desc(
"growRegion() does not scale with the number of BB edges, so "
127 "limit its budget and bail out once we reach the limit."),
131 "greedy-regclass-priority-trumps-globalness",
132 cl::desc(
"Change the greedy register allocator's live range priority "
133 "calculation to make the AllocationPriority of the register class "
134 "more important then whether the range is global"),
138 "greedy-reverse-local-assignment",
139 cl::desc(
"Reverse allocation order of local live ranges, such that "
140 "shorter local live ranges will tend to be allocated first"),
144 "split-threshold-for-reg-with-hint",
145 cl::desc(
"The threshold for splitting a virtual register with a hint, in "
156 "Greedy Register Allocator",
false,
false)
176const char *
const RAGreedy::StageName[] = {
234bool RAGreedy::LRE_CanEraseVirtReg(
Register VirtReg) {
249void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
260 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
265 if (!Info.inBounds(Old))
274 Info[New] = Info[Old];
278 SpillerInstance.reset();
284void RAGreedy::enqueue(PQueue &CurQueue,
const LiveInterval *LI) {
288 assert(Reg.isVirtual() &&
"Can only enqueue virtual registers");
290 auto Stage = ExtraInfo->getOrInitStage(Reg);
293 ExtraInfo->setStage(Reg, Stage);
296 unsigned Ret = PriorityAdvisor->getPriority(*LI);
300 CurQueue.push(std::make_pair(Ret, ~Reg));
303unsigned DefaultPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
318 static unsigned MemOp = 0;
325 (!ReverseLocalAssignment &&
328 unsigned GlobalBit = 0;
335 if (!ReverseLocalAssignment)
363 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
366 if (RegClassPriorityTrumpsGlobalness)
385 if (CurQueue.empty())
402 for (
auto I = Order.
begin(), E = Order.
end();
I != E && !PhysReg; ++
I) {
423 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
425 evictInterference(VirtReg, PhysHint, NewVRegs);
430 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
435 SetOfBrokenHints.insert(&VirtReg);
439 uint8_t
Cost = RegCosts[PhysReg];
446 << (
unsigned)
Cost <<
'\n');
447 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
448 return CheapReg ? CheapReg : PhysReg;
457 auto HasRegUnitInterference = [&](
MCRegUnit Unit) {
481void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
487 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
490 <<
" interference: Cascade " << Cascade <<
'\n');
511 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
513 "Cannot decrease cascade number, illegal eviction");
514 ExtraInfo->setCascade(Intf->reg(), Cascade);
530std::optional<unsigned>
533 unsigned CostPerUseLimit)
const {
534 unsigned OrderLimit = Order.
getOrder().size();
536 if (CostPerUseLimit < uint8_t(~0u)) {
540 if (MinCost >= CostPerUseLimit) {
542 << MinCost <<
", no cheaper registers to be found.\n");
548 if (RegCosts[Order.
getOrder().back()] >= CostPerUseLimit) {
559 if (RegCosts[PhysReg] >= CostPerUseLimit)
563 if (CostPerUseLimit == 1 && isUnusedCalleeSavedReg(PhysReg)) {
580 uint8_t CostPerUseLimit,
585 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
586 VirtReg, Order, CostPerUseLimit, FixedRegisters);
588 evictInterference(VirtReg, BestPhys, NewVRegs);
606 SplitConstraints.resize(UseBlocks.
size());
608 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
643 SA->getFirstSplitPoint(BC.
Number)))
649 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
676 const unsigned GroupSize = 8;
678 unsigned TBS[GroupSize];
679 unsigned B = 0,
T = 0;
685 assert(
T < GroupSize &&
"Array overflow");
687 if (++
T == GroupSize) {
694 assert(
B < GroupSize &&
"Array overflow");
700 if (FirstNonDebugInstr !=
MBB->
end() &&
702 SA->getFirstSplitPoint(
Number)))
711 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
716 if (++
B == GroupSize) {
727bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
731 unsigned AddedTo = 0;
733 unsigned Visited = 0;
740 for (
unsigned Bundle : NewBundles) {
744 if (
Blocks.size() >= Budget)
759 if (ActiveBlocks.
size() == AddedTo)
766 if (!addThroughConstraints(Cand.Intf, NewBlocks))
774 bool PrefSpill =
true;
775 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
781 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
782 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
783 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
790 AddedTo = ActiveBlocks.
size();
806bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
808 if (!SA->getNumThroughBlocks())
818 SpillPlacer->
prepare(Cand.LiveBundles);
822 if (!addSplitConstraints(Cand.Intf,
Cost)) {
827 if (!growRegion(Cand)) {
834 if (!Cand.LiveBundles.any()) {
840 for (
int I : Cand.LiveBundles.set_bits())
841 dbgs() <<
" EB#" <<
I;
868BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
871 const BitVector &LiveBundles = Cand.LiveBundles;
873 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
880 Cand.Intf.moveToBlock(BC.
Number);
890 for (
unsigned Number : Cand.ActiveBlocks) {
893 if (!RegIn && !RegOut)
895 if (RegIn && RegOut) {
897 Cand.Intf.moveToBlock(
Number);
898 if (Cand.Intf.hasInterference()) {
926 const unsigned NumGlobalIntvs = LREdit.
size();
929 assert(NumGlobalIntvs &&
"No global intervals configured");
941 unsigned IntvIn = 0, IntvOut = 0;
945 if (CandIn != NoCand) {
946 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
947 IntvIn = Cand.IntvIdx;
948 Cand.Intf.moveToBlock(
Number);
949 IntfIn = Cand.Intf.first();
954 if (CandOut != NoCand) {
955 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
956 IntvOut = Cand.IntvIdx;
957 Cand.Intf.moveToBlock(
Number);
958 IntfOut = Cand.Intf.last();
963 if (!IntvIn && !IntvOut) {
965 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
966 SE->splitSingleBlock(BI);
970 if (IntvIn && IntvOut)
971 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
973 SE->splitRegInBlock(BI, IntvIn, IntfIn);
975 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
982 for (
unsigned UsedCand : UsedCands) {
989 unsigned IntvIn = 0, IntvOut = 0;
993 if (CandIn != NoCand) {
994 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
995 IntvIn = Cand.IntvIdx;
996 Cand.Intf.moveToBlock(
Number);
997 IntfIn = Cand.Intf.first();
1001 if (CandOut != NoCand) {
1002 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1003 IntvOut = Cand.IntvIdx;
1004 Cand.Intf.moveToBlock(
Number);
1005 IntfOut = Cand.Intf.last();
1007 if (!IntvIn && !IntvOut)
1009 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1016 SE->finish(&IntvMap);
1019 unsigned OrigBlocks = SA->getNumLiveBlocks();
1026 for (
unsigned I = 0, E = LREdit.
size();
I != E; ++
I) {
1030 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1035 if (IntvMap[
I] == 0) {
1036 ExtraInfo->setStage(Reg,
RS_Spill);
1042 if (IntvMap[
I] < NumGlobalIntvs) {
1043 if (SA->countLiveBlocks(&Reg) >= OrigBlocks) {
1044 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1045 <<
" blocks as original.\n");
1057 MF->
verify(
this,
"After splitting live range around region");
1065 unsigned NumCands = 0;
1070 bool HasCompact = calcCompactRegion(GlobalCand.
front());
1078 BestCost = SpillCost;
1083 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1087 if (!HasCompact && BestCand == NoCand)
1090 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1094RAGreedy::calculateRegionSplitCostAroundReg(
MCPhysReg PhysReg,
1098 unsigned &BestCand) {
1102 unsigned WorstCount = ~0
u;
1104 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1105 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1107 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1108 if (Count < WorstCount) {
1114 GlobalCand[Worst] = GlobalCand[NumCands];
1115 if (BestCand == NumCands)
1119 if (GlobalCand.
size() <= NumCands)
1120 GlobalCand.
resize(NumCands+1);
1121 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1122 Cand.reset(IntfCache, PhysReg);
1124 SpillPlacer->
prepare(Cand.LiveBundles);
1126 if (!addSplitConstraints(Cand.Intf,
Cost)) {
1132 if (
Cost >= BestCost) {
1134 if (BestCand == NoCand)
1135 dbgs() <<
" worse than no bundles\n";
1137 dbgs() <<
" worse than "
1138 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1142 if (!growRegion(Cand)) {
1150 if (!Cand.LiveBundles.any()) {
1155 Cost += calcGlobalSplitCost(Cand, Order);
1158 for (
int I : Cand.LiveBundles.set_bits())
1159 dbgs() <<
" EB#" <<
I;
1162 if (
Cost < BestCost) {
1163 BestCand = NumCands;
1171unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1176 unsigned BestCand = NoCand;
1179 if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg))
1182 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1189unsigned RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
unsigned BestCand,
1201 if (BestCand != NoCand) {
1202 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1203 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1205 Cand.IntvIdx = SE->openIntv();
1207 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1214 GlobalSplitCandidate &Cand = GlobalCand.
front();
1215 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1216 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1218 Cand.IntvIdx = SE->openIntv();
1220 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1225 splitAroundRegion(LREdit, UsedCands);
1231bool RAGreedy::trySplitAroundHintReg(
MCPhysReg Hint,
1242 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1255 if (OtherReg == Reg) {
1256 OtherReg =
Instr.getOperand(0).getReg();
1257 if (OtherReg == Reg)
1265 if (OtherPhysReg == Hint)
1275 unsigned NumCands = 0;
1276 unsigned BestCand = NoCand;
1277 SA->analyze(&VirtReg);
1278 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1279 if (BestCand == NoCand)
1282 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1293unsigned RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1296 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1303 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1304 SE->splitSingleBlock(BI);
1312 SE->finish(&IntvMap);
1319 for (
unsigned I = 0, E = LREdit.
size();
I != E; ++
I) {
1321 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1326 MF->
verify(
this,
"After splitting live range around basic blocks");
1340 assert(SuperRC &&
"Invalid register class");
1343 MI->getRegClassConstraintEffectForVReg(Reg, SuperRC,
TII,
TRI,
1358 for (
auto [
MI, OpIdx] : Ops) {
1371 Mask |= ~SubRegMask;
1388 auto DestSrc =
TII->isCopyInstr(*
MI);
1389 if (DestSrc && !
MI->isBundled() &&
1390 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1399 LiveAtMask |= S.LaneMask;
1414unsigned RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1420 bool SplitSubClass =
true;
1424 SplitSubClass =
false;
1433 if (
Uses.size() <= 1)
1437 <<
" individual instrs.\n");
1441 unsigned SuperRCNumAllocatableRegs =
1451 SuperRCNumAllocatableRegs ==
1464 SE->useIntv(SegStart, SegStop);
1467 if (LREdit.
empty()) {
1473 SE->finish(&IntvMap);
1489void RAGreedy::calcGapWeights(
MCRegister PhysReg,
1491 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1494 const unsigned NumGaps =
Uses.size()-1;
1502 GapWeight.
assign(NumGaps, 0.0f);
1519 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1521 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1522 if (++Gap == NumGaps)
1528 const float weight = IntI.value()->weight();
1529 for (; Gap != NumGaps; ++Gap) {
1530 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1531 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1546 for (
unsigned Gap = 0;
I != E &&
I->start < StopIdx; ++
I) {
1547 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1548 if (++Gap == NumGaps)
1553 for (; Gap != NumGaps; ++Gap) {
1555 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1567unsigned RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1572 if (SA->getUseBlocks().size() != 1)
1585 if (
Uses.size() <= 2)
1587 const unsigned NumGaps =
Uses.size()-1;
1590 dbgs() <<
"tryLocalSplit: ";
1606 unsigned RE = RMS.
size();
1607 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1618 RegMaskGaps.push_back(
I);
1645 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1648 unsigned BestBefore = NumGaps;
1649 unsigned BestAfter = 0;
1652 const float blockFreq =
1661 calcGapWeights(PhysReg, GapWeight);
1665 for (
unsigned Gap : RegMaskGaps)
1672 unsigned SplitBefore = 0, SplitAfter = 1;
1676 float MaxGap = GapWeight[0];
1680 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1681 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1684 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1687 if (!LiveBefore && !LiveAfter) {
1695 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1698 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1707 blockFreq * (NewGaps + 1),
1708 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1716 float Diff = EstWeight - MaxGap;
1717 if (Diff > BestDiff) {
1720 BestBefore = SplitBefore;
1721 BestAfter = SplitAfter;
1728 if (++SplitBefore < SplitAfter) {
1731 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1732 MaxGap = GapWeight[SplitBefore];
1733 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1734 MaxGap = std::max(MaxGap, GapWeight[
I]);
1742 if (SplitAfter >= NumGaps) {
1748 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1753 if (BestBefore == NumGaps)
1757 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1758 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1766 SE->useIntv(SegStart, SegStop);
1768 SE->finish(&IntvMap);
1773 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1774 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1775 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1776 if (NewGaps >= NumGaps) {
1778 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1779 for (
unsigned I = 0, E = IntvMap.
size();
I != E; ++
I)
1780 if (IntvMap[
I] == 1) {
1802 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
1809 SA->analyze(&VirtReg);
1810 Register PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
1811 if (PhysReg || !NewVRegs.
empty())
1813 return tryInstructionSplit(VirtReg, Order, NewVRegs);
1819 SA->analyze(&VirtReg);
1824 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
1825 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
1826 if (PhysReg || !NewVRegs.
empty())
1831 return tryBlockSplit(VirtReg, Order, NewVRegs);
1854 if (PhysReg == AssignedReg)
1867bool RAGreedy::mayRecolorAllInterferences(
1869 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
1880 CutOffInfo |= CO_Interf;
1895 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
1900 FixedRegisters.
count(Intf->reg())) {
1902 dbgs() <<
"Early abort: the interference is not recolorable.\n");
1905 RecoloringCandidates.insert(Intf);
1954unsigned RAGreedy::tryLastChanceRecoloring(
const LiveInterval &VirtReg,
1958 RecoloringStack &RecolorStack,
1963 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
1965 const ssize_t EntryStackSize = RecolorStack.size();
1969 "Last chance recoloring should really be last chance");
1975 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
1976 CutOffInfo |= CO_Depth;
1981 SmallLISet RecoloringCandidates;
1993 RecoloringCandidates.clear();
1994 CurrentNewVRegs.
clear();
2000 dbgs() <<
"Some interferences are not with virtual registers.\n");
2007 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2009 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2016 PQueue RecoloringQueue;
2019 enqueue(RecoloringQueue, RC);
2021 "Interferences are supposed to be with allocated variables");
2024 RecolorStack.push_back(std::make_pair(RC,
VRM->
getPhys(ItVirtReg)));
2039 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2040 FixedRegisters, RecolorStack,
Depth)) {
2042 for (
Register NewVReg : CurrentNewVRegs)
2054 FixedRegisters = SaveFixedRegisters;
2061 for (
Register R : CurrentNewVRegs) {
2073 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2076 std::tie(LI, PhysReg) = RecolorStack[
I];
2082 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2085 std::tie(LI, PhysReg) = RecolorStack[
I];
2091 RecolorStack.resize(EntryStackSize);
2106bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2109 RecoloringStack &RecolorStack,
2111 while (!RecoloringQueue.empty()) {
2114 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2115 RecolorStack,
Depth + 1);
2120 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2124 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2126 <<
" succeeded. Empty LI.\n");
2130 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2144 CutOffInfo = CO_None;
2149 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2150 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2151 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2152 if (CutOffEncountered == CO_Depth)
2153 Ctx.
emitError(
"register allocation failed: maximum depth for recoloring "
2154 "reached. Use -fexhaustive-register-search to skip "
2156 else if (CutOffEncountered == CO_Interf)
2157 Ctx.
emitError(
"register allocation failed: maximum interference for "
2158 "recoloring reached. Use -fexhaustive-register-search "
2160 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2161 Ctx.
emitError(
"register allocation failed: maximum interference and "
2162 "depth for recoloring reached. Use "
2163 "-fexhaustive-register-search to skip cutoffs");
2180 SA->analyze(&VirtReg);
2181 if (calcSpillCost() >= CSRCost)
2186 CostPerUseLimit = 1;
2189 if (ExtraInfo->getStage(VirtReg) <
RS_Split) {
2192 SA->analyze(&VirtReg);
2193 unsigned NumCands = 0;
2195 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2197 if (BestCand == NoCand)
2202 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2210 SetOfBrokenHints.remove(&LI);
2213void RAGreedy::initializeCSRCost() {
2228 if (ActualEntry < FixedEntry)
2230 else if (ActualEntry <= UINT32_MAX)
2242void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2248 if (OtherReg == Reg) {
2249 OtherReg =
Instr.getOperand(1).getReg();
2250 if (OtherReg == Reg)
2268 for (
const HintInfo &Info :
List) {
2269 if (
Info.PhysReg != PhysReg)
2283void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2304 if (
Reg.isPhysical())
2310 "We have an unallocated variable which should have been handled");
2325 <<
") is recolorable.\n");
2329 collectHintInfo(Reg, Info);
2332 if (CurrPhys != PhysReg) {
2334 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2339 if (OldCopiesCost < NewCopiesCost) {
2353 for (
const HintInfo &HI : Info) {
2357 }
while (!RecoloringCandidates.
empty());
2396void RAGreedy::tryHintsRecoloring() {
2399 "Recoloring is possible only for virtual registers");
2404 tryHintRecoloring(*LI);
2411 RecoloringStack &RecolorStack,
2413 uint8_t CostPerUseLimit = uint8_t(~0u);
2418 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2423 EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.
empty()) {
2424 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2425 CostPerUseLimit, NewVRegs);
2426 if (CSRReg || !NewVRegs.
empty())
2434 if (!NewVRegs.
empty())
2439 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2446 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2454 if (Hint && Hint != PhysReg)
2455 SetOfBrokenHints.insert(&VirtReg);
2459 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2465 ExtraInfo->setStage(VirtReg,
RS_Split);
2473 unsigned NewVRegSizeBefore = NewVRegs.
size();
2474 Register PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2475 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2482 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2483 RecolorStack,
Depth);
2489 ExtraInfo->getStage(VirtReg) <
RS_Memory) {
2494 ExtraInfo->setStage(VirtReg,
RS_Memory);
2510 MF->
verify(
this,
"After spilling");
2519 using namespace ore;
2521 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2522 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2525 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2526 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2527 <<
" total folded spills cost ";
2530 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2531 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2533 if (FoldedReloads) {
2534 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2535 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2536 <<
" total folded reloads cost ";
2538 if (ZeroCostFoldedReloads)
2539 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2540 <<
" zero cost folded reloads ";
2542 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2543 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2548 RAGreedyStats
Stats;
2554 A->getPseudoValue())->getFrameIndex());
2557 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2558 MI.getOpcode() == TargetOpcode::STACKMAP ||
2559 MI.getOpcode() == TargetOpcode::STATEPOINT;
2572 if (SrcReg && Src.getSubReg())
2580 if (SrcReg != DestReg)
2597 if (!isPatchpointInstr(
MI)) {
2602 std::pair<unsigned, unsigned> NonZeroCostRange =
2606 for (
unsigned Idx = 0, E =
MI.getNumOperands();
Idx < E; ++
Idx) {
2610 if (
Idx >= NonZeroCostRange.first &&
Idx < NonZeroCostRange.second)
2616 for (
unsigned Slot : FoldedReloads)
2617 ZeroCostFoldedReloads.
erase(Slot);
2618 Stats.FoldedReloads += FoldedReloads.size();
2619 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2632 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2634 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2639RAGreedy::RAGreedyStats RAGreedy::reportStats(
MachineLoop *L) {
2640 RAGreedyStats
Stats;
2644 Stats.add(reportStats(SubLoop));
2651 if (!
Stats.isEmpty()) {
2652 using namespace ore;
2656 L->getStartLoc(),
L->getHeader());
2658 R <<
"generated in loop";
2665void RAGreedy::reportStats() {
2668 RAGreedyStats
Stats;
2670 Stats.add(reportStats(L));
2675 if (!
Stats.isEmpty()) {
2676 using namespace ore;
2680 if (
auto *SP = MF->getFunction().getSubprogram())
2685 R <<
"generated in function";
2691bool RAGreedy::hasVirtRegAlloc() {
2707 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
2708 <<
"********** Function: " << mf.
getName() <<
'\n');
2711 TII = MF->getSubtarget().getInstrInfo();
2714 MF->verify(
this,
"Before greedy register allocator");
2717 getAnalysis<LiveIntervalsWrapperPass>().getLIS(),
2718 getAnalysis<LiveRegMatrix>());
2722 if (!hasVirtRegAlloc())
2725 Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
2729 MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
2730 DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
2731 ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
2732 Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
2733 Bundles = &getAnalysis<EdgeBundles>();
2734 SpillPlacer = &getAnalysis<SpillPlacement>();
2735 DebugVars = &getAnalysis<LiveDebugVariables>();
2737 initializeCSRCost();
2740 RegClassPriorityTrumpsGlobalness =
2749 ExtraInfo.emplace();
2751 getAnalysis<RegAllocEvictionAdvisorAnalysis>().getAdvisor(*MF, *
this);
2753 getAnalysis<RegAllocPriorityAdvisorAnalysis>().getAdvisor(*MF, *
this);
2755 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *
Loops, *MBFI);
2758 VRAI->calculateSpillWeightsAndHints();
2767 SetOfBrokenHints.clear();
2770 tryHintsRecoloring();
2773 MF->verify(
this,
"Before post optimization");
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
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
DenseMap< Block *, BlockRelaxAux > Blocks
Rewrite Partial Register Uses
const HexagonInstrInfo * TII
This file implements an indexed map.
block placement Basic Block Placement Stats
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static cl::opt< bool > GreedyRegClassPriorityTrumpsGlobalness("greedy-regclass-priority-trumps-globalness", cl::desc("Change the greedy register allocator's live range priority " "calculation to make the AllocationPriority of the register class " "more important then whether the range is global"), cl::Hidden)
static cl::opt< bool > ExhaustiveSearch("exhaustive-register-search", cl::NotHidden, cl::desc("Exhaustive Search for registers bypassing the depth " "and interference cutoffs of last chance recoloring"), cl::Hidden)
static cl::opt< unsigned > LastChanceRecoloringMaxInterference("lcr-max-interf", cl::Hidden, cl::desc("Last chance recoloring maximum number of considered" " interference at a time"), cl::init(8))
static bool hasTiedDef(MachineRegisterInfo *MRI, unsigned reg)
Return true if reg has any tied def operand.
static bool readsLaneSubset(const MachineRegisterInfo &MRI, const MachineInstr *MI, const LiveInterval &VirtReg, const TargetRegisterInfo *TRI, SlotIndex Use, const TargetInstrInfo *TII)
Return true if MI at \P Use reads a subset of the lanes live in VirtReg.
static bool assignedRegPartiallyOverlaps(const TargetRegisterInfo &TRI, const VirtRegMap &VRM, MCRegister PhysReg, const LiveInterval &Intf)
Return true if the existing assignment of Intf overlaps, but is not the same, as PhysReg.
static cl::opt< unsigned > CSRFirstTimeCost("regalloc-csr-first-time-cost", cl::desc("Cost for first time use of callee-saved register."), cl::init(0), cl::Hidden)
static cl::opt< unsigned > LastChanceRecoloringMaxDepth("lcr-max-depth", cl::Hidden, cl::desc("Last chance recoloring max depth"), cl::init(5))
static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator", createGreedyRegisterAllocator)
static cl::opt< unsigned long > GrowRegionComplexityBudget("grow-region-complexity-budget", cl::desc("growRegion() does not scale with the number of BB edges, so " "limit its budget and bail out once we reach the limit."), cl::init(10000), cl::Hidden)
Greedy Register Allocator
static cl::opt< SplitEditor::ComplementSpillMode > SplitSpillMode("split-spill-mode", cl::Hidden, cl::desc("Spill mode for splitting live ranges"), cl::values(clEnumValN(SplitEditor::SM_Partition, "default", "Default"), clEnumValN(SplitEditor::SM_Size, "size", "Optimize for size"), clEnumValN(SplitEditor::SM_Speed, "speed", "Optimize for speed")), cl::init(SplitEditor::SM_Speed))
static unsigned getNumAllocatableRegsForConstraints(const MachineInstr *MI, Register Reg, const TargetRegisterClass *SuperRC, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, const RegisterClassInfo &RCI)
Get the number of allocatable registers that match the constraints of Reg on MI and that are also in ...
static cl::opt< bool > EnableDeferredSpilling("enable-deferred-spilling", cl::Hidden, cl::desc("Instead of spilling a variable right away, defer the actual " "code insertion to the end of the allocation. That way the " "allocator might still find a suitable coloring for this " "variable because of other evicted variables."), cl::init(false))
static cl::opt< unsigned > SplitThresholdForRegWithHint("split-threshold-for-reg-with-hint", cl::desc("The threshold for splitting a virtual register with a hint, in " "percentate"), cl::init(75), cl::Hidden)
static cl::opt< bool > GreedyReverseLocalAssignment("greedy-reverse-local-assignment", cl::desc("Reverse allocation order of local live ranges, such that " "shorter local live ranges will tend to be allocated first"), cl::Hidden)
static LaneBitmask getInstReadLaneMask(const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const MachineInstr &FirstMI, Register Reg)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
This file defines the SmallSet 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)
bool isHint(Register Reg) const
Return true if Reg is a preferred physical register.
ArrayRef< MCPhysReg > getOrder() const
Get the allocation order without reordered hints.
static AllocationOrder create(unsigned VirtReg, const VirtRegMap &VRM, const RegisterClassInfo &RegClassInfo, const LiveRegMatrix *Matrix)
Create a new AllocationOrder for VirtReg.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
bool test(unsigned Idx) const
static BlockFrequency max()
Returns the maximum possible frequency, the saturation value.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
ArrayRef< unsigned > getBlocks(unsigned Bundle) const
getBlocks - Return an array of blocks that are connected to Bundle.
unsigned getBundle(unsigned N, bool Out) const
getBundle - Return the ingoing (Out = false) or outgoing (Out = true) bundle number for basic block N
unsigned getNumBundles() const
getNumBundles - Return the total number of bundles in the CFG.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Cursor - The primary query interface for the block interference cache.
SlotIndex first()
first - Return the starting index of the first interfering range in the current block.
SlotIndex last()
last - Return the ending index of the last interfering range in the current block.
bool hasInterference()
hasInterference - Return true if the current block has any interference.
void moveToBlock(unsigned MBBNum)
moveTo - Move cursor to basic block MBBNum.
void init(MachineFunction *mf, LiveIntervalUnion *liuarray, SlotIndexes *indexes, LiveIntervals *lis, const TargetRegisterInfo *tri)
init - Prepare cache for a new function.
unsigned getMaxCursors() const
getMaxCursors - Return the maximum number of concurrent cursors that can be supported.
This is an important class for using LLVM in a threaded context.
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
void splitRegister(Register OldReg, ArrayRef< Register > NewRegs, LiveIntervals &LIS)
splitRegister - Move any user variables in OldReg to the live ranges in NewRegs where they are live.
Query interferences between a single live virtual register and a live interval union.
const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())
SegmentIter find(SlotIndex x)
LiveSegments::iterator SegmentIter
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.
unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
iterator_range< subrange_iterator > subranges()
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
ArrayRef< SlotIndex > getRegMaskSlotsInBlock(unsigned MBBNum) const
Returns a sorted array of slot indices of all instructions with register mask operands in the basic b...
LiveInterval & getInterval(Register Reg)
MachineBasicBlock * intervalIsInOneMBB(const LiveInterval &LI) const
If LI is confined to a single basic block, return a pointer to that block.
Register get(unsigned idx) const
ArrayRef< Register > regs() const
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
SlotIndex endIndex() const
endNumber - return the maximum point of the range of the whole, exclusive.
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
bool checkRegMaskInterference(const LiveInterval &VirtReg, MCRegister PhysReg=MCRegister::NoRegister)
Check for regmask interference only.
void unassign(const LiveInterval &VirtReg)
Unassign VirtReg from its PhysReg.
LiveIntervalUnion::Query & query(const LiveRange &LR, MCRegister RegUnit)
Query a line of the assigned virtual register matrix directly.
bool isPhysRegUsed(MCRegister PhysReg) const
Returns true if the given PhysReg has any live intervals assigned.
@ IK_VirtReg
Virtual register interference.
void assign(const LiveInterval &VirtReg, MCRegister PhysReg)
Assign VirtReg to PhysReg.
InterferenceKind checkInterference(const LiveInterval &VirtReg, MCRegister PhysReg)
Check for interference before assigning VirtReg to PhysReg.
LiveIntervalUnion * getLiveUnions()
Directly access the live interval unions per regunit.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static constexpr unsigned NoRegister
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const
Compute the frequency of the block, relative to the entry block.
BlockFrequency getEntryFreq() const
Divide a block's BlockFrequency::getFrequency() value by this value to obtain the entry block - relat...
Analysis pass which computes a MachineDominatorTree.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use.
Representation of each machine instruction.
bool isImplicitDef() const
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register getSimpleHint(Register VReg) const
getSimpleHint - same as getRegAllocationHint except it will only return a target independent hint.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool reg_nodbg_empty(Register RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions.
iterator_range< def_iterator > def_operands(Register Reg) const
LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
iterator_range< reg_instr_nodbg_iterator > reg_nodbg_instructions(Register Reg) const
Spiller & spiller() override
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
MCRegister selectOrSplit(const LiveInterval &, SmallVectorImpl< Register > &) override
bool runOnMachineFunction(MachineFunction &mf) override
Perform register allocation.
const LiveInterval * dequeue() override
dequeue - Return the next unassigned register, or NULL.
RAGreedy(const RegAllocFilterFunc F=nullptr)
void enqueueImpl(const LiveInterval *LI) override
enqueue - Add VirtReg to the priority queue of unassigned registers.
void getAnalysisUsage(AnalysisUsage &AU) const override
RAGreedy analysis usage.
void aboutToRemoveInterval(const LiveInterval &) override
Method called when the allocator is about to remove a LiveInterval.
RegAllocBase provides the register allocation driver and interface that can be extended to add intere...
void enqueue(const LiveInterval *LI)
enqueue - Add VirtReg to the priority queue of unassigned registers.
void init(VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat)
SmallPtrSet< MachineInstr *, 32 > DeadRemats
Inst which is a def of an original reg and whose defs are already all dead after remat is saved in De...
const TargetRegisterInfo * TRI
static const char TimerGroupName[]
static const char TimerGroupDescription[]
virtual void postOptimization()
RegisterClassInfo RegClassInfo
MachineRegisterInfo * MRI
bool shouldAllocateRegister(Register Reg)
Get whether a given register should be allocated.
static bool VerifyEnabled
VerifyEnabled - True when -verify-regalloc is given.
ImmutableAnalysis abstraction for fetching the Eviction Advisor.
std::optional< unsigned > getOrderLimit(const LiveInterval &VirtReg, const AllocationOrder &Order, unsigned CostPerUseLimit) const
bool isUnusedCalleeSavedReg(MCRegister PhysReg) const
Returns true if the given PhysReg is a callee saved register and has not been used for allocation yet...
bool canReassign(const LiveInterval &VirtReg, MCRegister FromReg) const
bool canAllocatePhysReg(unsigned CostPerUseLimit, MCRegister PhysReg) const
unsigned getLastCostChange(const TargetRegisterClass *RC) const
Get the position of the last cost change in getOrder(RC).
bool isProperSubClass(const TargetRegisterClass *RC) const
isProperSubClass - Returns true if RC has a legal super-class with more allocatable registers.
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const
getNumAllocatableRegs - Returns the number of actually allocatable registers in RC in the current fun...
uint8_t getMinCost(const TargetRegisterClass *RC) const
Get the minimum register cost in RC's allocation order.
MCRegister getLastCalleeSavedAlias(MCRegister PhysReg) const
getLastCalleeSavedAlias - Returns the last callee saved register that overlaps PhysReg,...
Wrapper class representing virtual and physical registers.
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 isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical 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.
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
bool isValid() const
Returns true if this is a valid index.
SlotIndex getBoundaryIndex() const
Returns the boundary index for associated with this index.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
@ InstrDist
The default distance between instructions as returned by distance().
int getApproxInstrDistance(SlotIndex other) const
Return the scaled distance from this index to the given one, where all slots on the same instruction ...
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getLastIndex()
Returns the base index of the last slot in this analysis.
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
void packIndexes()
Renumber all indexes using the default instruction distance.
SlotIndex getZeroIndex()
Returns the zero index for this analysis.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void addConstraints(ArrayRef< BlockConstraint > LiveBlocks)
addConstraints - Add constraints and biases.
bool finish()
finish - Compute the optimal spill code placement given the constraints.
void addPrefSpill(ArrayRef< unsigned > Blocks, bool Strong)
addPrefSpill - Add PrefSpill constraints to all blocks listed.
void prepare(BitVector &RegBundles)
prepare - Reset state and prepare for a new spill placement computation.
bool scanActiveBundles()
scanActiveBundles - Perform an initial scan of all bundles activated by addConstraints and addLinks,...
void addLinks(ArrayRef< unsigned > Links)
addLinks - Add transparent blocks with the given numbers.
void iterate()
iterate - Update the network iteratively until convergence, or new bundles are found.
@ MustSpill
A register is impossible, variable must be spilled.
@ DontCare
Block doesn't care / variable not live.
@ PrefReg
Block entry/exit prefers a register.
@ PrefSpill
Block entry/exit prefers a stack slot.
ArrayRef< unsigned > getRecentPositive()
getRecentPositive - Return an array of bundles that became positive during the previous call to scanA...
BlockFrequency getBlockFrequency(unsigned Number) const
getBlockFrequency - Return the estimated block execution frequency per function invocation.
virtual void spill(LiveRangeEdit &LRE)=0
spill - Spill the LRE.getParent() live interval.
SplitAnalysis - Analyze a LiveInterval, looking for live range splitting opportunities.
SplitEditor - Edit machine code and LiveIntervals for live range splitting.
@ SM_Partition
SM_Partition(Default) - Try to create the complement interval so it doesn't overlap any other interva...
@ SM_Speed
SM_Speed - Overlap intervals to minimize the expected execution frequency of the inserted copies.
@ SM_Size
SM_Size - Overlap intervals to minimize the number of inserted COPY instructions.
TargetInstrInfo - Interface to description of machine instruction set.
virtual std::pair< unsigned, unsigned > getPatchpointUnfoldableRange(const MachineInstr &MI) const
For a patchpoint, stackmap, or statepoint intrinsic, return the range of operands which can't be fold...
bool isFullCopyInstr(const MachineInstr &MI) const
virtual bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const
If the specified machine instruction has a store to a stack slot, return true along with the FrameInd...
virtual Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const
If the specified machine instruction is a direct load from a stack slot, return the virtual or physic...
virtual Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
std::optional< DestSourcePair > isCopyInstr(const MachineInstr &MI) const
If the specific machine instruction is a instruction that moves/copies value from one register to ano...
virtual bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const
If the specified machine instruction has a load from a stack slot, return true along with the FrameIn...
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
const bool GlobalPriority
const uint8_t AllocationPriority
Classes with a higher priority value are assigned first by register allocators using a greedy heurist...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool shouldUseDeferredSpillingForVirtReg(const MachineFunction &MF, const LiveInterval &VirtReg) const
Deferred spilling delays the spill insertion of a virtual register after every other allocation.
virtual bool shouldRegionSplitForVirtReg(const MachineFunction &MF, const LiveInterval &VirtReg) const
Region split has a high compile time cost especially for large live range.
virtual bool shouldUseLastChanceRecoloringForVirtReg(const MachineFunction &MF, const LiveInterval &VirtReg) const
Last chance recoloring has a high compile time cost especially for targets with a lot of registers.
virtual unsigned getCSRFirstUseCost() const
Allow the target to override the cost of using a callee-saved register for the first time.
LaneBitmask getCoveringLanes() const
The lane masks returned by getSubRegIndexLaneMask() above can only be used to determine if sub-regist...
ArrayRef< uint8_t > getRegisterCosts(const MachineFunction &MF) const
Get a list of cost values for all registers that correspond to the index returned by RegisterCostTabl...
virtual bool reverseLocalAssignment() const
Allow the target to reverse allocation order of local live ranges.
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx.
virtual const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const
Returns the largest super class of RC that is legal to use in the current sub-target and has the same...
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
virtual bool regClassPriorityTrumpsGlobalness(const MachineFunction &MF) const
When prioritizing live ranges in register allocation, if this hook returns true then the AllocationPr...
A Use represents the edge between a Value definition and its users.
bool hasKnownPreference(Register VirtReg) const
returns true if VirtReg has a known preferred register.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
Reg
All possible values of the reg field in the ModR/M byte.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
std::function< bool(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const Register Reg)> RegAllocFilterFunc
Filter function for register classes during regalloc.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
FunctionPass * createGreedyRegisterAllocator()
Greedy register allocation pass - This pass implements a global register allocator for optimized buil...
bool TimePassesIsEnabled
If the user specifies the -time-passes argument on an LLVM tool command line then the value of this b...
char & RAGreedyID
Greedy register allocator.
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
@ RS_Split2
Attempt more aggressive live range splitting that is guaranteed to make progress.
@ RS_Spill
Live range will be spilled. No more splitting will be attempted.
@ RS_Split
Attempt live range splitting if assignment is impossible.
@ RS_New
Newly created live range that has never been queued.
@ RS_Done
There is nothing more we can do to this live range.
@ RS_Assign
Only attempt assignment and eviction. Then requeue as RS_Split.
@ RS_Memory
Live range is in memory.
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.
const float huge_valf
Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
static float normalizeSpillWeight(float UseDefFreq, unsigned Size, unsigned NumInstr)
Normalize the spill weight of a live interval.
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.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
constexpr bool any() const
This class is basically a combination of TimeRegion and Timer.
BlockConstraint - Entry and exit constraints for a basic block.
BorderConstraint Exit
Constraint on block exit.
bool ChangesValue
True when this block changes the value of the live range.
BorderConstraint Entry
Constraint on block entry.
unsigned Number
Basic block number (from MBB::getNumber()).
Additional information about basic blocks where the current variable is live.
SlotIndex FirstDef
First non-phi valno->def, or SlotIndex().
bool LiveOut
Current reg is live out.
bool LiveIn
Current reg is live in.
SlotIndex LastInstr
Last instr accessing current reg.
SlotIndex FirstInstr
First instr accessing current reg.