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) {
594 VirtReg,
Matrix->getLiveUnions()[
static_cast<unsigned>(Unit)]);
603 if (
none_of(
TRI->regunits(Reg), HasRegUnitInterference)) {
616void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
622 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
625 <<
" interference: Cascade " << Cascade <<
'\n');
629 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
646 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
648 "Cannot decrease cascade number, illegal eviction");
649 ExtraInfo->setCascade(Intf->reg(), Cascade);
662 return !
Matrix->isPhysRegUsed(PhysReg);
665std::optional<unsigned>
668 unsigned CostPerUseLimit)
const {
669 unsigned OrderLimit = Order.
getOrder().size();
671 if (CostPerUseLimit <
uint8_t(~0u)) {
675 if (MinCost >= CostPerUseLimit) {
677 << MinCost <<
", no cheaper registers to be found.\n");
694 if (
RegCosts[PhysReg.
id()] >= CostPerUseLimit)
720 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
721 VirtReg, Order, CostPerUseLimit, FixedRegisters);
723 evictInterference(VirtReg, BestPhys, NewVRegs);
741 SplitConstraints.resize(UseBlocks.
size());
743 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
764 if (Intf.
first() <= Indexes->getMBBStartIdx(BC.
Number)) {
778 SA->getFirstSplitPoint(BC.
Number)))
784 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
797 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
803 SpillPlacer->addConstraints(SplitConstraints);
804 return SpillPlacer->scanActiveBundles();
809bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
810 ArrayRef<unsigned> Blocks) {
811 const unsigned GroupSize = 8;
812 SpillPlacement::BlockConstraint BCS[GroupSize];
813 unsigned TBS[GroupSize];
814 unsigned B = 0,
T = 0;
816 for (
unsigned Number : Blocks) {
820 assert(
T < GroupSize &&
"Array overflow");
822 if (++
T == GroupSize) {
829 assert(
B < GroupSize &&
"Array overflow");
833 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
835 if (FirstNonDebugInstr !=
MBB->
end() &&
837 SA->getFirstSplitPoint(
Number)))
840 if (Intf.
first() <= Indexes->getMBBStartIdx(
Number))
846 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
851 if (++
B == GroupSize) {
852 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
857 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
862bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
864 BitVector Todo = SA->getThroughBlocks();
865 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
866 unsigned AddedTo = 0;
868 unsigned Visited = 0;
873 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
875 for (
unsigned Bundle : NewBundles) {
877 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
879 if (Blocks.
size() >= Budget)
881 Budget -= Blocks.
size();
882 for (
unsigned Block : Blocks) {
894 if (ActiveBlocks.
size() == AddedTo)
899 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
901 if (!addThroughConstraints(Cand.Intf, NewBlocks))
909 bool PrefSpill =
true;
910 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
915 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
916 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
917 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
918 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
923 SpillPlacer->addPrefSpill(NewBlocks,
true);
925 AddedTo = ActiveBlocks.
size();
928 SpillPlacer->iterate();
941bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
943 if (!SA->getNumThroughBlocks())
953 SpillPlacer->prepare(Cand.LiveBundles);
957 if (!addSplitConstraints(Cand.Intf,
Cost)) {
962 if (!growRegion(Cand)) {
967 SpillPlacer->finish();
969 if (!Cand.LiveBundles.any()) {
975 for (
int I : Cand.LiveBundles.set_bits())
976 dbgs() <<
" EB#" <<
I;
984BlockFrequency RAGreedy::calcSpillCost() {
985 BlockFrequency
Cost = BlockFrequency(0);
987 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
990 Cost += SpillPlacer->getBlockFrequency(
Number);
994 Cost += SpillPlacer->getBlockFrequency(
Number);
1003BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1004 const AllocationOrder &Order) {
1005 BlockFrequency GlobalCost = BlockFrequency(0);
1006 const BitVector &LiveBundles = Cand.LiveBundles;
1008 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1009 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1010 SpillPlacement::BlockConstraint &BC = SplitConstraints[
I];
1011 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1012 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1015 Cand.Intf.moveToBlock(BC.
Number);
1022 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1025 for (
unsigned Number : Cand.ActiveBlocks) {
1026 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1027 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1028 if (!RegIn && !RegOut)
1030 if (RegIn && RegOut) {
1032 Cand.Intf.moveToBlock(
Number);
1033 if (Cand.Intf.hasInterference()) {
1034 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1035 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1040 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1057void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1058 ArrayRef<unsigned> UsedCands) {
1061 const unsigned NumGlobalIntvs = LREdit.
size();
1064 assert(NumGlobalIntvs &&
"No global intervals configured");
1074 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1076 unsigned IntvIn = 0, IntvOut = 0;
1077 SlotIndex IntfIn, IntfOut;
1079 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1080 if (CandIn != NoCand) {
1081 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1082 IntvIn = Cand.IntvIdx;
1083 Cand.Intf.moveToBlock(
Number);
1084 IntfIn = Cand.Intf.first();
1088 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1089 if (CandOut != NoCand) {
1090 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1091 IntvOut = Cand.IntvIdx;
1092 Cand.Intf.moveToBlock(
Number);
1093 IntfOut = Cand.Intf.last();
1098 if (!IntvIn && !IntvOut) {
1100 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1101 SE->splitSingleBlock(BI);
1105 if (IntvIn && IntvOut)
1106 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1108 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1110 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1116 BitVector Todo = SA->getThroughBlocks();
1117 for (
unsigned UsedCand : UsedCands) {
1118 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1119 for (
unsigned Number : Blocks) {
1124 unsigned IntvIn = 0, IntvOut = 0;
1125 SlotIndex IntfIn, IntfOut;
1127 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1128 if (CandIn != NoCand) {
1129 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1130 IntvIn = Cand.IntvIdx;
1131 Cand.Intf.moveToBlock(
Number);
1132 IntfIn = Cand.Intf.first();
1135 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1136 if (CandOut != NoCand) {
1137 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1138 IntvOut = Cand.IntvIdx;
1139 Cand.Intf.moveToBlock(
Number);
1140 IntfOut = Cand.Intf.last();
1142 if (!IntvIn && !IntvOut)
1144 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1150 SmallVector<unsigned, 8> IntvMap;
1151 SE->finish(&IntvMap);
1152 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1154 unsigned OrigBlocks = SA->getNumLiveBlocks();
1161 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1162 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1165 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1170 if (IntvMap[
I] == 0) {
1177 if (IntvMap[
I] < NumGlobalIntvs) {
1178 if (SA->countLiveBlocks(&
Reg) >= OrigBlocks) {
1179 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1180 <<
" blocks as original.\n");
1192 MF->verify(
LIS, Indexes,
"After splitting live range around region",
1196MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1197 AllocationOrder &Order,
1198 SmallVectorImpl<Register> &NewVRegs) {
1199 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1201 unsigned NumCands = 0;
1202 BlockFrequency SpillCost = calcSpillCost();
1203 BlockFrequency BestCost;
1206 bool HasCompact = calcCompactRegion(GlobalCand.front());
1214 BestCost = SpillCost;
1219 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1223 if (!HasCompact && BestCand == NoCand)
1226 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1229unsigned RAGreedy::calculateRegionSplitCostAroundReg(MCRegister 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;
1312 for (MCRegister PhysReg : Order) {
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(MCRegister 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 =
1431 if (OtherPhysReg == ThisHint)
1432 Cost += MBFI->getBlockFreq(
Instr.getParent());
1438 if (
Cost == BlockFrequency(0))
1441 unsigned NumCands = 0;
1442 unsigned BestCand = NoCand;
1443 SA->analyze(&VirtReg);
1444 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1445 if (BestCand == NoCand)
1448 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1459MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1460 AllocationOrder &Order,
1461 SmallVectorImpl<Register> &NewVRegs) {
1462 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1465 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1468 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1469 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1470 SE->splitSingleBlock(BI);
1474 return MCRegister();
1477 SmallVector<unsigned, 8> IntvMap;
1478 SE->finish(&IntvMap);
1481 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1485 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1486 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1487 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1492 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1494 return MCRegister();
1507 assert(SuperRC &&
"Invalid register class");
1510 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1532 return MRI.getMaxLaneMaskForVReg(
Reg);
1538 Mask |= ~SubRegMask;
1555 auto DestSrc =
TII->isCopyInstr(*
MI);
1556 if (DestSrc && !
MI->isBundled() &&
1557 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1566 LiveAtMask |= S.LaneMask;
1571 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1581MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1582 AllocationOrder &Order,
1583 SmallVectorImpl<Register> &NewVRegs) {
1584 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
1587 bool SplitSubClass =
true;
1590 return MCRegister();
1591 SplitSubClass =
false;
1596 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1600 if (
Uses.size() <= 1)
1601 return MCRegister();
1604 <<
" individual instrs.\n");
1606 const TargetRegisterClass *SuperRC =
1607 TRI->getLargestLegalSuperClass(CurRC, *MF);
1608 unsigned SuperRCNumAllocatableRegs =
1614 for (
const SlotIndex Use :
Uses) {
1615 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1616 if (TII->isFullCopyInstr(*
MI) ||
1618 SuperRCNumAllocatableRegs ==
1629 SlotIndex SegStart = SE->enterIntvBefore(Use);
1630 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1631 SE->useIntv(SegStart, SegStop);
1634 if (LREdit.
empty()) {
1636 return MCRegister();
1639 SmallVector<unsigned, 8> IntvMap;
1640 SE->finish(&IntvMap);
1641 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1644 return MCRegister();
1656void RAGreedy::calcGapWeights(MCRegister PhysReg,
1657 SmallVectorImpl<float> &GapWeight) {
1658 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1659 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1661 const unsigned NumGaps =
Uses.size()-1;
1664 SlotIndex StartIdx =
1669 GapWeight.
assign(NumGaps, 0.0f);
1672 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1673 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1674 .checkInterference())
1685 Matrix->getLiveUnions()[
static_cast<unsigned>(
Unit)].
find(StartIdx);
1686 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1688 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1689 if (++Gap == NumGaps)
1695 const float weight = IntI.value()->weight();
1696 for (; Gap != NumGaps; ++Gap) {
1697 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1698 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1707 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1713 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1714 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1715 if (++Gap == NumGaps)
1720 for (; Gap != NumGaps; ++Gap) {
1722 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1734MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1735 AllocationOrder &Order,
1736 SmallVectorImpl<Register> &NewVRegs) {
1739 if (SA->getUseBlocks().size() != 1)
1740 return MCRegister();
1742 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1752 if (
Uses.size() <= 2)
1753 return MCRegister();
1754 const unsigned NumGaps =
Uses.size()-1;
1757 dbgs() <<
"tryLocalSplit: ";
1758 for (
const auto &Use :
Uses)
1765 SmallVector<unsigned, 8> RegMaskGaps;
1766 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1773 unsigned RE = RMS.
size();
1774 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1785 RegMaskGaps.push_back(
I);
1812 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1815 unsigned BestBefore = NumGaps;
1816 unsigned BestAfter = 0;
1819 const float blockFreq =
1820 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1821 (1.0f / MBFI->getEntryFreq().getFrequency());
1824 for (MCRegister PhysReg : Order) {
1828 calcGapWeights(PhysReg, GapWeight);
1831 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1832 for (
unsigned Gap : RegMaskGaps)
1839 unsigned SplitBefore = 0, SplitAfter = 1;
1843 float MaxGap = GapWeight[0];
1847 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1848 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1851 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1854 if (!LiveBefore && !LiveAfter) {
1862 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1865 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1874 blockFreq * (NewGaps + 1),
1875 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1883 float Diff = EstWeight - MaxGap;
1884 if (Diff > BestDiff) {
1887 BestBefore = SplitBefore;
1888 BestAfter = SplitAfter;
1895 if (++SplitBefore < SplitAfter) {
1898 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1899 MaxGap = GapWeight[SplitBefore];
1900 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1901 MaxGap = std::max(MaxGap, GapWeight[
I]);
1909 if (SplitAfter >= NumGaps) {
1915 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1920 if (BestBefore == NumGaps)
1921 return MCRegister();
1924 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1925 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1927 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1931 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1932 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1933 SE->useIntv(SegStart, SegStop);
1934 SmallVector<unsigned, 8> IntvMap;
1935 SE->finish(&IntvMap);
1936 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1940 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1941 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1942 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1943 if (NewGaps >= NumGaps) {
1945 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1946 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1947 if (IntvMap[
I] == 1) {
1955 return MCRegister();
1965MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
1966 AllocationOrder &Order,
1967 SmallVectorImpl<Register> &NewVRegs,
1970 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
1971 return MCRegister();
1974 if (
LIS->intervalIsInOneMBB(VirtReg)) {
1977 SA->analyze(&VirtReg);
1978 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
1979 if (PhysReg || !NewVRegs.
empty())
1981 return tryInstructionSplit(VirtReg, Order, NewVRegs);
1984 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
1987 SA->analyze(&VirtReg);
1992 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
1993 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
1994 if (PhysReg || !NewVRegs.
empty())
1999 return tryBlockSplit(VirtReg, Order, NewVRegs);
2022 if (PhysReg == AssignedReg)
2024 return TRI.regsOverlap(PhysReg, AssignedReg);
2035bool RAGreedy::mayRecolorAllInterferences(
2036 MCRegister PhysReg,
const LiveInterval &VirtReg,
2037 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2038 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
2040 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
2041 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2048 CutOffInfo |= CO_Interf;
2063 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2064 MRI->getRegClass(Intf->reg()) == CurRC &&
2068 FixedRegisters.
count(Intf->reg())) {
2070 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2073 RecoloringCandidates.insert(Intf);
2122MCRegister RAGreedy::tryLastChanceRecoloring(
2123 const LiveInterval &VirtReg, AllocationOrder &Order,
2125 RecoloringStack &RecolorStack,
unsigned Depth) {
2126 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2129 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2131 const ssize_t EntryStackSize = RecolorStack.size();
2135 "Last chance recoloring should really be last chance");
2141 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2142 CutOffInfo |= CO_Depth;
2147 SmallLISet RecoloringCandidates;
2155 for (MCRegister PhysReg : Order) {
2159 RecoloringCandidates.clear();
2160 CurrentNewVRegs.
clear();
2163 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2166 dbgs() <<
"Some interferences are not with virtual registers.\n");
2173 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2175 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2182 PQueue RecoloringQueue;
2183 for (
const LiveInterval *RC : RecoloringCandidates) {
2185 enqueue(RecoloringQueue, RC);
2187 "Interferences are supposed to be with allocated variables");
2190 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2199 Matrix->assign(VirtReg, PhysReg);
2208 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2209 FixedRegisters, RecolorStack,
Depth)) {
2214 if (
VRM->hasPhys(ThisVirtReg)) {
2215 Matrix->unassign(VirtReg);
2220 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2222 FixedRegisters.
erase(ThisVirtReg);
2223 return MCRegister();
2230 FixedRegisters = SaveFixedRegisters;
2231 Matrix->unassign(VirtReg);
2237 for (
Register R : CurrentNewVRegs) {
2238 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2249 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2250 const LiveInterval *LI;
2252 std::tie(LI, PhysReg) = RecolorStack[
I];
2254 if (
VRM->hasPhys(LI->
reg()))
2258 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2259 const LiveInterval *LI;
2261 std::tie(LI, PhysReg) = RecolorStack[
I];
2262 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2263 Matrix->assign(*LI, PhysReg);
2267 RecolorStack.resize(EntryStackSize);
2282bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2283 SmallVectorImpl<Register> &NewVRegs,
2285 RecoloringStack &RecolorStack,
2287 while (!RecoloringQueue.empty()) {
2288 const LiveInterval *LI =
dequeue(RecoloringQueue);
2290 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2291 RecolorStack,
Depth + 1);
2296 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2300 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2302 <<
" succeeded. Empty LI.\n");
2306 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2308 Matrix->assign(*LI, PhysReg);
2320 CutOffInfo = CO_None;
2321 LLVMContext &Ctx = MF->getFunction().getContext();
2323 RecoloringStack RecolorStack;
2325 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2326 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2327 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2328 if (CutOffEncountered == CO_Depth)
2329 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2330 "reached. Use -fexhaustive-register-search to skip "
2332 else if (CutOffEncountered == CO_Interf)
2333 Ctx.emitError(
"register allocation failed: maximum interference for "
2334 "recoloring reached. Use -fexhaustive-register-search "
2336 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2337 Ctx.emitError(
"register allocation failed: maximum interference and "
2338 "depth for recoloring reached. Use "
2339 "-fexhaustive-register-search to skip cutoffs");
2356 SA->analyze(&VirtReg);
2357 if (calcSpillCost() >= CSRCost)
2362 CostPerUseLimit = 1;
2365 if (ExtraInfo->getStage(VirtReg) <
RS_Split) {
2368 SA->analyze(&VirtReg);
2369 unsigned NumCands = 0;
2371 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2378 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2386 SetOfBrokenHints.remove(&LI);
2389void RAGreedy::initializeCSRCost() {
2396 if (!CSRCost.getFrequency())
2400 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2406 if (ActualEntry < FixedEntry)
2408 else if (ActualEntry <= UINT32_MAX)
2414 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2420void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2421 const TargetRegisterClass *RC =
MRI->getRegClass(
Reg);
2423 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2424 const MachineInstr &
Instr = *Opnd.getParent();
2425 if (!
Instr.isCopy() || Opnd.isImplicit())
2429 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2431 if (OtherReg ==
Reg)
2433 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2434 unsigned SubReg = Opnd.getSubReg();
2437 MCRegister OtherPhysReg;
2440 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2442 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg,
SubReg, RC);
2444 OtherPhysReg = OtherReg;
2446 OtherPhysReg =
VRM->getPhys(OtherReg);
2456 Out.push_back(HintInfo(MBFI->getBlockFreq(
Instr.getParent()), OtherReg,
2465BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2466 MCRegister PhysReg) {
2467 BlockFrequency
Cost = BlockFrequency(0);
2468 for (
const HintInfo &
Info :
List) {
2469 if (
Info.PhysReg != PhysReg)
2483void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2489 MCRegister PhysReg =
VRM->getPhys(
Reg);
2492 SmallSet<Register, 4> Visited = {
Reg};
2501 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2506 "We have an unallocated variable which should have been handled");
2512 LiveInterval &LI =
LIS->getInterval(
Reg);
2515 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2516 Matrix->checkInterference(LI, PhysReg)))
2520 <<
") is recolorable.\n");
2527 if (CurrPhys != PhysReg) {
2529 BlockFrequency OldCopiesCost = getBrokenHintFreq(
Info, CurrPhys);
2530 BlockFrequency NewCopiesCost = getBrokenHintFreq(
Info, PhysReg);
2534 if (OldCopiesCost < NewCopiesCost) {
2544 Matrix->assign(LI, PhysReg);
2548 for (
const HintInfo &HI :
Info) {
2550 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2553 }
while (!RecoloringCandidates.
empty());
2592void RAGreedy::tryHintsRecoloring() {
2593 for (
const LiveInterval *LI : SetOfBrokenHints) {
2595 "Recoloring is possible only for virtual registers");
2598 if (!
VRM->hasPhys(LI->
reg()))
2600 tryHintRecoloring(*LI);
2604MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2605 SmallVectorImpl<Register> &NewVRegs,
2607 RecoloringStack &RecolorStack,
2609 uint8_t CostPerUseLimit = uint8_t(~0u);
2613 if (MCRegister PhysReg =
2614 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2618 if (CSRCost.getFrequency() &&
2619 EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.
empty()) {
2620 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2621 CostPerUseLimit, NewVRegs);
2622 if (CSRReg || !NewVRegs.
empty())
2630 if (!NewVRegs.
empty())
2631 return MCRegister();
2635 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2641 if (MCRegister PhysReg =
2642 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2650 if (Hint && Hint != PhysReg)
2651 SetOfBrokenHints.insert(&VirtReg);
2656 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2662 ExtraInfo->setStage(VirtReg,
RS_Split);
2665 return MCRegister();
2670 unsigned NewVRegSizeBefore = NewVRegs.
size();
2671 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2672 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2679 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2680 RecolorStack,
Depth);
2694 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2696 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2699 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2703 return MCRegister();
2706void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2707 using namespace ore;
2709 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2710 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2713 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2714 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2715 <<
" total folded spills cost ";
2718 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2719 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2721 if (FoldedReloads) {
2722 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2723 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2724 <<
" total folded reloads cost ";
2726 if (ZeroCostFoldedReloads)
2727 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2728 <<
" zero cost folded reloads ";
2730 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2731 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2735RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2736 RAGreedyStats
Stats;
2737 const MachineFrameInfo &MFI = MF->getFrameInfo();
2740 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2742 A->getPseudoValue())->getFrameIndex());
2744 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2745 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2746 MI.getOpcode() == TargetOpcode::STACKMAP ||
2747 MI.getOpcode() == TargetOpcode::STATEPOINT;
2749 for (MachineInstr &
MI :
MBB) {
2750 auto DestSrc = TII->isCopyInstr(
MI);
2752 const MachineOperand &Dest = *DestSrc->Destination;
2753 const MachineOperand &Src = *DestSrc->Source;
2759 SrcReg =
VRM->getPhys(SrcReg);
2760 if (SrcReg && Src.getSubReg())
2761 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2764 DestReg =
VRM->getPhys(DestReg);
2768 if (SrcReg != DestReg)
2774 SmallVector<const MachineMemOperand *, 2>
Accesses;
2783 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2785 if (!isPatchpointInstr(
MI)) {
2790 std::pair<unsigned, unsigned> NonZeroCostRange =
2791 TII->getPatchpointUnfoldableRange(
MI);
2792 SmallSet<unsigned, 16> FoldedReloads;
2793 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2794 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2795 MachineOperand &MO =
MI.getOperand(Idx);
2798 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2804 for (
unsigned Slot : FoldedReloads)
2805 ZeroCostFoldedReloads.
erase(Slot);
2806 Stats.FoldedReloads += FoldedReloads.size();
2807 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2811 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2818 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2820 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2822 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2827RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2828 RAGreedyStats
Stats;
2831 for (MachineLoop *SubLoop : *L)
2832 Stats.add(reportStats(SubLoop));
2834 for (MachineBasicBlock *
MBB :
L->getBlocks())
2836 if (Loops->getLoopFor(
MBB) == L)
2839 if (!
Stats.isEmpty()) {
2840 using namespace ore;
2843 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
2844 L->getStartLoc(),
L->getHeader());
2846 R <<
"generated in loop";
2853void RAGreedy::reportStats() {
2856 RAGreedyStats
Stats;
2857 for (MachineLoop *L : *Loops)
2858 Stats.add(reportStats(L));
2860 for (MachineBasicBlock &
MBB : *MF)
2861 if (!Loops->getLoopFor(&
MBB))
2863 if (!
Stats.isEmpty()) {
2864 using namespace ore;
2868 if (
auto *SP = MF->getFunction().getSubprogram())
2870 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
2873 R <<
"generated in function";
2879bool RAGreedy::hasVirtRegAlloc() {
2880 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
2882 if (
MRI->reg_nodbg_empty(
Reg))
2892 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
2893 <<
"********** Function: " << mf.
getName() <<
'\n');
2899 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
2905 if (!hasVirtRegAlloc())
2910 Indexes->packIndexes();
2912 initializeCSRCost();
2914 RegCosts =
TRI->getRegisterCosts(*MF);
2915 RegClassPriorityTrumpsGlobalness =
2918 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
2922 :
TRI->reverseLocalAssignment();
2924 ExtraInfo.emplace();
2926 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
2927 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
2929 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
2933 VRAI->calculateSpillWeightsAndHints();
2940 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
2941 GlobalCand.resize(32);
2942 SetOfBrokenHints.clear();
2945 tryHintsRecoloring();
2948 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.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
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.
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...
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.