35#include "llvm/Config/llvm-config.h"
55#define DEBUG_TYPE "reg-bank-select"
63 std::numeric_limits<unsigned>::max();
68 "Run the Fast mode (default mapping)"),
70 "Use the Greedy mode (best local mapping)")));
75 "Assign register bank of generic virtual registers",
81 "Assign register bank of generic virtual registers",
false,
86 if (RegBankSelectModeOption != RequestedMode)
87 LLVM_DEBUG(dbgs() <<
"RegBankSelect mode overrided by command line\n");
88 return RegBankSelectModeOption;
95class RegBankSelectImpl {
105 bool WasMaterialized =
false;
115 virtual void materialize() = 0;
121 virtual MachineBasicBlock &getInsertMBBImpl() = 0;
130 virtual ~InsertPoint() =
default;
141 if (!WasMaterialized) {
142 WasMaterialized =
true;
143 assert(canMaterialize() &&
"Impossible to materialize this point");
147 assert(!isSplit() &&
"Wrong pre-condition");
148 return getPointImpl();
159 MachineBasicBlock &getInsertMBB() {
160 if (!WasMaterialized) {
161 WasMaterialized =
true;
162 assert(canMaterialize() &&
"Impossible to materialize this point");
166 assert(!isSplit() &&
"Wrong pre-condition");
167 return getInsertMBBImpl();
172 return getInsertMBB().insert(getPoint(), &
MI);
179 virtual bool isSplit()
const {
return false; }
187 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
188 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI)
const {
195 virtual bool canMaterialize()
const {
return false; }
199 class LLVM_ABI InstrInsertPoint :
public InsertPoint {
207 void materialize()
override;
212 return Instr.getNextNode() ? *
Instr.getNextNode()
213 :
Instr.getParent()->end();
216 MachineBasicBlock &getInsertMBBImpl()
override {
217 return *
Instr.getParent();
222 InstrInsertPoint(MachineInstr &Instr,
bool Before =
true);
224 bool isSplit()
const override;
226 frequency(function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
227 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI)
231 bool canMaterialize()
const override {
return true; }
235 class LLVM_ABI MBBInsertPoint :
public InsertPoint {
238 MachineBasicBlock &
MBB;
243 void materialize()
override { }
249 MachineBasicBlock &getInsertMBBImpl()
override {
return MBB; }
252 MBBInsertPoint(MachineBasicBlock &
MBB,
bool Beginning =
true)
253 :
MBB(
MBB), Beginning(Beginning) {
257 "Invalid beginning point");
261 "Invalid end point");
264 bool isSplit()
const override {
return false; }
266 frequency(function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
267 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI)
269 bool canMaterialize()
const override {
return true; };
273 class LLVM_ABI EdgeInsertPoint :
public InsertPoint {
276 MachineBasicBlock &Src;
281 MachineBasicBlock *DstOrSplit;
288 void materialize()
override;
297 return DstOrSplit->
begin();
300 MachineBasicBlock &getInsertMBBImpl()
override {
return *DstOrSplit; }
303 EdgeInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst,
Pass *
P,
305 : Src(Src), DstOrSplit(&Dst),
P(
P), MFAM(MFAM) {}
307 bool isSplit()
const override {
308 return Src.succ_size() > 1 && DstOrSplit->
pred_size() > 1;
312 frequency(function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
313 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI)
315 bool canMaterialize()
const override;
320 class RepairingPlacement {
349 bool HasSplit =
false;
352 InsertionPoints InsertPoints;
363 LLVM_ABI RepairingPlacement(MachineInstr &
MI,
unsigned OpIdx,
364 const TargetRegisterInfo &
TRI,
Pass *P,
366 RepairingKind Kind = RepairingKind::Insert);
370 RepairingKind getKind()
const {
return Kind; }
371 unsigned getOpIdx()
const {
return OpIdx; }
372 bool canMaterialize()
const {
return CanMaterialize; }
373 bool hasSplit() {
return HasSplit; }
379 LLVM_ABI void addInsertPoint(MachineBasicBlock &
MBB,
bool Beginning);
381 LLVM_ABI void addInsertPoint(MachineInstr &
MI,
bool Before);
383 LLVM_ABI void addInsertPoint(MachineBasicBlock &Src,
384 MachineBasicBlock &Dst);
387 LLVM_ABI void addInsertPoint(InsertPoint &Point);
392 insertpt_iterator
begin() {
return InsertPoints.begin(); }
393 insertpt_iterator
end() {
return InsertPoints.end(); }
395 const_insertpt_iterator
begin()
const {
return InsertPoints.begin(); }
396 const_insertpt_iterator
end()
const {
return InsertPoints.end(); }
398 unsigned getNumInsertPoints()
const {
return InsertPoints.size(); }
408 void switchTo(RepairingKind NewKind) {
409 assert(NewKind != Kind &&
"Already of the right Kind");
411 InsertPoints.clear();
412 CanMaterialize = NewKind != RepairingKind::Impossible;
414 assert(NewKind != RepairingKind::Insert &&
415 "We would need more MI to switch to Insert");
443 : LocalCost(LocalCost), NonLocalCost(NonLocalCost),
444 LocalFreq(LocalFreq) {}
447 bool isSaturated()
const;
452 LLVM_ABI MappingCost(BlockFrequency LocalFreq);
468 LLVM_ABI static MappingCost ImpossibleCost();
478 return *
this !=
Cost &&
Cost < *
this;
488 [[maybe_unused]]
friend raw_ostream &
operator<<(raw_ostream &OS,
489 const MappingCost &
Cost) {
497 const RegisterBankInfo *RBI =
nullptr;
501 MachineRegisterInfo *MRI =
nullptr;
504 const TargetRegisterInfo *TRI =
nullptr;
508 MachineBlockFrequencyInfo *MBFI =
nullptr;
512 MachineBranchProbabilityInfo *MBPI =
nullptr;
515 std::unique_ptr<MachineOptimizationRemarkEmitter> MORE;
518 MachineIRBuilder MIRBuilder;
530 assignInstr(MachineInstr &
MI,
531 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
532 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
536 function_ref<MachineBlockFrequencyInfo *()> GetMBFI,
537 function_ref<MachineBranchProbabilityInfo *()> GetMBPI);
544 const RegisterBankInfo::ValueMapping &ValMapping,
545 bool &OnlyAssign)
const;
579 bool repairReg(MachineOperand &MO,
580 const RegisterBankInfo::ValueMapping &ValMapping,
581 RegBankSelectImpl::RepairingPlacement &RepairPt,
591 getRepairCost(
const MachineOperand &MO,
592 const RegisterBankInfo::ValueMapping &ValMapping)
const;
596 const RegisterBankInfo::InstructionMapping &
597 findBestMapping(MachineInstr &
MI,
599 SmallVectorImpl<RepairingPlacement> &RepairPts,
600 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
601 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
611 computeMapping(MachineInstr &
MI,
612 const RegisterBankInfo::InstructionMapping &InstrMapping,
613 SmallVectorImpl<RepairingPlacement> &RepairPts,
614 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
615 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI,
616 const MappingCost *BestCost =
nullptr);
626 void tryAvoidingSplit(RegBankSelectImpl::RepairingPlacement &RepairPt,
627 const MachineOperand &MO,
628 const RegisterBankInfo::ValueMapping &ValMapping)
const;
634 bool applyMapping(MachineInstr &
MI,
635 const RegisterBankInfo::InstructionMapping &InstrMapping,
636 SmallVectorImpl<RepairingPlacement> &RepairPts);
671 bool assignRegisterBanks(
673 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
674 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
676 bool runOnMachineFunction(
679 function_ref<MachineBlockFrequencyInfo *()> GetMBFI,
680 function_ref<MachineBranchProbabilityInfo *()> GetMBPI,
681 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
682 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
688 : OptMode(RunningMode) {}
693void RegBankSelectImpl::init(
697 assert(RBI &&
"Cannot work without RegisterBankInfo");
707 MIRBuilder.
setMF(MF);
708 MORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI);
723bool RegBankSelectImpl::assignmentMatch(
725 bool &OnlyAssign)
const {
737 OnlyAssign = CurRegBank ==
nullptr;
739 if (CurRegBank)
dbgs() << *CurRegBank;
else dbgs() <<
"none";
740 dbgs() <<
" against ";
741 assert(DesiredRegBank &&
"The mapping must be valid");
742 dbgs() << *DesiredRegBank <<
'\n';);
743 return CurRegBank == DesiredRegBank;
746bool RegBankSelectImpl::repairReg(
748 RegBankSelectImpl::RepairingPlacement &RepairPt,
752 "need new vreg for each breakdown");
755 assert(!NewVRegs.empty() &&
"We should not have to repair");
769 assert((RepairPt.getNumInsertPoints() == 1 || Dst.isPhysical()) &&
770 "We are about to create several defs for Dst");
792 MergeOp = TargetOpcode::G_BUILD_VECTOR;
799 "don't understand this value breakdown");
801 MergeOp = TargetOpcode::G_CONCAT_VECTORS;
804 MergeOp = TargetOpcode::G_MERGE_VALUES;
811 MergeBuilder.
addUse(SrcReg);
818 UnMergeBuilder.
addDef(DefReg);
825 if (RepairPt.getNumInsertPoints() != 1)
831 std::unique_ptr<MachineInstr *[]> NewInstrs(
835 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
840 CurMI = MIRBuilder.
getMF().CloneMachineInstr(
MI);
842 NewInstrs[Idx++] = CurMI;
850uint64_t RegBankSelectImpl::getRepairCost(
853 assert(MO.
isReg() &&
"We should only repair register operand");
875 if (IsSameNumOfValues) {
892 unsigned Cost = RBI->
copyCost(*DesiredRegBank, *CurRegBank,
907 "Do not know how to map this instruction");
910 MappingCost
Cost = MappingCost::ImpossibleCost();
914 MappingCost CurCost = computeMapping(
MI, *CurMapping, LocalRepairPts,
915 GetCachedMBFI, GetCachedMBPI, &
Cost);
916 if (CurCost <
Cost) {
919 BestMapping = CurMapping;
921 for (RepairingPlacement &RepairPt : LocalRepairPts)
925 if (!BestMapping &&
MI.getMF()->getTarget().Options.GlobalISelAbort !=
930 BestMapping = *PossibleMappings.begin();
932 RepairingPlacement::Impossible));
934 assert(BestMapping &&
"No suitable mapping for instruction");
938void RegBankSelectImpl::tryAvoidingSplit(
939 RegBankSelectImpl::RepairingPlacement &RepairPt,
const MachineOperand &MO,
942 assert(RepairPt.hasSplit() &&
"We should not have to adjust for split");
945 assert((
MI.isPHI() ||
MI.isTerminator()) &&
"Why do we split?");
947 assert(&
MI.getOperand(RepairPt.getOpIdx()) == &MO &&
948 "Repairing placement does not match operand");
954 assert((!
MI.isPHI() || !MO.
isDef()) &&
"Need split for phi def?");
958 if (
MI.isTerminator()) {
959 assert(&
MI != &(*
MI.getParent()->getFirstTerminator()) &&
960 "Need to split for the first terminator?!");
967 RepairPt.switchTo(RepairingPlacement::RepairingKind::Reassign);
982 "This code is for the def of a terminator");
1029 assert(&
MI == &(*
MI.getParent()->getFirstTerminator()) &&
1030 "Do not know which outgoing edges are relevant");
1033 "Do not know where each terminator ends up");
1039 "Need to split between terminators");
1048 assert(
false &&
"Repairing cost may not be accurate");
1053 RepairPt.switchTo(RepairingPlacement::RepairingKind::Impossible);
1058RegBankSelectImpl::MappingCost RegBankSelectImpl::computeMapping(
1063 const RegBankSelectImpl::MappingCost *BestCost) {
1064 assert((MBFI || !BestCost) &&
"Costs comparison require MBFI");
1067 return MappingCost::ImpossibleCost();
1072 bool Saturated =
Cost.addLocalCost(InstrMapping.
getCost());
1073 assert(!Saturated &&
"Possible mapping saturated the cost");
1077 if (BestCost &&
Cost > *BestCost) {
1078 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive from the start\n");
1087 for (
unsigned OpIdx = 0, EndOpIdx = InstrMapping.
getNumOperands();
1088 OpIdx != EndOpIdx; ++OpIdx) {
1101 InstrMapping.getOperandMapping(OpIdx);
1104 if (assignmentMatch(
Reg, ValMapping, Assign)) {
1111 RepairingPlacement::Reassign));
1117 RepairingPlacement::Insert));
1118 RepairingPlacement &RepairPt = RepairPts.
back();
1123 if (RepairPt.hasSplit())
1124 tryAvoidingSplit(RepairPt, MO, ValMapping);
1127 if (!RepairPt.canMaterialize()) {
1129 return MappingCost::ImpossibleCost();
1134 if (!BestCost || Saturated)
1139 assert(MBFI && MBPI &&
"Cost computation requires MBFI and MBPI");
1151 uint64_t RepairCost = getRepairCost(MO, ValMapping);
1155 return MappingCost::ImpossibleCost();
1158 const uint64_t PercentageForBias = 5;
1159 uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100;
1164 assert(((RepairCost < RepairCost * PercentageForBias) &&
1165 (RepairCost * PercentageForBias <
1166 RepairCost * PercentageForBias + 99)) &&
1167 "Repairing involves more than a billion of instructions?!");
1168 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
1169 assert(InsertPt->canMaterialize() &&
"We should not have made it here");
1171 if (!InsertPt->isSplit())
1172 Saturated =
Cost.addLocalCost(RepairCost);
1174 uint64_t CostForInsertPt = RepairCost;
1177 assert(CostForInsertPt + Bias > CostForInsertPt &&
1178 "Repairing + split bias overflows");
1179 CostForInsertPt += Bias;
1181 InsertPt->frequency(GetCachedMBFI, GetCachedMBPI) * CostForInsertPt;
1183 if ((Saturated = PtCost < CostForInsertPt))
1186 Saturated =
Cost.addNonLocalCost(PtCost);
1191 if (BestCost &&
Cost > *BestCost) {
1192 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive, stop processing\n");
1206bool RegBankSelectImpl::applyMapping(
1210 std::optional<RegisterBankInfo::OperandsMapper> OpdMapper;
1213 for (RepairingPlacement &RepairPt : RepairPts) {
1214 if (!RepairPt.canMaterialize() ||
1215 RepairPt.getKind() == RepairingPlacement::Impossible)
1217 assert(RepairPt.getKind() != RepairingPlacement::None &&
1218 "This should not make its way in the list");
1219 unsigned OpIdx = RepairPt.getOpIdx();
1222 InstrMapping.getOperandMapping(OpIdx);
1225 switch (RepairPt.getKind()) {
1226 case RepairingPlacement::Reassign:
1228 "Reassignment should only be for simple mapping");
1231 case RepairingPlacement::Insert:
1233 if (
MI.isDebugInstr())
1236 OpdMapper.emplace(
MI, InstrMapping, *MRI);
1237 OpdMapper->createVRegs(OpIdx);
1238 if (!repairReg(MO, ValMapping, RepairPt, OpdMapper->getVRegs(OpIdx)))
1251 OpdMapper.emplace(
MI, InstrMapping, *MRI);
1253 LLVM_DEBUG(
dbgs() <<
"Actual mapping of the operands: " << *OpdMapper
1260bool RegBankSelectImpl::assignInstr(
1265 unsigned Opc =
MI.getOpcode();
1267 assert((
Opc == TargetOpcode::G_ASSERT_ZEXT ||
1268 Opc == TargetOpcode::G_ASSERT_SEXT ||
1269 Opc == TargetOpcode::G_ASSERT_ALIGN) &&
1270 "Unexpected hint opcode!");
1277 assert(RB &&
"Expected source register to have a register bank?");
1278 LLVM_DEBUG(
dbgs() <<
"... Hint always uses source's register bank.\n");
1289 MappingCost DefaultCost = computeMapping(
MI, *BestMapping, RepairPts,
1290 GetCachedMBFI, GetCachedMBPI);
1292 if (DefaultCost == MappingCost::ImpossibleCost())
1297 if (PossibleMappings.
empty())
1299 BestMapping = &findBestMapping(
MI, PossibleMappings, RepairPts,
1300 GetCachedMBFI, GetCachedMBPI);
1303 assert(BestMapping->
verify(
MI) &&
"Invalid instruction mapping");
1309 return applyMapping(
MI, *BestMapping, RepairPts);
1312bool RegBankSelectImpl::assignRegisterBanks(
1327 while (!WorkList.empty()) {
1337 if (
MI.isInlineAsm())
1341 if (
MI.isImplicitDef())
1344 if (!assignInstr(
MI, GetCachedMBFI, GetCachedMBPI)) {
1346 "unable to map instruction",
MI);
1355bool RegBankSelectImpl::checkFunctionIsLegal(
MachineFunction &MF)
const {
1360 "instruction is not legal", *
MI);
1368bool RegBankSelectImpl::runOnMachineFunction(
1386 init(MF, GetMBFI, GetMBPI);
1389 if (!checkFunctionIsLegal(MF))
1393 assignRegisterBanks(MF, GetCachedMBFI, GetCachedMBPI);
1395 OptMode = SaveOptMode;
1402RegBankSelectImpl::RepairingPlacement::RepairingPlacement(
1405 RepairingPlacement::RepairingKind Kind)
1408 CanMaterialize(
Kind != RepairingKind::Impossible),
P(
P) {
1409 const MachineOperand &MO =
MI.getOperand(OpIdx);
1410 assert(MO.
isReg() &&
"Trying to repair a non-reg operand");
1412 if (Kind != RepairingKind::Insert)
1416 bool Before = !MO.
isDef();
1419 if (!
MI.isPHI() && !
MI.isTerminator()) {
1420 addInsertPoint(
MI, Before);
1432 if (It !=
MI.getParent()->end())
1433 addInsertPoint(*It,
true);
1435 addInsertPoint(*(--It),
false);
1439 MachineBasicBlock &Pred = *
MI.getOperand(OpIdx + 1).getMBB();
1444 for (
auto Begin = Pred.
begin(); It != Begin && It->isTerminator(); --It)
1445 if (It->modifiesRegister(
Reg, &
TRI)) {
1448 addInsertPoint(Pred, *
MI.getParent());
1456 if (It == Pred.
end())
1457 addInsertPoint(Pred,
false);
1459 addInsertPoint(*It,
false);
1467 auto REnd =
MI.getParent()->rend();
1469 for (; It != REnd && It->isTerminator(); ++It) {
1471 "copy insertion in middle of terminators not handled");
1475 addInsertPoint(*
MI.getParent()->begin(),
true);
1480 addInsertPoint(*It,
false);
1489 "Do not know where to split");
1491 MachineBasicBlock &Src = *
MI.getParent();
1492 for (
auto &Succ : Src.successors())
1493 addInsertPoint(Src, Succ);
1497void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
MachineInstr &
MI,
1499 addInsertPoint(*
new InstrInsertPoint(
MI, Before));
1502void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1504 addInsertPoint(*
new MBBInsertPoint(
MBB, Beginning));
1507void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1509 addInsertPoint(*
new EdgeInsertPoint(Src, Dst,
P, MFAM));
1512void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1513 RegBankSelectImpl::InsertPoint &Point) {
1514 CanMaterialize &= Point.canMaterialize();
1515 HasSplit |= Point.isSplit();
1516 InsertPoints.emplace_back(&Point);
1519RegBankSelectImpl::InstrInsertPoint::InstrInsertPoint(
MachineInstr &Instr,
1525 "Splitting before phis requires more points");
1526 assert((!Before || !
Instr.getNextNode() || !
Instr.getNextNode()->isPHI()) &&
1527 "Splitting between phis does not make sense");
1530void RegBankSelectImpl::InstrInsertPoint::materialize() {
1552bool RegBankSelectImpl::InstrInsertPoint::isSplit()
const {
1555 return Instr.isTerminator();
1558 return Instr.getPrevNode() &&
Instr.getPrevNode()->isTerminator();
1561uint64_t RegBankSelectImpl::InstrInsertPoint::frequency(
1572uint64_t RegBankSelectImpl::MBBInsertPoint::frequency(
1581void RegBankSelectImpl::EdgeInsertPoint::materialize() {
1587 "This point has already been split");
1589 assert(NewBB &&
"Invalid call to materialize");
1594uint64_t RegBankSelectImpl::EdgeInsertPoint::frequency(
1600 if (WasMaterialized)
1611bool RegBankSelectImpl::EdgeInsertPoint::canMaterialize()
const {
1616 "Edge is not critical");
1617 return Src.canSplitCriticalEdge(DstOrSplit);
1620RegBankSelectImpl::MappingCost::MappingCost(
BlockFrequency LocalFreq)
1621 : LocalFreq(LocalFreq.getFrequency()) {}
1623bool RegBankSelectImpl::MappingCost::addLocalCost(
uint64_t Cost) {
1625 if (LocalCost +
Cost < LocalCost) {
1630 return isSaturated();
1633bool RegBankSelectImpl::MappingCost::addNonLocalCost(
uint64_t Cost) {
1635 if (NonLocalCost +
Cost < NonLocalCost) {
1639 NonLocalCost +=
Cost;
1640 return isSaturated();
1643bool RegBankSelectImpl::MappingCost::isSaturated()
const {
1648void RegBankSelectImpl::MappingCost::saturate() {
1649 *
this = ImpossibleCost();
1653RegBankSelectImpl::MappingCost
1654RegBankSelectImpl::MappingCost::ImpossibleCost() {
1658bool RegBankSelectImpl::MappingCost::operator<(
const MappingCost &
Cost)
const {
1664 if ((*
this == ImpossibleCost()) || (
Cost == ImpossibleCost()))
1665 return (*
this == ImpossibleCost()) < (
Cost == ImpossibleCost());
1668 if (isSaturated() ||
Cost.isSaturated())
1669 return isSaturated() <
Cost.isSaturated();
1682 if (NonLocalCost ==
Cost.NonLocalCost)
1685 return LocalCost <
Cost.LocalCost;
1689 ThisLocalAdjust = 0;
1690 OtherLocalAdjust = 0;
1691 if (LocalCost <
Cost.LocalCost)
1692 OtherLocalAdjust =
Cost.LocalCost - LocalCost;
1694 ThisLocalAdjust = LocalCost -
Cost.LocalCost;
1696 ThisLocalAdjust = LocalCost;
1697 OtherLocalAdjust =
Cost.LocalCost;
1703 if (NonLocalCost <
Cost.NonLocalCost)
1704 OtherNonLocalAdjust =
Cost.NonLocalCost - NonLocalCost;
1706 ThisNonLocalAdjust = NonLocalCost -
Cost.NonLocalCost;
1708 uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq;
1710 bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust ||
1711 ThisScaledCost < LocalFreq);
1712 uint64_t OtherScaledCost = OtherLocalAdjust *
Cost.LocalFreq;
1714 bool OtherOverflows =
1716 (OtherScaledCost < OtherLocalAdjust || OtherScaledCost <
Cost.LocalFreq);
1718 ThisOverflows |= ThisNonLocalAdjust &&
1719 ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust;
1720 ThisScaledCost += ThisNonLocalAdjust;
1721 OtherOverflows |= OtherNonLocalAdjust &&
1722 OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust;
1723 OtherScaledCost += OtherNonLocalAdjust;
1726 if (ThisOverflows && OtherOverflows)
1729 if (ThisOverflows || OtherOverflows)
1730 return ThisOverflows < OtherOverflows;
1732 return ThisScaledCost < OtherScaledCost;
1735bool RegBankSelectImpl::MappingCost::operator==(
const MappingCost &
Cost)
const {
1736 return LocalCost ==
Cost.LocalCost && NonLocalCost ==
Cost.NonLocalCost &&
1737 LocalFreq ==
Cost.LocalFreq;
1740#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1747void RegBankSelectImpl::MappingCost::print(
raw_ostream &OS)
const {
1748 if (*
this == ImpossibleCost()) {
1752 if (isSaturated()) {
1756 OS << LocalFreq <<
" * " << LocalCost <<
" + " << NonLocalCost;
1760 RegBankSelectImpl Impl(OptMode);
1761 return Impl.runOnMachineFunction(
1782 : OptMode(RunningMode) {}
1787 RegBankSelectImpl Impl(OptMode);
1788 bool Changed = Impl.runOnMachineFunction(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_LIKELY(EXPR)
Interface for Targets to specify which operations they can successfully select and how the others sho...
print mir2vec MIR2Vec Vocabulary Printer Pass
This file declares the MachineIRBuilder class.
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 file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static constexpr unsigned ImpossibleRepairCost
Cost value representing an impossible or invalid repairing.
static cl::opt< RegBankSelectMode > RegBankSelectModeOption(cl::desc("Mode of the RegBankSelect pass"), cl::Hidden, cl::Optional, cl::values(clEnumValN(RegBankSelectMode::Fast, "regbankselect-fast", "Run the Fast mode (default mapping)"), clEnumValN(RegBankSelectMode::Greedy, "regbankselect-greedy", "Use the Greedy mode (best local mapping)")))
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
This file defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
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()
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
Represents analyses that only rely on functions' control flow.
LLVM_ABI void print(raw_ostream &OS) const
constexpr unsigned getScalarSizeInBits() const
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
An RAII based helper class to modify MachineFunctionProperties when running pass.
unsigned pred_size() const
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
MachineInstrBundleIterator< MachineInstr > iterator
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
MachineFunctionPass(char &ID)
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
void insert(iterator MBBI, MachineBasicBlock *MBB)
MachineFunction & getMF()
Getter for the function we currently build.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
void setMF(MachineFunction &MF)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
LLVM_ABI void setRegBank(Register Reg, const RegisterBank &RegBank)
Set the register bank to RegBank for Reg.
const MachineFunction & getMF() const
Pass interface - Implemented by all 'passes'.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
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.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
RegBankSelectLegacy(RegBankSelectMode RunningMode=RegBankSelectMode::Fast)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
RegBankSelectPass(RegBankSelectMode RunningMode=RegBankSelectMode::Fast)
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned getNumOperands() const
Get the number of operands.
unsigned getCost() const
Get the cost.
unsigned getID() const
Get the ID.
LLVM_ABI bool verify(const MachineInstr &MI) const
Verifiy that this mapping makes sense for MI.
bool isValid() const
Check whether this object is valid.
void applyMapping(MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const
Apply OpdMapper.getInstrMapping() to OpdMapper.getMI().
virtual const InstructionMapping & getInstrMapping(const MachineInstr &MI) const
Get the mapping of the different operands of MI on the register bank.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
TypeSize getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
InstructionMappings getInstrPossibleMappings(const MachineInstr &MI) const
Get the possible mapping for MI.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
SmallVector< const InstructionMapping *, 4 > InstructionMappings
Convenient type to represent the alternatives for mapping an instruction.
virtual unsigned copyCost(const RegisterBank &A, const RegisterBank &B, TypeSize Size) const
Get the cost of a copy from B to A, or put differently, get the cost of A = COPY B.
virtual unsigned getBreakDownCost(const ValueMapping &ValMapping, const RegisterBank *CurBank=nullptr) const
Get the cost of using ValMapping to decompose a register.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
typename SuperClass::const_iterator const_iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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)
NodeAddr< InstrNode * > Instr
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool operator<(int64_t V1, const APSInt &V2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool operator!=(uint64_t V1, const APInt &V2)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
bool isPreISelGenericOptimizationHint(unsigned Opcode)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool operator>(int64_t V1, const APSInt &V2)
LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo, const TargetRegisterInfo *TRI)
Create Printable object to print register classes or register banks on a raw_ostream.
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
RegBankSelectMode
List of the modes supported by the RegBankSelect pass.
@ Greedy
Greedily minimize the cost of assigning register banks.
@ Fast
Assign the register banks as fast as possible (default).
bool isTargetSpecificOpcode(unsigned Opcode)
Check whether the given Opcode is a target-specific opcode.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
const RegisterBank * RegBank
Register bank where the partial value lives.
unsigned Length
Length of this mapping in bits.
Helper struct that represents how a value is mapped through different register banks.
LLVM_ABI bool partsAllUniform() const
unsigned NumBreakDowns
Number of partial mapping to break down this value.
const PartialMapping * BreakDown
How the value is broken down between the different register banks.