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 "
153 StringRef getPassName()
const override {
return "Greedy Register Allocator"; }
156 void getAnalysisUsage(AnalysisUsage &AU)
const override;
158 bool runOnMachineFunction(MachineFunction &mf)
override;
160 MachineFunctionProperties getRequiredProperties()
const override {
161 return MachineFunctionProperties().setNoPHIs();
164 MachineFunctionProperties getClearedProperties()
const override {
165 return MachineFunctionProperties().setIsSSA();
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);
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) {
370 LiveInterval &LI =
LIS->getInterval(VirtReg);
371 if (
VRM->hasPhys(VirtReg)) {
384void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
385 if (!
VRM->hasPhys(VirtReg))
389 LiveInterval &LI =
LIS->getInterval(VirtReg);
395 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
400 if (!Info.inBounds(Old))
409 Info[New] = Info[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 {
451 const TargetRegisterClass &RC = *
MRI->getRegClass(
Reg);
453 (!ReverseLocalAssignment &&
456 unsigned GlobalBit = 0;
459 LIS->intervalIsInOneMBB(LI)) {
463 if (!ReverseLocalAssignment)
469 Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.
endIndex());
491 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
494 if (RegClassPriorityTrumpsGlobalness)
503 if (
VRM->hasKnownPreference(
Reg))
510unsigned DummyPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
519 if (CurQueue.empty())
536 for (
auto I = Order.
begin(),
E = Order.
end();
I !=
E && !PhysReg; ++
I) {
538 if (!
Matrix->checkInterference(VirtReg, *
I)) {
554 MCRegister PhysHint =
Hint.asMCReg();
557 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
559 evictInterference(VirtReg, PhysHint, NewVRegs);
564 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
569 SetOfBrokenHints.insert(&VirtReg);
573 uint8_t
Cost = RegCosts[PhysReg.
id()];
580 << (
unsigned)
Cost <<
'\n');
581 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
582 return CheapReg ? CheapReg : PhysReg;
591 auto HasRegUnitInterference = [&](
MCRegUnit Unit) {
602 if (
none_of(
TRI->regunits(Reg), HasRegUnitInterference)) {
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);
661 return !
Matrix->isPhysRegUsed(PhysReg);
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");
693 if (
RegCosts[PhysReg.
id()] >= CostPerUseLimit)
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();
808bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
809 ArrayRef<unsigned> Blocks) {
810 const unsigned GroupSize = 8;
811 SpillPlacement::BlockConstraint BCS[GroupSize];
812 unsigned TBS[GroupSize];
813 unsigned B = 0,
T = 0;
815 for (
unsigned Number : Blocks) {
819 assert(
T < GroupSize &&
"Array overflow");
821 if (++
T == GroupSize) {
828 assert(
B < GroupSize &&
"Array overflow");
832 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
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) {
863 BitVector Todo = SA->getThroughBlocks();
864 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
865 unsigned AddedTo = 0;
867 unsigned Visited = 0;
872 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
874 for (
unsigned Bundle : NewBundles) {
876 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
878 if (Blocks.
size() >= Budget)
880 Budget -= Blocks.
size();
881 for (
unsigned Block : Blocks) {
893 if (ActiveBlocks.
size() == AddedTo)
898 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
900 if (!addThroughConstraints(Cand.Intf, NewBlocks))
908 bool PrefSpill =
true;
909 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
914 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
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;
983BlockFrequency RAGreedy::calcSpillCost() {
984 BlockFrequency
Cost = BlockFrequency(0);
986 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
989 Cost += SpillPlacer->getBlockFrequency(
Number);
993 Cost += SpillPlacer->getBlockFrequency(
Number);
1002BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1003 const AllocationOrder &Order) {
1004 BlockFrequency GlobalCost = BlockFrequency(0);
1005 const BitVector &LiveBundles = Cand.LiveBundles;
1007 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1008 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1009 SpillPlacement::BlockConstraint &BC = SplitConstraints[
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);
1056void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1057 ArrayRef<unsigned> UsedCands) {
1060 const unsigned NumGlobalIntvs = LREdit.
size();
1063 assert(NumGlobalIntvs &&
"No global intervals configured");
1073 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1075 unsigned IntvIn = 0, IntvOut = 0;
1076 SlotIndex IntfIn, IntfOut;
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) {
1117 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1118 for (
unsigned Number : Blocks) {
1123 unsigned IntvIn = 0, IntvOut = 0;
1124 SlotIndex IntfIn, IntfOut;
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);
1149 SmallVector<unsigned, 8> IntvMap;
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) {
1161 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1164 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1169 if (IntvMap[
I] == 0) {
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",
1195MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1196 AllocationOrder &Order,
1197 SmallVectorImpl<Register> &NewVRegs) {
1198 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1200 unsigned NumCands = 0;
1201 BlockFrequency SpillCost = calcSpillCost();
1202 BlockFrequency BestCost;
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,
1230 AllocationOrder &Order,
1231 BlockFrequency &BestCost,
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);
1260 BlockFrequency
Cost;
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,
1307 AllocationOrder &Order,
1308 BlockFrequency &BestCost,
1311 unsigned BestCand = NoCand;
1314 if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg))
1317 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1324MCRegister RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
1325 unsigned BestCand,
bool HasCompact,
1326 SmallVectorImpl<Register> &NewVRegs) {
1327 SmallVector<unsigned, 8> UsedCands;
1329 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
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);
1361 return MCRegister();
1366bool RAGreedy::trySplitAroundHintReg(
MCPhysReg Hint,
1367 const LiveInterval &VirtReg,
1368 SmallVectorImpl<Register> &NewVRegs,
1369 AllocationOrder &Order) {
1373 if (MF->getFunction().hasOptSize())
1377 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1380 BlockFrequency
Cost = BlockFrequency(0);
1390 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
1391 const MachineInstr &
Instr = *Opnd.getParent();
1392 if (!
Instr.isCopy() || Opnd.isImplicit())
1396 const bool IsDef = Opnd.isDef();
1397 const MachineOperand &OtherOpnd =
Instr.getOperand(IsDef);
1400 if (OtherReg ==
Reg)
1403 unsigned SubReg = Opnd.getSubReg();
1404 unsigned OtherSubReg = OtherOpnd.
getSubReg();
1409 if (Opnd.readsReg()) {
1410 SlotIndex
Index =
LIS->getInstructionIndex(Instr).getRegSlot();
1417 if (
any_of(VirtReg.
subranges(), [=](
const LiveInterval::SubRange &S) {
1418 return (S.LaneMask & Mask).any() && S.liveAt(Index);
1423 if (VirtReg.
liveAt(Index))
1428 MCRegister OtherPhysReg =
1430 MCRegister ThisHint =
1432 if (OtherPhysReg == ThisHint)
1433 Cost += MBFI->getBlockFreq(
Instr.getParent());
1439 if (
Cost == BlockFrequency(0))
1442 unsigned NumCands = 0;
1443 unsigned BestCand = NoCand;
1444 SA->analyze(&VirtReg);
1445 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1446 if (BestCand == NoCand)
1449 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1460MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1461 AllocationOrder &Order,
1462 SmallVectorImpl<Register> &NewVRegs) {
1463 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1466 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1469 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1470 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1471 SE->splitSingleBlock(BI);
1475 return MCRegister();
1478 SmallVector<unsigned, 8> IntvMap;
1479 SE->finish(&IntvMap);
1482 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1486 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1487 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1488 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1493 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1495 return MCRegister();
1508 assert(SuperRC &&
"Invalid register class");
1511 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1533 return MRI.getMaxLaneMaskForVReg(
Reg);
1539 Mask |= ~SubRegMask;
1556 auto DestSrc =
TII->isCopyInstr(*
MI);
1557 if (DestSrc && !
MI->isBundled() &&
1558 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1567 LiveAtMask |= S.LaneMask;
1572 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1582MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1583 AllocationOrder &Order,
1584 SmallVectorImpl<Register> &NewVRegs) {
1585 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
1588 bool SplitSubClass =
true;
1591 return MCRegister();
1592 SplitSubClass =
false;
1597 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1601 if (
Uses.size() <= 1)
1602 return MCRegister();
1605 <<
" individual instrs.\n");
1607 const TargetRegisterClass *SuperRC =
1608 TRI->getLargestLegalSuperClass(CurRC, *MF);
1609 unsigned SuperRCNumAllocatableRegs =
1615 for (
const SlotIndex Use :
Uses) {
1616 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1617 if (TII->isFullCopyInstr(*
MI) ||
1619 SuperRCNumAllocatableRegs ==
1630 SlotIndex SegStart = SE->enterIntvBefore(Use);
1631 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1632 SE->useIntv(SegStart, SegStop);
1635 if (LREdit.
empty()) {
1637 return MCRegister();
1640 SmallVector<unsigned, 8> IntvMap;
1641 SE->finish(&IntvMap);
1642 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1645 return MCRegister();
1657void RAGreedy::calcGapWeights(MCRegister PhysReg,
1658 SmallVectorImpl<float> &GapWeight) {
1659 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1660 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1662 const unsigned NumGaps =
Uses.size()-1;
1665 SlotIndex StartIdx =
1670 GapWeight.
assign(NumGaps, 0.0f);
1674 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1675 .checkInterference())
1686 Matrix->getLiveUnions()[
Unit].find(StartIdx);
1687 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1689 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1690 if (++Gap == NumGaps)
1696 const float weight = IntI.value()->weight();
1697 for (; Gap != NumGaps; ++Gap) {
1698 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1699 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1714 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1715 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1716 if (++Gap == NumGaps)
1721 for (; Gap != NumGaps; ++Gap) {
1723 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1735MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1736 AllocationOrder &Order,
1737 SmallVectorImpl<Register> &NewVRegs) {
1740 if (SA->getUseBlocks().size() != 1)
1741 return MCRegister();
1743 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1753 if (
Uses.size() <= 2)
1754 return MCRegister();
1755 const unsigned NumGaps =
Uses.size()-1;
1758 dbgs() <<
"tryLocalSplit: ";
1759 for (
const auto &Use :
Uses)
1766 SmallVector<unsigned, 8> RegMaskGaps;
1767 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1774 unsigned RE = RMS.
size();
1775 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1786 RegMaskGaps.push_back(
I);
1813 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1816 unsigned BestBefore = NumGaps;
1817 unsigned BestAfter = 0;
1820 const float blockFreq =
1821 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1822 (1.0f / MBFI->getEntryFreq().getFrequency());
1829 calcGapWeights(PhysReg, GapWeight);
1832 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1833 for (
unsigned Gap : RegMaskGaps)
1840 unsigned SplitBefore = 0, SplitAfter = 1;
1844 float MaxGap = GapWeight[0];
1848 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1849 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1852 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1855 if (!LiveBefore && !LiveAfter) {
1863 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1866 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1875 blockFreq * (NewGaps + 1),
1876 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1884 float Diff = EstWeight - MaxGap;
1885 if (Diff > BestDiff) {
1888 BestBefore = SplitBefore;
1889 BestAfter = SplitAfter;
1896 if (++SplitBefore < SplitAfter) {
1899 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1900 MaxGap = GapWeight[SplitBefore];
1901 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1902 MaxGap = std::max(MaxGap, GapWeight[
I]);
1910 if (SplitAfter >= NumGaps) {
1916 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1921 if (BestBefore == NumGaps)
1922 return MCRegister();
1925 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1926 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1928 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1932 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1933 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1934 SE->useIntv(SegStart, SegStop);
1935 SmallVector<unsigned, 8> IntvMap;
1936 SE->finish(&IntvMap);
1937 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1941 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1942 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1943 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1944 if (NewGaps >= NumGaps) {
1946 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1947 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1948 if (IntvMap[
I] == 1) {
1956 return MCRegister();
1966MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
1967 AllocationOrder &Order,
1968 SmallVectorImpl<Register> &NewVRegs,
1971 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
1972 return MCRegister();
1975 if (
LIS->intervalIsInOneMBB(VirtReg)) {
1978 SA->analyze(&VirtReg);
1979 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
1980 if (PhysReg || !NewVRegs.
empty())
1982 return tryInstructionSplit(VirtReg, Order, NewVRegs);
1985 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
1988 SA->analyze(&VirtReg);
1993 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
1994 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
1995 if (PhysReg || !NewVRegs.
empty())
2000 return tryBlockSplit(VirtReg, Order, NewVRegs);
2023 if (PhysReg == AssignedReg)
2025 return TRI.regsOverlap(PhysReg, AssignedReg);
2036bool RAGreedy::mayRecolorAllInterferences(
2037 MCRegister PhysReg,
const LiveInterval &VirtReg,
2038 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2039 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
2042 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2049 CutOffInfo |= CO_Interf;
2064 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2065 MRI->getRegClass(Intf->reg()) == CurRC &&
2069 FixedRegisters.
count(Intf->reg())) {
2071 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2074 RecoloringCandidates.insert(Intf);
2123MCRegister RAGreedy::tryLastChanceRecoloring(
2124 const LiveInterval &VirtReg, AllocationOrder &Order,
2126 RecoloringStack &RecolorStack,
unsigned Depth) {
2127 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2130 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2132 const ssize_t EntryStackSize = RecolorStack.size();
2136 "Last chance recoloring should really be last chance");
2142 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2143 CutOffInfo |= CO_Depth;
2148 SmallLISet RecoloringCandidates;
2156 for (MCRegister PhysReg : Order) {
2160 RecoloringCandidates.clear();
2161 CurrentNewVRegs.
clear();
2164 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2167 dbgs() <<
"Some interferences are not with virtual registers.\n");
2174 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2176 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2183 PQueue RecoloringQueue;
2184 for (
const LiveInterval *RC : RecoloringCandidates) {
2186 enqueue(RecoloringQueue, RC);
2188 "Interferences are supposed to be with allocated variables");
2191 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2200 Matrix->assign(VirtReg, PhysReg);
2209 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2210 FixedRegisters, RecolorStack,
Depth)) {
2215 if (
VRM->hasPhys(ThisVirtReg)) {
2216 Matrix->unassign(VirtReg);
2221 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2223 FixedRegisters.
erase(ThisVirtReg);
2224 return MCRegister();
2231 FixedRegisters = SaveFixedRegisters;
2232 Matrix->unassign(VirtReg);
2238 for (
Register R : CurrentNewVRegs) {
2239 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2250 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2251 const LiveInterval *LI;
2253 std::tie(LI, PhysReg) = RecolorStack[
I];
2255 if (
VRM->hasPhys(LI->
reg()))
2259 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2260 const LiveInterval *LI;
2262 std::tie(LI, PhysReg) = RecolorStack[
I];
2263 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2264 Matrix->assign(*LI, PhysReg);
2268 RecolorStack.resize(EntryStackSize);
2283bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2284 SmallVectorImpl<Register> &NewVRegs,
2286 RecoloringStack &RecolorStack,
2288 while (!RecoloringQueue.empty()) {
2289 const LiveInterval *LI =
dequeue(RecoloringQueue);
2291 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2292 RecolorStack,
Depth + 1);
2297 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2301 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2303 <<
" succeeded. Empty LI.\n");
2307 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2309 Matrix->assign(*LI, PhysReg);
2321 CutOffInfo = CO_None;
2322 LLVMContext &Ctx = MF->getFunction().getContext();
2324 RecoloringStack RecolorStack;
2326 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2327 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2328 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2329 if (CutOffEncountered == CO_Depth)
2330 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2331 "reached. Use -fexhaustive-register-search to skip "
2333 else if (CutOffEncountered == CO_Interf)
2334 Ctx.emitError(
"register allocation failed: maximum interference for "
2335 "recoloring reached. Use -fexhaustive-register-search "
2337 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2338 Ctx.emitError(
"register allocation failed: maximum interference and "
2339 "depth for recoloring reached. Use "
2340 "-fexhaustive-register-search to skip cutoffs");
2357 SA->analyze(&VirtReg);
2358 if (calcSpillCost() >= CSRCost)
2363 CostPerUseLimit = 1;
2366 if (ExtraInfo->getStage(VirtReg) <
RS_Split) {
2369 SA->analyze(&VirtReg);
2370 unsigned NumCands = 0;
2372 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2379 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2387 SetOfBrokenHints.remove(&LI);
2390void RAGreedy::initializeCSRCost() {
2397 if (!CSRCost.getFrequency())
2401 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2407 if (ActualEntry < FixedEntry)
2409 else if (ActualEntry <= UINT32_MAX)
2415 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2421void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2422 const TargetRegisterClass *RC =
MRI->getRegClass(
Reg);
2424 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2425 const MachineInstr &
Instr = *Opnd.getParent();
2426 if (!
Instr.isCopy() || Opnd.isImplicit())
2430 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2432 if (OtherReg ==
Reg)
2434 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2435 unsigned SubReg = Opnd.getSubReg();
2438 MCRegister OtherPhysReg;
2441 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2443 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg,
SubReg, RC);
2445 OtherPhysReg = OtherReg;
2447 OtherPhysReg =
VRM->getPhys(OtherReg);
2457 Out.push_back(HintInfo(MBFI->getBlockFreq(
Instr.getParent()), OtherReg,
2466BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2467 MCRegister PhysReg) {
2468 BlockFrequency
Cost = BlockFrequency(0);
2469 for (
const HintInfo &
Info :
List) {
2470 if (
Info.PhysReg != PhysReg)
2484void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2490 MCRegister PhysReg =
VRM->getPhys(
Reg);
2493 SmallSet<Register, 4> Visited = {
Reg};
2502 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2507 "We have an unallocated variable which should have been handled");
2513 LiveInterval &LI =
LIS->getInterval(
Reg);
2516 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2517 Matrix->checkInterference(LI, PhysReg)))
2521 <<
") is recolorable.\n");
2528 if (CurrPhys != PhysReg) {
2530 BlockFrequency OldCopiesCost = getBrokenHintFreq(
Info, CurrPhys);
2531 BlockFrequency NewCopiesCost = getBrokenHintFreq(
Info, PhysReg);
2535 if (OldCopiesCost < NewCopiesCost) {
2545 Matrix->assign(LI, PhysReg);
2549 for (
const HintInfo &HI :
Info) {
2551 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2554 }
while (!RecoloringCandidates.
empty());
2593void RAGreedy::tryHintsRecoloring() {
2594 for (
const LiveInterval *LI : SetOfBrokenHints) {
2596 "Recoloring is possible only for virtual registers");
2599 if (!
VRM->hasPhys(LI->
reg()))
2601 tryHintRecoloring(*LI);
2605MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2606 SmallVectorImpl<Register> &NewVRegs,
2608 RecoloringStack &RecolorStack,
2610 uint8_t CostPerUseLimit = uint8_t(~0u);
2614 if (MCRegister PhysReg =
2615 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2619 if (CSRCost.getFrequency() &&
2620 EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.
empty()) {
2621 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2622 CostPerUseLimit, NewVRegs);
2623 if (CSRReg || !NewVRegs.
empty())
2631 if (!NewVRegs.
empty())
2632 return MCRegister();
2636 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2642 if (MCRegister PhysReg =
2643 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2651 if (Hint && Hint != PhysReg)
2652 SetOfBrokenHints.insert(&VirtReg);
2657 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2663 ExtraInfo->setStage(VirtReg,
RS_Split);
2666 return MCRegister();
2671 unsigned NewVRegSizeBefore = NewVRegs.
size();
2672 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2673 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2680 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2681 RecolorStack,
Depth);
2695 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2697 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2700 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2704 return MCRegister();
2707void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2708 using namespace ore;
2710 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2711 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2714 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2715 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2716 <<
" total folded spills cost ";
2719 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2720 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2722 if (FoldedReloads) {
2723 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2724 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2725 <<
" total folded reloads cost ";
2727 if (ZeroCostFoldedReloads)
2728 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2729 <<
" zero cost folded reloads ";
2731 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2732 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2736RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2737 RAGreedyStats
Stats;
2738 const MachineFrameInfo &MFI = MF->getFrameInfo();
2741 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2743 A->getPseudoValue())->getFrameIndex());
2745 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2746 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2747 MI.getOpcode() == TargetOpcode::STACKMAP ||
2748 MI.getOpcode() == TargetOpcode::STATEPOINT;
2750 for (MachineInstr &
MI :
MBB) {
2751 auto DestSrc = TII->isCopyInstr(
MI);
2753 const MachineOperand &Dest = *DestSrc->Destination;
2754 const MachineOperand &Src = *DestSrc->Source;
2760 SrcReg =
VRM->getPhys(SrcReg);
2761 if (SrcReg && Src.getSubReg())
2762 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2765 DestReg =
VRM->getPhys(DestReg);
2769 if (SrcReg != DestReg)
2775 SmallVector<const MachineMemOperand *, 2>
Accesses;
2784 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2786 if (!isPatchpointInstr(
MI)) {
2791 std::pair<unsigned, unsigned> NonZeroCostRange =
2792 TII->getPatchpointUnfoldableRange(
MI);
2793 SmallSet<unsigned, 16> FoldedReloads;
2794 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2795 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2796 MachineOperand &MO =
MI.getOperand(Idx);
2799 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2805 for (
unsigned Slot : FoldedReloads)
2806 ZeroCostFoldedReloads.
erase(Slot);
2807 Stats.FoldedReloads += FoldedReloads.size();
2808 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2812 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2819 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2821 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2823 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2828RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2829 RAGreedyStats
Stats;
2832 for (MachineLoop *SubLoop : *L)
2833 Stats.add(reportStats(SubLoop));
2835 for (MachineBasicBlock *
MBB :
L->getBlocks())
2837 if (Loops->getLoopFor(
MBB) == L)
2840 if (!
Stats.isEmpty()) {
2841 using namespace ore;
2844 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
2845 L->getStartLoc(),
L->getHeader());
2847 R <<
"generated in loop";
2854void RAGreedy::reportStats() {
2857 RAGreedyStats
Stats;
2858 for (MachineLoop *L : *Loops)
2859 Stats.add(reportStats(L));
2861 for (MachineBasicBlock &
MBB : *MF)
2862 if (!Loops->getLoopFor(&
MBB))
2864 if (!
Stats.isEmpty()) {
2865 using namespace ore;
2869 if (
auto *SP = MF->getFunction().getSubprogram())
2871 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
2874 R <<
"generated in function";
2880bool RAGreedy::hasVirtRegAlloc() {
2881 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
2883 if (
MRI->reg_nodbg_empty(
Reg))
2893 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
2894 <<
"********** Function: " << mf.
getName() <<
'\n');
2900 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
2906 if (!hasVirtRegAlloc())
2911 Indexes->packIndexes();
2913 initializeCSRCost();
2915 RegCosts =
TRI->getRegisterCosts(*MF);
2916 RegClassPriorityTrumpsGlobalness =
2919 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
2923 :
TRI->reverseLocalAssignment();
2925 ExtraInfo.emplace();
2927 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
2928 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
2930 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
2934 VRAI->calculateSpillWeightsAndHints();
2941 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
2942 GlobalCand.resize(32);
2943 SetOfBrokenHints.clear();
2946 tryHintsRecoloring();
2949 MF->verify(
LIS, Indexes,
"Before post optimization", &
errs());
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
DXIL Forward Handle Accesses
const HexagonInstrInfo * TII
This file implements an indexed map.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
block placement Basic Block Placement Stats
Register const TargetRegisterInfo * TRI
Promote Memory to Register
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
SI Optimize VGPR LiveRange
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.
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.
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.
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.
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())
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.
LiveInterval & getInterval(Register Reg)
Register get(unsigned idx) const
ArrayRef< Register > regs() const
Segments::const_iterator const_iterator
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().
@ IK_VirtReg
Virtual register interference.
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...
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Representation of each machine instruction.
bool isImplicitDef() const
Analysis pass that exposes the MachineLoopInfo for a machine function.
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,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
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(const RegAllocFilterFunc F=nullptr)
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.
const TargetRegisterInfo *const TRI
std::optional< unsigned > getOrderLimit(const LiveInterval &VirtReg, const AllocationOrder &Order, unsigned CostPerUseLimit) const
const ArrayRef< uint8_t > RegCosts
MachineRegisterInfo *const MRI
const RegisterClassInfo & RegClassInfo
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
LiveRegMatrix *const Matrix
Common provider for getting the priority advisor and logging rewards.
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const
getNumAllocatableRegs - Returns the number of actually allocatable registers in RC in the current fun...
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.
@ InstrDist
The default distance between instructions as returned by distance().
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 ...
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.
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 const TargetInstrInfo * getInstrInfo() const
A Use represents the edge between a Value definition and its users.
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
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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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
NodeAddr< UseNode * > Use
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.
SmallSet< Register, 16 > SmallVirtRegSet
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
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.
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
unsigned MCRegUnit
Register units are used to compute register aliasing.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.