80#define DEBUG_TYPE "regalloc"
82STATISTIC(NumGlobalSplits,
"Number of split global live ranges");
83STATISTIC(NumLocalSplits,
"Number of split local live ranges");
84STATISTIC(NumEvicted,
"Number of interferences evicted");
88 cl::desc(
"Spill mode for splitting live ranges"),
96 cl::desc(
"Last chance recoloring max depth"),
101 cl::desc(
"Last chance recoloring maximum number of considered"
102 " interference at a time"),
107 cl::desc(
"Exhaustive Search for registers bypassing the depth "
108 "and interference cutoffs of last chance recoloring"),
115 cl::desc(
"Cost for first time use of callee-saved register."),
119 "regalloc-csr-cost-scale",
120 cl::desc(
"Scale for the callee-saved register cost, in percentage."),
124 "grow-region-complexity-budget",
125 cl::desc(
"growRegion() does not scale with the number of BB edges, so "
126 "limit its budget and bail out once we reach the limit."),
130 "greedy-regclass-priority-trumps-globalness",
131 cl::desc(
"Change the greedy register allocator's live range priority "
132 "calculation to make the AllocationPriority of the register class "
133 "more important then whether the range is global"),
137 "greedy-reverse-local-assignment",
138 cl::desc(
"Reverse allocation order of local live ranges, such that "
139 "shorter local live ranges will tend to be allocated first"),
143 "split-threshold-for-reg-with-hint",
144 cl::desc(
"The threshold for splitting a virtual register with a hint, in "
160 StringRef getPassName()
const override {
return "Greedy Register Allocator"; }
163 void getAnalysisUsage(AnalysisUsage &AU)
const override;
165 bool runOnMachineFunction(MachineFunction &mf)
override;
167 MachineFunctionProperties getRequiredProperties()
const override {
168 return MachineFunctionProperties().setNoPHIs();
171 MachineFunctionProperties getClearedProperties()
const override {
172 return MachineFunctionProperties().setIsSSA();
211 MBFI = Analyses.
MBFI;
213 Loops = Analyses.
Loops;
226 StringRef FilterName = Opts.FilterName.
empty() ?
"all" : Opts.FilterName;
227 OS <<
"greedy<" << FilterName <<
'>';
254 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 {
374bool RAGreedy::LRE_CanEraseVirtReg(
Register VirtReg) {
375 LiveInterval &LI =
LIS->getInterval(VirtReg);
376 if (
VRM->hasPhys(VirtReg)) {
389void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
390 if (!
VRM->hasPhys(VirtReg))
394 LiveInterval &LI =
LIS->getInterval(VirtReg);
400 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
405 if (!Info.inBounds(Old))
414 Info[New] = Info[Old];
418 SpillerInstance.reset();
424void RAGreedy::enqueue(PQueue &CurQueue,
const LiveInterval *LI) {
428 assert(Reg.isVirtual() &&
"Can only enqueue virtual registers");
430 auto Stage = ExtraInfo->getOrInitStage(Reg);
433 ExtraInfo->setStage(Reg, Stage);
436 unsigned Ret = PriorityAdvisor->getPriority(*LI);
440 CurQueue.push(std::make_pair(Ret, ~
Reg.id()));
443unsigned DefaultPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
456 const TargetRegisterClass &RC = *
MRI->getRegClass(
Reg);
458 (!ReverseLocalAssignment &&
461 unsigned GlobalBit = 0;
464 LIS->intervalIsInOneMBB(LI)) {
468 if (!ReverseLocalAssignment)
474 Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.
endIndex());
496 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
499 if (RegClassPriorityTrumpsGlobalness)
508 if (
VRM->hasKnownPreference(
Reg))
515unsigned DummyPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
524 if (CurQueue.empty())
541 for (
auto I = Order.
begin(),
E = Order.
end();
I !=
E && !PhysReg; ++
I) {
543 if (!
Matrix->checkInterference(VirtReg, *
I)) {
559 MCRegister PhysHint =
Hint.asMCReg();
562 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
564 evictInterference(VirtReg, PhysHint, NewVRegs);
569 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
574 SetOfBrokenHints.insert(&VirtReg);
578 uint8_t
Cost = RegCosts[PhysReg.
id()];
585 << (
unsigned)
Cost <<
'\n');
586 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
587 return CheapReg ? CheapReg : PhysReg;
596 auto HasRegUnitInterference = [&](MCRegUnit Unit) {
599 VirtReg,
Matrix->getLiveUnions()[
static_cast<unsigned>(Unit)]);
608 if (
none_of(
TRI->regunits(Reg), HasRegUnitInterference)) {
621void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
627 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
630 <<
" interference: Cascade " << Cascade <<
'\n');
634 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
651 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
653 "Cannot decrease cascade number, illegal eviction");
654 ExtraInfo->setCascade(Intf->reg(), Cascade);
667 return !
Matrix->isPhysRegUsed(PhysReg);
670std::optional<unsigned>
673 unsigned CostPerUseLimit)
const {
674 unsigned OrderLimit = Order.
getOrder().size();
676 if (CostPerUseLimit <
uint8_t(~0u)) {
680 if (MinCost >= CostPerUseLimit) {
682 << MinCost <<
", no cheaper registers to be found.\n");
699 if (
RegCosts[PhysReg.
id()] >= CostPerUseLimit)
725 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
726 VirtReg, Order, CostPerUseLimit, FixedRegisters);
728 evictInterference(VirtReg, BestPhys, NewVRegs);
746 SplitConstraints.resize(UseBlocks.
size());
748 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
769 if (Intf.
first() <= Indexes->getMBBStartIdx(BC.
Number)) {
783 SA->getFirstSplitPoint(BC.
Number)))
789 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
802 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
808 SpillPlacer->addConstraints(SplitConstraints);
809 return SpillPlacer->scanActiveBundles();
814bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
815 ArrayRef<unsigned> Blocks) {
816 const unsigned GroupSize = 8;
817 SpillPlacement::BlockConstraint BCS[GroupSize];
818 unsigned TBS[GroupSize];
819 unsigned B = 0,
T = 0;
821 for (
unsigned Number : Blocks) {
825 assert(
T < GroupSize &&
"Array overflow");
827 if (++
T == GroupSize) {
834 assert(
B < GroupSize &&
"Array overflow");
838 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
840 if (FirstNonDebugInstr !=
MBB->
end() &&
842 SA->getFirstSplitPoint(
Number)))
845 if (Intf.
first() <= Indexes->getMBBStartIdx(
Number))
851 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
856 if (++
B == GroupSize) {
857 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
862 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
867bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
869 BitVector Todo = SA->getThroughBlocks();
870 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
871 unsigned AddedTo = 0;
873 unsigned Visited = 0;
878 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
880 for (
unsigned Bundle : NewBundles) {
882 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
884 if (Blocks.
size() >= Budget)
886 Budget -= Blocks.
size();
887 for (
unsigned Block : Blocks) {
899 if (ActiveBlocks.
size() == AddedTo)
904 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
906 if (!addThroughConstraints(Cand.Intf, NewBlocks))
914 bool PrefSpill =
true;
915 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
920 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
921 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
922 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
923 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
928 SpillPlacer->addPrefSpill(NewBlocks,
true);
930 AddedTo = ActiveBlocks.
size();
933 SpillPlacer->iterate();
946bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
948 if (!SA->getNumThroughBlocks())
958 SpillPlacer->prepare(Cand.LiveBundles);
962 if (!addSplitConstraints(Cand.Intf,
Cost)) {
967 if (!growRegion(Cand)) {
972 SpillPlacer->finish();
974 if (!Cand.LiveBundles.any()) {
980 for (
int I : Cand.LiveBundles.set_bits())
981 dbgs() <<
" EB#" <<
I;
989BlockFrequency RAGreedy::calcBlockSplitCost() {
990 BlockFrequency
Cost = BlockFrequency(0);
992 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
995 Cost += SpillPlacer->getBlockFrequency(
Number);
999 Cost += SpillPlacer->getBlockFrequency(
Number);
1008BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1009 const AllocationOrder &Order) {
1010 BlockFrequency GlobalCost = BlockFrequency(0);
1011 const BitVector &LiveBundles = Cand.LiveBundles;
1013 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1014 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1015 SpillPlacement::BlockConstraint &BC = SplitConstraints[
I];
1016 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1017 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1020 Cand.Intf.moveToBlock(BC.
Number);
1027 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1030 for (
unsigned Number : Cand.ActiveBlocks) {
1031 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1032 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1033 if (!RegIn && !RegOut)
1035 if (RegIn && RegOut) {
1037 Cand.Intf.moveToBlock(
Number);
1038 if (Cand.Intf.hasInterference()) {
1039 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1040 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1045 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1062void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1063 ArrayRef<unsigned> UsedCands) {
1066 const unsigned NumGlobalIntvs = LREdit.
size();
1069 assert(NumGlobalIntvs &&
"No global intervals configured");
1079 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1081 unsigned IntvIn = 0, IntvOut = 0;
1082 SlotIndex IntfIn, IntfOut;
1084 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1085 if (CandIn != NoCand) {
1086 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1087 IntvIn = Cand.IntvIdx;
1088 Cand.Intf.moveToBlock(
Number);
1089 IntfIn = Cand.Intf.first();
1093 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1094 if (CandOut != NoCand) {
1095 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1096 IntvOut = Cand.IntvIdx;
1097 Cand.Intf.moveToBlock(
Number);
1098 IntfOut = Cand.Intf.last();
1103 if (!IntvIn && !IntvOut) {
1105 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1106 SE->splitSingleBlock(BI);
1110 if (IntvIn && IntvOut)
1111 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1113 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1115 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1121 BitVector Todo = SA->getThroughBlocks();
1122 for (
unsigned UsedCand : UsedCands) {
1123 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1124 for (
unsigned Number : Blocks) {
1129 unsigned IntvIn = 0, IntvOut = 0;
1130 SlotIndex IntfIn, IntfOut;
1132 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1133 if (CandIn != NoCand) {
1134 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1135 IntvIn = Cand.IntvIdx;
1136 Cand.Intf.moveToBlock(
Number);
1137 IntfIn = Cand.Intf.first();
1140 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1141 if (CandOut != NoCand) {
1142 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1143 IntvOut = Cand.IntvIdx;
1144 Cand.Intf.moveToBlock(
Number);
1145 IntfOut = Cand.Intf.last();
1147 if (!IntvIn && !IntvOut)
1149 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1155 SmallVector<unsigned, 8> IntvMap;
1156 SE->finish(&IntvMap);
1157 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1159 unsigned OrigBlocks = SA->getNumLiveBlocks();
1166 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1167 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1170 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1175 if (IntvMap[
I] == 0) {
1182 if (IntvMap[
I] < NumGlobalIntvs) {
1183 if (SA->countLiveBlocks(&
Reg) >= OrigBlocks) {
1184 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1185 <<
" blocks as original.\n");
1197 MF->verify(
LIS, Indexes,
"After splitting live range around region",
1201MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1202 AllocationOrder &Order,
1203 SmallVectorImpl<Register> &NewVRegs) {
1204 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1206 unsigned NumCands = 0;
1207 BlockFrequency SpillCost = calcBlockSplitCost();
1208 BlockFrequency BestCost;
1211 bool HasCompact = calcCompactRegion(GlobalCand.front());
1219 BestCost = SpillCost;
1224 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1228 if (!HasCompact && BestCand == NoCand)
1231 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1234unsigned RAGreedy::calculateRegionSplitCostAroundReg(MCRegister PhysReg,
1235 AllocationOrder &Order,
1236 BlockFrequency &BestCost,
1238 unsigned &BestCand) {
1241 if (NumCands == IntfCache.getMaxCursors()) {
1242 unsigned WorstCount = ~0
u;
1244 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1245 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1247 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1248 if (
Count < WorstCount) {
1254 GlobalCand[Worst] = GlobalCand[NumCands];
1255 if (BestCand == NumCands)
1259 if (GlobalCand.size() <= NumCands)
1260 GlobalCand.resize(NumCands+1);
1261 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1262 Cand.reset(IntfCache, PhysReg);
1264 SpillPlacer->prepare(Cand.LiveBundles);
1265 BlockFrequency
Cost;
1266 if (!addSplitConstraints(Cand.Intf,
Cost)) {
1272 if (
Cost >= BestCost) {
1274 if (BestCand == NoCand)
1275 dbgs() <<
" worse than no bundles\n";
1277 dbgs() <<
" worse than "
1278 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1282 if (!growRegion(Cand)) {
1287 SpillPlacer->finish();
1290 if (!Cand.LiveBundles.any()) {
1295 Cost += calcGlobalSplitCost(Cand, Order);
1298 for (
int I : Cand.LiveBundles.set_bits())
1299 dbgs() <<
" EB#" <<
I;
1302 if (
Cost < BestCost) {
1303 BestCand = NumCands;
1311unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1312 AllocationOrder &Order,
1313 BlockFrequency &BestCost,
1316 unsigned BestCand = NoCand;
1317 for (MCRegister PhysReg : Order) {
1319 if (IgnoreCSR && EvictAdvisor->isUnusedCalleeSavedReg(PhysReg))
1322 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1329MCRegister RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
1330 unsigned BestCand,
bool HasCompact,
1331 SmallVectorImpl<Register> &NewVRegs) {
1332 SmallVector<unsigned, 8> UsedCands;
1334 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1338 BundleCand.assign(Bundles->getNumBundles(), NoCand);
1341 if (BestCand != NoCand) {
1342 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1343 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1345 Cand.IntvIdx = SE->openIntv();
1347 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1354 GlobalSplitCandidate &Cand = GlobalCand.front();
1355 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1356 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1358 Cand.IntvIdx = SE->openIntv();
1360 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1365 splitAroundRegion(LREdit, UsedCands);
1366 return MCRegister();
1371bool RAGreedy::trySplitAroundHintReg(MCRegister Hint,
1372 const LiveInterval &VirtReg,
1373 SmallVectorImpl<Register> &NewVRegs,
1374 AllocationOrder &Order) {
1378 if (MF->getFunction().hasOptSize())
1382 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1385 BlockFrequency
Cost = BlockFrequency(0);
1395 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
1396 const MachineInstr &
Instr = *Opnd.getParent();
1397 if (!
Instr.isCopy() || Opnd.isImplicit())
1401 const bool IsDef = Opnd.isDef();
1402 const MachineOperand &OtherOpnd =
Instr.getOperand(IsDef);
1405 if (OtherReg ==
Reg)
1408 unsigned SubReg = Opnd.getSubReg();
1409 unsigned OtherSubReg = OtherOpnd.
getSubReg();
1410 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
1414 if (Opnd.readsReg()) {
1415 SlotIndex
Index =
LIS->getInstructionIndex(Instr).getRegSlot();
1418 LaneBitmask
Mask =
TRI->getSubRegIndexLaneMask(SubReg);
1422 if (
any_of(VirtReg.
subranges(), [=](
const LiveInterval::SubRange &S) {
1423 return (S.LaneMask & Mask).any() && S.liveAt(Index);
1428 if (VirtReg.
liveAt(Index))
1433 MCRegister OtherPhysReg =
1435 MCRegister ThisHint = SubReg ?
TRI->getSubReg(Hint, SubReg) :
Hint;
1436 if (OtherPhysReg == ThisHint)
1437 Cost += MBFI->getBlockFreq(
Instr.getParent());
1443 if (
Cost == BlockFrequency(0))
1446 unsigned NumCands = 0;
1447 unsigned BestCand = NoCand;
1448 SA->analyze(&VirtReg);
1449 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1450 if (BestCand == NoCand)
1453 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1464MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1465 AllocationOrder &Order,
1466 SmallVectorImpl<Register> &NewVRegs) {
1467 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1470 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1473 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1474 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1475 SE->splitSingleBlock(BI);
1479 return MCRegister();
1482 SmallVector<unsigned, 8> IntvMap;
1483 SE->finish(&IntvMap);
1486 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1490 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1491 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1492 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1497 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1499 return MCRegister();
1512 assert(SuperRC &&
"Invalid register class");
1515 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1534 if (SubReg == 0 && MO.
isUse()) {
1543 Mask |= ~SubRegMask;
1560 auto DestSrc =
TII->isCopyInstr(*
MI);
1561 if (DestSrc && !
MI->isBundled() &&
1562 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1571 LiveAtMask |= S.LaneMask;
1576 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1586MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1587 AllocationOrder &Order,
1588 SmallVectorImpl<Register> &NewVRegs) {
1589 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
1592 bool SplitSubClass =
true;
1595 return MCRegister();
1596 SplitSubClass =
false;
1601 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1605 if (
Uses.size() <= 1)
1606 return MCRegister();
1609 <<
" individual instrs.\n");
1611 const TargetRegisterClass *SuperRC =
1612 TRI->getLargestLegalSuperClass(CurRC, *MF);
1613 unsigned SuperRCNumAllocatableRegs =
1619 for (
const SlotIndex Use :
Uses) {
1620 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1621 if (TII->isFullCopyInstr(*
MI) ||
1623 SuperRCNumAllocatableRegs ==
1634 SlotIndex SegStart = SE->enterIntvBefore(Use);
1635 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1636 SE->useIntv(SegStart, SegStop);
1639 if (LREdit.
empty()) {
1641 return MCRegister();
1644 SmallVector<unsigned, 8> IntvMap;
1645 SE->finish(&IntvMap);
1646 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1649 return MCRegister();
1661void RAGreedy::calcGapWeights(MCRegister PhysReg,
1662 SmallVectorImpl<float> &GapWeight) {
1663 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1664 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1666 const unsigned NumGaps =
Uses.size()-1;
1669 SlotIndex StartIdx =
1674 GapWeight.
assign(NumGaps, 0.0f);
1677 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1678 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1679 .checkInterference())
1690 Matrix->getLiveUnions()[
static_cast<unsigned>(
Unit)].
find(StartIdx);
1691 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1693 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1694 if (++Gap == NumGaps)
1700 const float weight = IntI.value()->weight();
1701 for (; Gap != NumGaps; ++Gap) {
1702 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1703 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1712 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1718 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1719 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1720 if (++Gap == NumGaps)
1725 for (; Gap != NumGaps; ++Gap) {
1727 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1739MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1740 AllocationOrder &Order,
1741 SmallVectorImpl<Register> &NewVRegs) {
1744 if (SA->getUseBlocks().size() != 1)
1745 return MCRegister();
1747 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1757 if (
Uses.size() <= 2)
1758 return MCRegister();
1759 const unsigned NumGaps =
Uses.size()-1;
1762 dbgs() <<
"tryLocalSplit: ";
1763 for (
const auto &Use :
Uses)
1770 SmallVector<unsigned, 8> RegMaskGaps;
1771 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1778 unsigned RE = RMS.
size();
1779 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1790 RegMaskGaps.push_back(
I);
1817 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1820 unsigned BestBefore = NumGaps;
1821 unsigned BestAfter = 0;
1824 const float blockFreq =
1825 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1826 (1.0f / MBFI->getEntryFreq().getFrequency());
1829 for (MCRegister PhysReg : Order) {
1833 calcGapWeights(PhysReg, GapWeight);
1836 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1837 for (
unsigned Gap : RegMaskGaps)
1844 unsigned SplitBefore = 0, SplitAfter = 1;
1848 float MaxGap = GapWeight[0];
1852 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1853 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1856 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1859 if (!LiveBefore && !LiveAfter) {
1867 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1870 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1879 blockFreq * (NewGaps + 1),
1880 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1888 float Diff = EstWeight - MaxGap;
1889 if (Diff > BestDiff) {
1892 BestBefore = SplitBefore;
1893 BestAfter = SplitAfter;
1900 if (++SplitBefore < SplitAfter) {
1903 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1904 MaxGap = GapWeight[SplitBefore];
1905 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1906 MaxGap = std::max(MaxGap, GapWeight[
I]);
1914 if (SplitAfter >= NumGaps) {
1920 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1925 if (BestBefore == NumGaps)
1926 return MCRegister();
1929 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1930 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1932 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1936 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1937 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1938 SE->useIntv(SegStart, SegStop);
1939 SmallVector<unsigned, 8> IntvMap;
1940 SE->finish(&IntvMap);
1941 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1945 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1946 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1947 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1948 if (NewGaps >= NumGaps) {
1950 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1951 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1952 if (IntvMap[
I] == 1) {
1960 return MCRegister();
1970MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
1971 AllocationOrder &Order,
1972 SmallVectorImpl<Register> &NewVRegs,
1975 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
1976 return MCRegister();
1979 if (
LIS->intervalIsInOneMBB(VirtReg)) {
1982 SA->analyze(&VirtReg);
1983 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
1984 if (PhysReg || !NewVRegs.
empty())
1986 return tryInstructionSplit(VirtReg, Order, NewVRegs);
1989 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
1992 SA->analyze(&VirtReg);
1997 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
1998 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
1999 if (PhysReg || !NewVRegs.
empty())
2004 return tryBlockSplit(VirtReg, Order, NewVRegs);
2027 if (PhysReg == AssignedReg)
2029 return TRI.regsOverlap(PhysReg, AssignedReg);
2040bool RAGreedy::mayRecolorAllInterferences(
2041 MCRegister PhysReg,
const LiveInterval &VirtReg,
2042 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2043 const TargetRegisterClass *CurRC =
MRI->getRegClass(VirtReg.
reg());
2045 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
2046 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2053 CutOffInfo |= CO_Interf;
2068 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2069 MRI->getRegClass(Intf->reg()) == CurRC &&
2073 FixedRegisters.
count(Intf->reg())) {
2075 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2078 RecoloringCandidates.insert(Intf);
2127MCRegister RAGreedy::tryLastChanceRecoloring(
2128 const LiveInterval &VirtReg, AllocationOrder &Order,
2130 RecoloringStack &RecolorStack,
unsigned Depth) {
2131 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2134 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2136 const ssize_t EntryStackSize = RecolorStack.size();
2140 "Last chance recoloring should really be last chance");
2146 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2147 CutOffInfo |= CO_Depth;
2152 SmallLISet RecoloringCandidates;
2160 for (MCRegister PhysReg : Order) {
2164 RecoloringCandidates.clear();
2165 CurrentNewVRegs.
clear();
2168 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2171 dbgs() <<
"Some interferences are not with virtual registers.\n");
2178 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2180 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2187 PQueue RecoloringQueue;
2188 for (
const LiveInterval *RC : RecoloringCandidates) {
2190 enqueue(RecoloringQueue, RC);
2192 "Interferences are supposed to be with allocated variables");
2195 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2204 Matrix->assign(VirtReg, PhysReg);
2213 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2214 FixedRegisters, RecolorStack,
Depth)) {
2219 if (
VRM->hasPhys(ThisVirtReg)) {
2220 Matrix->unassign(VirtReg);
2225 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2227 FixedRegisters.
erase(ThisVirtReg);
2228 return MCRegister();
2235 FixedRegisters = SaveFixedRegisters;
2236 Matrix->unassign(VirtReg);
2242 for (
Register R : CurrentNewVRegs) {
2243 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2254 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2255 const LiveInterval *LI;
2257 std::tie(LI, PhysReg) = RecolorStack[
I];
2259 if (
VRM->hasPhys(LI->
reg()))
2263 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2264 const LiveInterval *LI;
2266 std::tie(LI, PhysReg) = RecolorStack[
I];
2267 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2268 Matrix->assign(*LI, PhysReg);
2272 RecolorStack.resize(EntryStackSize);
2287bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2288 SmallVectorImpl<Register> &NewVRegs,
2290 RecoloringStack &RecolorStack,
2292 while (!RecoloringQueue.empty()) {
2293 const LiveInterval *LI =
dequeue(RecoloringQueue);
2295 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2296 RecolorStack,
Depth + 1);
2301 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2305 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2307 <<
" succeeded. Empty LI.\n");
2311 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2313 Matrix->assign(*LI, PhysReg);
2325 CutOffInfo = CO_None;
2326 LLVMContext &Ctx = MF->getFunction().getContext();
2328 RecoloringStack RecolorStack;
2330 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2331 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2332 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2333 if (CutOffEncountered == CO_Depth)
2334 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2335 "reached. Use -fexhaustive-register-search to skip "
2337 else if (CutOffEncountered == CO_Interf)
2338 Ctx.emitError(
"register allocation failed: maximum interference for "
2339 "recoloring reached. Use -fexhaustive-register-search "
2341 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2342 Ctx.emitError(
"register allocation failed: maximum interference and "
2343 "depth for recoloring reached. Use "
2344 "-fexhaustive-register-search to skip cutoffs");
2360 if (
MI->isMetaInstruction())
2365 auto [Reads, Writes] =
MI->readsWritesVirtualRegister(LI.
reg());
2366 auto MBBFreq = SpillPlacer->getBlockFrequency(
MI->getParent()->getNumber());
2367 SpillCost += (Reads + Writes) * MBBFreq.getFrequency();
2379MCRegister RAGreedy::tryAssignCSRFirstTime(
2380 const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg,
2381 uint8_t &CostPerUseLimit, SmallVectorImpl<Register> &NewVRegs) {
2385 SA->analyze(&VirtReg);
2386 if (calcSpillCost(VirtReg) >= CSRCost)
2391 CostPerUseLimit = 1;
2392 return MCRegister();
2394 if (ExtraInfo->getStage(VirtReg) <
RS_Split) {
2397 SA->analyze(&VirtReg);
2398 unsigned NumCands = 0;
2399 BlockFrequency BestCost = CSRCost;
2400 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2402 if (BestCand == NoCand)
2407 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2408 return MCRegister();
2415 SetOfBrokenHints.remove(&LI);
2418void RAGreedy::initializeCSRCost() {
2428 if (!CSRCost.getFrequency())
2432 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2438 if (ActualEntry < FixedEntry) {
2440 }
else if (ActualEntry <= UINT32_MAX) {
2442 CSRCost /= BranchProbability(FixedEntry, ActualEntry);
2446 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2449 uint64_t EntryFreq = MBFI->getEntryFreq().getFrequency();
2450 CSRCost = BlockFrequency(
TRI->getCSRFirstUseCost() * EntryFreq);
2461void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2462 const TargetRegisterClass *RC =
MRI->getRegClass(
Reg);
2464 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2465 const MachineInstr &
Instr = *Opnd.getParent();
2466 if (!
Instr.isCopy() || Opnd.isImplicit())
2470 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2472 if (OtherReg ==
Reg)
2474 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2475 unsigned SubReg = Opnd.getSubReg();
2478 MCRegister OtherPhysReg;
2481 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2483 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, SubReg, RC);
2485 OtherPhysReg = OtherReg;
2487 OtherPhysReg =
VRM->getPhys(OtherReg);
2491 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
2497 Out.push_back(HintInfo(MBFI->getBlockFreq(
Instr.getParent()), OtherReg,
2506BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2507 MCRegister PhysReg) {
2508 BlockFrequency
Cost = BlockFrequency(0);
2509 for (
const HintInfo &Info :
List) {
2510 if (
Info.PhysReg != PhysReg)
2524void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2530 MCRegister PhysReg =
VRM->getPhys(
Reg);
2533 SmallSet<Register, 4> Visited = {
Reg};
2542 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2547 "We have an unallocated variable which should have been handled");
2553 LiveInterval &LI =
LIS->getInterval(
Reg);
2556 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2557 Matrix->checkInterference(LI, PhysReg)))
2561 <<
") is recolorable.\n");
2565 collectHintInfo(
Reg, Info);
2568 if (CurrPhys != PhysReg) {
2570 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2571 BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
2575 if (OldCopiesCost < NewCopiesCost) {
2585 Matrix->assign(LI, PhysReg);
2589 for (
const HintInfo &HI : Info) {
2591 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2594 }
while (!RecoloringCandidates.
empty());
2633void RAGreedy::tryHintsRecoloring() {
2634 for (
const LiveInterval *LI : SetOfBrokenHints) {
2636 "Recoloring is possible only for virtual registers");
2639 if (!
VRM->hasPhys(LI->
reg()))
2641 tryHintRecoloring(*LI);
2645MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2646 SmallVectorImpl<Register> &NewVRegs,
2648 RecoloringStack &RecolorStack,
2650 uint8_t CostPerUseLimit = uint8_t(~0u);
2654 if (MCRegister PhysReg =
2655 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2659 if (CSRCost.getFrequency() &&
2660 EvictAdvisor->isUnusedCalleeSavedReg(PhysReg) && NewVRegs.
empty()) {
2661 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2662 CostPerUseLimit, NewVRegs);
2663 if (CSRReg || !NewVRegs.
empty())
2671 if (!NewVRegs.
empty())
2672 return MCRegister();
2676 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2682 if (MCRegister PhysReg =
2683 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2691 if (Hint && Hint != PhysReg)
2692 SetOfBrokenHints.insert(&VirtReg);
2697 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2703 ExtraInfo->setStage(VirtReg,
RS_Split);
2706 return MCRegister();
2711 unsigned NewVRegSizeBefore = NewVRegs.
size();
2712 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2713 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2720 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2721 RecolorStack,
Depth);
2735 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2737 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2740 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2744 return MCRegister();
2747void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2748 using namespace ore;
2750 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2751 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2754 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2755 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2756 <<
" total folded spills cost ";
2759 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2760 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2762 if (FoldedReloads) {
2763 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2764 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2765 <<
" total folded reloads cost ";
2767 if (ZeroCostFoldedReloads)
2768 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2769 <<
" zero cost folded reloads ";
2771 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2772 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2776RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2777 RAGreedyStats
Stats;
2778 const MachineFrameInfo &MFI = MF->getFrameInfo();
2781 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2783 A->getPseudoValue())->getFrameIndex());
2785 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2786 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2787 MI.getOpcode() == TargetOpcode::STACKMAP ||
2788 MI.getOpcode() == TargetOpcode::STATEPOINT;
2790 for (MachineInstr &
MI :
MBB) {
2791 auto DestSrc = TII->isCopyInstr(
MI);
2793 const MachineOperand &Dest = *DestSrc->Destination;
2794 const MachineOperand &Src = *DestSrc->Source;
2800 SrcReg =
VRM->getPhys(SrcReg);
2801 if (SrcReg && Src.getSubReg())
2802 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2805 DestReg =
VRM->getPhys(DestReg);
2809 if (SrcReg != DestReg)
2815 SmallVector<const MachineMemOperand *, 2>
Accesses;
2824 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2826 if (!isPatchpointInstr(
MI)) {
2831 std::pair<unsigned, unsigned> NonZeroCostRange =
2832 TII->getPatchpointUnfoldableRange(
MI);
2833 SmallSet<unsigned, 16> FoldedReloads;
2834 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2835 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2836 MachineOperand &MO =
MI.getOperand(Idx);
2839 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2845 for (
unsigned Slot : FoldedReloads)
2846 ZeroCostFoldedReloads.
erase(Slot);
2847 Stats.FoldedReloads += FoldedReloads.size();
2848 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2852 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2859 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2861 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2863 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2868RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2869 RAGreedyStats
Stats;
2872 for (MachineLoop *SubLoop : *L)
2873 Stats.add(reportStats(SubLoop));
2875 for (MachineBasicBlock *
MBB :
L->getBlocks())
2877 if (Loops->getLoopFor(
MBB) == L)
2880 if (!
Stats.isEmpty()) {
2881 using namespace ore;
2884 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
2885 L->getStartLoc(),
L->getHeader());
2887 R <<
"generated in loop";
2894void RAGreedy::reportStats() {
2897 RAGreedyStats
Stats;
2898 for (MachineLoop *L : *Loops)
2899 Stats.add(reportStats(L));
2901 for (MachineBasicBlock &
MBB : *MF)
2902 if (!Loops->getLoopFor(&
MBB))
2904 if (!
Stats.isEmpty()) {
2905 using namespace ore;
2909 if (
auto *SP = MF->getFunction().getSubprogram())
2911 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
2914 R <<
"generated in function";
2920bool RAGreedy::hasVirtRegAlloc() {
2921 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
2923 if (
MRI->reg_nodbg_empty(
Reg))
2933 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
2934 <<
"********** Function: " << mf.
getName() <<
'\n');
2940 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
2946 if (!hasVirtRegAlloc())
2951 Indexes->packIndexes();
2953 initializeCSRCost();
2955 RegCosts =
TRI->getRegisterCosts(*MF);
2956 RegClassPriorityTrumpsGlobalness =
2959 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
2963 :
TRI->reverseLocalAssignment();
2965 ExtraInfo.emplace();
2967 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
2968 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
2970 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
2974 VRAI->calculateSpillWeightsAndHints();
2981 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
2982 GlobalCand.resize(32);
2983 SetOfBrokenHints.clear();
2986 tryHintsRecoloring();
2989 MF->verify(
LIS, Indexes,
"Before post optimization", &
errs());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< 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)
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)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName) const
PreservedAnalyses run(MachineFunction &F, MachineFunctionAnalysisManager &AM)
bool isHint(Register Reg) const
Return true if Reg is a preferred physical register.
ArrayRef< MCPhysReg > getOrder() const
Get the allocation order without reordered hints.
static AllocationOrder create(Register VirtReg, const VirtRegMap &VRM, const RegisterClassInfo &RegClassInfo, const LiveRegMatrix *Matrix)
Create a new AllocationOrder for VirtReg.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool test(unsigned Idx) const
static BlockFrequency max()
Returns the maximum possible frequency, the saturation value.
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
Cursor - The primary query interface for the block interference cache.
SlotIndex first()
first - Return the starting index of the first interfering range in the current block.
SlotIndex last()
last - Return the ending index of the last interfering range in the current block.
bool hasInterference()
hasInterference - Return true if the current block has any interference.
void moveToBlock(unsigned MBBNum)
moveTo - Move cursor to basic block MBBNum.
This is an important class for using LLVM in a threaded context.
Query interferences between a single live virtual register and a live interval union.
const SmallVectorImpl< const LiveInterval * > & interferingVRegs(unsigned MaxInterferingRegs=std::numeric_limits< unsigned >::max())
LiveSegments::iterator SegmentIter
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool isSpillable() const
isSpillable - Can this interval be spilled?
bool hasSubRanges() const
Returns true if subregister liveness information is available.
LLVM_ABI unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
iterator_range< subrange_iterator > subranges()
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
LiveInterval & getInterval(Register Reg)
Register get(unsigned idx) const
ArrayRef< Register > regs() const
Segments::const_iterator const_iterator
bool liveAt(SlotIndex index) const
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
SlotIndex endIndex() const
endNumber - return the maximum point of the range of the whole, exclusive.
LLVM_ABI iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
@ IK_VirtReg
Virtual register interference.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static constexpr unsigned NoRegister
constexpr unsigned id() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
An RAII based helper class to modify MachineFunctionProperties when running pass.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Representation of each machine instruction.
bool isImplicitDef() const
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static 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
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 ...
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.
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.