81#define DEBUG_TYPE "regalloc"
83STATISTIC(NumGlobalSplits,
"Number of split global live ranges");
84STATISTIC(NumLocalSplits,
"Number of split local live ranges");
85STATISTIC(NumEvicted,
"Number of interferences evicted");
89 cl::desc(
"Spill mode for splitting live ranges"),
97 cl::desc(
"Last chance recoloring max depth"),
102 cl::desc(
"Last chance recoloring maximum number of considered"
103 " interference at a time"),
108 cl::desc(
"Exhaustive Search for registers bypassing the depth "
109 "and interference cutoffs of last chance recoloring"),
116 cl::desc(
"Cost for first time use of callee-saved register."),
120 "regalloc-csr-cost-scale",
121 cl::desc(
"Scale for the callee-saved register cost, in percentage."),
125 "grow-region-complexity-budget",
126 cl::desc(
"growRegion() does not scale with the number of BB edges, so "
127 "limit its budget and bail out once we reach the limit."),
131 "greedy-regclass-priority-trumps-globalness",
132 cl::desc(
"Change the greedy register allocator's live range priority "
133 "calculation to make the AllocationPriority of the register class "
134 "more important then whether the range is global"),
138 "greedy-reverse-local-assignment",
139 cl::desc(
"Reverse allocation order of local live ranges, such that "
140 "shorter local live ranges will tend to be allocated first"),
144 "split-threshold-for-reg-with-hint",
145 cl::desc(
"The threshold for splitting a virtual register with a hint, in "
161 StringRef getPassName()
const override {
return "Greedy Register Allocator"; }
164 void getAnalysisUsage(AnalysisUsage &AU)
const override;
168 MachineFunctionProperties getRequiredProperties()
const override {
169 return MachineFunctionProperties().setNoPHIs();
172 MachineFunctionProperties getClearedProperties()
const override {
173 return MachineFunctionProperties().setIsSSA();
212 MBFI = Analyses.
MBFI;
214 Loops = Analyses.
Loops;
227 StringRef FilterName = Opts.FilterName.
empty() ?
"all" : Opts.FilterName;
228 OS <<
"greedy<" << FilterName <<
'>';
255 RAGreedy Impl(Analyses, Opts.Filter);
296char RAGreedyLegacy::ID = 0;
320const char *
const RAGreedy::StageName[] = {
335 return new RAGreedyLegacy();
339 return new RAGreedyLegacy(Ftor);
342void RAGreedyLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
371bool RAGreedy::LRE_CanEraseVirtReg(
Register VirtReg) {
372 LiveInterval &LI =
LIS->getInterval(VirtReg);
373 if (
VRM->hasPhys(VirtReg)) {
386void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
387 if (!
VRM->hasPhys(VirtReg))
391 LiveInterval &LI =
LIS->getInterval(VirtReg);
397 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
402 if (!Info.inBounds(Old))
411 Info[New] = Info[Old];
415 SpillerInstance.reset();
421void RAGreedy::enqueue(PQueue &CurQueue,
const LiveInterval *LI) {
425 assert(Reg.isVirtual() &&
"Can only enqueue virtual registers");
427 auto Stage = ExtraInfo->getOrInitStage(Reg);
430 ExtraInfo->setStage(Reg, Stage);
433 unsigned Ret = PriorityAdvisor->getPriority(*LI);
437 CurQueue.push(std::make_pair(Ret, ~
Reg.id()));
440unsigned DefaultPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
455 (!ReverseLocalAssignment &&
458 unsigned GlobalBit = 0;
461 LIS->intervalIsInOneMBB(LI)) {
465 if (!ReverseLocalAssignment)
471 Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.
endIndex());
493 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
496 if (RegClassPriorityTrumpsGlobalness)
505 if (
VRM->hasKnownPreference(
Reg))
512unsigned DummyPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
521 if (CurQueue.empty())
538 for (
auto I = Order.
begin(),
E = Order.
end();
I !=
E && !PhysReg; ++
I) {
540 if (!
Matrix->checkInterference(VirtReg, *
I)) {
556 MCRegister PhysHint =
Hint.asMCReg();
559 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
561 evictInterference(VirtReg, PhysHint, NewVRegs);
566 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
571 SetOfBrokenHints.insert(&VirtReg);
575 uint8_t
Cost = RegCosts[PhysReg.
id()];
582 << (
unsigned)
Cost <<
'\n');
583 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
584 return CheapReg ? CheapReg : PhysReg;
593 auto HasRegUnitInterference = [&](MCRegUnit Unit) {
596 VirtReg,
Matrix->getLiveUnions()[
static_cast<unsigned>(Unit)]);
605 if (
none_of(
TRI->regunits(Reg), HasRegUnitInterference)) {
618void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
624 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
627 <<
" interference: Cascade " << Cascade <<
'\n');
631 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
648 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
649 (Cascade < ExtraInfo->getCascade(Intf->reg()) &&
650 EvictAdvisor->isUrgentEviction(VirtReg, *Intf)) ||
652 "Cannot decrease cascade number, illegal eviction");
653 ExtraInfo->setCascade(Intf->reg(), Cascade);
662 auto IsUnusedCSR = [&](MCRegUnit Unit) {
664 if (CSR && !
Matrix->isPhysRegUsed(CSR))
670 MCRegUnit Unit = (*Units).first;
675 return (S.LaneMask & Mask).any();
684std::optional<unsigned>
687 unsigned CostPerUseLimit)
const {
688 unsigned OrderLimit = Order.
getOrder().size();
690 if (CostPerUseLimit <
uint8_t(~0u)) {
694 if (MinCost >= CostPerUseLimit) {
696 << MinCost <<
", no cheaper registers to be found.\n");
715 unsigned CostPerUseLimit,
717 if (
RegCosts[PhysReg.
id()] >= CostPerUseLimit)
721 if (CostPerUseLimit == 1) {
743 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
744 VirtReg, Order, CostPerUseLimit, FixedRegisters);
746 evictInterference(VirtReg, BestPhys, NewVRegs);
766 SplitConstraints.resize(UseBlocks.
size());
768 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
789 if (Intf.
first() <= Indexes->getMBBStartIdx(BI.
MBB)) {
803 SA->getFirstSplitPoint(BC.
Number)))
809 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
822 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
824 if (StaticCost >= MaxCost)
831 SpillPlacer->addConstraints(SplitConstraints);
832 return SpillPlacer->scanActiveBundles();
837bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
838 ArrayRef<unsigned> Blocks) {
839 const unsigned GroupSize = 8;
840 SpillPlacement::BlockConstraint BCS[GroupSize];
841 unsigned TBS[GroupSize];
842 unsigned B = 0,
T = 0;
844 for (
unsigned Number : Blocks) {
848 assert(
T < GroupSize &&
"Array overflow");
850 if (++
T == GroupSize) {
857 assert(
B < GroupSize &&
"Array overflow");
861 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
863 if (FirstNonDebugInstr !=
MBB->
end() &&
865 SA->getFirstSplitPoint(
Number)))
871 SlotIndex InsertIdx = InsertPt ==
MBB->
end()
872 ? Indexes->getMBBEndIdx(
MBB)
873 :
LIS->getInstructionIndex(*InsertPt);
874 if (Intf.
first() <= Indexes->getMBBStartIdx(
MBB) ||
881 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
886 if (++
B == GroupSize) {
887 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
892 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
897bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
899 BitVector Todo = SA->getThroughBlocks();
900 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
901 unsigned AddedTo = 0;
903 unsigned Visited = 0;
908 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
910 for (
unsigned Bundle : NewBundles) {
912 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
914 if (Blocks.
size() >= Budget)
916 Budget -= Blocks.
size();
917 for (
unsigned Block : Blocks) {
929 if (ActiveBlocks.
size() == AddedTo)
934 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
936 if (!addThroughConstraints(Cand.Intf, NewBlocks))
944 bool PrefSpill =
true;
945 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
950 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
951 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
952 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
953 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
958 SpillPlacer->addPrefSpill(NewBlocks,
true);
960 AddedTo = ActiveBlocks.
size();
963 SpillPlacer->iterate();
976bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
978 if (!SA->getNumThroughBlocks())
988 SpillPlacer->prepare(Cand.LiveBundles);
997 if (!growRegion(Cand)) {
1002 SpillPlacer->finish();
1004 if (!Cand.LiveBundles.any()) {
1010 for (
int I : Cand.LiveBundles.set_bits())
1011 dbgs() <<
" EB#" <<
I;
1019BlockFrequency RAGreedy::calcBlockSplitCost() {
1020 BlockFrequency
Cost = BlockFrequency(0);
1022 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1025 Cost += SpillPlacer->getBlockFrequency(
Number);
1029 Cost += SpillPlacer->getBlockFrequency(
Number);
1038BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1039 const AllocationOrder &Order) {
1040 BlockFrequency GlobalCost = BlockFrequency(0);
1041 const BitVector &LiveBundles = Cand.LiveBundles;
1043 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1044 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1045 SpillPlacement::BlockConstraint &BC = SplitConstraints[
I];
1046 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1047 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1050 Cand.Intf.moveToBlock(BC.
Number);
1057 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1060 for (
unsigned Number : Cand.ActiveBlocks) {
1061 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1062 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1063 if (!RegIn && !RegOut)
1065 if (RegIn && RegOut) {
1067 Cand.Intf.moveToBlock(
Number);
1068 if (Cand.Intf.hasInterference()) {
1069 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1070 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1075 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1092void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1093 ArrayRef<unsigned> UsedCands) {
1096 const unsigned NumGlobalIntvs = LREdit.
size();
1099 assert(NumGlobalIntvs &&
"No global intervals configured");
1109 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1111 unsigned IntvIn = 0, IntvOut = 0;
1112 SlotIndex IntfIn, IntfOut;
1114 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1115 if (CandIn != NoCand) {
1116 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1117 IntvIn = Cand.IntvIdx;
1118 Cand.Intf.moveToBlock(
Number);
1119 IntfIn = Cand.Intf.first();
1123 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1124 if (CandOut != NoCand) {
1125 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1126 IntvOut = Cand.IntvIdx;
1127 Cand.Intf.moveToBlock(
Number);
1128 IntfOut = Cand.Intf.last();
1133 if (!IntvIn && !IntvOut) {
1135 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1136 SE->splitSingleBlock(BI);
1140 if (IntvIn && IntvOut)
1141 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1143 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1145 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1151 BitVector Todo = SA->getThroughBlocks();
1152 for (
unsigned UsedCand : UsedCands) {
1153 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1154 for (
unsigned Number : Blocks) {
1159 unsigned IntvIn = 0, IntvOut = 0;
1160 SlotIndex IntfIn, IntfOut;
1162 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1163 if (CandIn != NoCand) {
1164 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1165 IntvIn = Cand.IntvIdx;
1166 Cand.Intf.moveToBlock(
Number);
1167 IntfIn = Cand.Intf.first();
1170 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1171 if (CandOut != NoCand) {
1172 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1173 IntvOut = Cand.IntvIdx;
1174 Cand.Intf.moveToBlock(
Number);
1175 IntfOut = Cand.Intf.last();
1177 if (!IntvIn && !IntvOut)
1179 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1185 SmallVector<unsigned, 8> IntvMap;
1186 SE->finish(&IntvMap);
1187 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1189 unsigned OrigBlocks = SA->getNumLiveBlocks();
1196 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1197 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1200 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1205 if (IntvMap[
I] == 0) {
1212 if (IntvMap[
I] < NumGlobalIntvs) {
1213 if (SA->countLiveBlocks(&
Reg) >= OrigBlocks) {
1214 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1215 <<
" blocks as original.\n");
1227 MF->verify(
LIS, Indexes,
"After splitting live range around region",
1231MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1232 AllocationOrder &Order,
1233 SmallVectorImpl<Register> &NewVRegs) {
1234 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1236 unsigned NumCands = 0;
1237 BlockFrequency SpillCost = calcBlockSplitCost();
1238 BlockFrequency BestCost;
1241 bool HasCompact = calcCompactRegion(GlobalCand.front());
1249 BestCost = SpillCost;
1254 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1258 if (!HasCompact && BestCand == NoCand)
1261 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1264unsigned RAGreedy::calculateRegionSplitCostAroundReg(MCRegister PhysReg,
1265 AllocationOrder &Order,
1266 BlockFrequency &BestCost,
1268 unsigned &BestCand) {
1271 if (NumCands == IntfCache.getMaxCursors()) {
1272 unsigned WorstCount = ~0
u;
1274 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1275 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1277 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1278 if (
Count < WorstCount) {
1284 GlobalCand[Worst] = GlobalCand[NumCands];
1285 if (BestCand == NumCands)
1289 if (GlobalCand.size() <= NumCands)
1290 GlobalCand.resize(NumCands+1);
1291 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1292 Cand.reset(IntfCache, PhysReg);
1294 SpillPlacer->prepare(Cand.LiveBundles);
1295 BlockFrequency
Cost;
1296 if (!addSplitConstraints(Cand.Intf,
Cost, BestCost)) {
1298 <<
"\tno positive bundles or too expensive\n");
1303 if (
Cost >= BestCost) {
1305 if (BestCand == NoCand)
1306 dbgs() <<
" worse than no bundles\n";
1308 dbgs() <<
" worse than "
1309 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1313 if (!growRegion(Cand)) {
1318 SpillPlacer->finish();
1321 if (!Cand.LiveBundles.any()) {
1326 Cost += calcGlobalSplitCost(Cand, Order);
1329 for (
int I : Cand.LiveBundles.set_bits())
1330 dbgs() <<
" EB#" <<
I;
1333 if (
Cost < BestCost) {
1334 BestCand = NumCands;
1342unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1343 AllocationOrder &Order,
1344 BlockFrequency &BestCost,
1347 unsigned BestCand = NoCand;
1348 for (MCRegister PhysReg : Order) {
1350 if (IgnoreCSR && EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, PhysReg))
1353 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1360MCRegister RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
1361 unsigned BestCand,
bool HasCompact,
1362 SmallVectorImpl<Register> &NewVRegs) {
1363 SmallVector<unsigned, 8> UsedCands;
1365 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1369 BundleCand.assign(Bundles->getNumBundles(), NoCand);
1372 if (BestCand != NoCand) {
1373 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1374 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1376 Cand.IntvIdx = SE->openIntv();
1378 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1385 GlobalSplitCandidate &Cand = GlobalCand.front();
1386 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1387 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1389 Cand.IntvIdx = SE->openIntv();
1391 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1396 splitAroundRegion(LREdit, UsedCands);
1397 return MCRegister();
1402bool RAGreedy::trySplitAroundHintReg(MCRegister Hint,
1403 const LiveInterval &VirtReg,
1404 SmallVectorImpl<Register> &NewVRegs,
1405 AllocationOrder &Order) {
1409 if (MF->getFunction().hasOptSize())
1413 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1416 BlockFrequency
Cost = BlockFrequency(0);
1426 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
1427 const MachineInstr &
Instr = *Opnd.getParent();
1428 if (!
Instr.isCopy() || Opnd.isImplicit())
1432 const bool IsDef = Opnd.isDef();
1433 const MachineOperand &OtherOpnd =
Instr.getOperand(IsDef);
1436 if (OtherReg ==
Reg)
1439 unsigned SubReg = Opnd.getSubReg();
1440 unsigned OtherSubReg = OtherOpnd.
getSubReg();
1441 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
1445 if (Opnd.readsReg()) {
1446 SlotIndex
Index =
LIS->getInstructionIndex(Instr).getRegSlot();
1449 LaneBitmask
Mask =
TRI->getSubRegIndexLaneMask(SubReg);
1453 if (
any_of(VirtReg.
subranges(), [=](
const LiveInterval::SubRange &S) {
1454 return (S.LaneMask & Mask).any() && S.liveAt(Index);
1459 if (VirtReg.
liveAt(Index))
1464 MCRegister OtherPhysReg =
1466 MCRegister ThisHint = SubReg ?
TRI->getSubReg(Hint, SubReg) :
Hint;
1467 if (OtherPhysReg == ThisHint)
1468 Cost += MBFI->getBlockFreq(
Instr.getParent());
1474 if (
Cost == BlockFrequency(0))
1477 unsigned NumCands = 0;
1478 unsigned BestCand = NoCand;
1479 SA->analyze(&VirtReg);
1480 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1481 if (BestCand == NoCand)
1484 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1495MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1496 AllocationOrder &Order,
1497 SmallVectorImpl<Register> &NewVRegs) {
1498 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1501 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1504 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1505 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1506 SE->splitSingleBlock(BI);
1510 return MCRegister();
1513 SmallVector<unsigned, 8> IntvMap;
1514 SE->finish(&IntvMap);
1517 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1521 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1522 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1523 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1528 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1530 return MCRegister();
1543 assert(SuperRC &&
"Invalid register class");
1546 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1561 for (
auto [
MI, OpIdx] :
Ops) {
1565 if (SubReg == 0 && MO.
isUse()) {
1574 Mask |= ~SubRegMask;
1591 auto DestSrc =
TII->isCopyInstr(*
MI);
1592 if (DestSrc && !
MI->isBundled() &&
1593 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1602 LiveAtMask |= S.LaneMask;
1607 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1617MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1618 AllocationOrder &Order,
1619 SmallVectorImpl<Register> &NewVRegs) {
1623 bool SplitSubClass =
true;
1626 return MCRegister();
1627 SplitSubClass =
false;
1632 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1636 if (
Uses.size() <= 1)
1637 return MCRegister();
1640 <<
" individual instrs.\n");
1643 TRI->getLargestLegalSuperClass(CurRC, *MF);
1644 unsigned SuperRCNumAllocatableRegs =
1650 for (
const SlotIndex Use :
Uses) {
1651 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1652 if (TII->isFullCopyInstr(*
MI) ||
1654 SuperRCNumAllocatableRegs ==
1665 SlotIndex SegStart = SE->enterIntvBefore(Use);
1666 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1667 SE->useIntv(SegStart, SegStop);
1670 if (LREdit.
empty()) {
1672 return MCRegister();
1675 SmallVector<unsigned, 8> IntvMap;
1676 SE->finish(&IntvMap);
1677 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1680 return MCRegister();
1692void RAGreedy::calcGapWeights(MCRegister PhysReg,
1693 SmallVectorImpl<float> &GapWeight) {
1694 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1695 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1697 const unsigned NumGaps =
Uses.size()-1;
1700 SlotIndex StartIdx =
1705 GapWeight.
assign(NumGaps, 0.0f);
1708 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1709 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1710 .checkInterference())
1721 Matrix->getLiveUnions()[
static_cast<unsigned>(
Unit)].
find(StartIdx);
1722 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1724 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1725 if (++Gap == NumGaps)
1731 const float weight = IntI.value()->weight();
1732 for (; Gap != NumGaps; ++Gap) {
1733 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1734 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1743 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1749 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1750 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1751 if (++Gap == NumGaps)
1756 for (; Gap != NumGaps; ++Gap) {
1758 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1770MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1771 AllocationOrder &Order,
1772 SmallVectorImpl<Register> &NewVRegs) {
1775 if (SA->getUseBlocks().size() != 1)
1776 return MCRegister();
1778 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1788 if (
Uses.size() <= 2)
1789 return MCRegister();
1790 const unsigned NumGaps =
Uses.size()-1;
1793 dbgs() <<
"tryLocalSplit: ";
1794 for (
const auto &Use :
Uses)
1801 SmallVector<unsigned, 8> RegMaskGaps;
1802 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1809 unsigned RE = RMS.
size();
1810 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1821 RegMaskGaps.push_back(
I);
1848 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1851 unsigned BestBefore = NumGaps;
1852 unsigned BestAfter = 0;
1855 const float blockFreq =
1856 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1857 (1.0f / MBFI->getEntryFreq().getFrequency());
1860 for (MCRegister PhysReg : Order) {
1864 calcGapWeights(PhysReg, GapWeight);
1867 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1868 for (
unsigned Gap : RegMaskGaps)
1875 unsigned SplitBefore = 0, SplitAfter = 1;
1879 float MaxGap = GapWeight[0];
1883 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1884 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1887 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1890 if (!LiveBefore && !LiveAfter) {
1898 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1901 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1910 blockFreq * (NewGaps + 1),
1911 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1919 float Diff = EstWeight - MaxGap;
1920 if (Diff > BestDiff) {
1923 BestBefore = SplitBefore;
1924 BestAfter = SplitAfter;
1931 if (++SplitBefore < SplitAfter) {
1934 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1935 MaxGap = GapWeight[SplitBefore];
1936 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1937 MaxGap = std::max(MaxGap, GapWeight[
I]);
1945 if (SplitAfter >= NumGaps) {
1951 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1956 if (BestBefore == NumGaps)
1957 return MCRegister();
1960 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1961 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1963 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1967 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1968 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1969 SE->useIntv(SegStart, SegStop);
1970 SmallVector<unsigned, 8> IntvMap;
1971 SE->finish(&IntvMap);
1972 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1976 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1977 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1978 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1979 if (NewGaps >= NumGaps) {
1981 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1982 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1983 if (IntvMap[
I] == 1) {
1991 return MCRegister();
2001MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
2002 AllocationOrder &Order,
2003 SmallVectorImpl<Register> &NewVRegs,
2006 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
2007 return MCRegister();
2010 if (
LIS->intervalIsInOneMBB(VirtReg)) {
2013 SA->analyze(&VirtReg);
2014 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
2015 if (PhysReg || !NewVRegs.
empty())
2017 return tryInstructionSplit(VirtReg, Order, NewVRegs);
2020 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
2023 SA->analyze(&VirtReg);
2028 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
2029 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
2030 if (PhysReg || !NewVRegs.
empty())
2035 return tryBlockSplit(VirtReg, Order, NewVRegs);
2058 if (PhysReg == AssignedReg)
2060 return TRI.regsOverlap(PhysReg, AssignedReg);
2071bool RAGreedy::mayRecolorAllInterferences(
2072 MCRegister PhysReg,
const LiveInterval &VirtReg,
2073 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2076 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
2077 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2084 CutOffInfo |= CO_Interf;
2099 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2100 MRI->getRegClass(Intf->reg()) == CurRC &&
2104 FixedRegisters.
count(Intf->reg())) {
2106 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2109 RecoloringCandidates.insert(Intf);
2158MCRegister RAGreedy::tryLastChanceRecoloring(
2159 const LiveInterval &VirtReg, AllocationOrder &Order,
2161 RecoloringStack &RecolorStack,
unsigned Depth) {
2162 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2165 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2167 const ssize_t EntryStackSize = RecolorStack.size();
2171 "Last chance recoloring should really be last chance");
2177 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2178 CutOffInfo |= CO_Depth;
2183 SmallLISet RecoloringCandidates;
2191 for (MCRegister PhysReg : Order) {
2195 RecoloringCandidates.clear();
2196 CurrentNewVRegs.
clear();
2199 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2202 dbgs() <<
"Some interferences are not with virtual registers.\n");
2209 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2211 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2218 PQueue RecoloringQueue;
2219 for (
const LiveInterval *RC : RecoloringCandidates) {
2221 enqueue(RecoloringQueue, RC);
2223 "Interferences are supposed to be with allocated variables");
2226 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2235 Matrix->assign(VirtReg, PhysReg);
2244 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2245 FixedRegisters, RecolorStack,
Depth)) {
2250 if (
VRM->hasPhys(ThisVirtReg)) {
2251 Matrix->unassign(VirtReg);
2256 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2258 FixedRegisters.
erase(ThisVirtReg);
2259 return MCRegister();
2266 FixedRegisters = SaveFixedRegisters;
2267 Matrix->unassign(VirtReg);
2273 for (
Register R : CurrentNewVRegs) {
2274 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2285 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2286 const LiveInterval *LI;
2288 std::tie(LI, PhysReg) = RecolorStack[
I];
2290 if (
VRM->hasPhys(LI->
reg()))
2294 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2295 const LiveInterval *LI;
2297 std::tie(LI, PhysReg) = RecolorStack[
I];
2298 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2299 Matrix->assign(*LI, PhysReg);
2303 RecolorStack.resize(EntryStackSize);
2318bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2319 SmallVectorImpl<Register> &NewVRegs,
2321 RecoloringStack &RecolorStack,
2323 while (!RecoloringQueue.empty()) {
2324 const LiveInterval *LI =
dequeue(RecoloringQueue);
2326 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2327 RecolorStack,
Depth + 1);
2332 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2336 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2338 <<
" succeeded. Empty LI.\n");
2342 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2344 Matrix->assign(*LI, PhysReg);
2356 CutOffInfo = CO_None;
2357 LLVMContext &Ctx = MF->getFunction().getContext();
2359 RecoloringStack RecolorStack;
2361 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2362 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2363 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2364 if (CutOffEncountered == CO_Depth)
2365 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2366 "reached. Use -fexhaustive-register-search to skip "
2368 else if (CutOffEncountered == CO_Interf)
2369 Ctx.emitError(
"register allocation failed: maximum interference for "
2370 "recoloring reached. Use -fexhaustive-register-search "
2372 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2373 Ctx.emitError(
"register allocation failed: maximum interference and "
2374 "depth for recoloring reached. Use "
2375 "-fexhaustive-register-search to skip cutoffs");
2383 uint64_t SpillCost = 0;
2391 if (
MI->isMetaInstruction())
2396 auto [Reads, Writes] =
MI->readsWritesVirtualRegister(LI.
reg());
2397 auto MBBFreq = SpillPlacer->getBlockFrequency(
MI->getParent()->getNumber());
2398 SpillCost += (Reads + Writes) * MBBFreq.getFrequency();
2404BlockFrequency RAGreedy::calcRematCost(
const LiveInterval &VirtReg,
2405 AllocationOrder &Order)
const {
2417 MachineInstr *
DefMI =
LIS->getInstructionFromIndex(OnlyVNI->
def);
2418 if (!
DefMI || !TII->isReMaterializable(*
DefMI) ||
2425 if (!
Matrix->checkRegMaskInterference(VirtReg))
2428 BlockFrequency RematCost;
2429 bool HasUse =
false;
2430 for (MachineInstr &
UseMI :
MRI->use_nodbg_instructions(VirtReg.
reg())) {
2431 if (!
UseMI.readsVirtualRegister(VirtReg.
reg()))
2437 SlotIndex UseIdx =
LIS->getInstructionIndex(
UseMI).getRegSlot(
true);
2444 bool HasNoFirstCSRReg =
false;
2445 for (MCRegister RematPhysReg : Order) {
2446 if (EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, RematPhysReg))
2448 if (!
Matrix->checkInterference(PrevIdx, UseIdx, RematPhysReg)) {
2449 HasNoFirstCSRReg =
true;
2453 if (!HasNoFirstCSRReg)
2456 RematCost += SpillPlacer->getBlockFrequency(
UseMI.getParent()->getNumber());
2469MCRegister RAGreedy::tryAssignCSRFirstTime(
2470 const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg,
2471 uint8_t &CostPerUseLimit, SmallVectorImpl<Register> &NewVRegs) {
2477 SA->analyze(&VirtReg);
2478 if (calcSpillCost(VirtReg) >= CSRCost &&
2479 calcRematCost(VirtReg, Order) >= CSRCost) {
2485 CostPerUseLimit = 1;
2486 return MCRegister();
2491 SA->analyze(&VirtReg);
2492 unsigned NumCands = 0;
2493 BlockFrequency BestCost = CSRCost;
2494 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2496 if (BestCand == NoCand) {
2497 if (calcRematCost(VirtReg, Order) < CSRCost) {
2498 CostPerUseLimit = 1;
2499 return MCRegister();
2506 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2507 return MCRegister();
2509 if (calcRematCost(VirtReg, Order) < CSRCost) {
2510 CostPerUseLimit = 1;
2511 return MCRegister();
2518 SetOfBrokenHints.remove(&LI);
2521void RAGreedy::initializeCSRCost() {
2531 if (!CSRCost.getFrequency())
2535 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2541 if (ActualEntry < FixedEntry) {
2543 }
else if (ActualEntry <= UINT32_MAX) {
2545 CSRCost /= BranchProbability(FixedEntry, ActualEntry);
2549 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2552 uint64_t EntryFreq = MBFI->getEntryFreq().getFrequency();
2553 CSRCost = BlockFrequency(
TRI->getCSRFirstUseCost(*MF) * EntryFreq);
2554 unsigned Scale =
TRI->getCSRCostScale(*MF);
2560 CSRCost *= BranchProbability(Scale, 100);
2562 CSRCost /= BranchProbability(100, Scale);
2569void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2572 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2573 const MachineInstr &
Instr = *Opnd.getParent();
2574 if (!
Instr.isCopy() || Opnd.isImplicit())
2578 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2580 if (OtherReg ==
Reg)
2582 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2583 unsigned SubReg = Opnd.getSubReg();
2586 MCRegister OtherPhysReg;
2589 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2591 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, SubReg, RC);
2593 OtherPhysReg = OtherReg;
2595 OtherPhysReg =
VRM->getPhys(OtherReg);
2599 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
2605 Out.push_back(HintInfo(
Instr.getParent(), OtherReg, OtherPhysReg));
2613BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2614 MCRegister PhysReg) {
2615 BlockFrequency
Cost = BlockFrequency(0);
2616 for (
const HintInfo &Info :
List) {
2617 if (
Info.PhysReg != PhysReg)
2618 Cost += MBFI->getBlockFreq(
Info.MBB);
2633void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg,
2634 DenseSet<Register> &NoRecolorRegs) {
2640 MCRegister PhysReg =
VRM->getPhys(
Reg);
2643 SmallDenseSet<Register, 8> Visited = {
Reg};
2654 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2659 "We have an unallocated variable which should have been handled");
2665 LiveInterval &LI =
LIS->getInterval(
Reg);
2668 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2669 Matrix->checkInterference(LI, PhysReg)))
2673 <<
") is recolorable.\n");
2677 collectHintInfo(
Reg, Info);
2680 if (CurrPhys != PhysReg) {
2682 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2683 BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
2687 if (OldCopiesCost < NewCopiesCost) {
2697 Matrix->assign(LI, PhysReg);
2704 for (
const HintInfo &HI : Info) {
2706 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2709 }
while (!RecoloringCandidates.
empty());
2712 NoRecolorRegs.
clear();
2753void RAGreedy::tryHintsRecoloring() {
2754 DenseSet<Register> NoRecolorRegs;
2755 for (
const LiveInterval *LI : SetOfBrokenHints) {
2757 "Recoloring is possible only for virtual registers");
2762 tryHintRecoloring(*LI, NoRecolorRegs);
2766MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2767 SmallVectorImpl<Register> &NewVRegs,
2769 RecoloringStack &RecolorStack,
2771 uint8_t CostPerUseLimit = uint8_t(~0u);
2775 if (MCRegister PhysReg =
2776 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2780 if (CSRCost.getFrequency() &&
2781 EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, PhysReg) &&
2783 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2784 CostPerUseLimit, NewVRegs);
2785 if (CSRReg || !NewVRegs.
empty())
2793 if (!NewVRegs.
empty())
2794 return MCRegister();
2798 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2804 if (MCRegister PhysReg =
2805 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2813 if (Hint && Hint != PhysReg)
2814 SetOfBrokenHints.insert(&VirtReg);
2819 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2825 ExtraInfo->setStage(VirtReg,
RS_Split);
2828 return MCRegister();
2833 unsigned NewVRegSizeBefore = NewVRegs.
size();
2834 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2835 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2842 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2843 RecolorStack,
Depth);
2857 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2859 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2862 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2866 return MCRegister();
2869void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2870 using namespace ore;
2872 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2873 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2876 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2877 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2878 <<
" total folded spills cost ";
2881 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2882 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2884 if (FoldedReloads) {
2885 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2886 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2887 <<
" total folded reloads cost ";
2889 if (ZeroCostFoldedReloads)
2890 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2891 <<
" zero cost folded reloads ";
2893 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2894 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2898RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2899 RAGreedyStats
Stats;
2900 const MachineFrameInfo &MFI = MF->getFrameInfo();
2903 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2905 A->getPseudoValue())->getFrameIndex());
2907 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2908 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2909 MI.getOpcode() == TargetOpcode::STACKMAP ||
2910 MI.getOpcode() == TargetOpcode::STATEPOINT;
2912 for (MachineInstr &
MI :
MBB) {
2913 auto DestSrc = TII->isCopyInstr(
MI);
2915 const MachineOperand &Dest = *DestSrc->Destination;
2916 const MachineOperand &Src = *DestSrc->Source;
2922 SrcReg =
VRM->getPhys(SrcReg);
2923 if (SrcReg && Src.getSubReg())
2924 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2927 DestReg =
VRM->getPhys(DestReg);
2931 if (SrcReg != DestReg)
2937 SmallVector<const MachineMemOperand *, 2>
Accesses;
2946 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2948 if (!isPatchpointInstr(
MI)) {
2953 std::pair<unsigned, unsigned> NonZeroCostRange =
2954 TII->getPatchpointUnfoldableRange(
MI);
2955 SmallSet<unsigned, 16> FoldedReloads;
2956 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2957 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2958 MachineOperand &MO =
MI.getOperand(Idx);
2961 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2967 for (
unsigned Slot : FoldedReloads)
2968 ZeroCostFoldedReloads.
erase(Slot);
2969 Stats.FoldedReloads += FoldedReloads.size();
2970 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2974 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2981 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2983 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2985 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2990RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2991 RAGreedyStats
Stats;
2994 for (MachineLoop *SubLoop : *L)
2995 Stats.add(reportStats(SubLoop));
2997 for (MachineBasicBlock *
MBB :
L->getBlocks())
2999 if (Loops->getLoopFor(
MBB) == L)
3002 if (!
Stats.isEmpty()) {
3003 using namespace ore;
3006 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
3007 L->getStartLoc(),
L->getHeader());
3009 R <<
"generated in loop";
3016void RAGreedy::reportStats() {
3019 RAGreedyStats
Stats;
3020 for (MachineLoop *L : *Loops)
3021 Stats.add(reportStats(L));
3023 for (MachineBasicBlock &
MBB : *MF)
3024 if (!Loops->getLoopFor(&
MBB))
3026 if (!
Stats.isEmpty()) {
3027 using namespace ore;
3031 if (
auto *SP = MF->getFunction().getSubprogram())
3033 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
3036 R <<
"generated in function";
3042bool RAGreedy::hasVirtRegAlloc() {
3043 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
3045 if (
MRI->reg_nodbg_empty(
Reg))
3055 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
3056 <<
"********** Function: " << mf.
getName() <<
'\n');
3062 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
3068 if (!hasVirtRegAlloc())
3076 DebugVars->canonicalizeIndexes(*Indexes);
3080 Indexes->packIndexes();
3082 initializeCSRCost();
3084 RegCosts =
TRI->getRegisterCosts(*MF);
3085 RegClassPriorityTrumpsGlobalness =
3088 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
3092 :
TRI->reverseLocalAssignment();
3094 ExtraInfo.emplace();
3096 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
3097 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
3099 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
3103 VRAI->calculateSpillWeightsAndHints();
3110 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
3111 GlobalCand.resize(32);
3112 SetOfBrokenHints.clear();
3115 tryHintsRecoloring();
3118 MF->verify(
LIS, Indexes,
"Before post optimization", &
errs());
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
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
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This header defines classes/functions to handle pass execution timing information with interfaces for...
static DominatorTree getDomTree(Function &F)
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 > CSRCostScale("regalloc-csr-cost-scale", cl::desc("Scale for the callee-saved register cost, in percentage."), cl::init(80), 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)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName) const
LLVM_ABI 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.
bool hasCustomOrder() const
Return true if a custom order replaced the RegisterClassInfo order.
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:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
BitVector & reset()
Reset all bits in the bitvector.
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
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
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.
bool containsOneValue() const
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.
MCRegUnitMaskIterator enumerates a list of register units and their associated lane masks for Reg.
bool isValid() const
Returns true if this iterator is not yet at the end.
const uint8_t AllocationPriority
Classes with a higher priority value are assigned first by register allocators using a greedy heurist...
const bool GlobalPriority
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 SkipPHIsLabelsAndDebug(iterator I, Register Reg=Register(), bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
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
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
Returns true if this instruction has the same cost (or less) than a move instruction.
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 reg_instr_nodbg_iterator reg_instr_nodbg_end()
defusechain_instr_iterator< true, true, true, true > reg_instr_nodbg_iterator
reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk all defs and uses of the sp...
iterator_range< def_iterator > def_operands(Register Reg) const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
reg_instr_nodbg_iterator reg_instr_nodbg_begin(Register RegNo) const
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
LLVM_ABI MCRegister getUnusedCalleeSavedReg(const LiveInterval &VirtReg, MCRegister PhysReg) const
Return an unused callee-saved register that would be used by assigning VirtReg to PhysReg,...
LLVM_ABI std::optional< unsigned > getOrderLimit(const LiveInterval &VirtReg, const AllocationOrder &Order, unsigned CostPerUseLimit) const
const ArrayRef< uint8_t > RegCosts
MachineRegisterInfo *const MRI
const RegisterClassInfo & RegClassInfo
LLVM_ABI bool canAllocatePhysReg(const LiveInterval &VirtReg, unsigned CostPerUseLimit, MCRegister PhysReg) const
LLVM_ABI bool canReassign(const LiveInterval &VirtReg, MCRegister FromReg) 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.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
int getApproxInstrDistance(SlotIndex other) const
Return the scaled distance from this index to the given one, where all slots on the same instruction ...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
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.
bool isUnused() const
Returns true if this value is unused.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
static LLVM_ABI bool allUsesAvailableAt(const MachineInstr *MI, SlotIndex UseIdx, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
int getNumOccurrences() const
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
void insert_range(Range &&R)
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.
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
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.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
LLVM_ABI 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...
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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.
bool canGuaranteeAssignmentAfterRemat(Register VReg, const MachineInstr &MI)
Return whether we can guarantee physical register assignment if VReg's value is rematerialized immedi...
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.
MCRegisterClass TargetRegisterClass
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.