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"),
114 cl::desc(
"Drop SlotIndexes entries for erased instructions before "
115 "allocating, so live range sizes reflect real code distance"));
121 cl::desc(
"Cost for first time use of callee-saved register."),
125 "regalloc-csr-cost-scale",
126 cl::desc(
"Scale for the callee-saved register cost, in percentage."),
130 "grow-region-complexity-budget",
131 cl::desc(
"growRegion() does not scale with the number of BB edges, so "
132 "limit its budget and bail out once we reach the limit."),
136 "greedy-regclass-priority-trumps-globalness",
137 cl::desc(
"Change the greedy register allocator's live range priority "
138 "calculation to make the AllocationPriority of the register class "
139 "more important then whether the range is global"),
143 "greedy-reverse-local-assignment",
144 cl::desc(
"Reverse allocation order of local live ranges, such that "
145 "shorter local live ranges will tend to be allocated first"),
149 "split-threshold-for-reg-with-hint",
150 cl::desc(
"The threshold for splitting a virtual register with a hint, in "
166 StringRef getPassName()
const override {
return "Greedy Register Allocator"; }
169 void getAnalysisUsage(AnalysisUsage &AU)
const override;
173 MachineFunctionProperties getRequiredProperties()
const override {
174 return MachineFunctionProperties().setNoPHIs();
177 MachineFunctionProperties getClearedProperties()
const override {
178 return MachineFunctionProperties().setIsSSA();
218 MBFI = Analyses.
MBFI;
220 Loops = Analyses.
Loops;
234 StringRef FilterName = Opts.FilterName.
empty() ?
"all" : Opts.FilterName;
235 OS <<
"greedy<" << FilterName <<
'>';
263 RAGreedy Impl(Analyses, Opts.Filter);
305char RAGreedyLegacy::ID = 0;
330const char *
const RAGreedy::StageName[] = {
345 return new RAGreedyLegacy();
349 return new RAGreedyLegacy(Ftor);
352void RAGreedyLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
382bool RAGreedy::LRE_CanEraseVirtReg(
Register VirtReg) {
383 LiveInterval &LI =
LIS->getInterval(VirtReg);
384 if (
VRM->hasPhys(VirtReg)) {
397void RAGreedy::LRE_WillShrinkVirtReg(
Register VirtReg) {
398 if (!
VRM->hasPhys(VirtReg))
402 LiveInterval &LI =
LIS->getInterval(VirtReg);
408 ExtraInfo->LRE_DidCloneVirtReg(New, Old);
413 if (!Info.inBounds(Old))
422 Info[New] = Info[Old];
426 SpillerInstance.reset();
432void RAGreedy::enqueue(PQueue &CurQueue,
const LiveInterval *LI) {
436 assert(Reg.isVirtual() &&
"Can only enqueue virtual registers");
438 auto Stage = ExtraInfo->getOrInitStage(Reg);
441 ExtraInfo->setStage(Reg, Stage);
444 unsigned Ret = PriorityAdvisor->getPriority(*LI);
448 CurQueue.push(std::make_pair(Ret, ~
Reg.id()));
451unsigned DefaultPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
466 (!ReverseLocalAssignment &&
469 unsigned GlobalBit = 0;
472 LIS->intervalIsInOneMBB(LI)) {
476 if (!ReverseLocalAssignment)
482 Prio = Indexes->getZeroIndex().getApproxInstrDistance(LI.
endIndex());
504 Prio = std::min(Prio, (
unsigned)
maxUIntN(24));
507 if (RegClassPriorityTrumpsGlobalness)
516 if (
VRM->hasKnownPreference(
Reg))
523unsigned DummyPriorityAdvisor::getPriority(
const LiveInterval &LI)
const {
532 if (CurQueue.empty())
549 for (
auto I = Order.
begin(),
E = Order.
end();
I !=
E && !PhysReg; ++
I) {
551 if (!
Matrix->checkInterference(VirtReg, *
I)) {
567 MCRegister PhysHint =
Hint.asMCReg();
570 if (EvictAdvisor->canEvictHintInterference(VirtReg, PhysHint,
572 evictInterference(VirtReg, PhysHint, NewVRegs);
577 if (trySplitAroundHintReg(PhysHint, VirtReg, NewVRegs, Order))
582 SetOfBrokenHints.insert(&VirtReg);
586 uint8_t
Cost = RegCosts[PhysReg.
id()];
593 << (
unsigned)
Cost <<
'\n');
594 MCRegister CheapReg = tryEvict(VirtReg, Order, NewVRegs,
Cost, FixedRegisters);
595 return CheapReg ? CheapReg : PhysReg;
604 auto HasRegUnitInterference = [&](MCRegUnit Unit) {
607 VirtReg,
Matrix->getLiveUnions()[
static_cast<unsigned>(Unit)]);
616 if (
none_of(
TRI->regunits(Reg), HasRegUnitInterference)) {
629void RAGreedy::evictInterference(
const LiveInterval &VirtReg,
635 unsigned Cascade = ExtraInfo->getOrAssignNewCascade(VirtReg.
reg());
638 <<
" interference: Cascade " << Cascade <<
'\n');
642 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
659 assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
660 (Cascade < ExtraInfo->getCascade(Intf->reg()) &&
661 EvictAdvisor->isUrgentEviction(VirtReg, *Intf)) ||
663 "Cannot decrease cascade number, illegal eviction");
664 ExtraInfo->setCascade(Intf->reg(), Cascade);
673 auto IsUnusedCSR = [&](MCRegUnit Unit) {
675 if (CSR && !
Matrix->isPhysRegUsed(CSR))
681 MCRegUnit Unit = (*Units).first;
686 return (S.LaneMask & Mask).any();
695std::optional<unsigned>
698 unsigned CostPerUseLimit)
const {
699 unsigned OrderLimit = Order.
getOrder().size();
701 if (CostPerUseLimit <
uint8_t(~0u)) {
705 if (MinCost >= CostPerUseLimit) {
707 << MinCost <<
", no cheaper registers to be found.\n");
726 unsigned CostPerUseLimit,
728 if (
RegCosts[PhysReg.
id()] >= CostPerUseLimit)
732 if (CostPerUseLimit == 1) {
754 MCRegister BestPhys = EvictAdvisor->tryFindEvictionCandidate(
755 VirtReg, Order, CostPerUseLimit, FixedRegisters);
757 evictInterference(VirtReg, BestPhys, NewVRegs);
777 SplitConstraints.resize(UseBlocks.
size());
779 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
800 if (Intf.
first() <= Indexes->getMBBStartIdx(BI.
MBB)) {
814 SA->getFirstSplitPoint(BC.
Number)))
820 if (Intf.
last() >= SA->getLastSplitPoint(BC.
Number)) {
833 StaticCost += SpillPlacer->getBlockFrequency(BC.
Number);
835 if (StaticCost >= MaxCost)
842 SpillPlacer->addConstraints(SplitConstraints);
843 return SpillPlacer->scanActiveBundles();
848bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
849 ArrayRef<unsigned> Blocks) {
850 const unsigned GroupSize = 8;
851 SpillPlacement::BlockConstraint BCS[GroupSize];
852 unsigned TBS[GroupSize];
853 unsigned B = 0,
T = 0;
855 for (
unsigned Number : Blocks) {
859 assert(
T < GroupSize &&
"Array overflow");
861 if (++
T == GroupSize) {
868 assert(
B < GroupSize &&
"Array overflow");
872 MachineBasicBlock *
MBB = MF->getBlockNumbered(
Number);
874 if (FirstNonDebugInstr !=
MBB->
end() &&
876 SA->getFirstSplitPoint(
Number)))
882 SlotIndex InsertIdx = InsertPt ==
MBB->
end()
883 ? Indexes->getMBBEndIdx(
MBB)
884 :
LIS->getInstructionIndex(*InsertPt);
885 if (Intf.
first() <= Indexes->getMBBStartIdx(
MBB) ||
892 if (Intf.
last() >= SA->getLastSplitPoint(
Number))
897 if (++
B == GroupSize) {
898 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
903 SpillPlacer->addConstraints(
ArrayRef(BCS,
B));
908bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
910 BitVector Todo = SA->getThroughBlocks();
911 SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
912 unsigned AddedTo = 0;
914 unsigned Visited = 0;
919 ArrayRef<unsigned> NewBundles = SpillPlacer->getRecentPositive();
921 for (
unsigned Bundle : NewBundles) {
923 ArrayRef<unsigned> Blocks = Bundles->getBlocks(Bundle);
925 if (Blocks.
size() >= Budget)
927 Budget -= Blocks.
size();
928 for (
unsigned Block : Blocks) {
940 if (ActiveBlocks.
size() == AddedTo)
945 auto NewBlocks =
ArrayRef(ActiveBlocks).slice(AddedTo);
947 if (!addThroughConstraints(Cand.Intf, NewBlocks))
955 bool PrefSpill =
true;
956 if (SA->looksLikeLoopIV() && NewBlocks.size() >= 2) {
961 MachineLoop *
L = Loops->getLoopFor(MF->getBlockNumbered(NewBlocks[0]));
962 if (L &&
L->getHeader()->getNumber() == (
int)NewBlocks[0] &&
963 all_of(NewBlocks.drop_front(), [&](
unsigned Block) {
964 return L == Loops->getLoopFor(MF->getBlockNumbered(Block));
969 SpillPlacer->addPrefSpill(NewBlocks,
true);
971 AddedTo = ActiveBlocks.
size();
974 SpillPlacer->iterate();
987bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
989 if (!SA->getNumThroughBlocks())
999 SpillPlacer->prepare(Cand.LiveBundles);
1002 BlockFrequency
Cost;
1008 if (!growRegion(Cand)) {
1013 SpillPlacer->finish();
1015 if (!Cand.LiveBundles.any()) {
1021 for (
int I : Cand.LiveBundles.set_bits())
1022 dbgs() <<
" EB#" <<
I;
1030BlockFrequency RAGreedy::calcBlockSplitCost() {
1031 BlockFrequency
Cost = BlockFrequency(0);
1033 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1036 Cost += SpillPlacer->getBlockFrequency(
Number);
1040 Cost += SpillPlacer->getBlockFrequency(
Number);
1049BlockFrequency RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand,
1050 const AllocationOrder &Order) {
1051 BlockFrequency GlobalCost = BlockFrequency(0);
1052 const BitVector &LiveBundles = Cand.LiveBundles;
1054 for (
unsigned I = 0;
I != UseBlocks.
size(); ++
I) {
1055 const SplitAnalysis::BlockInfo &BI = UseBlocks[
I];
1056 SpillPlacement::BlockConstraint &BC = SplitConstraints[
I];
1057 bool RegIn = LiveBundles[Bundles->getBundle(BC.
Number,
false)];
1058 bool RegOut = LiveBundles[Bundles->getBundle(BC.
Number,
true)];
1061 Cand.Intf.moveToBlock(BC.
Number);
1068 GlobalCost += SpillPlacer->getBlockFrequency(BC.
Number);
1071 for (
unsigned Number : Cand.ActiveBlocks) {
1072 bool RegIn = LiveBundles[Bundles->getBundle(
Number,
false)];
1073 bool RegOut = LiveBundles[Bundles->getBundle(
Number,
true)];
1074 if (!RegIn && !RegOut)
1076 if (RegIn && RegOut) {
1078 Cand.Intf.moveToBlock(
Number);
1079 if (Cand.Intf.hasInterference()) {
1080 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1081 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1086 GlobalCost += SpillPlacer->getBlockFrequency(
Number);
1103void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit,
1104 ArrayRef<unsigned> UsedCands) {
1107 const unsigned NumGlobalIntvs = LREdit.
size();
1110 assert(NumGlobalIntvs &&
"No global intervals configured");
1120 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1122 unsigned IntvIn = 0, IntvOut = 0;
1123 SlotIndex IntfIn, IntfOut;
1125 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1126 if (CandIn != NoCand) {
1127 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1128 IntvIn = Cand.IntvIdx;
1129 Cand.Intf.moveToBlock(
Number);
1130 IntfIn = Cand.Intf.first();
1134 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1135 if (CandOut != NoCand) {
1136 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1137 IntvOut = Cand.IntvIdx;
1138 Cand.Intf.moveToBlock(
Number);
1139 IntfOut = Cand.Intf.last();
1144 if (!IntvIn && !IntvOut) {
1146 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1147 SE->splitSingleBlock(BI);
1151 if (IntvIn && IntvOut)
1152 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1154 SE->splitRegInBlock(BI, IntvIn, IntfIn);
1156 SE->splitRegOutBlock(BI, IntvOut, IntfOut);
1162 BitVector Todo = SA->getThroughBlocks();
1163 for (
unsigned UsedCand : UsedCands) {
1164 ArrayRef<unsigned> Blocks = GlobalCand[UsedCand].ActiveBlocks;
1165 for (
unsigned Number : Blocks) {
1170 unsigned IntvIn = 0, IntvOut = 0;
1171 SlotIndex IntfIn, IntfOut;
1173 unsigned CandIn = BundleCand[Bundles->getBundle(
Number,
false)];
1174 if (CandIn != NoCand) {
1175 GlobalSplitCandidate &Cand = GlobalCand[CandIn];
1176 IntvIn = Cand.IntvIdx;
1177 Cand.Intf.moveToBlock(
Number);
1178 IntfIn = Cand.Intf.first();
1181 unsigned CandOut = BundleCand[Bundles->getBundle(
Number,
true)];
1182 if (CandOut != NoCand) {
1183 GlobalSplitCandidate &Cand = GlobalCand[CandOut];
1184 IntvOut = Cand.IntvIdx;
1185 Cand.Intf.moveToBlock(
Number);
1186 IntfOut = Cand.Intf.last();
1188 if (!IntvIn && !IntvOut)
1190 SE->splitLiveThroughBlock(
Number, IntvIn, IntfIn, IntvOut, IntfOut);
1196 SmallVector<unsigned, 8> IntvMap;
1197 SE->finish(&IntvMap);
1198 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1200 unsigned OrigBlocks = SA->getNumLiveBlocks();
1207 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1208 const LiveInterval &
Reg =
LIS->getInterval(LREdit.
get(
I));
1211 if (ExtraInfo->getOrInitStage(
Reg.reg()) !=
RS_New)
1216 if (IntvMap[
I] == 0) {
1223 if (IntvMap[
I] < NumGlobalIntvs) {
1224 if (SA->countLiveBlocks(&
Reg) >= OrigBlocks) {
1225 LLVM_DEBUG(
dbgs() <<
"Main interval covers the same " << OrigBlocks
1226 <<
" blocks as original.\n");
1238 MF->verify(
LIS, Indexes,
"After splitting live range around region",
1242MCRegister RAGreedy::tryRegionSplit(
const LiveInterval &VirtReg,
1243 AllocationOrder &Order,
1244 SmallVectorImpl<Register> &NewVRegs) {
1245 if (!
TRI->shouldRegionSplitForVirtReg(*MF, VirtReg))
1247 unsigned NumCands = 0;
1248 BlockFrequency SpillCost = calcBlockSplitCost();
1249 BlockFrequency BestCost;
1252 bool HasCompact = calcCompactRegion(GlobalCand.front());
1260 BestCost = SpillCost;
1265 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
1269 if (!HasCompact && BestCand == NoCand)
1272 return doRegionSplit(VirtReg, BestCand, HasCompact, NewVRegs);
1275unsigned RAGreedy::calculateRegionSplitCostAroundReg(MCRegister PhysReg,
1276 AllocationOrder &Order,
1277 BlockFrequency &BestCost,
1279 unsigned &BestCand) {
1282 if (NumCands == IntfCache.getMaxCursors()) {
1283 unsigned WorstCount = ~0
u;
1285 for (
unsigned CandIndex = 0; CandIndex != NumCands; ++CandIndex) {
1286 if (CandIndex == BestCand || !GlobalCand[CandIndex].PhysReg)
1288 unsigned Count = GlobalCand[CandIndex].LiveBundles.count();
1289 if (
Count < WorstCount) {
1295 GlobalCand[Worst] = GlobalCand[NumCands];
1296 if (BestCand == NumCands)
1300 if (GlobalCand.size() <= NumCands)
1301 GlobalCand.resize(NumCands+1);
1302 GlobalSplitCandidate &Cand = GlobalCand[NumCands];
1303 Cand.reset(IntfCache, PhysReg);
1305 SpillPlacer->prepare(Cand.LiveBundles);
1306 BlockFrequency
Cost;
1307 if (!addSplitConstraints(Cand.Intf,
Cost, BestCost)) {
1309 <<
"\tno positive bundles or too expensive\n");
1314 if (
Cost >= BestCost) {
1316 if (BestCand == NoCand)
1317 dbgs() <<
" worse than no bundles\n";
1319 dbgs() <<
" worse than "
1320 <<
printReg(GlobalCand[BestCand].PhysReg,
TRI) <<
'\n';
1324 if (!growRegion(Cand)) {
1329 SpillPlacer->finish();
1332 if (!Cand.LiveBundles.any()) {
1337 Cost += calcGlobalSplitCost(Cand, Order);
1340 for (
int I : Cand.LiveBundles.set_bits())
1341 dbgs() <<
" EB#" <<
I;
1344 if (
Cost < BestCost) {
1345 BestCand = NumCands;
1353unsigned RAGreedy::calculateRegionSplitCost(
const LiveInterval &VirtReg,
1354 AllocationOrder &Order,
1355 BlockFrequency &BestCost,
1358 unsigned BestCand = NoCand;
1359 for (MCRegister PhysReg : Order) {
1361 if (IgnoreCSR && EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, PhysReg))
1364 calculateRegionSplitCostAroundReg(PhysReg, Order, BestCost, NumCands,
1371MCRegister RAGreedy::doRegionSplit(
const LiveInterval &VirtReg,
1372 unsigned BestCand,
bool HasCompact,
1373 SmallVectorImpl<Register> &NewVRegs) {
1374 SmallVector<unsigned, 8> UsedCands;
1376 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1380 BundleCand.assign(Bundles->getNumBundles(), NoCand);
1383 if (BestCand != NoCand) {
1384 GlobalSplitCandidate &Cand = GlobalCand[BestCand];
1385 if (
unsigned B = Cand.getBundles(BundleCand, BestCand)) {
1387 Cand.IntvIdx = SE->openIntv();
1389 <<
B <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1396 GlobalSplitCandidate &Cand = GlobalCand.front();
1397 assert(!Cand.PhysReg &&
"Compact region has no physreg");
1398 if (
unsigned B = Cand.getBundles(BundleCand, 0)) {
1400 Cand.IntvIdx = SE->openIntv();
1402 <<
" bundles, intv " << Cand.IntvIdx <<
".\n");
1407 splitAroundRegion(LREdit, UsedCands);
1408 return MCRegister();
1413bool RAGreedy::trySplitAroundHintReg(MCRegister Hint,
1414 const LiveInterval &VirtReg,
1415 SmallVectorImpl<Register> &NewVRegs,
1416 AllocationOrder &Order) {
1420 if (MF->getFunction().hasOptSize())
1424 if (ExtraInfo->getStage(VirtReg) >=
RS_Split2)
1427 BlockFrequency
Cost = BlockFrequency(0);
1437 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
1438 const MachineInstr &
Instr = *Opnd.getParent();
1439 if (!
Instr.isCopy() || Opnd.isImplicit())
1443 const bool IsDef = Opnd.isDef();
1444 const MachineOperand &OtherOpnd =
Instr.getOperand(IsDef);
1447 if (OtherReg ==
Reg)
1450 unsigned SubReg = Opnd.getSubReg();
1451 unsigned OtherSubReg = OtherOpnd.
getSubReg();
1452 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
1456 if (Opnd.readsReg()) {
1457 SlotIndex
Index =
LIS->getInstructionIndex(Instr).getRegSlot();
1460 LaneBitmask
Mask =
TRI->getSubRegIndexLaneMask(SubReg);
1464 if (
any_of(VirtReg.
subranges(), [=](
const LiveInterval::SubRange &S) {
1465 return (S.LaneMask & Mask).any() && S.liveAt(Index);
1470 if (VirtReg.
liveAt(Index))
1475 MCRegister OtherPhysReg =
1477 MCRegister ThisHint = SubReg ?
TRI->getSubReg(Hint, SubReg) :
Hint;
1478 if (OtherPhysReg == ThisHint)
1479 Cost += MBFI->getBlockFreq(
Instr.getParent());
1485 if (
Cost == BlockFrequency(0))
1488 unsigned NumCands = 0;
1489 unsigned BestCand = NoCand;
1490 SA->analyze(&VirtReg);
1491 calculateRegionSplitCostAroundReg(Hint, Order,
Cost, NumCands, BestCand);
1492 if (BestCand == NoCand)
1495 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
1506MCRegister RAGreedy::tryBlockSplit(
const LiveInterval &VirtReg,
1507 AllocationOrder &Order,
1508 SmallVectorImpl<Register> &NewVRegs) {
1509 assert(&SA->getParent() == &VirtReg &&
"Live range wasn't analyzed");
1512 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1515 for (
const SplitAnalysis::BlockInfo &BI : UseBlocks) {
1516 if (SA->shouldSplitSingleBlock(BI, SingleInstrs))
1517 SE->splitSingleBlock(BI);
1521 return MCRegister();
1524 SmallVector<unsigned, 8> IntvMap;
1525 SE->finish(&IntvMap);
1528 DebugVars->splitRegister(
Reg, LREdit.
regs(), *
LIS);
1532 for (
unsigned I = 0,
E = LREdit.
size();
I !=
E; ++
I) {
1533 const LiveInterval &LI =
LIS->getInterval(LREdit.
get(
I));
1534 if (ExtraInfo->getOrInitStage(LI.
reg()) ==
RS_New && IntvMap[
I] == 0)
1539 MF->verify(
LIS, Indexes,
"After splitting live range around basic blocks",
1541 return MCRegister();
1554 assert(SuperRC &&
"Invalid register class");
1557 MI->getRegClassConstraintEffectForVReg(
Reg, SuperRC,
TII,
TRI,
1572 for (
auto [
MI, OpIdx] :
Ops) {
1576 if (SubReg == 0 && MO.
isUse()) {
1579 return MRI.getMaxLaneMaskForVReg(
Reg);
1585 Mask |= ~SubRegMask;
1602 auto DestSrc =
TII->isCopyInstr(*
MI);
1603 if (DestSrc && !
MI->isBundled() &&
1604 DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
1613 LiveAtMask |= S.LaneMask;
1618 return (ReadMask & ~(LiveAtMask &
TRI->getCoveringLanes())).
any();
1628MCRegister RAGreedy::tryInstructionSplit(
const LiveInterval &VirtReg,
1629 AllocationOrder &Order,
1630 SmallVectorImpl<Register> &NewVRegs) {
1634 bool SplitSubClass =
true;
1637 return MCRegister();
1638 SplitSubClass =
false;
1643 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1647 if (
Uses.size() <= 1)
1648 return MCRegister();
1651 <<
" individual instrs.\n");
1654 TRI->getLargestLegalSuperClass(CurRC, *MF);
1655 unsigned SuperRCNumAllocatableRegs =
1661 for (
const SlotIndex Use :
Uses) {
1662 if (
const MachineInstr *
MI = Indexes->getInstructionFromIndex(Use)) {
1663 if (TII->isFullCopyInstr(*
MI) ||
1665 SuperRCNumAllocatableRegs ==
1676 SlotIndex SegStart = SE->enterIntvBefore(Use);
1677 SlotIndex SegStop = SE->leaveIntvAfter(Use);
1678 SE->useIntv(SegStart, SegStop);
1681 if (LREdit.
empty()) {
1683 return MCRegister();
1686 SmallVector<unsigned, 8> IntvMap;
1687 SE->finish(&IntvMap);
1688 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1691 return MCRegister();
1703void RAGreedy::calcGapWeights(MCRegister PhysReg,
1704 SmallVectorImpl<float> &GapWeight) {
1705 assert(SA->getUseBlocks().size() == 1 &&
"Not a local interval");
1706 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1708 const unsigned NumGaps =
Uses.size()-1;
1711 SlotIndex StartIdx =
1716 GapWeight.
assign(NumGaps, 0.0f);
1719 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1720 if (!
Matrix->query(
const_cast<LiveInterval &
>(SA->getParent()), Unit)
1721 .checkInterference())
1732 Matrix->getLiveUnions()[
static_cast<unsigned>(
Unit)].
find(StartIdx);
1733 for (
unsigned Gap = 0; IntI.valid() && IntI.start() < StopIdx; ++IntI) {
1735 while (
Uses[Gap+1].getBoundaryIndex() < IntI.start())
1736 if (++Gap == NumGaps)
1742 const float weight = IntI.value()->weight();
1743 for (; Gap != NumGaps; ++Gap) {
1744 GapWeight[Gap] = std::max(GapWeight[Gap], weight);
1745 if (
Uses[Gap+1].getBaseIndex() >= IntI.stop())
1754 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1760 for (
unsigned Gap = 0;
I !=
E &&
I->start < StopIdx; ++
I) {
1761 while (
Uses[Gap+1].getBoundaryIndex() <
I->start)
1762 if (++Gap == NumGaps)
1767 for (; Gap != NumGaps; ++Gap) {
1769 if (
Uses[Gap+1].getBaseIndex() >=
I->end)
1781MCRegister RAGreedy::tryLocalSplit(
const LiveInterval &VirtReg,
1782 AllocationOrder &Order,
1783 SmallVectorImpl<Register> &NewVRegs) {
1786 if (SA->getUseBlocks().size() != 1)
1787 return MCRegister();
1789 const SplitAnalysis::BlockInfo &BI = SA->getUseBlocks().front();
1799 if (
Uses.size() <= 2)
1800 return MCRegister();
1801 const unsigned NumGaps =
Uses.size()-1;
1804 dbgs() <<
"tryLocalSplit: ";
1805 for (
const auto &Use :
Uses)
1812 SmallVector<unsigned, 8> RegMaskGaps;
1813 if (
Matrix->checkRegMaskInterference(VirtReg)) {
1820 unsigned RE = RMS.
size();
1821 for (
unsigned I = 0;
I != NumGaps && RI != RE; ++
I) {
1832 RegMaskGaps.push_back(
I);
1859 bool ProgressRequired = ExtraInfo->getStage(VirtReg) >=
RS_Split2;
1862 unsigned BestBefore = NumGaps;
1863 unsigned BestAfter = 0;
1866 const float blockFreq =
1867 SpillPlacer->getBlockFrequency(BI.
MBB->
getNumber()).getFrequency() *
1868 (1.0f / MBFI->getEntryFreq().getFrequency());
1871 for (MCRegister PhysReg : Order) {
1875 calcGapWeights(PhysReg, GapWeight);
1878 if (
Matrix->checkRegMaskInterference(VirtReg, PhysReg))
1879 for (
unsigned Gap : RegMaskGaps)
1886 unsigned SplitBefore = 0, SplitAfter = 1;
1890 float MaxGap = GapWeight[0];
1894 const bool LiveBefore = SplitBefore != 0 || BI.
LiveIn;
1895 const bool LiveAfter = SplitAfter != NumGaps || BI.
LiveOut;
1898 <<
'-' <<
Uses[SplitAfter] <<
" I=" << MaxGap);
1901 if (!LiveBefore && !LiveAfter) {
1909 unsigned NewGaps = LiveBefore + SplitAfter - SplitBefore + LiveAfter;
1912 bool Legal = !ProgressRequired || NewGaps < NumGaps;
1921 blockFreq * (NewGaps + 1),
1922 Uses[SplitBefore].distance(
Uses[SplitAfter]) +
1930 float Diff = EstWeight - MaxGap;
1931 if (Diff > BestDiff) {
1934 BestBefore = SplitBefore;
1935 BestAfter = SplitAfter;
1942 if (++SplitBefore < SplitAfter) {
1945 if (GapWeight[SplitBefore - 1] >= MaxGap) {
1946 MaxGap = GapWeight[SplitBefore];
1947 for (
unsigned I = SplitBefore + 1;
I != SplitAfter; ++
I)
1948 MaxGap = std::max(MaxGap, GapWeight[
I]);
1956 if (SplitAfter >= NumGaps) {
1962 MaxGap = std::max(MaxGap, GapWeight[SplitAfter++]);
1967 if (BestBefore == NumGaps)
1968 return MCRegister();
1971 <<
Uses[BestAfter] <<
", " << BestDiff <<
", "
1972 << (BestAfter - BestBefore + 1) <<
" instrs\n");
1974 LiveRangeEdit LREdit(&VirtReg, NewVRegs, *MF, *
LIS,
VRM,
this, &
DeadRemats);
1978 SlotIndex SegStart = SE->enterIntvBefore(
Uses[BestBefore]);
1979 SlotIndex SegStop = SE->leaveIntvAfter(
Uses[BestAfter]);
1980 SE->useIntv(SegStart, SegStop);
1981 SmallVector<unsigned, 8> IntvMap;
1982 SE->finish(&IntvMap);
1983 DebugVars->splitRegister(VirtReg.
reg(), LREdit.
regs(), *
LIS);
1987 bool LiveBefore = BestBefore != 0 || BI.
LiveIn;
1988 bool LiveAfter = BestAfter != NumGaps || BI.
LiveOut;
1989 unsigned NewGaps = LiveBefore + BestAfter - BestBefore + LiveAfter;
1990 if (NewGaps >= NumGaps) {
1992 assert(!ProgressRequired &&
"Didn't make progress when it was required.");
1993 for (
unsigned I = 0,
E = IntvMap.
size();
I !=
E; ++
I)
1994 if (IntvMap[
I] == 1) {
2002 return MCRegister();
2012MCRegister RAGreedy::trySplit(
const LiveInterval &VirtReg,
2013 AllocationOrder &Order,
2014 SmallVectorImpl<Register> &NewVRegs,
2017 if (ExtraInfo->getStage(VirtReg) >=
RS_Spill)
2018 return MCRegister();
2021 if (
LIS->intervalIsInOneMBB(VirtReg)) {
2024 SA->analyze(&VirtReg);
2025 MCRegister PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs);
2026 if (PhysReg || !NewVRegs.
empty())
2028 return tryInstructionSplit(VirtReg, Order, NewVRegs);
2031 NamedRegionTimer
T(
"global_split",
"Global Splitting",
TimerGroupName,
2034 SA->analyze(&VirtReg);
2039 if (ExtraInfo->getStage(VirtReg) <
RS_Split2) {
2040 MCRegister PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs);
2041 if (PhysReg || !NewVRegs.
empty())
2046 return tryBlockSplit(VirtReg, Order, NewVRegs);
2069 if (PhysReg == AssignedReg)
2071 return TRI.regsOverlap(PhysReg, AssignedReg);
2082bool RAGreedy::mayRecolorAllInterferences(
2083 MCRegister PhysReg,
const LiveInterval &VirtReg,
2084 SmallLISet &RecoloringCandidates,
const SmallVirtRegSet &FixedRegisters) {
2087 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
2088 LiveIntervalUnion::Query &Q =
Matrix->query(VirtReg, Unit);
2095 CutOffInfo |= CO_Interf;
2110 if (((ExtraInfo->getStage(*Intf) ==
RS_Done &&
2111 MRI->getRegClass(Intf->reg()) == CurRC &&
2115 FixedRegisters.
count(Intf->reg())) {
2117 dbgs() <<
"Early abort: the interference is not recolorable.\n");
2120 RecoloringCandidates.insert(Intf);
2169MCRegister RAGreedy::tryLastChanceRecoloring(
2170 const LiveInterval &VirtReg, AllocationOrder &Order,
2172 RecoloringStack &RecolorStack,
unsigned Depth) {
2173 if (!
TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2176 LLVM_DEBUG(
dbgs() <<
"Try last chance recoloring for " << VirtReg <<
'\n');
2178 const ssize_t EntryStackSize = RecolorStack.size();
2182 "Last chance recoloring should really be last chance");
2188 LLVM_DEBUG(
dbgs() <<
"Abort because max depth has been reached.\n");
2189 CutOffInfo |= CO_Depth;
2194 SmallLISet RecoloringCandidates;
2202 for (MCRegister PhysReg : Order) {
2206 RecoloringCandidates.clear();
2207 CurrentNewVRegs.
clear();
2210 if (
Matrix->checkInterference(VirtReg, PhysReg) >
2213 dbgs() <<
"Some interferences are not with virtual registers.\n");
2220 if (!mayRecolorAllInterferences(PhysReg, VirtReg, RecoloringCandidates,
2222 LLVM_DEBUG(
dbgs() <<
"Some interferences cannot be recolored.\n");
2229 PQueue RecoloringQueue;
2230 for (
const LiveInterval *RC : RecoloringCandidates) {
2232 enqueue(RecoloringQueue, RC);
2234 "Interferences are supposed to be with allocated variables");
2237 RecolorStack.push_back(std::make_pair(RC,
VRM->getPhys(ItVirtReg)));
2246 Matrix->assign(VirtReg, PhysReg);
2255 if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
2256 FixedRegisters, RecolorStack,
Depth)) {
2261 if (
VRM->hasPhys(ThisVirtReg)) {
2262 Matrix->unassign(VirtReg);
2267 LLVM_DEBUG(
dbgs() <<
"tryRecoloringCandidates deleted a fixed register "
2269 FixedRegisters.
erase(ThisVirtReg);
2270 return MCRegister();
2277 FixedRegisters = SaveFixedRegisters;
2278 Matrix->unassign(VirtReg);
2284 for (
Register R : CurrentNewVRegs) {
2285 if (RecoloringCandidates.count(&
LIS->getInterval(R)))
2296 for (ssize_t
I = RecolorStack.size() - 1;
I >= EntryStackSize; --
I) {
2297 const LiveInterval *LI;
2299 std::tie(LI, PhysReg) = RecolorStack[
I];
2301 if (
VRM->hasPhys(LI->
reg()))
2305 for (
size_t I = EntryStackSize;
I != RecolorStack.size(); ++
I) {
2306 const LiveInterval *LI;
2308 std::tie(LI, PhysReg) = RecolorStack[
I];
2309 if (!LI->
empty() && !
MRI->reg_nodbg_empty(LI->
reg()))
2310 Matrix->assign(*LI, PhysReg);
2314 RecolorStack.resize(EntryStackSize);
2329bool RAGreedy::tryRecoloringCandidates(PQueue &RecoloringQueue,
2330 SmallVectorImpl<Register> &NewVRegs,
2332 RecoloringStack &RecolorStack,
2334 while (!RecoloringQueue.empty()) {
2335 const LiveInterval *LI =
dequeue(RecoloringQueue);
2337 MCRegister PhysReg = selectOrSplitImpl(*LI, NewVRegs, FixedRegisters,
2338 RecolorStack,
Depth + 1);
2343 if (PhysReg == ~0u || (!PhysReg && !LI->
empty()))
2347 assert(LI->
empty() &&
"Only empty live-range do not require a register");
2349 <<
" succeeded. Empty LI.\n");
2353 <<
" succeeded with: " <<
printReg(PhysReg,
TRI) <<
'\n');
2355 Matrix->assign(*LI, PhysReg);
2367 CutOffInfo = CO_None;
2368 LLVMContext &Ctx = MF->getFunction().getContext();
2370 RecoloringStack RecolorStack;
2372 selectOrSplitImpl(VirtReg, NewVRegs, FixedRegisters, RecolorStack);
2373 if (Reg == ~0U && (CutOffInfo != CO_None)) {
2374 uint8_t CutOffEncountered = CutOffInfo & (CO_Depth | CO_Interf);
2375 if (CutOffEncountered == CO_Depth)
2376 Ctx.emitError(
"register allocation failed: maximum depth for recoloring "
2377 "reached. Use -fexhaustive-register-search to skip "
2379 else if (CutOffEncountered == CO_Interf)
2380 Ctx.emitError(
"register allocation failed: maximum interference for "
2381 "recoloring reached. Use -fexhaustive-register-search "
2383 else if (CutOffEncountered == (CO_Depth | CO_Interf))
2384 Ctx.emitError(
"register allocation failed: maximum interference and "
2385 "depth for recoloring reached. Use "
2386 "-fexhaustive-register-search to skip cutoffs");
2394 uint64_t SpillCost = 0;
2398 I =
MRI->reg_instr_nodbg_begin(LI.
reg()),
2399 E =
MRI->reg_instr_nodbg_end();
2402 if (
MI->isMetaInstruction())
2407 auto [Reads, Writes] =
MI->readsWritesVirtualRegister(LI.
reg());
2408 auto MBBFreq = SpillPlacer->getBlockFrequency(
MI->getParent()->getNumber());
2409 SpillCost += (Reads + Writes) * MBBFreq.getFrequency();
2415BlockFrequency RAGreedy::calcRematCost(
const LiveInterval &VirtReg,
2416 AllocationOrder &Order)
const {
2428 MachineInstr *
DefMI =
LIS->getInstructionFromIndex(OnlyVNI->
def);
2429 if (!
DefMI || !TII->isReMaterializable(*
DefMI) ||
2436 if (!
Matrix->checkRegMaskInterference(VirtReg))
2439 BlockFrequency RematCost;
2440 bool HasUse =
false;
2441 for (MachineInstr &
UseMI :
MRI->use_nodbg_instructions(VirtReg.
reg())) {
2442 if (!
UseMI.readsVirtualRegister(VirtReg.
reg()))
2448 SlotIndex UseIdx =
LIS->getInstructionIndex(
UseMI).getRegSlot(
true);
2455 bool HasNoFirstCSRReg =
false;
2456 for (MCRegister RematPhysReg : Order) {
2457 if (EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, RematPhysReg))
2459 if (!
Matrix->checkInterference(PrevIdx, UseIdx, RematPhysReg)) {
2460 HasNoFirstCSRReg =
true;
2464 if (!HasNoFirstCSRReg)
2467 RematCost += SpillPlacer->getBlockFrequency(
UseMI.getParent()->getNumber());
2480MCRegister RAGreedy::tryAssignCSRFirstTime(
2481 const LiveInterval &VirtReg, AllocationOrder &Order, MCRegister PhysReg,
2482 uint8_t &CostPerUseLimit, SmallVectorImpl<Register> &NewVRegs) {
2488 SA->analyze(&VirtReg);
2489 if (calcSpillCost(VirtReg) >= CSRCost &&
2490 calcRematCost(VirtReg, Order) >= CSRCost) {
2496 CostPerUseLimit = 1;
2497 return MCRegister();
2502 SA->analyze(&VirtReg);
2503 unsigned NumCands = 0;
2504 BlockFrequency BestCost = CSRCost;
2505 unsigned BestCand = calculateRegionSplitCost(VirtReg, Order, BestCost,
2507 if (BestCand == NoCand) {
2508 if (calcRematCost(VirtReg, Order) < CSRCost) {
2509 CostPerUseLimit = 1;
2510 return MCRegister();
2517 doRegionSplit(VirtReg, BestCand,
false, NewVRegs);
2518 return MCRegister();
2520 if (calcRematCost(VirtReg, Order) < CSRCost) {
2521 CostPerUseLimit = 1;
2522 return MCRegister();
2529 SetOfBrokenHints.remove(&LI);
2532void RAGreedy::initializeCSRCost() {
2542 if (!CSRCost.getFrequency())
2546 uint64_t ActualEntry = MBFI->getEntryFreq().getFrequency();
2552 if (ActualEntry < FixedEntry) {
2554 }
else if (ActualEntry <= UINT32_MAX) {
2556 CSRCost /= BranchProbability(FixedEntry, ActualEntry);
2560 BlockFrequency(CSRCost.getFrequency() * (ActualEntry / FixedEntry));
2563 uint64_t EntryFreq = MBFI->getEntryFreq().getFrequency();
2564 CSRCost = BlockFrequency(
TRI->getCSRFirstUseCost(*MF) * EntryFreq);
2565 unsigned Scale =
TRI->getCSRCostScale(*MF);
2571 CSRCost *= BranchProbability(Scale, 100);
2573 CSRCost /= BranchProbability(100, Scale);
2580void RAGreedy::collectHintInfo(
Register Reg, HintsInfo &Out) {
2583 for (
const MachineOperand &Opnd :
MRI->reg_nodbg_operands(
Reg)) {
2584 const MachineInstr &
Instr = *Opnd.getParent();
2585 if (!
Instr.isCopy() || Opnd.isImplicit())
2589 const MachineOperand &OtherOpnd =
Instr.getOperand(Opnd.isDef());
2591 if (OtherReg ==
Reg)
2593 unsigned OtherSubReg = OtherOpnd.
getSubReg();
2594 unsigned SubReg = Opnd.getSubReg();
2597 MCRegister OtherPhysReg;
2600 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
2602 OtherPhysReg =
TRI->getMatchingSuperReg(OtherReg, SubReg, RC);
2604 OtherPhysReg = OtherReg;
2606 OtherPhysReg =
VRM->getPhys(OtherReg);
2610 if (SubReg && OtherSubReg && SubReg != OtherSubReg)
2616 Out.push_back(HintInfo(
Instr.getParent(), OtherReg, OtherPhysReg));
2624BlockFrequency RAGreedy::getBrokenHintFreq(
const HintsInfo &
List,
2625 MCRegister PhysReg) {
2626 BlockFrequency
Cost = BlockFrequency(0);
2627 for (
const HintInfo &Info :
List) {
2628 if (
Info.PhysReg != PhysReg)
2629 Cost += MBFI->getBlockFreq(
Info.MBB);
2644void RAGreedy::tryHintRecoloring(
const LiveInterval &VirtReg,
2645 DenseSet<Register> &NoRecolorRegs) {
2651 MCRegister PhysReg =
VRM->getPhys(
Reg);
2654 SmallDenseSet<Register, 8> Visited = {
Reg};
2665 MCRegister CurrPhys =
VRM->getPhys(
Reg);
2670 "We have an unallocated variable which should have been handled");
2676 LiveInterval &LI =
LIS->getInterval(
Reg);
2679 if (CurrPhys != PhysReg && (!
MRI->getRegClass(
Reg)->contains(PhysReg) ||
2680 Matrix->checkInterference(LI, PhysReg)))
2684 <<
") is recolorable.\n");
2688 collectHintInfo(
Reg, Info);
2691 if (CurrPhys != PhysReg) {
2693 BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
2694 BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
2698 if (OldCopiesCost < NewCopiesCost) {
2708 Matrix->assign(LI, PhysReg);
2715 for (
const HintInfo &HI : Info) {
2717 if (
HI.Reg.isVirtual() && Visited.
insert(
HI.Reg).second)
2720 }
while (!RecoloringCandidates.
empty());
2723 NoRecolorRegs.
clear();
2764void RAGreedy::tryHintsRecoloring() {
2765 DenseSet<Register> NoRecolorRegs;
2766 for (
const LiveInterval *LI : SetOfBrokenHints) {
2768 "Recoloring is possible only for virtual registers");
2773 tryHintRecoloring(*LI, NoRecolorRegs);
2777MCRegister RAGreedy::selectOrSplitImpl(
const LiveInterval &VirtReg,
2778 SmallVectorImpl<Register> &NewVRegs,
2780 RecoloringStack &RecolorStack,
2782 uint8_t CostPerUseLimit = uint8_t(~0u);
2786 if (MCRegister PhysReg =
2787 tryAssign(VirtReg, Order, NewVRegs, FixedRegisters)) {
2791 if (CSRCost.getFrequency() &&
2792 EvictAdvisor->getUnusedCalleeSavedReg(VirtReg, PhysReg) &&
2794 MCRegister CSRReg = tryAssignCSRFirstTime(VirtReg, Order, PhysReg,
2795 CostPerUseLimit, NewVRegs);
2796 if (CSRReg || !NewVRegs.
empty())
2804 if (!NewVRegs.
empty())
2805 return MCRegister();
2809 << ExtraInfo->getCascade(VirtReg.
reg()) <<
'\n');
2815 if (MCRegister PhysReg =
2816 tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit,
2824 if (Hint && Hint != PhysReg)
2825 SetOfBrokenHints.insert(&VirtReg);
2830 assert((NewVRegs.
empty() ||
Depth) &&
"Cannot append to existing NewVRegs");
2836 ExtraInfo->setStage(VirtReg,
RS_Split);
2839 return MCRegister();
2844 unsigned NewVRegSizeBefore = NewVRegs.
size();
2845 MCRegister PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);
2846 if (PhysReg || (NewVRegs.
size() - NewVRegSizeBefore))
2853 return tryLastChanceRecoloring(VirtReg, Order, NewVRegs, FixedRegisters,
2854 RecolorStack,
Depth);
2868 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2870 DebugVars->splitRegister(r, LRE.regs(), *
LIS);
2873 MF->verify(
LIS, Indexes,
"After spilling", &
errs());
2877 return MCRegister();
2880void RAGreedy::RAGreedyStats::report(MachineOptimizationRemarkMissed &R) {
2881 using namespace ore;
2883 R <<
NV(
"NumSpills", Spills) <<
" spills ";
2884 R <<
NV(
"TotalSpillsCost", SpillsCost) <<
" total spills cost ";
2887 R <<
NV(
"NumFoldedSpills", FoldedSpills) <<
" folded spills ";
2888 R <<
NV(
"TotalFoldedSpillsCost", FoldedSpillsCost)
2889 <<
" total folded spills cost ";
2892 R <<
NV(
"NumReloads", Reloads) <<
" reloads ";
2893 R <<
NV(
"TotalReloadsCost", ReloadsCost) <<
" total reloads cost ";
2895 if (FoldedReloads) {
2896 R <<
NV(
"NumFoldedReloads", FoldedReloads) <<
" folded reloads ";
2897 R <<
NV(
"TotalFoldedReloadsCost", FoldedReloadsCost)
2898 <<
" total folded reloads cost ";
2900 if (ZeroCostFoldedReloads)
2901 R <<
NV(
"NumZeroCostFoldedReloads", ZeroCostFoldedReloads)
2902 <<
" zero cost folded reloads ";
2904 R <<
NV(
"NumVRCopies",
Copies) <<
" virtual registers copies ";
2905 R <<
NV(
"TotalCopiesCost", CopiesCost) <<
" total copies cost ";
2909RAGreedy::RAGreedyStats RAGreedy::computeStats(MachineBasicBlock &
MBB) {
2910 RAGreedyStats
Stats;
2911 const MachineFrameInfo &MFI = MF->getFrameInfo();
2914 auto isSpillSlotAccess = [&MFI](
const MachineMemOperand *
A) {
2916 A->getPseudoValue())->getFrameIndex());
2918 auto isPatchpointInstr = [](
const MachineInstr &
MI) {
2919 return MI.getOpcode() == TargetOpcode::PATCHPOINT ||
2920 MI.getOpcode() == TargetOpcode::STACKMAP ||
2921 MI.getOpcode() == TargetOpcode::STATEPOINT;
2923 for (MachineInstr &
MI :
MBB) {
2924 auto DestSrc = TII->isCopyInstr(
MI);
2926 const MachineOperand &Dest = *DestSrc->Destination;
2927 const MachineOperand &Src = *DestSrc->Source;
2933 SrcReg =
VRM->getPhys(SrcReg);
2934 if (SrcReg && Src.getSubReg())
2935 SrcReg =
TRI->getSubReg(SrcReg, Src.getSubReg());
2938 DestReg =
VRM->getPhys(DestReg);
2942 if (SrcReg != DestReg)
2948 SmallVector<const MachineMemOperand *, 2>
Accesses;
2957 if (TII->hasLoadFromStackSlot(
MI,
Accesses) &&
2959 if (!isPatchpointInstr(
MI)) {
2964 std::pair<unsigned, unsigned> NonZeroCostRange =
2965 TII->getPatchpointUnfoldableRange(
MI);
2966 SmallSet<unsigned, 16> FoldedReloads;
2967 SmallSet<unsigned, 16> ZeroCostFoldedReloads;
2968 for (
unsigned Idx = 0,
E =
MI.getNumOperands(); Idx <
E; ++Idx) {
2969 MachineOperand &MO =
MI.getOperand(Idx);
2972 if (Idx >= NonZeroCostRange.first && Idx < NonZeroCostRange.second)
2978 for (
unsigned Slot : FoldedReloads)
2979 ZeroCostFoldedReloads.
erase(Slot);
2980 Stats.FoldedReloads += FoldedReloads.size();
2981 Stats.ZeroCostFoldedReloads += ZeroCostFoldedReloads.
size();
2985 if (TII->hasStoreToStackSlot(
MI,
Accesses) &&
2992 float RelFreq = MBFI->getBlockFreqRelativeToEntryBlock(&
MBB);
2994 Stats.FoldedReloadsCost = RelFreq *
Stats.FoldedReloads;
2996 Stats.FoldedSpillsCost = RelFreq *
Stats.FoldedSpills;
3001RAGreedy::RAGreedyStats RAGreedy::reportStats(MachineLoop *L) {
3002 RAGreedyStats
Stats;
3005 for (MachineLoop *SubLoop : *L)
3006 Stats.add(reportStats(SubLoop));
3008 for (MachineBasicBlock *
MBB :
L->getBlocks())
3010 if (Loops->getLoopFor(
MBB) == L)
3013 if (!
Stats.isEmpty()) {
3014 using namespace ore;
3017 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"LoopSpillReloadCopies",
3018 L->getStartLoc(),
L->getHeader());
3020 R <<
"generated in loop";
3027void RAGreedy::reportStats() {
3030 RAGreedyStats
Stats;
3031 for (MachineLoop *L : *Loops)
3032 Stats.add(reportStats(L));
3034 for (MachineBasicBlock &
MBB : *MF)
3035 if (!Loops->getLoopFor(&
MBB))
3037 if (!
Stats.isEmpty()) {
3038 using namespace ore;
3042 if (
auto *SP = MF->getFunction().getSubprogram())
3044 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"SpillReloadCopies", Loc,
3047 R <<
"generated in function";
3053bool RAGreedy::hasVirtRegAlloc() {
3054 for (
unsigned I = 0,
E =
MRI->getNumVirtRegs();
I !=
E; ++
I) {
3056 if (
MRI->reg_nodbg_empty(
Reg))
3066 LLVM_DEBUG(
dbgs() <<
"********** GREEDY REGISTER ALLOCATION **********\n"
3067 <<
"********** Function: " << mf.
getName() <<
'\n');
3073 MF->verify(
LIS, Indexes,
"Before greedy register allocator", &
errs());
3080 if (!hasVirtRegAlloc())
3088 DebugVars->canonicalizeIndexes(*Indexes);
3094 :
TRI->shouldCompactSlotIndexes(*MF);
3097 LIS->removeUnreferencedIntervals();
3098 Indexes->compactIndexes();
3100 Indexes->packIndexes();
3103 initializeCSRCost();
3105 RegCosts =
TRI->getRegisterCosts(*MF);
3106 RegClassPriorityTrumpsGlobalness =
3109 :
TRI->regClassPriorityTrumpsGlobalness(*MF);
3113 :
TRI->reverseLocalAssignment();
3115 ExtraInfo.emplace();
3117 EvictAdvisor = EvictProvider->getAdvisor(*MF, *
this, MBFI, Loops);
3118 PriorityAdvisor = PriorityProvider->getAdvisor(*MF, *
this, *Indexes);
3120 VRAI = std::make_unique<VirtRegAuxInfo>(*MF, *
LIS, *
VRM, *Loops, *MBFI);
3124 VRAI->calculateSpillWeightsAndHints();
3131 IntfCache.init(MF,
Matrix->getLiveUnions(), Indexes,
LIS,
TRI);
3132 GlobalCand.resize(32);
3133 SetOfBrokenHints.clear();
3136 tryHintsRecoloring();
3139 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...
MachineRegisterInfo & MRI
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 cl::opt< bool > CompactSlotIndexes("greedy-compact-slot-indexes", cl::Hidden, cl::init(false), cl::desc("Drop SlotIndexes entries for erased instructions before " "allocating, so live range sizes reflect real code distance"))
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,...
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...
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.
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[]
void init(VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat, RegisterClassInfo &rci)
virtual void postOptimization()
MachineRegisterInfo * MRI
bool shouldAllocateRegister(Register Reg)
Get whether a given register should be allocated.
RegisterClassInfo * RegClassInfo
static bool VerifyEnabled
VerifyEnabled - True when -verify-regalloc is given.
ImmutableAnalysis abstraction for fetching the Eviction Advisor.
A MachineFunction analysis for fetching the Eviction Advisor.
Common provider for legacy and new pass managers.
const TargetRegisterInfo *const TRI
LLVM_ABI MCRegister getUnusedCalleeSavedReg(const LiveInterval &VirtReg, MCRegister PhysReg) const
Return an unused callee-saved register that would be used by assigning VirtReg to PhysReg,...
LLVM_ABI std::optional< unsigned > getOrderLimit(const LiveInterval &VirtReg, const AllocationOrder &Order, unsigned CostPerUseLimit) const
const ArrayRef< uint8_t > RegCosts
MachineRegisterInfo *const MRI
const RegisterClassInfo & RegClassInfo
LLVM_ABI bool canAllocatePhysReg(const LiveInterval &VirtReg, unsigned CostPerUseLimit, MCRegister PhysReg) const
LLVM_ABI bool canReassign(const LiveInterval &VirtReg, MCRegister FromReg) const
LiveRegMatrix *const Matrix
Common provider for getting the priority advisor and logging rewards.
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const
getNumAllocatableRegs - Returns the number of actually allocatable registers in RC in the current fun...
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
SlotIndex - An opaque wrapper around machine indexes.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
@ InstrDist
The default distance between instructions as returned by distance().
bool isValid() const
Returns true if this is a valid index.
SlotIndex getBoundaryIndex() const
Returns the boundary index for associated with this index.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
int getApproxInstrDistance(SlotIndex other) const
Return the scaled distance from this index to the given one, where all slots on the same instruction ...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
@ MustSpill
A register is impossible, variable must be spilled.
@ DontCare
Block doesn't care / variable not live.
@ PrefReg
Block entry/exit prefers a register.
@ PrefSpill
Block entry/exit prefers a stack slot.
virtual void spill(LiveRangeEdit &LRE, AllocationOrder *Order=nullptr)=0
spill - Spill the LRE.getParent() live interval.
SplitAnalysis - Analyze a LiveInterval, looking for live range splitting opportunities.
SplitEditor - Edit machine code and LiveIntervals for live range splitting.
@ SM_Partition
SM_Partition(Default) - Try to create the complement interval so it doesn't overlap any other interva...
@ SM_Speed
SM_Speed - Overlap intervals to minimize the expected execution frequency of the inserted copies.
@ SM_Size
SM_Size - Overlap intervals to minimize the number of inserted COPY instructions.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
A Use represents the edge between a Value definition and its users.
bool isUnused() const
Returns true if this value is unused.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
static LLVM_ABI bool allUsesAvailableAt(const MachineInstr *MI, SlotIndex UseIdx, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
int getNumOccurrences() const
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
void insert_range(Range &&R)
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Pass manager infrastructure for declaring and invalidating analyses.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< InstrNode * > Instr
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::function< bool(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const Register Reg)> RegAllocFilterFunc
Filter function for register classes during regalloc.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
constexpr uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
SmallSet< Register, 16 > SmallVirtRegSet
LLVM_ABI FunctionPass * createGreedyRegisterAllocator()
Greedy register allocation pass - This pass implements a global register allocator for optimized buil...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI bool TimePassesIsEnabled
If the user specifies the -time-passes argument on an LLVM tool command line then the value of this b...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
@ RS_Split2
Attempt more aggressive live range splitting that is guaranteed to make progress.
@ RS_Spill
Live range will be spilled. No more splitting will be attempted.
@ RS_Split
Attempt live range splitting if assignment is impossible.
@ RS_New
Newly created live range that has never been queued.
@ RS_Done
There is nothing more we can do to this live range.
@ RS_Assign
Only attempt assignment and eviction. Then requeue as RS_Split.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
LLVM_ABI Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix=nullptr)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI VirtRegInfo AnalyzeVirtRegInBundle(MachineInstr &MI, Register Reg, SmallVectorImpl< std::pair< MachineInstr *, unsigned > > *Ops=nullptr)
AnalyzeVirtRegInBundle - Analyze how the current instruction or bundle uses a virtual register.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI const float huge_valf
Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool canGuaranteeAssignmentAfterRemat(Register VReg, const MachineInstr &MI)
Return whether we can guarantee physical register assignment if VReg's value is rematerialized immedi...
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
LLVM_ABI char & RAGreedyLegacyID
Greedy register allocator.
static float normalizeSpillWeight(float UseDefFreq, unsigned Size, unsigned NumInstr)
Normalize the spill weight of a live interval.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
MachineBlockFrequencyInfo * MBFI
RegAllocEvictionAdvisorProvider * EvictProvider
MachineOptimizationRemarkEmitter * ORE
LiveDebugVariables * DebugVars
SpillPlacement * SpillPlacer
RegAllocPriorityAdvisorProvider * PriorityProvider
MachineDominatorTree * DomTree
RequiredAnalyses()=delete
constexpr bool any() const
This class is basically a combination of TimeRegion and Timer.
BlockConstraint - Entry and exit constraints for a basic block.
BorderConstraint Exit
Constraint on block exit.
bool ChangesValue
True when this block changes the value of the live range.
BorderConstraint Entry
Constraint on block entry.
unsigned Number
Basic block number (from MBB::getNumber()).
Additional information about basic blocks where the current variable is live.
SlotIndex FirstDef
First non-phi valno->def, or SlotIndex().
bool LiveOut
Current reg is live out.
bool LiveIn
Current reg is live in.
SlotIndex LastInstr
Last instr accessing current reg.
SlotIndex FirstInstr
First instr accessing current reg.