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);
764 SplitConstraints.resize(UseBlocks.
size());
766 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
787 if (Intf.
first() <= Indexes->getMBBStartIdx(BI.
MBB)) {
801 SA->getFirstSplitPoint(BC.
Number)))
807 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
820 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
826 SpillPlacer->addConstraints(SplitConstraints);
827 return SpillPlacer->scanActiveBundles();
832bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
833 ArrayRef<unsigned> Blocks) {
834 const unsigned GroupSize = 8;
835 SpillPlacement::BlockConstraint BCS[GroupSize];
836 unsigned TBS[GroupSize];
837 unsigned B = 0,
T = 0;
839 for (
unsigned Number : Blocks) {
843 assert(
T < GroupSize &&
"Array overflow");
845 if (++
T == GroupSize) {
852 assert(
B < GroupSize &&
"Array overflow");
856 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
858 if (FirstNonDebugInstr !=
MBB->
end() &&
860 SA->getFirstSplitPoint(
Number)))
866 SlotIndex InsertIdx = InsertPt ==
MBB->
end()
867 ? Indexes->getMBBEndIdx(
MBB)
868 :
LIS->getInstructionIndex(*InsertPt);
869 if (Intf.
first() <= Indexes->getMBBStartIdx(
MBB) ||
876 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
881 if (++
B == GroupSize) {
882 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
887 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
892bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
894 BitVector Todo = SA->getThroughBlocks();
895 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
896 unsigned AddedTo = 0;
898 unsigned Visited = 0;
903 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
905 for (
unsigned Bundle : NewBundles) {
907 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
909 if (Blocks.
size() >= Budget)
911 Budget -= Blocks.
size();
912 for (
unsigned Block : Blocks) {
924 if (ActiveBlocks.
size() == AddedTo)
929 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
931 if (!addThroughConstraints(Cand.Intf, NewBlocks))
939 bool PrefSpill =
true;
940 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
945 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
946 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
947 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
948 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
953 SpillPlacer->addPrefSpill(NewBlocks,
true);
955 AddedTo = ActiveBlocks.
size();
958 SpillPlacer->iterate();
971bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
973 if (!SA->getNumThroughBlocks())
983 SpillPlacer->prepare(Cand.LiveBundles);
987 if (!addSplitConstraints(Cand.Intf,
Cost)) {
992 if (!growRegion(Cand)) {
997 SpillPlacer->finish();
999 if (!Cand.LiveBundles.any()) {
1005 for (
int I : Cand.LiveBundles.set_bits())
1006 dbgs() <<
" EB#" <<
I;
1014BlockFrequency RAGreedy::calcBlockSplitCost() {
1015 BlockFrequency
Cost = BlockFrequency(0);
1017 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1020 Cost += SpillPlacer->getBlockFrequency(
Number);
1024 Cost += SpillPlacer->getBlockFrequency(
Number);
1033BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1034 const AllocationOrder &Order) {
1035 BlockFrequency GlobalCost = BlockFrequency(0);
1036 const BitVector &LiveBundles = Cand.LiveBundles;
1038 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1039 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1040 SpillPlacement::BlockConstraint &BC = SplitConstraints[
I];
1041 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1042 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1045 Cand.Intf.moveToBlock(BC.
Number);
1052 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1055 for (
unsigned Number : Cand.ActiveBlocks) {
1056 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1057 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1058 if (!RegIn && !RegOut)
1060 if (RegIn && RegOut) {
1062 Cand.Intf.moveToBlock(
Number);
1063 if (Cand.Intf.hasInterference()) {
1064 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1065 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1070 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1087void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1088 ArrayRef<unsigned> UsedCands) {
1091 const unsigned NumGlobalIntvs = LREdit.
size();
1094 assert(NumGlobalIntvs &&
"No global intervals configured");
1104 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1106 unsigned IntvIn = 0, IntvOut = 0;
1107 SlotIndex IntfIn, IntfOut;
1109 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1110 if (CandIn != NoCand) {
1111 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1112 IntvIn = Cand.IntvIdx;
1113 Cand.Intf.moveToBlock(
Number);
1114 IntfIn = Cand.Intf.first();
1118 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1119 if (CandOut != NoCand) {
1120 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1121 IntvOut = Cand.IntvIdx;
1122 Cand.Intf.moveToBlock(
Number);
1123 IntfOut = Cand.Intf.last();
1128 if (!IntvIn && !IntvOut) {
1130 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1131 SE->splitSingleBlock(BI);
1135 if (IntvIn && IntvOut)
1136 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1138 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1140 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1146 BitVector Todo = SA->getThroughBlocks();
1147 for (
unsigned UsedCand : UsedCands) {
1148 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1149 for (
unsigned Number : Blocks) {
1154 unsigned IntvIn = 0, IntvOut = 0;
1155 SlotIndex IntfIn, IntfOut;
1157 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1158 if (CandIn != NoCand) {
1159 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1160 IntvIn = Cand.IntvIdx;
1161 Cand.Intf.moveToBlock(
Number);
1162 IntfIn = Cand.Intf.first();
1165 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1166 if (CandOut != NoCand) {
1167 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1168 IntvOut = Cand.IntvIdx;
1169 Cand.Intf.moveToBlock(
Number);
1170 IntfOut = Cand.Intf.last();
1172 if (!IntvIn && !IntvOut)
1174 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1180 SmallVector<unsigned, 8> IntvMap;
1181 SE->finish(&IntvMap);
1182 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1184 unsigned OrigBlocks = SA->getNumLiveBlocks();
1191 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1192 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1195 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1200 if (IntvMap[
I] == 0) {
1207 if (IntvMap[
I] < NumGlobalIntvs) {
1208 if (SA->countLiveBlocks(&
Reg) >= OrigBlocks) {
1209 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1210 <<
" blocks as original.\n");
1222 MF->verify(
LIS, Indexes,
"After splitting live range around region",
1226MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1227 AllocationOrder &Order,
1228 SmallVectorImpl<Register> &NewVRegs) {
1229 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1231 unsigned NumCands = 0;
1232 BlockFrequency SpillCost = calcBlockSplitCost();
1233 BlockFrequency BestCost;
1236 bool HasCompact = calcCompactRegion(GlobalCand.front());
1244 BestCost = SpillCost;
1249 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1253 if (!HasCompact && BestCand == NoCand)
1256 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1259unsigned RAGreedy::calculateRegionSplitCostAroundReg(MCRegister PhysReg,
1260 AllocationOrder &Order,
1261 BlockFrequency &BestCost,
1263 unsigned &BestCand) {
1266 if (NumCands == IntfCache.getMaxCursors()) {
1267 unsigned WorstCount = ~0
u;
1269 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1270 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1272 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1273 if (
Count < WorstCount) {
1279 GlobalCand[Worst] = GlobalCand[NumCands];
1280 if (BestCand == NumCands)
1284 if (GlobalCand.size() <= NumCands)
1285 GlobalCand.resize(NumCands+1);
1286 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1287 Cand.reset(IntfCache, PhysReg);
1289 SpillPlacer->prepare(Cand.LiveBundles);
1290 BlockFrequency
Cost;
1291 if (!addSplitConstraints(Cand.Intf,
Cost)) {
1297 if (
Cost >= BestCost) {
1299 if (BestCand == NoCand)
1300 dbgs() <<
" worse than no bundles\n";
1302 dbgs() <<
" worse than "
1303 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1307 if (!growRegion(Cand)) {
1312 SpillPlacer->finish();
1315 if (!Cand.LiveBundles.any()) {
1320 Cost += calcGlobalSplitCost(Cand, Order);
1323 for (
int I : Cand.LiveBundles.set_bits())
1324 dbgs() <<
" EB#" <<
I;
1327 if (
Cost < BestCost) {
1328 BestCand = NumCands;
1336unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1337 AllocationOrder &Order,
1338 BlockFrequency &BestCost,
1341 unsigned BestCand = NoCand;
1342 for (MCRegister PhysReg : Order) {
1344 if (IgnoreCSR && EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, PhysReg))
1347 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1354MCRegister RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
1355 unsigned BestCand,
bool HasCompact,
1356 SmallVectorImpl<Register> &NewVRegs) {
1357 SmallVector<unsigned, 8> UsedCands;
1359 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1363 BundleCand.assign(Bundles->getNumBundles(), NoCand);
1366 if (BestCand != NoCand) {
1367 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1368 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1370 Cand.IntvIdx = SE->openIntv();
1372 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1379 GlobalSplitCandidate &Cand = GlobalCand.front();
1380 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1381 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1383 Cand.IntvIdx = SE->openIntv();
1385 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1390 splitAroundRegion(LREdit, UsedCands);
1391 return MCRegister();
1396bool RAGreedy::trySplitAroundHintReg(MCRegister Hint,
1397 const LiveInterval &VirtReg,
1398 SmallVectorImpl<Register> &NewVRegs,
1399 AllocationOrder &Order) {
1403 if (MF->getFunction().hasOptSize())
1407 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1410 BlockFrequency
Cost = BlockFrequency(0);
1420 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
1421 const MachineInstr &
Instr = *Opnd.getParent();
1422 if (!
Instr.isCopy() || Opnd.isImplicit())
1426 const bool IsDef = Opnd.isDef();
1427 const MachineOperand &OtherOpnd =
Instr.getOperand(IsDef);
1430 if (OtherReg ==
Reg)
1433 unsigned SubReg = Opnd.getSubReg();
1434 unsigned OtherSubReg = OtherOpnd.
getSubReg();
1435 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
1439 if (Opnd.readsReg()) {
1440 SlotIndex
Index =
LIS->getInstructionIndex(Instr).getRegSlot();
1443 LaneBitmask
Mask =
TRI->getSubRegIndexLaneMask(SubReg);
1447 if (
any_of(VirtReg.
subranges(), [=](
const LiveInterval::SubRange &S) {
1448 return (S.LaneMask & Mask).any() && S.liveAt(Index);
1453 if (VirtReg.
liveAt(Index))
1458 MCRegister OtherPhysReg =
1460 MCRegister ThisHint = SubReg ?
TRI->getSubReg(Hint, SubReg) :
Hint;
1461 if (OtherPhysReg == ThisHint)
1462 Cost += MBFI->getBlockFreq(
Instr.getParent());
1468 if (
Cost == BlockFrequency(0))
1471 unsigned NumCands = 0;
1472 unsigned BestCand = NoCand;
1473 SA->analyze(&VirtReg);
1474 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1475 if (BestCand == NoCand)
1478 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1489MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1490 AllocationOrder &Order,
1491 SmallVectorImpl<Register> &NewVRegs) {
1492 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1495 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1498 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1499 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1500 SE->splitSingleBlock(BI);
1504 return MCRegister();
1507 SmallVector<unsigned, 8> IntvMap;
1508 SE->finish(&IntvMap);
1511 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1515 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1516 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1517 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1522 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1524 return MCRegister();
1537 assert(SuperRC &&
"Invalid register class");
1540 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1555 for (
auto [
MI, OpIdx] :
Ops) {
1559 if (SubReg == 0 && MO.
isUse()) {
1568 Mask |= ~SubRegMask;
1585 auto DestSrc =
TII->isCopyInstr(*
MI);
1586 if (DestSrc && !
MI->isBundled() &&
1587 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1596 LiveAtMask |= S.LaneMask;
1601 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1611MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1612 AllocationOrder &Order,
1613 SmallVectorImpl<Register> &NewVRegs) {
1617 bool SplitSubClass =
true;
1620 return MCRegister();
1621 SplitSubClass =
false;
1626 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1630 if (
Uses.size() <= 1)
1631 return MCRegister();
1634 <<
" individual instrs.\n");
1637 TRI->getLargestLegalSuperClass(CurRC, *MF);
1638 unsigned SuperRCNumAllocatableRegs =
1644 for (
const SlotIndex Use :
Uses) {
1645 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1646 if (TII->isFullCopyInstr(*
MI) ||
1648 SuperRCNumAllocatableRegs ==
1659 SlotIndex SegStart = SE->enterIntvBefore(Use);
1660 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1661 SE->useIntv(SegStart, SegStop);
1664 if (LREdit.
empty()) {
1666 return MCRegister();
1669 SmallVector<unsigned, 8> IntvMap;
1670 SE->finish(&IntvMap);
1671 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1674 return MCRegister();
1686void RAGreedy::calcGapWeights(MCRegister PhysReg,
1687 SmallVectorImpl<float> &GapWeight) {
1688 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1689 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1691 const unsigned NumGaps =
Uses.size()-1;
1694 SlotIndex StartIdx =
1699 GapWeight.
assign(NumGaps, 0.0f);
1702 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1703 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1704 .checkInterference())
1715 Matrix->getLiveUnions()[
static_cast<unsigned>(
Unit)].
find(StartIdx);
1716 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1718 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1719 if (++Gap == NumGaps)
1725 const float weight = IntI.value()->weight();
1726 for (; Gap != NumGaps; ++Gap) {
1727 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1728 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1737 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1743 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1744 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1745 if (++Gap == NumGaps)
1750 for (; Gap != NumGaps; ++Gap) {
1752 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1764MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1765 AllocationOrder &Order,
1766 SmallVectorImpl<Register> &NewVRegs) {
1769 if (SA->getUseBlocks().size() != 1)
1770 return MCRegister();
1772 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1782 if (
Uses.size() <= 2)
1783 return MCRegister();
1784 const unsigned NumGaps =
Uses.size()-1;
1787 dbgs() <<
"tryLocalSplit: ";
1788 for (
const auto &Use :
Uses)
1795 SmallVector<unsigned, 8> RegMaskGaps;
1796 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1803 unsigned RE = RMS.
size();
1804 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1815 RegMaskGaps.push_back(
I);
1842 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1845 unsigned BestBefore = NumGaps;
1846 unsigned BestAfter = 0;
1849 const float blockFreq =
1850 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1851 (1.0f / MBFI->getEntryFreq().getFrequency());
1854 for (MCRegister PhysReg : Order) {
1858 calcGapWeights(PhysReg, GapWeight);
1861 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1862 for (
unsigned Gap : RegMaskGaps)
1869 unsigned SplitBefore = 0, SplitAfter = 1;
1873 float MaxGap = GapWeight[0];
1877 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1878 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1881 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1884 if (!LiveBefore && !LiveAfter) {
1892 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1895 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1904 blockFreq * (NewGaps + 1),
1905 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1913 float Diff = EstWeight - MaxGap;
1914 if (Diff > BestDiff) {
1917 BestBefore = SplitBefore;
1918 BestAfter = SplitAfter;
1925 if (++SplitBefore < SplitAfter) {
1928 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1929 MaxGap = GapWeight[SplitBefore];
1930 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1931 MaxGap = std::max(MaxGap, GapWeight[
I]);
1939 if (SplitAfter >= NumGaps) {
1945 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1950 if (BestBefore == NumGaps)
1951 return MCRegister();
1954 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1955 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1957 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1961 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1962 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1963 SE->useIntv(SegStart, SegStop);
1964 SmallVector<unsigned, 8> IntvMap;
1965 SE->finish(&IntvMap);
1966 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1970 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1971 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1972 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1973 if (NewGaps >= NumGaps) {
1975 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1976 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1977 if (IntvMap[
I] == 1) {
1985 return MCRegister();
1995MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
1996 AllocationOrder &Order,
1997 SmallVectorImpl<Register> &NewVRegs,
2000 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
2001 return MCRegister();
2004 if (
LIS->intervalIsInOneMBB(VirtReg)) {
2007 SA->analyze(&VirtReg);
2008 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
2009 if (PhysReg || !NewVRegs.
empty())
2011 return tryInstructionSplit(VirtReg, Order, NewVRegs);
2014 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
2017 SA->analyze(&VirtReg);
2022 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
2023 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
2024 if (PhysReg || !NewVRegs.
empty())
2029 return tryBlockSplit(VirtReg, Order, NewVRegs);
2052 if (PhysReg == AssignedReg)
2054 return TRI.regsOverlap(PhysReg, AssignedReg);
2065bool RAGreedy::mayRecolorAllInterferences(
2066 MCRegister PhysReg,
const LiveInterval &VirtReg,
2067 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2070 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
2071 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2078 CutOffInfo |= CO_Interf;
2093 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2094 MRI->getRegClass(Intf->reg()) == CurRC &&
2098 FixedRegisters.
count(Intf->reg())) {
2100 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2103 RecoloringCandidates.insert(Intf);
2152MCRegister RAGreedy::tryLastChanceRecoloring(
2153 const LiveInterval &VirtReg, AllocationOrder &Order,
2155 RecoloringStack &RecolorStack,
unsigned Depth) {
2156 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2159 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2161 const ssize_t EntryStackSize = RecolorStack.size();
2165 "Last chance recoloring should really be last chance");
2171 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2172 CutOffInfo |= CO_Depth;
2177 SmallLISet RecoloringCandidates;
2185 for (MCRegister PhysReg : Order) {
2189 RecoloringCandidates.clear();
2190 CurrentNewVRegs.
clear();
2193 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2196 dbgs() <<
"Some interferences are not with virtual registers.\n");
2203 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2205 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2212 PQueue RecoloringQueue;
2213 for (
const LiveInterval *RC : RecoloringCandidates) {
2215 enqueue(RecoloringQueue, RC);
2217 "Interferences are supposed to be with allocated variables");
2220 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2229 Matrix->assign(VirtReg, PhysReg);
2238 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2239 FixedRegisters, RecolorStack,
Depth)) {
2244 if (
VRM->hasPhys(ThisVirtReg)) {
2245 Matrix->unassign(VirtReg);
2250 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2252 FixedRegisters.
erase(ThisVirtReg);
2253 return MCRegister();
2260 FixedRegisters = SaveFixedRegisters;
2261 Matrix->unassign(VirtReg);
2267 for (
Register R : CurrentNewVRegs) {
2268 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2279 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2280 const LiveInterval *LI;
2282 std::tie(LI, PhysReg) = RecolorStack[
I];
2284 if (
VRM->hasPhys(LI->
reg()))
2288 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2289 const LiveInterval *LI;
2291 std::tie(LI, PhysReg) = RecolorStack[
I];
2292 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2293 Matrix->assign(*LI, PhysReg);
2297 RecolorStack.resize(EntryStackSize);
2312bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2313 SmallVectorImpl<Register> &NewVRegs,
2315 RecoloringStack &RecolorStack,
2317 while (!RecoloringQueue.empty()) {
2318 const LiveInterval *LI =
dequeue(RecoloringQueue);
2320 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2321 RecolorStack,
Depth + 1);
2326 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2330 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2332 <<
" succeeded. Empty LI.\n");
2336 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2338 Matrix->assign(*LI, PhysReg);
2350 CutOffInfo = CO_None;
2351 LLVMContext &Ctx = MF->getFunction().getContext();
2353 RecoloringStack RecolorStack;
2355 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2356 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2357 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2358 if (CutOffEncountered == CO_Depth)
2359 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2360 "reached. Use -fexhaustive-register-search to skip "
2362 else if (CutOffEncountered == CO_Interf)
2363 Ctx.emitError(
"register allocation failed: maximum interference for "
2364 "recoloring reached. Use -fexhaustive-register-search "
2366 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2367 Ctx.emitError(
"register allocation failed: maximum interference and "
2368 "depth for recoloring reached. Use "
2369 "-fexhaustive-register-search to skip cutoffs");
2377 uint64_t SpillCost = 0;
2385 if (
MI->isMetaInstruction())
2390 auto [Reads, Writes] =
MI->readsWritesVirtualRegister(LI.
reg());
2391 auto MBBFreq = SpillPlacer->getBlockFrequency(
MI->getParent()->getNumber());
2392 SpillCost += (Reads + Writes) * MBBFreq.getFrequency();
2398BlockFrequency RAGreedy::calcRematCost(
const LiveInterval &VirtReg,
2399 AllocationOrder &Order)
const {
2411 MachineInstr *
DefMI =
LIS->getInstructionFromIndex(OnlyVNI->
def);
2412 if (!
DefMI || !TII->isReMaterializable(*
DefMI) ||
2419 if (!
Matrix->checkRegMaskInterference(VirtReg))
2422 BlockFrequency RematCost;
2423 bool HasUse =
false;
2424 for (MachineInstr &
UseMI :
MRI->use_nodbg_instructions(VirtReg.
reg())) {
2425 if (!
UseMI.readsVirtualRegister(VirtReg.
reg()))
2431 SlotIndex UseIdx =
LIS->getInstructionIndex(
UseMI).getRegSlot(
true);
2438 bool HasNoFirstCSRReg =
false;
2439 for (MCRegister RematPhysReg : Order) {
2440 if (EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, RematPhysReg))
2442 if (!
Matrix->checkInterference(PrevIdx, UseIdx, RematPhysReg)) {
2443 HasNoFirstCSRReg =
true;
2447 if (!HasNoFirstCSRReg)
2450 RematCost += SpillPlacer->getBlockFrequency(
UseMI.getParent()->getNumber());
2463MCRegister RAGreedy::tryAssignCSRFirstTime(
2464 const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg,
2465 uint8_t &CostPerUseLimit, SmallVectorImpl<Register> &NewVRegs) {
2471 SA->analyze(&VirtReg);
2472 if (calcSpillCost(VirtReg) >= CSRCost &&
2473 calcRematCost(VirtReg, Order) >= CSRCost) {
2479 CostPerUseLimit = 1;
2480 return MCRegister();
2485 SA->analyze(&VirtReg);
2486 unsigned NumCands = 0;
2487 BlockFrequency BestCost = CSRCost;
2488 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2490 if (BestCand == NoCand) {
2491 if (calcRematCost(VirtReg, Order) < CSRCost) {
2492 CostPerUseLimit = 1;
2493 return MCRegister();
2500 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2501 return MCRegister();
2503 if (calcRematCost(VirtReg, Order) < CSRCost) {
2504 CostPerUseLimit = 1;
2505 return MCRegister();
2512 SetOfBrokenHints.remove(&LI);
2515void RAGreedy::initializeCSRCost() {
2525 if (!CSRCost.getFrequency())
2529 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2535 if (ActualEntry < FixedEntry) {
2537 }
else if (ActualEntry <= UINT32_MAX) {
2539 CSRCost /= BranchProbability(FixedEntry, ActualEntry);
2543 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2546 uint64_t EntryFreq = MBFI->getEntryFreq().getFrequency();
2547 CSRCost = BlockFrequency(
TRI->getCSRFirstUseCost(*MF) * EntryFreq);
2548 unsigned Scale =
TRI->getCSRCostScale(*MF);
2554 CSRCost *= BranchProbability(Scale, 100);
2556 CSRCost /= BranchProbability(100, Scale);
2563void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2566 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2567 const MachineInstr &
Instr = *Opnd.getParent();
2568 if (!
Instr.isCopy() || Opnd.isImplicit())
2572 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2574 if (OtherReg ==
Reg)
2576 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2577 unsigned SubReg = Opnd.getSubReg();
2580 MCRegister OtherPhysReg;
2583 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2585 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, SubReg, RC);
2587 OtherPhysReg = OtherReg;
2589 OtherPhysReg =
VRM->getPhys(OtherReg);
2593 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
2599 Out.push_back(HintInfo(
Instr.getParent(), OtherReg, OtherPhysReg));
2607BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2608 MCRegister PhysReg) {
2609 BlockFrequency
Cost = BlockFrequency(0);
2610 for (
const HintInfo &Info :
List) {
2611 if (
Info.PhysReg != PhysReg)
2612 Cost += MBFI->getBlockFreq(
Info.MBB);
2625void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg) {
2631 MCRegister PhysReg =
VRM->getPhys(
Reg);
2634 SmallDenseSet<Register, 8> Visited = {
Reg};
2643 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2648 "We have an unallocated variable which should have been handled");
2654 LiveInterval &LI =
LIS->getInterval(
Reg);
2657 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2658 Matrix->checkInterference(LI, PhysReg)))
2662 <<
") is recolorable.\n");
2666 collectHintInfo(
Reg, Info);
2669 if (CurrPhys != PhysReg) {
2671 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2672 BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
2676 if (OldCopiesCost < NewCopiesCost) {
2686 Matrix->assign(LI, PhysReg);
2690 for (
const HintInfo &HI : Info) {
2692 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2695 }
while (!RecoloringCandidates.
empty());
2734void RAGreedy::tryHintsRecoloring() {
2735 for (
const LiveInterval *LI : SetOfBrokenHints) {
2737 "Recoloring is possible only for virtual registers");
2740 if (!
VRM->hasPhys(LI->
reg()))
2742 tryHintRecoloring(*LI);
2746MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2747 SmallVectorImpl<Register> &NewVRegs,
2749 RecoloringStack &RecolorStack,
2751 uint8_t CostPerUseLimit = uint8_t(~0u);
2755 if (MCRegister PhysReg =
2756 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2760 if (CSRCost.getFrequency() &&
2761 EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, PhysReg) &&
2763 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2764 CostPerUseLimit, NewVRegs);
2765 if (CSRReg || !NewVRegs.
empty())
2773 if (!NewVRegs.
empty())
2774 return MCRegister();
2778 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2784 if (MCRegister PhysReg =
2785 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2793 if (Hint && Hint != PhysReg)
2794 SetOfBrokenHints.insert(&VirtReg);
2799 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2805 ExtraInfo->setStage(VirtReg,
RS_Split);
2808 return MCRegister();
2813 unsigned NewVRegSizeBefore = NewVRegs.
size();
2814 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2815 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2822 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2823 RecolorStack,
Depth);
2837 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2839 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2842 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2846 return MCRegister();
2849void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2850 using namespace ore;
2852 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2853 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2856 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2857 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2858 <<
" total folded spills cost ";
2861 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2862 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2864 if (FoldedReloads) {
2865 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2866 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2867 <<
" total folded reloads cost ";
2869 if (ZeroCostFoldedReloads)
2870 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2871 <<
" zero cost folded reloads ";
2873 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2874 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2878RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2879 RAGreedyStats
Stats;
2880 const MachineFrameInfo &MFI = MF->getFrameInfo();
2883 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2885 A->getPseudoValue())->getFrameIndex());
2887 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2888 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2889 MI.getOpcode() == TargetOpcode::STACKMAP ||
2890 MI.getOpcode() == TargetOpcode::STATEPOINT;
2892 for (MachineInstr &
MI :
MBB) {
2893 auto DestSrc = TII->isCopyInstr(
MI);
2895 const MachineOperand &Dest = *DestSrc->Destination;
2896 const MachineOperand &Src = *DestSrc->Source;
2902 SrcReg =
VRM->getPhys(SrcReg);
2903 if (SrcReg && Src.getSubReg())
2904 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2907 DestReg =
VRM->getPhys(DestReg);
2911 if (SrcReg != DestReg)
2917 SmallVector<const MachineMemOperand *, 2>
Accesses;
2926 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2928 if (!isPatchpointInstr(
MI)) {
2933 std::pair<unsigned, unsigned> NonZeroCostRange =
2934 TII->getPatchpointUnfoldableRange(
MI);
2935 SmallSet<unsigned, 16> FoldedReloads;
2936 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2937 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2938 MachineOperand &MO =
MI.getOperand(Idx);
2941 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2947 for (
unsigned Slot : FoldedReloads)
2948 ZeroCostFoldedReloads.
erase(Slot);
2949 Stats.FoldedReloads += FoldedReloads.size();
2950 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2954 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2961 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2963 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2965 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
2970RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
2971 RAGreedyStats
Stats;
2974 for (MachineLoop *SubLoop : *L)
2975 Stats.add(reportStats(SubLoop));
2977 for (MachineBasicBlock *
MBB :
L->getBlocks())
2979 if (Loops->getLoopFor(
MBB) == L)
2982 if (!
Stats.isEmpty()) {
2983 using namespace ore;
2986 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
2987 L->getStartLoc(),
L->getHeader());
2989 R <<
"generated in loop";
2996void RAGreedy::reportStats() {
2999 RAGreedyStats
Stats;
3000 for (MachineLoop *L : *Loops)
3001 Stats.add(reportStats(L));
3003 for (MachineBasicBlock &
MBB : *MF)
3004 if (!Loops->getLoopFor(&
MBB))
3006 if (!
Stats.isEmpty()) {
3007 using namespace ore;
3011 if (
auto *SP = MF->getFunction().getSubprogram())
3013 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
3016 R <<
"generated in function";
3022bool RAGreedy::hasVirtRegAlloc() {
3023 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
3025 if (
MRI->reg_nodbg_empty(
Reg))
3035 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
3036 <<
"********** Function: " << mf.
getName() <<
'\n');
3042 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
3048 if (!hasVirtRegAlloc())
3056 DebugVars->canonicalizeIndexes(*Indexes);
3060 Indexes->packIndexes();
3062 initializeCSRCost();
3064 RegCosts =
TRI->getRegisterCosts(*MF);
3065 RegClassPriorityTrumpsGlobalness =
3068 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
3072 :
TRI->reverseLocalAssignment();
3074 ExtraInfo.emplace();
3076 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
3077 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
3079 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
3083 VRAI->calculateSpillWeightsAndHints();
3090 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
3091 GlobalCand.resize(32);
3092 SetOfBrokenHints.clear();
3095 tryHintsRecoloring();
3098 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)
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.