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"),
113 cl::desc(
"Cost for first time use of callee-saved register."),
117 "grow-region-complexity-budget",
118 cl::desc(
"growRegion() does not scale with the number of BB edges, so "
119 "limit its budget and bail out once we reach the limit."),
123 "greedy-regclass-priority-trumps-globalness",
124 cl::desc(
"Change the greedy register allocator's live range priority "
125 "calculation to make the AllocationPriority of the register class "
126 "more important then whether the range is global"),
130 "greedy-reverse-local-assignment",
131 cl::desc(
"Reverse allocation order of local live ranges, such that "
132 "shorter local live ranges will tend to be allocated first"),
136 "split-threshold-for-reg-with-hint",
137 cl::desc(
"The threshold for splitting a virtual register with a hint, in "
206 MBFI = Analyses.
MBFI;
208 Loops = Analyses.
Loops;
221 StringRef FilterName = Opts.FilterName.
empty() ?
"all" : Opts.FilterName;
222 OS <<
"greedy<" << FilterName <<
'>';
249 RAGreedy Impl(Analyses, Opts.Filter);
251 bool Changed = Impl.
run(MF);
291char RAGreedyLegacy::ID = 0;
315const char *
const RAGreedy::StageName[] = {
330 return new RAGreedyLegacy();
334 return new RAGreedyLegacy(Ftor);
337void RAGreedyLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
369bool RAGreedy::LRE_CanEraseVirtReg(
Register VirtReg) {
384void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
395 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
400 if (!
Info.inBounds(Old))
413 SpillerInstance.reset();
419void RAGreedy::enqueue(PQueue &CurQueue,
const LiveInterval *LI) {
423 assert(Reg.isVirtual() &&
"Can only enqueue virtual registers");
425 auto Stage = ExtraInfo->getOrInitStage(Reg);
428 ExtraInfo->setStage(Reg, Stage);
431 unsigned Ret = PriorityAdvisor->getPriority(*LI);
435 CurQueue.push(std::make_pair(Ret, ~Reg.id()));
438unsigned DefaultPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
453 (!ReverseLocalAssignment &&
456 unsigned GlobalBit = 0;
463 if (!ReverseLocalAssignment)
469 Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.
endIndex());
491 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
494 if (RegClassPriorityTrumpsGlobalness)
510unsigned DummyPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
519 if (CurQueue.empty())
536 for (
auto I = Order.
begin(), E = Order.
end();
I != E && !PhysReg; ++
I) {
557 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
559 evictInterference(VirtReg, PhysHint, NewVRegs);
564 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
569 SetOfBrokenHints.insert(&VirtReg);
580 << (
unsigned)
Cost <<
'\n');
581 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
582 return CheapReg ? CheapReg : PhysReg;
591 auto HasRegUnitInterference = [&](
MCRegUnit Unit) {
615void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
621 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
624 <<
" interference: Cascade " << Cascade <<
'\n');
645 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
647 "Cannot decrease cascade number, illegal eviction");
648 ExtraInfo->setCascade(Intf->reg(), Cascade);
664std::optional<unsigned>
667 unsigned CostPerUseLimit)
const {
668 unsigned OrderLimit = Order.
getOrder().size();
670 if (CostPerUseLimit <
uint8_t(~0u)) {
674 if (MinCost >= CostPerUseLimit) {
676 << MinCost <<
", no cheaper registers to be found.\n");
682 if (RegCosts[Order.
getOrder().back()] >= CostPerUseLimit) {
693 if (RegCosts[PhysReg.
id()] >= CostPerUseLimit)
697 if (CostPerUseLimit == 1 && isUnusedCalleeSavedReg(PhysReg)) {
719 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
720 VirtReg, Order, CostPerUseLimit, FixedRegisters);
722 evictInterference(VirtReg, BestPhys, NewVRegs);
740 SplitConstraints.resize(UseBlocks.
size());
742 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
763 if (Intf.
first() <= Indexes->getMBBStartIdx(BC.
Number)) {
777 SA->getFirstSplitPoint(BC.
Number)))
783 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
796 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
802 SpillPlacer->addConstraints(SplitConstraints);
803 return SpillPlacer->scanActiveBundles();
810 const unsigned GroupSize = 8;
812 unsigned TBS[GroupSize];
813 unsigned B = 0,
T = 0;
819 assert(
T < GroupSize &&
"Array overflow");
821 if (++
T == GroupSize) {
828 assert(
B < GroupSize &&
"Array overflow");
834 if (FirstNonDebugInstr !=
MBB->
end() &&
836 SA->getFirstSplitPoint(
Number)))
839 if (Intf.
first() <= Indexes->getMBBStartIdx(
Number))
845 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
850 if (++
B == GroupSize) {
851 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
856 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
861bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
865 unsigned AddedTo = 0;
867 unsigned Visited = 0;
874 for (
unsigned Bundle : NewBundles) {
878 if (
Blocks.size() >= Budget)
893 if (ActiveBlocks.
size() == AddedTo)
900 if (!addThroughConstraints(Cand.Intf, NewBlocks))
908 bool PrefSpill =
true;
909 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
915 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
916 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
917 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
922 SpillPlacer->addPrefSpill(NewBlocks,
true);
924 AddedTo = ActiveBlocks.
size();
927 SpillPlacer->iterate();
940bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
942 if (!SA->getNumThroughBlocks())
952 SpillPlacer->prepare(Cand.LiveBundles);
956 if (!addSplitConstraints(Cand.Intf,
Cost)) {
961 if (!growRegion(Cand)) {
966 SpillPlacer->finish();
968 if (!Cand.LiveBundles.any()) {
974 for (
int I : Cand.LiveBundles.set_bits())
975 dbgs() <<
" EB#" <<
I;
989 Cost += SpillPlacer->getBlockFrequency(
Number);
993 Cost += SpillPlacer->getBlockFrequency(
Number);
1002BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1005 const BitVector &LiveBundles = Cand.LiveBundles;
1007 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1010 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1011 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1014 Cand.Intf.moveToBlock(BC.
Number);
1021 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1024 for (
unsigned Number : Cand.ActiveBlocks) {
1025 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1026 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1027 if (!RegIn && !RegOut)
1029 if (RegIn && RegOut) {
1031 Cand.Intf.moveToBlock(
Number);
1032 if (Cand.Intf.hasInterference()) {
1033 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1034 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1039 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1060 const unsigned NumGlobalIntvs = LREdit.
size();
1063 assert(NumGlobalIntvs &&
"No global intervals configured");
1075 unsigned IntvIn = 0, IntvOut = 0;
1078 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1079 if (CandIn != NoCand) {
1080 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1081 IntvIn = Cand.IntvIdx;
1082 Cand.Intf.moveToBlock(
Number);
1083 IntfIn = Cand.Intf.first();
1087 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1088 if (CandOut != NoCand) {
1089 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1090 IntvOut = Cand.IntvIdx;
1091 Cand.Intf.moveToBlock(
Number);
1092 IntfOut = Cand.Intf.last();
1097 if (!IntvIn && !IntvOut) {
1099 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1100 SE->splitSingleBlock(BI);
1104 if (IntvIn && IntvOut)
1105 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1107 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1109 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1115 BitVector Todo = SA->getThroughBlocks();
1116 for (
unsigned UsedCand : UsedCands) {
1123 unsigned IntvIn = 0, IntvOut = 0;
1126 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1127 if (CandIn != NoCand) {
1128 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1129 IntvIn = Cand.IntvIdx;
1130 Cand.Intf.moveToBlock(
Number);
1131 IntfIn = Cand.Intf.first();
1134 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1135 if (CandOut != NoCand) {
1136 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1137 IntvOut = Cand.IntvIdx;
1138 Cand.Intf.moveToBlock(
Number);
1139 IntfOut = Cand.Intf.last();
1141 if (!IntvIn && !IntvOut)
1143 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1150 SE->finish(&IntvMap);
1151 DebugVars->splitRegister(Reg, LREdit.
regs(), *
LIS);
1153 unsigned OrigBlocks = SA->getNumLiveBlocks();
1160 for (
unsigned I = 0, E = LREdit.
size();
I != E; ++
I) {
1164 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1169 if (IntvMap[
I] == 0) {
1170 ExtraInfo->setStage(Reg,
RS_Spill);
1176 if (IntvMap[
I] < NumGlobalIntvs) {
1177 if (SA->countLiveBlocks(&Reg) >= OrigBlocks) {
1178 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1179 <<
" blocks as original.\n");
1191 MF->
verify(
LIS, Indexes,
"After splitting live range around region",
1200 unsigned NumCands = 0;
1205 bool HasCompact = calcCompactRegion(GlobalCand.front());
1213 BestCost = SpillCost;
1218 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1222 if (!HasCompact && BestCand == NoCand)
1225 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1229RAGreedy::calculateRegionSplitCostAroundReg(
MCPhysReg PhysReg,
1233 unsigned &BestCand) {
1236 if (NumCands == IntfCache.getMaxCursors()) {
1237 unsigned WorstCount = ~0
u;
1239 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1240 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1242 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1243 if (Count < WorstCount) {
1249 GlobalCand[Worst] = GlobalCand[NumCands];
1250 if (BestCand == NumCands)
1254 if (GlobalCand.size() <= NumCands)
1255 GlobalCand.resize(NumCands+1);
1256 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1257 Cand.reset(IntfCache, PhysReg);
1259 SpillPlacer->prepare(Cand.LiveBundles);
1261 if (!addSplitConstraints(Cand.Intf,
Cost)) {
1267 if (
Cost >= BestCost) {
1269 if (BestCand == NoCand)
1270 dbgs() <<
" worse than no bundles\n";
1272 dbgs() <<
" worse than "
1273 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1277 if (!growRegion(Cand)) {
1282 SpillPlacer->finish();
1285 if (!Cand.LiveBundles.any()) {
1290 Cost += calcGlobalSplitCost(Cand, Order);
1293 for (
int I : Cand.LiveBundles.set_bits())
1294 dbgs() <<
" EB#" <<
I;
1297 if (
Cost < BestCost) {
1298 BestCand = NumCands;
1306unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1311 unsigned BestCand =
NoCand;
1314 if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg))
1317 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1325 unsigned BestCand,
bool HasCompact,
1333 BundleCand.assign(Bundles->getNumBundles(), NoCand);
1336 if (BestCand != NoCand) {
1337 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1338 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1340 Cand.IntvIdx = SE->openIntv();
1342 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1349 GlobalSplitCandidate &Cand = GlobalCand.front();
1350 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1351 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1353 Cand.IntvIdx = SE->openIntv();
1355 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1360 splitAroundRegion(LREdit, UsedCands);
1366bool RAGreedy::trySplitAroundHintReg(
MCPhysReg Hint,
1377 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1387 if (!
TII->isFullCopyInstr(Instr))
1390 if (OtherReg == Reg) {
1391 OtherReg =
Instr.getOperand(0).getReg();
1392 if (OtherReg == Reg)
1400 if (OtherPhysReg == Hint)
1401 Cost += MBFI->getBlockFreq(
Instr.getParent());
1410 unsigned NumCands = 0;
1411 unsigned BestCand =
NoCand;
1412 SA->analyze(&VirtReg);
1413 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1414 if (BestCand == NoCand)
1417 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1431 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1438 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1439 SE->splitSingleBlock(BI);
1447 SE->finish(&IntvMap);
1450 DebugVars->splitRegister(Reg, LREdit.
regs(), *
LIS);
1454 for (
unsigned I = 0, E = LREdit.
size();
I != E; ++
I) {
1456 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1461 MF->
verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1476 assert(SuperRC &&
"Invalid register class");
1479 MI->getRegClassConstraintEffectForVReg(Reg, SuperRC,
TII,
TRI,
1494 for (
auto [
MI,
OpIdx] : Ops) {
1507 Mask |= ~SubRegMask;
1524 auto DestSrc =
TII->isCopyInstr(*
MI);
1525 if (DestSrc && !
MI->isBundled() &&
1526 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1535 LiveAtMask |= S.LaneMask;
1556 bool SplitSubClass =
true;
1560 SplitSubClass =
false;
1569 if (
Uses.size() <= 1)
1573 <<
" individual instrs.\n");
1577 unsigned SuperRCNumAllocatableRegs =
1585 if (
TII->isFullCopyInstr(*
MI) ||
1587 SuperRCNumAllocatableRegs ==
1600 SE->useIntv(SegStart, SegStop);
1603 if (LREdit.
empty()) {
1609 SE->finish(&IntvMap);
1610 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1625void RAGreedy::calcGapWeights(
MCRegister PhysReg,
1627 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1630 const unsigned NumGaps =
Uses.size()-1;
1638 GapWeight.
assign(NumGaps, 0.0f);
1655 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1657 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1658 if (++Gap == NumGaps)
1664 const float weight = IntI.value()->weight();
1665 for (; Gap != NumGaps; ++Gap) {
1666 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1667 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1682 for (
unsigned Gap = 0;
I != E &&
I->start < StopIdx; ++
I) {
1683 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1684 if (++Gap == NumGaps)
1689 for (; Gap != NumGaps; ++Gap) {
1691 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1708 if (SA->getUseBlocks().size() != 1)
1721 if (
Uses.size() <= 2)
1723 const unsigned NumGaps =
Uses.size()-1;
1726 dbgs() <<
"tryLocalSplit: ";
1742 unsigned RE = RMS.
size();
1743 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1754 RegMaskGaps.push_back(
I);
1781 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1784 unsigned BestBefore = NumGaps;
1785 unsigned BestAfter = 0;
1788 const float blockFreq =
1789 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1790 (1.0f / MBFI->getEntryFreq().getFrequency());
1797 calcGapWeights(PhysReg, GapWeight);
1801 for (
unsigned Gap : RegMaskGaps)
1808 unsigned SplitBefore = 0, SplitAfter = 1;
1812 float MaxGap = GapWeight[0];
1816 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1817 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1820 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1823 if (!LiveBefore && !LiveAfter) {
1831 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1834 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1843 blockFreq * (NewGaps + 1),
1844 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1852 float Diff = EstWeight - MaxGap;
1853 if (Diff > BestDiff) {
1856 BestBefore = SplitBefore;
1857 BestAfter = SplitAfter;
1864 if (++SplitBefore < SplitAfter) {
1867 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1868 MaxGap = GapWeight[SplitBefore];
1869 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1870 MaxGap = std::max(MaxGap, GapWeight[
I]);
1878 if (SplitAfter >= NumGaps) {
1884 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1889 if (BestBefore == NumGaps)
1893 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1894 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1902 SE->useIntv(SegStart, SegStop);
1904 SE->finish(&IntvMap);
1905 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1909 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1910 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1911 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1912 if (NewGaps >= NumGaps) {
1914 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1915 for (
unsigned I = 0, E = IntvMap.
size();
I != E; ++
I)
1916 if (IntvMap[
I] == 1) {
1939 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
1946 SA->analyze(&VirtReg);
1947 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
1948 if (PhysReg || !NewVRegs.
empty())
1950 return tryInstructionSplit(VirtReg, Order, NewVRegs);
1956 SA->analyze(&VirtReg);
1961 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
1962 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
1963 if (PhysReg || !NewVRegs.
empty())
1968 return tryBlockSplit(VirtReg, Order, NewVRegs);
1991 if (PhysReg == AssignedReg)
2004bool RAGreedy::mayRecolorAllInterferences(
2006 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2017 CutOffInfo |= CO_Interf;
2032 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2037 FixedRegisters.
count(Intf->reg())) {
2039 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2042 RecoloringCandidates.insert(Intf);
2094 RecoloringStack &RecolorStack,
unsigned Depth) {
2098 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2100 const ssize_t EntryStackSize = RecolorStack.size();
2104 "Last chance recoloring should really be last chance");
2110 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2111 CutOffInfo |= CO_Depth;
2116 SmallLISet RecoloringCandidates;
2128 RecoloringCandidates.clear();
2129 CurrentNewVRegs.
clear();
2135 dbgs() <<
"Some interferences are not with virtual registers.\n");
2142 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2144 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2151 PQueue RecoloringQueue;
2154 enqueue(RecoloringQueue, RC);
2156 "Interferences are supposed to be with allocated variables");
2159 RecolorStack.push_back(std::make_pair(RC,
VRM->
getPhys(ItVirtReg)));
2177 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2178 FixedRegisters, RecolorStack,
Depth)) {
2189 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2191 FixedRegisters.
erase(ThisVirtReg);
2199 FixedRegisters = SaveFixedRegisters;
2206 for (
Register R : CurrentNewVRegs) {
2218 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2221 std::tie(LI, PhysReg) = RecolorStack[
I];
2227 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2230 std::tie(LI, PhysReg) = RecolorStack[
I];
2236 RecolorStack.resize(EntryStackSize);
2251bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2254 RecoloringStack &RecolorStack,
2256 while (!RecoloringQueue.empty()) {
2259 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2260 RecolorStack,
Depth + 1);
2265 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2269 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2271 <<
" succeeded. Empty LI.\n");
2275 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2289 CutOffInfo = CO_None;
2294 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2295 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2296 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2297 if (CutOffEncountered == CO_Depth)
2298 Ctx.
emitError(
"register allocation failed: maximum depth for recoloring "
2299 "reached. Use -fexhaustive-register-search to skip "
2301 else if (CutOffEncountered == CO_Interf)
2302 Ctx.
emitError(
"register allocation failed: maximum interference for "
2303 "recoloring reached. Use -fexhaustive-register-search "
2305 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2306 Ctx.
emitError(
"register allocation failed: maximum interference and "
2307 "depth for recoloring reached. Use "
2308 "-fexhaustive-register-search to skip cutoffs");
2325 SA->analyze(&VirtReg);
2326 if (calcSpillCost() >= CSRCost)
2331 CostPerUseLimit = 1;
2334 if (ExtraInfo->getStage(VirtReg) <
RS_Split) {
2337 SA->analyze(&VirtReg);
2338 unsigned NumCands = 0;
2340 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2342 if (BestCand == NoCand)
2347 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2355 SetOfBrokenHints.remove(&LI);
2358void RAGreedy::initializeCSRCost() {
2365 if (!CSRCost.getFrequency())
2369 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2375 if (ActualEntry < FixedEntry)
2377 else if (ActualEntry <= UINT32_MAX)
2383 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2389void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2391 if (!
TII->isFullCopyInstr(Instr))
2395 if (OtherReg == Reg) {
2396 OtherReg =
Instr.getOperand(1).getReg();
2397 if (OtherReg == Reg)
2404 Out.push_back(HintInfo(MBFI->getBlockFreq(
Instr.getParent()), OtherReg,
2415 for (
const HintInfo &Info :
List) {
2416 if (
Info.PhysReg != PhysReg)
2430void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2451 if (
Reg.isPhysical())
2457 "We have an unallocated variable which should have been handled");
2472 <<
") is recolorable.\n");
2476 collectHintInfo(Reg, Info);
2479 if (CurrPhys != PhysReg) {
2481 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2486 if (OldCopiesCost < NewCopiesCost) {
2500 for (
const HintInfo &HI : Info) {
2504 }
while (!RecoloringCandidates.
empty());
2543void RAGreedy::tryHintsRecoloring() {
2546 "Recoloring is possible only for virtual registers");
2551 tryHintRecoloring(*LI);
2558 RecoloringStack &RecolorStack,
2565 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2569 if (CSRCost.getFrequency() &&
2570 EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.
empty()) {
2571 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2572 CostPerUseLimit, NewVRegs);
2573 if (CSRReg || !NewVRegs.
empty())
2581 if (!NewVRegs.
empty())
2586 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2593 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2601 if (Hint && Hint != PhysReg)
2602 SetOfBrokenHints.insert(&VirtReg);
2607 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2613 ExtraInfo->setStage(VirtReg,
RS_Split);
2621 unsigned NewVRegSizeBefore = NewVRegs.
size();
2622 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2623 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2630 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2631 RecolorStack,
Depth);
2645 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2647 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2658 using namespace ore;
2660 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2661 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2664 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2665 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2666 <<
" total folded spills cost ";
2669 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2670 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2672 if (FoldedReloads) {
2673 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2674 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2675 <<
" total folded reloads cost ";
2677 if (ZeroCostFoldedReloads)
2678 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2679 <<
" zero cost folded reloads ";
2681 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2682 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2687 RAGreedyStats
Stats;
2693 A->getPseudoValue())->getFrameIndex());
2696 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2697 MI.getOpcode() == TargetOpcode::STACKMAP ||
2698 MI.getOpcode() == TargetOpcode::STATEPOINT;
2701 auto DestSrc =
TII->isCopyInstr(
MI);
2711 if (SrcReg && Src.getSubReg())
2719 if (SrcReg != DestReg)
2736 if (!isPatchpointInstr(
MI)) {
2741 std::pair<unsigned, unsigned> NonZeroCostRange =
2742 TII->getPatchpointUnfoldableRange(
MI);
2745 for (
unsigned Idx = 0, E =
MI.getNumOperands();
Idx < E; ++
Idx) {
2749 if (
Idx >= NonZeroCostRange.first &&
Idx < NonZeroCostRange.second)
2755 for (
unsigned Slot : FoldedReloads)
2756 ZeroCostFoldedReloads.
erase(Slot);
2757 Stats.FoldedReloads += FoldedReloads.size();
2758 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2769 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2771 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2773 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2778RAGreedy::RAGreedyStats RAGreedy::reportStats(
MachineLoop *L) {
2779 RAGreedyStats
Stats;
2783 Stats.add(reportStats(SubLoop));
2790 if (!
Stats.isEmpty()) {
2791 using namespace ore;
2795 L->getStartLoc(),
L->getHeader());
2797 R <<
"generated in loop";
2804void RAGreedy::reportStats() {
2807 RAGreedyStats
Stats;
2809 Stats.add(reportStats(L));
2814 if (!
Stats.isEmpty()) {
2815 using namespace ore;
2819 if (
auto *SP = MF->getFunction().getSubprogram())
2824 R <<
"generated in function";
2830bool RAGreedy::hasVirtRegAlloc() {
2843 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
2844 <<
"********** Function: " << mf.
getName() <<
'\n');
2847 TII = MF->getSubtarget().getInstrInfo();
2850 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
2856 if (!hasVirtRegAlloc())
2861 Indexes->packIndexes();
2863 initializeCSRCost();
2866 RegClassPriorityTrumpsGlobalness =
2875 ExtraInfo.emplace();
2877 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI,
Loops);
2878 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
2880 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *
Loops, *MBFI);
2884 VRAI->calculateSpillWeightsAndHints();
2892 GlobalCand.resize(32);
2893 SetOfBrokenHints.clear();
2896 tryHintsRecoloring();
2899 MF->verify(
LIS, Indexes,
"Before post optimization", &
errs());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
DXIL Forward Handle Accesses
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
const HexagonInstrInfo * TII
This file implements an indexed map.
block placement Basic Block Placement Stats
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static bool hasTiedDef(MachineRegisterInfo *MRI, Register reg)
Return true if reg has any tied def operand.
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 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)
static cl::opt< unsigned > SplitThresholdForRegWithHint("split-threshold-for-reg-with-hint", cl::desc("The threshold for splitting a virtual register with a hint, in " "percentage"), cl::init(75), cl::Hidden)
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 > 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)
Remove Loads Into Fake Uses
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)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName) const
PreservedAnalyses run(MachineFunction &F, MachineFunctionAnalysisManager &AM)
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(Register VirtReg, const VirtRegMap &VRM, const RegisterClassInfo &RegClassInfo, const LiveRegMatrix *Matrix)
Create a new AllocationOrder for VirtReg.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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.
LLVM_ABI 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.
Represents analyses that only rely on functions' control flow.
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.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const override
Check if the instruction or the bundle of instructions has store to stack slots.
bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const override
Check if the instruction or the bundle of instructions has load from stack slots.
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...
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.
This is an important class for using LLVM in a threaded context.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
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.
LLVM_ABI 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)
LLVM_ABI MachineBasicBlock * intervalIsInOneMBB(const LiveInterval &LI) const
If LI is confined to a single basic block, return a pointer to that block.
LLVM_ABI void dump() const
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.
LLVM_ABI 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.
bool isPhysRegUsed(MCRegister PhysReg) const
Returns true if the given PhysReg has any live intervals assigned.
LiveIntervalUnion::Query & query(const LiveRange &LR, MCRegUnit RegUnit)
Query a line of the assigned virtual register matrix directly.
@ 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.
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static constexpr unsigned NoRegister
constexpr unsigned id() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
An RAII based helper class to modify MachineFunctionProperties when running pass.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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...
virtual MachineFunctionProperties getClearedProperties() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
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...
bool verify(Pass *p=nullptr, const char *Banner=nullptr, raw_ostream *OS=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
bool isImplicitDef() const
Analysis pass that exposes the MachineLoopInfo for a machine function.
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
LLVM_ABI 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
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool run(MachineFunction &mf)
Perform register allocation.
Spiller & spiller() override
MCRegister selectOrSplit(const LiveInterval &, SmallVectorImpl< Register > &) override
RAGreedy(RequiredAnalyses &Analyses, const RegAllocFilterFunc F=nullptr)
const LiveInterval * dequeue() override
dequeue - Return the next unassigned register, or NULL.
void enqueueImpl(const LiveInterval *LI) override
enqueue - Add VirtReg to the priority queue of unassigned registers.
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.
A MachineFunction analysis for fetching the Eviction Advisor.
Common provider for legacy and new pass managers.
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
Common provider for getting the priority advisor and logging rewards.
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.
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
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.
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.
@ InstrDist
The default distance between instructions as returned by distance().
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.
@ 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.
virtual void spill(LiveRangeEdit &LRE, AllocationOrder *Order=nullptr)=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.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
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 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...
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.
LLVM_ABI 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
int getNumOccurrences() const
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Pass manager infrastructure for declaring and invalidating analyses.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
constexpr uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
LLVM_ABI FunctionPass * createGreedyRegisterAllocator()
Greedy register allocation pass - This pass implements a global register allocator for optimized buil...
LLVM_ABI void initializeRAGreedyLegacyPass(PassRegistry &)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool TimePassesIsEnabled
If the user specifies the -time-passes argument on an LLVM tool command line then the value of this b...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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)
LLVM_ABI 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.
LLVM_ABI VirtRegInfo AnalyzeVirtRegInBundle(MachineInstr &MI, Register Reg, SmallVectorImpl< std::pair< MachineInstr *, unsigned > > *Ops=nullptr)
AnalyzeVirtRegInBundle - Analyze how the current instruction or bundle uses a virtual register.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI 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...
Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix=nullptr)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
LLVM_ABI char & RAGreedyLegacyID
Greedy register allocator.
static float normalizeSpillWeight(float UseDefFreq, unsigned Size, unsigned NumInstr)
Normalize the spill weight of a live interval.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Implement std::hash so that hash_code can be used in STL containers.
MachineBlockFrequencyInfo * MBFI
RegAllocEvictionAdvisorProvider * EvictProvider
MachineOptimizationRemarkEmitter * ORE
LiveDebugVariables * DebugVars
SpillPlacement * SpillPlacer
RegAllocPriorityAdvisorProvider * PriorityProvider
MachineDominatorTree * DomTree
RequiredAnalyses()=delete
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.