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();
204 MBFI = Analyses.
MBFI;
206 Loops = Analyses.
Loops;
219 StringRef FilterName = Opts.FilterName.
empty() ?
"all" : Opts.FilterName;
220 OS <<
"greedy<" << FilterName <<
'>';
247 RAGreedy Impl(Analyses, Opts.Filter);
289char RAGreedyLegacy::ID = 0;
313const char *
const RAGreedy::StageName[] = {
328 return new RAGreedyLegacy();
332 return new RAGreedyLegacy(Ftor);
335void RAGreedyLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
367bool RAGreedy::LRE_CanEraseVirtReg(
Register VirtReg) {
368 LiveInterval &LI =
LIS->getInterval(VirtReg);
369 if (
VRM->hasPhys(VirtReg)) {
382void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
383 if (!
VRM->hasPhys(VirtReg))
387 LiveInterval &LI =
LIS->getInterval(VirtReg);
393 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
398 if (!Info.inBounds(Old))
407 Info[New] = Info[Old];
411 SpillerInstance.reset();
417void RAGreedy::enqueue(PQueue &CurQueue,
const LiveInterval *LI) {
421 assert(Reg.isVirtual() &&
"Can only enqueue virtual registers");
423 auto Stage = ExtraInfo->getOrInitStage(Reg);
426 ExtraInfo->setStage(Reg, Stage);
429 unsigned Ret = PriorityAdvisor->getPriority(*LI);
433 CurQueue.push(std::make_pair(Ret, ~
Reg.id()));
436unsigned DefaultPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
449 const TargetRegisterClass &RC = *
MRI->getRegClass(
Reg);
451 (!ReverseLocalAssignment &&
454 unsigned GlobalBit = 0;
457 LIS->intervalIsInOneMBB(LI)) {
461 if (!ReverseLocalAssignment)
467 Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.
endIndex());
489 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
492 if (RegClassPriorityTrumpsGlobalness)
501 if (
VRM->hasKnownPreference(
Reg))
508unsigned DummyPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
517 if (CurQueue.empty())
534 for (
auto I = Order.
begin(),
E = Order.
end();
I !=
E && !PhysReg; ++
I) {
536 if (!
Matrix->checkInterference(VirtReg, *
I)) {
552 MCRegister PhysHint =
Hint.asMCReg();
555 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
557 evictInterference(VirtReg, PhysHint, NewVRegs);
562 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
567 SetOfBrokenHints.insert(&VirtReg);
571 uint8_t
Cost = RegCosts[PhysReg.
id()];
578 << (
unsigned)
Cost <<
'\n');
579 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
580 return CheapReg ? CheapReg : PhysReg;
589 auto HasRegUnitInterference = [&](MCRegUnit Unit) {
592 VirtReg,
Matrix->getLiveUnions()[
static_cast<unsigned>(Unit)]);
601 if (
none_of(
TRI->regunits(Reg), HasRegUnitInterference)) {
614void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
620 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
623 <<
" interference: Cascade " << Cascade <<
'\n');
627 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
644 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
646 "Cannot decrease cascade number, illegal eviction");
647 ExtraInfo->setCascade(Intf->reg(), Cascade);
660 return !
Matrix->isPhysRegUsed(PhysReg);
663std::optional<unsigned>
666 unsigned CostPerUseLimit)
const {
667 unsigned OrderLimit = Order.
getOrder().size();
669 if (CostPerUseLimit <
uint8_t(~0u)) {
673 if (MinCost >= CostPerUseLimit) {
675 << MinCost <<
", no cheaper registers to be found.\n");
692 if (
RegCosts[PhysReg.
id()] >= CostPerUseLimit)
718 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
719 VirtReg, Order, CostPerUseLimit, FixedRegisters);
721 evictInterference(VirtReg, BestPhys, NewVRegs);
739 SplitConstraints.resize(UseBlocks.
size());
741 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
762 if (Intf.
first() <= Indexes->getMBBStartIdx(BC.
Number)) {
776 SA->getFirstSplitPoint(BC.
Number)))
782 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
795 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
801 SpillPlacer->addConstraints(SplitConstraints);
802 return SpillPlacer->scanActiveBundles();
807bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
808 ArrayRef<unsigned> Blocks) {
809 const unsigned GroupSize = 8;
810 SpillPlacement::BlockConstraint BCS[GroupSize];
811 unsigned TBS[GroupSize];
812 unsigned B = 0,
T = 0;
814 for (
unsigned Number : Blocks) {
818 assert(
T < GroupSize &&
"Array overflow");
820 if (++
T == GroupSize) {
827 assert(
B < GroupSize &&
"Array overflow");
831 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
833 if (FirstNonDebugInstr !=
MBB->
end() &&
835 SA->getFirstSplitPoint(
Number)))
838 if (Intf.
first() <= Indexes->getMBBStartIdx(
Number))
844 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
849 if (++
B == GroupSize) {
850 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
855 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
860bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
862 BitVector Todo = SA->getThroughBlocks();
863 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
864 unsigned AddedTo = 0;
866 unsigned Visited = 0;
871 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
873 for (
unsigned Bundle : NewBundles) {
875 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
877 if (Blocks.
size() >= Budget)
879 Budget -= Blocks.
size();
880 for (
unsigned Block : Blocks) {
892 if (ActiveBlocks.
size() == AddedTo)
897 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
899 if (!addThroughConstraints(Cand.Intf, NewBlocks))
907 bool PrefSpill =
true;
908 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
913 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
914 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
915 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
916 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
921 SpillPlacer->addPrefSpill(NewBlocks,
true);
923 AddedTo = ActiveBlocks.
size();
926 SpillPlacer->iterate();
939bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
941 if (!SA->getNumThroughBlocks())
951 SpillPlacer->prepare(Cand.LiveBundles);
955 if (!addSplitConstraints(Cand.Intf,
Cost)) {
960 if (!growRegion(Cand)) {
965 SpillPlacer->finish();
967 if (!Cand.LiveBundles.any()) {
973 for (
int I : Cand.LiveBundles.set_bits())
974 dbgs() <<
" EB#" <<
I;
982BlockFrequency RAGreedy::calcSpillCost() {
983 BlockFrequency
Cost = BlockFrequency(0);
985 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
988 Cost += SpillPlacer->getBlockFrequency(
Number);
992 Cost += SpillPlacer->getBlockFrequency(
Number);
1001BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1002 const AllocationOrder &Order) {
1003 BlockFrequency GlobalCost = BlockFrequency(0);
1004 const BitVector &LiveBundles = Cand.LiveBundles;
1006 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1007 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1008 SpillPlacement::BlockConstraint &BC = SplitConstraints[
I];
1009 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1010 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1013 Cand.Intf.moveToBlock(BC.
Number);
1020 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1023 for (
unsigned Number : Cand.ActiveBlocks) {
1024 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1025 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1026 if (!RegIn && !RegOut)
1028 if (RegIn && RegOut) {
1030 Cand.Intf.moveToBlock(
Number);
1031 if (Cand.Intf.hasInterference()) {
1032 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1033 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1038 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1055void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1056 ArrayRef<unsigned> UsedCands) {
1059 const unsigned NumGlobalIntvs = LREdit.
size();
1062 assert(NumGlobalIntvs &&
"No global intervals configured");
1072 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1074 unsigned IntvIn = 0, IntvOut = 0;
1075 SlotIndex IntfIn, IntfOut;
1077 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1078 if (CandIn != NoCand) {
1079 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1080 IntvIn = Cand.IntvIdx;
1081 Cand.Intf.moveToBlock(
Number);
1082 IntfIn = Cand.Intf.first();
1086 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1087 if (CandOut != NoCand) {
1088 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1089 IntvOut = Cand.IntvIdx;
1090 Cand.Intf.moveToBlock(
Number);
1091 IntfOut = Cand.Intf.last();
1096 if (!IntvIn && !IntvOut) {
1098 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1099 SE->splitSingleBlock(BI);
1103 if (IntvIn && IntvOut)
1104 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1106 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1108 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1114 BitVector Todo = SA->getThroughBlocks();
1115 for (
unsigned UsedCand : UsedCands) {
1116 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1117 for (
unsigned Number : Blocks) {
1122 unsigned IntvIn = 0, IntvOut = 0;
1123 SlotIndex IntfIn, IntfOut;
1125 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1126 if (CandIn != NoCand) {
1127 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1128 IntvIn = Cand.IntvIdx;
1129 Cand.Intf.moveToBlock(
Number);
1130 IntfIn = Cand.Intf.first();
1133 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1134 if (CandOut != NoCand) {
1135 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1136 IntvOut = Cand.IntvIdx;
1137 Cand.Intf.moveToBlock(
Number);
1138 IntfOut = Cand.Intf.last();
1140 if (!IntvIn && !IntvOut)
1142 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1148 SmallVector<unsigned, 8> IntvMap;
1149 SE->finish(&IntvMap);
1150 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1152 unsigned OrigBlocks = SA->getNumLiveBlocks();
1159 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1160 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1163 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1168 if (IntvMap[
I] == 0) {
1175 if (IntvMap[
I] < NumGlobalIntvs) {
1176 if (SA->countLiveBlocks(&
Reg) >= OrigBlocks) {
1177 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1178 <<
" blocks as original.\n");
1190 MF->verify(
LIS, Indexes,
"After splitting live range around region",
1194MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1195 AllocationOrder &Order,
1196 SmallVectorImpl<Register> &NewVRegs) {
1197 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1199 unsigned NumCands = 0;
1200 BlockFrequency SpillCost = calcSpillCost();
1201 BlockFrequency BestCost;
1204 bool HasCompact = calcCompactRegion(GlobalCand.front());
1212 BestCost = SpillCost;
1217 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1221 if (!HasCompact && BestCand == NoCand)
1224 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1227unsigned RAGreedy::calculateRegionSplitCostAroundReg(MCRegister PhysReg,
1228 AllocationOrder &Order,
1229 BlockFrequency &BestCost,
1231 unsigned &BestCand) {
1234 if (NumCands == IntfCache.getMaxCursors()) {
1235 unsigned WorstCount = ~0
u;
1237 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1238 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1240 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1241 if (
Count < WorstCount) {
1247 GlobalCand[Worst] = GlobalCand[NumCands];
1248 if (BestCand == NumCands)
1252 if (GlobalCand.size() <= NumCands)
1253 GlobalCand.resize(NumCands+1);
1254 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1255 Cand.reset(IntfCache, PhysReg);
1257 SpillPlacer->prepare(Cand.LiveBundles);
1258 BlockFrequency
Cost;
1259 if (!addSplitConstraints(Cand.Intf,
Cost)) {
1265 if (
Cost >= BestCost) {
1267 if (BestCand == NoCand)
1268 dbgs() <<
" worse than no bundles\n";
1270 dbgs() <<
" worse than "
1271 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1275 if (!growRegion(Cand)) {
1280 SpillPlacer->finish();
1283 if (!Cand.LiveBundles.any()) {
1288 Cost += calcGlobalSplitCost(Cand, Order);
1291 for (
int I : Cand.LiveBundles.set_bits())
1292 dbgs() <<
" EB#" <<
I;
1295 if (
Cost < BestCost) {
1296 BestCand = NumCands;
1304unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1305 AllocationOrder &Order,
1306 BlockFrequency &BestCost,
1309 unsigned BestCand = NoCand;
1310 for (MCRegister PhysReg : Order) {
1312 if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg))
1315 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1322MCRegister RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
1323 unsigned BestCand,
bool HasCompact,
1324 SmallVectorImpl<Register> &NewVRegs) {
1325 SmallVector<unsigned, 8> UsedCands;
1327 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1331 BundleCand.assign(Bundles->getNumBundles(), NoCand);
1334 if (BestCand != NoCand) {
1335 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1336 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1338 Cand.IntvIdx = SE->openIntv();
1340 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1347 GlobalSplitCandidate &Cand = GlobalCand.front();
1348 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1349 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1351 Cand.IntvIdx = SE->openIntv();
1353 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1358 splitAroundRegion(LREdit, UsedCands);
1359 return MCRegister();
1364bool RAGreedy::trySplitAroundHintReg(MCRegister Hint,
1365 const LiveInterval &VirtReg,
1366 SmallVectorImpl<Register> &NewVRegs,
1367 AllocationOrder &Order) {
1371 if (MF->getFunction().hasOptSize())
1375 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1378 BlockFrequency
Cost = BlockFrequency(0);
1388 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
1389 const MachineInstr &
Instr = *Opnd.getParent();
1390 if (!
Instr.isCopy() || Opnd.isImplicit())
1394 const bool IsDef = Opnd.isDef();
1395 const MachineOperand &OtherOpnd =
Instr.getOperand(IsDef);
1398 if (OtherReg ==
Reg)
1401 unsigned SubReg = Opnd.getSubReg();
1402 unsigned OtherSubReg = OtherOpnd.
getSubReg();
1407 if (Opnd.readsReg()) {
1408 SlotIndex
Index =
LIS->getInstructionIndex(Instr).getRegSlot();
1415 if (
any_of(VirtReg.
subranges(), [=](
const LiveInterval::SubRange &S) {
1416 return (S.LaneMask & Mask).any() && S.liveAt(Index);
1421 if (VirtReg.
liveAt(Index))
1426 MCRegister OtherPhysReg =
1429 if (OtherPhysReg == ThisHint)
1430 Cost += MBFI->getBlockFreq(
Instr.getParent());
1436 if (
Cost == BlockFrequency(0))
1439 unsigned NumCands = 0;
1440 unsigned BestCand = NoCand;
1441 SA->analyze(&VirtReg);
1442 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1443 if (BestCand == NoCand)
1446 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1457MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1458 AllocationOrder &Order,
1459 SmallVectorImpl<Register> &NewVRegs) {
1460 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1463 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1466 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1467 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1468 SE->splitSingleBlock(BI);
1472 return MCRegister();
1475 SmallVector<unsigned, 8> IntvMap;
1476 SE->finish(&IntvMap);
1479 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1483 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1484 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1485 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1490 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1492 return MCRegister();
1505 assert(SuperRC &&
"Invalid register class");
1508 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1530 return MRI.getMaxLaneMaskForVReg(
Reg);
1536 Mask |= ~SubRegMask;
1553 auto DestSrc =
TII->isCopyInstr(*
MI);
1554 if (DestSrc && !
MI->isBundled() &&
1555 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1564 LiveAtMask |= S.LaneMask;
1569 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1579MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1580 AllocationOrder &Order,
1581 SmallVectorImpl<Register> &NewVRegs) {
1582 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
1585 bool SplitSubClass =
true;
1588 return MCRegister();
1589 SplitSubClass =
false;
1594 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1598 if (
Uses.size() <= 1)
1599 return MCRegister();
1602 <<
" individual instrs.\n");
1604 const TargetRegisterClass *SuperRC =
1605 TRI->getLargestLegalSuperClass(CurRC, *MF);
1606 unsigned SuperRCNumAllocatableRegs =
1612 for (
const SlotIndex Use :
Uses) {
1613 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1614 if (TII->isFullCopyInstr(*
MI) ||
1616 SuperRCNumAllocatableRegs ==
1627 SlotIndex SegStart = SE->enterIntvBefore(Use);
1628 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1629 SE->useIntv(SegStart, SegStop);
1632 if (LREdit.
empty()) {
1634 return MCRegister();
1637 SmallVector<unsigned, 8> IntvMap;
1638 SE->finish(&IntvMap);
1639 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1642 return MCRegister();
1654void RAGreedy::calcGapWeights(MCRegister PhysReg,
1655 SmallVectorImpl<float> &GapWeight) {
1656 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1657 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1659 const unsigned NumGaps =
Uses.size()-1;
1662 SlotIndex StartIdx =
1667 GapWeight.
assign(NumGaps, 0.0f);
1670 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1671 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1672 .checkInterference())
1683 Matrix->getLiveUnions()[
static_cast<unsigned>(
Unit)].
find(StartIdx);
1684 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1686 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1687 if (++Gap == NumGaps)
1693 const float weight = IntI.value()->weight();
1694 for (; Gap != NumGaps; ++Gap) {
1695 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1696 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1705 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1711 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1712 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1713 if (++Gap == NumGaps)
1718 for (; Gap != NumGaps; ++Gap) {
1720 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1732MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1733 AllocationOrder &Order,
1734 SmallVectorImpl<Register> &NewVRegs) {
1737 if (SA->getUseBlocks().size() != 1)
1738 return MCRegister();
1740 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1750 if (
Uses.size() <= 2)
1751 return MCRegister();
1752 const unsigned NumGaps =
Uses.size()-1;
1755 dbgs() <<
"tryLocalSplit: ";
1756 for (
const auto &Use :
Uses)
1763 SmallVector<unsigned, 8> RegMaskGaps;
1764 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1771 unsigned RE = RMS.
size();
1772 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1783 RegMaskGaps.push_back(
I);
1810 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1813 unsigned BestBefore = NumGaps;
1814 unsigned BestAfter = 0;
1817 const float blockFreq =
1818 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1819 (1.0f / MBFI->getEntryFreq().getFrequency());
1822 for (MCRegister PhysReg : Order) {
1826 calcGapWeights(PhysReg, GapWeight);
1829 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1830 for (
unsigned Gap : RegMaskGaps)
1837 unsigned SplitBefore = 0, SplitAfter = 1;
1841 float MaxGap = GapWeight[0];
1845 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1846 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1849 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1852 if (!LiveBefore && !LiveAfter) {
1860 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1863 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1872 blockFreq * (NewGaps + 1),
1873 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1881 float Diff = EstWeight - MaxGap;
1882 if (Diff > BestDiff) {
1885 BestBefore = SplitBefore;
1886 BestAfter = SplitAfter;
1893 if (++SplitBefore < SplitAfter) {
1896 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1897 MaxGap = GapWeight[SplitBefore];
1898 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1899 MaxGap = std::max(MaxGap, GapWeight[
I]);
1907 if (SplitAfter >= NumGaps) {
1913 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1918 if (BestBefore == NumGaps)
1919 return MCRegister();
1922 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1923 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1925 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1929 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1930 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1931 SE->useIntv(SegStart, SegStop);
1932 SmallVector<unsigned, 8> IntvMap;
1933 SE->finish(&IntvMap);
1934 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1938 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1939 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1940 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1941 if (NewGaps >= NumGaps) {
1943 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1944 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1945 if (IntvMap[
I] == 1) {
1953 return MCRegister();
1963MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
1964 AllocationOrder &Order,
1965 SmallVectorImpl<Register> &NewVRegs,
1968 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
1969 return MCRegister();
1972 if (
LIS->intervalIsInOneMBB(VirtReg)) {
1975 SA->analyze(&VirtReg);
1976 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
1977 if (PhysReg || !NewVRegs.
empty())
1979 return tryInstructionSplit(VirtReg, Order, NewVRegs);
1982 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
1985 SA->analyze(&VirtReg);
1990 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
1991 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
1992 if (PhysReg || !NewVRegs.
empty())
1997 return tryBlockSplit(VirtReg, Order, NewVRegs);
2020 if (PhysReg == AssignedReg)
2022 return TRI.regsOverlap(PhysReg, AssignedReg);
2033bool RAGreedy::mayRecolorAllInterferences(
2034 MCRegister PhysReg,
const LiveInterval &VirtReg,
2035 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2036 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
2038 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
2039 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2046 CutOffInfo |= CO_Interf;
2061 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2062 MRI->getRegClass(Intf->reg()) == CurRC &&
2066 FixedRegisters.
count(Intf->reg())) {
2068 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2071 RecoloringCandidates.insert(Intf);
2120MCRegister RAGreedy::tryLastChanceRecoloring(
2121 const LiveInterval &VirtReg, AllocationOrder &Order,
2123 RecoloringStack &RecolorStack,
unsigned Depth) {
2124 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2127 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2129 const ssize_t EntryStackSize = RecolorStack.size();
2133 "Last chance recoloring should really be last chance");
2139 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2140 CutOffInfo |= CO_Depth;
2145 SmallLISet RecoloringCandidates;
2153 for (MCRegister PhysReg : Order) {
2157 RecoloringCandidates.clear();
2158 CurrentNewVRegs.
clear();
2161 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2164 dbgs() <<
"Some interferences are not with virtual registers.\n");
2171 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2173 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2180 PQueue RecoloringQueue;
2181 for (
const LiveInterval *RC : RecoloringCandidates) {
2183 enqueue(RecoloringQueue, RC);
2185 "Interferences are supposed to be with allocated variables");
2188 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2197 Matrix->assign(VirtReg, PhysReg);
2206 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2207 FixedRegisters, RecolorStack,
Depth)) {
2212 if (
VRM->hasPhys(ThisVirtReg)) {
2213 Matrix->unassign(VirtReg);
2218 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2220 FixedRegisters.
erase(ThisVirtReg);
2221 return MCRegister();
2228 FixedRegisters = SaveFixedRegisters;
2229 Matrix->unassign(VirtReg);
2235 for (
Register R : CurrentNewVRegs) {
2236 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2247 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2248 const LiveInterval *LI;
2250 std::tie(LI, PhysReg) = RecolorStack[
I];
2252 if (
VRM->hasPhys(LI->
reg()))
2256 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2257 const LiveInterval *LI;
2259 std::tie(LI, PhysReg) = RecolorStack[
I];
2260 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2261 Matrix->assign(*LI, PhysReg);
2265 RecolorStack.resize(EntryStackSize);
2280bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2281 SmallVectorImpl<Register> &NewVRegs,
2283 RecoloringStack &RecolorStack,
2285 while (!RecoloringQueue.empty()) {
2286 const LiveInterval *LI =
dequeue(RecoloringQueue);
2288 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2289 RecolorStack,
Depth + 1);
2294 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2298 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2300 <<
" succeeded. Empty LI.\n");
2304 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2306 Matrix->assign(*LI, PhysReg);
2318 CutOffInfo = CO_None;
2319 LLVMContext &Ctx = MF->getFunction().getContext();
2321 RecoloringStack RecolorStack;
2323 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2324 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2325 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2326 if (CutOffEncountered == CO_Depth)
2327 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2328 "reached. Use -fexhaustive-register-search to skip "
2330 else if (CutOffEncountered == CO_Interf)
2331 Ctx.emitError(
"register allocation failed: maximum interference for "
2332 "recoloring reached. Use -fexhaustive-register-search "
2334 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2335 Ctx.emitError(
"register allocation failed: maximum interference and "
2336 "depth for recoloring reached. Use "
2337 "-fexhaustive-register-search to skip cutoffs");
2354 SA->analyze(&VirtReg);
2355 if (calcSpillCost() >= CSRCost)
2360 CostPerUseLimit = 1;
2363 if (ExtraInfo->getStage(VirtReg) <
RS_Split) {
2366 SA->analyze(&VirtReg);
2367 unsigned NumCands = 0;
2369 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2376 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2384 SetOfBrokenHints.remove(&LI);
2387void RAGreedy::initializeCSRCost() {
2394 if (!CSRCost.getFrequency())
2398 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2404 if (ActualEntry < FixedEntry)
2406 else if (ActualEntry <= UINT32_MAX)
2412 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2418void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2419 const TargetRegisterClass *RC =
MRI->getRegClass(
Reg);
2421 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2422 const MachineInstr &
Instr = *Opnd.getParent();
2423 if (!
Instr.isCopy() || Opnd.isImplicit())
2427 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2429 if (OtherReg ==
Reg)
2431 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2432 unsigned SubReg = Opnd.getSubReg();
2435 MCRegister OtherPhysReg;
2438 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2440 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg,
SubReg, RC);
2442 OtherPhysReg = OtherReg;
2444 OtherPhysReg =
VRM->getPhys(OtherReg);
2454 Out.push_back(HintInfo(MBFI->getBlockFreq(
Instr.getParent()), OtherReg,
2463BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2464 MCRegister PhysReg) {
2465 BlockFrequency
Cost = BlockFrequency(0);
2466 for (
const HintInfo &Info :
List) {
2467 if (
Info.PhysReg != PhysReg)
2481void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2487 MCRegister PhysReg =
VRM->getPhys(
Reg);
2490 SmallSet<Register, 4> Visited = {
Reg};
2499 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2504 "We have an unallocated variable which should have been handled");
2510 LiveInterval &LI =
LIS->getInterval(
Reg);
2513 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2514 Matrix->checkInterference(LI, PhysReg)))
2518 <<
") is recolorable.\n");
2522 collectHintInfo(
Reg, Info);
2525 if (CurrPhys != PhysReg) {
2527 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2528 BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
2532 if (OldCopiesCost < NewCopiesCost) {
2542 Matrix->assign(LI, PhysReg);
2546 for (
const HintInfo &HI : Info) {
2548 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2551 }
while (!RecoloringCandidates.
empty());
2590void RAGreedy::tryHintsRecoloring() {
2591 for (
const LiveInterval *LI : SetOfBrokenHints) {
2593 "Recoloring is possible only for virtual registers");
2596 if (!
VRM->hasPhys(LI->
reg()))
2598 tryHintRecoloring(*LI);
2602MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2603 SmallVectorImpl<Register> &NewVRegs,
2605 RecoloringStack &RecolorStack,
2607 uint8_t CostPerUseLimit = uint8_t(~0u);
2611 if (MCRegister PhysReg =
2612 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2616 if (CSRCost.getFrequency() &&
2617 EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.
empty()) {
2618 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2619 CostPerUseLimit, NewVRegs);
2620 if (CSRReg || !NewVRegs.
empty())
2628 if (!NewVRegs.
empty())
2629 return MCRegister();
2633 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2639 if (MCRegister PhysReg =
2640 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2648 if (Hint && Hint != PhysReg)
2649 SetOfBrokenHints.insert(&VirtReg);
2654 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2660 ExtraInfo->setStage(VirtReg,
RS_Split);
2663 return MCRegister();
2668 unsigned NewVRegSizeBefore = NewVRegs.
size();
2669 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2670 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2677 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2678 RecolorStack,
Depth);
2692 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2694 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2697 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2701 return MCRegister();
2704void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2705 using namespace ore;
2707 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2708 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2711 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2712 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2713 <<
" total folded spills cost ";
2716 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2717 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2719 if (FoldedReloads) {
2720 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2721 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2722 <<
" total folded reloads cost ";
2724 if (ZeroCostFoldedReloads)
2725 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2726 <<
" zero cost folded reloads ";
2728 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2729 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2733RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2734 RAGreedyStats
Stats;
2735 const MachineFrameInfo &MFI = MF->getFrameInfo();
2738 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2740 A->getPseudoValue())->getFrameIndex());
2742 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2743 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2744 MI.getOpcode() == TargetOpcode::STACKMAP ||
2745 MI.getOpcode() == TargetOpcode::STATEPOINT;
2747 for (MachineInstr &
MI :
MBB) {
2748 auto DestSrc = TII->isCopyInstr(
MI);
2750 const MachineOperand &Dest = *DestSrc->Destination;
2751 const MachineOperand &Src = *DestSrc->Source;
2757 SrcReg =
VRM->getPhys(SrcReg);
2758 if (SrcReg && Src.getSubReg())
2759 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2762 DestReg =
VRM->getPhys(DestReg);
2766 if (SrcReg != DestReg)
2772 SmallVector<const MachineMemOperand *, 2>
Accesses;
2781 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2783 if (!isPatchpointInstr(
MI)) {
2788 std::pair<unsigned, unsigned> NonZeroCostRange =
2789 TII->getPatchpointUnfoldableRange(
MI);
2790 SmallSet<unsigned, 16> FoldedReloads;
2791 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2792 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2793 MachineOperand &MO =
MI.getOperand(Idx);
2796 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2802 for (
unsigned Slot : FoldedReloads)
2803 ZeroCostFoldedReloads.
erase(Slot);
2804 Stats.FoldedReloads += FoldedReloads.size();
2805 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2809 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2816 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2818 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2820 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2825RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2826 RAGreedyStats
Stats;
2829 for (MachineLoop *SubLoop : *L)
2830 Stats.add(reportStats(SubLoop));
2832 for (MachineBasicBlock *
MBB :
L->getBlocks())
2834 if (Loops->getLoopFor(
MBB) == L)
2837 if (!
Stats.isEmpty()) {
2838 using namespace ore;
2841 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
2842 L->getStartLoc(),
L->getHeader());
2844 R <<
"generated in loop";
2851void RAGreedy::reportStats() {
2854 RAGreedyStats
Stats;
2855 for (MachineLoop *L : *Loops)
2856 Stats.add(reportStats(L));
2858 for (MachineBasicBlock &
MBB : *MF)
2859 if (!Loops->getLoopFor(&
MBB))
2861 if (!
Stats.isEmpty()) {
2862 using namespace ore;
2866 if (
auto *SP = MF->getFunction().getSubprogram())
2868 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
2871 R <<
"generated in function";
2877bool RAGreedy::hasVirtRegAlloc() {
2878 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
2880 if (
MRI->reg_nodbg_empty(
Reg))
2890 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
2891 <<
"********** Function: " << mf.
getName() <<
'\n');
2897 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
2903 if (!hasVirtRegAlloc())
2908 Indexes->packIndexes();
2910 initializeCSRCost();
2912 RegCosts =
TRI->getRegisterCosts(*MF);
2913 RegClassPriorityTrumpsGlobalness =
2916 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
2920 :
TRI->reverseLocalAssignment();
2922 ExtraInfo.emplace();
2924 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
2925 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
2927 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
2931 VRAI->calculateSpillWeightsAndHints();
2938 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
2939 GlobalCand.resize(32);
2940 SetOfBrokenHints.clear();
2943 tryHintsRecoloring();
2946 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")
#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,...
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...
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.