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);
625 void tryAvoidingSplit(RegBankSelectImpl::RepairingPlacement &RepairPt,
626 const MachineInstr &
MI,
627 const RegisterBankInfo::ValueMapping &ValMapping)
const;
633 bool applyMapping(MachineInstr &
MI,
634 const RegisterBankInfo::InstructionMapping &InstrMapping,
635 SmallVectorImpl<RepairingPlacement> &RepairPts);
670 bool assignRegisterBanks(
672 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
673 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
675 bool runOnMachineFunction(
678 function_ref<MachineBlockFrequencyInfo *()> GetMBFI,
679 function_ref<MachineBranchProbabilityInfo *()> GetMBPI,
680 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
681 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
687 : OptMode(RunningMode) {}
692void RegBankSelectImpl::init(
696 assert(RBI &&
"Cannot work without RegisterBankInfo");
706 MIRBuilder.
setMF(MF);
707 MORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI);
722bool RegBankSelectImpl::assignmentMatch(
724 bool &OnlyAssign)
const {
736 OnlyAssign = CurRegBank ==
nullptr;
738 if (CurRegBank)
dbgs() << *CurRegBank;
else dbgs() <<
"none";
739 dbgs() <<
" against ";
740 assert(DesiredRegBank &&
"The mapping must be valid");
741 dbgs() << *DesiredRegBank <<
'\n';);
742 return CurRegBank == DesiredRegBank;
745bool RegBankSelectImpl::repairReg(
747 RegBankSelectImpl::RepairingPlacement &RepairPt,
751 "need new vreg for each breakdown");
754 assert(!NewVRegs.empty() &&
"We should not have to repair");
768 assert((RepairPt.getNumInsertPoints() == 1 || Dst.isPhysical()) &&
769 "We are about to create several defs for Dst");
791 MergeOp = TargetOpcode::G_BUILD_VECTOR;
798 "don't understand this value breakdown");
800 MergeOp = TargetOpcode::G_CONCAT_VECTORS;
803 MergeOp = TargetOpcode::G_MERGE_VALUES;
810 MergeBuilder.
addUse(SrcReg);
817 UnMergeBuilder.
addDef(DefReg);
824 if (RepairPt.getNumInsertPoints() != 1)
830 std::unique_ptr<MachineInstr *[]> NewInstrs(
834 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
839 CurMI = MIRBuilder.
getMF().CloneMachineInstr(
MI);
841 NewInstrs[Idx++] = CurMI;
849uint64_t RegBankSelectImpl::getRepairCost(
852 assert(MO.
isReg() &&
"We should only repair register operand");
874 if (IsSameNumOfValues) {
891 unsigned Cost = RBI->
copyCost(*DesiredRegBank, *CurRegBank,
906 "Do not know how to map this instruction");
909 MappingCost
Cost = MappingCost::ImpossibleCost();
913 MappingCost CurCost = computeMapping(
MI, *CurMapping, LocalRepairPts,
914 GetCachedMBFI, GetCachedMBPI, &
Cost);
915 if (CurCost <
Cost) {
918 BestMapping = CurMapping;
920 for (RepairingPlacement &RepairPt : LocalRepairPts)
924 if (!BestMapping &&
MI.getMF()->getTarget().Options.GlobalISelAbort !=
929 BestMapping = *PossibleMappings.begin();
931 RepairingPlacement::Impossible));
933 assert(BestMapping &&
"No suitable mapping for instruction");
937void RegBankSelectImpl::tryAvoidingSplit(
938 RegBankSelectImpl::RepairingPlacement &RepairPt,
const MachineInstr &
MI,
941 assert(RepairPt.hasSplit() &&
"We should not have to adjust for split");
944 assert((
MI.isPHI() ||
MI.isTerminator()) &&
"Why do we split?");
950 assert((!
MI.isPHI() || !MO.
isDef()) &&
"Need split for phi def?");
954 if (
MI.isTerminator()) {
955 assert(&
MI != &(*
MI.getParent()->getFirstTerminator()) &&
956 "Need to split for the first terminator?!");
963 RepairPt.switchTo(RepairingPlacement::RepairingKind::Reassign);
978 "This code is for the def of a terminator");
1025 assert(&
MI == &(*
MI.getParent()->getFirstTerminator()) &&
1026 "Do not know which outgoing edges are relevant");
1029 "Do not know where each terminator ends up");
1035 "Need to split between terminators");
1044 assert(
false &&
"Repairing cost may not be accurate");
1049 RepairPt.switchTo(RepairingPlacement::RepairingKind::Impossible);
1054RegBankSelectImpl::MappingCost RegBankSelectImpl::computeMapping(
1059 const RegBankSelectImpl::MappingCost *BestCost) {
1060 assert((MBFI || !BestCost) &&
"Costs comparison require MBFI");
1063 return MappingCost::ImpossibleCost();
1068 bool Saturated =
Cost.addLocalCost(InstrMapping.
getCost());
1069 assert(!Saturated &&
"Possible mapping saturated the cost");
1073 if (BestCost &&
Cost > *BestCost) {
1074 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive from the start\n");
1083 for (
unsigned OpIdx = 0, EndOpIdx = InstrMapping.
getNumOperands();
1084 OpIdx != EndOpIdx; ++OpIdx) {
1097 InstrMapping.getOperandMapping(OpIdx);
1100 if (assignmentMatch(
Reg, ValMapping, Assign)) {
1107 RepairingPlacement::Reassign));
1113 RepairingPlacement::Insert));
1114 RepairingPlacement &RepairPt = RepairPts.
back();
1119 if (RepairPt.hasSplit())
1120 tryAvoidingSplit(RepairPt,
MI, ValMapping);
1123 if (!RepairPt.canMaterialize()) {
1125 return MappingCost::ImpossibleCost();
1130 if (!BestCost || Saturated)
1135 assert(MBFI && MBPI &&
"Cost computation requires MBFI and MBPI");
1147 uint64_t RepairCost = getRepairCost(MO, ValMapping);
1151 return MappingCost::ImpossibleCost();
1154 const uint64_t PercentageForBias = 5;
1155 uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100;
1160 assert(((RepairCost < RepairCost * PercentageForBias) &&
1161 (RepairCost * PercentageForBias <
1162 RepairCost * PercentageForBias + 99)) &&
1163 "Repairing involves more than a billion of instructions?!");
1164 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
1165 assert(InsertPt->canMaterialize() &&
"We should not have made it here");
1167 if (!InsertPt->isSplit())
1168 Saturated =
Cost.addLocalCost(RepairCost);
1170 uint64_t CostForInsertPt = RepairCost;
1173 assert(CostForInsertPt + Bias > CostForInsertPt &&
1174 "Repairing + split bias overflows");
1175 CostForInsertPt += Bias;
1177 InsertPt->frequency(GetCachedMBFI, GetCachedMBPI) * CostForInsertPt;
1179 if ((Saturated = PtCost < CostForInsertPt))
1182 Saturated =
Cost.addNonLocalCost(PtCost);
1187 if (BestCost &&
Cost > *BestCost) {
1188 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive, stop processing\n");
1202bool RegBankSelectImpl::applyMapping(
1206 std::optional<RegisterBankInfo::OperandsMapper> OpdMapper;
1209 for (RepairingPlacement &RepairPt : RepairPts) {
1210 if (!RepairPt.canMaterialize() ||
1211 RepairPt.getKind() == RepairingPlacement::Impossible)
1213 assert(RepairPt.getKind() != RepairingPlacement::None &&
1214 "This should not make its way in the list");
1215 unsigned OpIdx = RepairPt.getOpIdx();
1218 InstrMapping.getOperandMapping(OpIdx);
1221 switch (RepairPt.getKind()) {
1222 case RepairingPlacement::Reassign:
1224 "Reassignment should only be for simple mapping");
1227 case RepairingPlacement::Insert:
1229 if (
MI.isDebugInstr())
1232 OpdMapper.emplace(
MI, InstrMapping, *MRI);
1233 OpdMapper->createVRegs(OpIdx);
1234 if (!repairReg(MO, ValMapping, RepairPt, OpdMapper->getVRegs(OpIdx)))
1247 OpdMapper.emplace(
MI, InstrMapping, *MRI);
1249 LLVM_DEBUG(
dbgs() <<
"Actual mapping of the operands: " << *OpdMapper
1256bool RegBankSelectImpl::assignInstr(
1261 unsigned Opc =
MI.getOpcode();
1263 assert((
Opc == TargetOpcode::G_ASSERT_ZEXT ||
1264 Opc == TargetOpcode::G_ASSERT_SEXT ||
1265 Opc == TargetOpcode::G_ASSERT_ALIGN) &&
1266 "Unexpected hint opcode!");
1273 assert(RB &&
"Expected source register to have a register bank?");
1274 LLVM_DEBUG(
dbgs() <<
"... Hint always uses source's register bank.\n");
1285 MappingCost DefaultCost = computeMapping(
MI, *BestMapping, RepairPts,
1286 GetCachedMBFI, GetCachedMBPI);
1288 if (DefaultCost == MappingCost::ImpossibleCost())
1293 if (PossibleMappings.
empty())
1295 BestMapping = &findBestMapping(
MI, PossibleMappings, RepairPts,
1296 GetCachedMBFI, GetCachedMBPI);
1299 assert(BestMapping->
verify(
MI) &&
"Invalid instruction mapping");
1305 return applyMapping(
MI, *BestMapping, RepairPts);
1308bool RegBankSelectImpl::assignRegisterBanks(
1323 while (!WorkList.empty()) {
1333 if (
MI.isInlineAsm())
1337 if (
MI.isImplicitDef())
1340 if (!assignInstr(
MI, GetCachedMBFI, GetCachedMBPI)) {
1342 "unable to map instruction",
MI);
1351bool RegBankSelectImpl::checkFunctionIsLegal(
MachineFunction &MF)
const {
1356 "instruction is not legal", *
MI);
1364bool RegBankSelectImpl::runOnMachineFunction(
1382 init(MF, GetMBFI, GetMBPI);
1385 if (!checkFunctionIsLegal(MF))
1389 assignRegisterBanks(MF, GetCachedMBFI, GetCachedMBPI);
1391 OptMode = SaveOptMode;
1398RegBankSelectImpl::RepairingPlacement::RepairingPlacement(
1401 RepairingPlacement::RepairingKind Kind)
1404 CanMaterialize(
Kind != RepairingKind::Impossible),
P(
P) {
1405 const MachineOperand &MO =
MI.getOperand(OpIdx);
1406 assert(MO.
isReg() &&
"Trying to repair a non-reg operand");
1408 if (Kind != RepairingKind::Insert)
1412 bool Before = !MO.
isDef();
1415 if (!
MI.isPHI() && !
MI.isTerminator()) {
1416 addInsertPoint(
MI, Before);
1428 if (It !=
MI.getParent()->end())
1429 addInsertPoint(*It,
true);
1431 addInsertPoint(*(--It),
false);
1435 MachineBasicBlock &Pred = *
MI.getOperand(OpIdx + 1).getMBB();
1440 for (
auto Begin = Pred.
begin(); It != Begin && It->isTerminator(); --It)
1441 if (It->modifiesRegister(
Reg, &
TRI)) {
1444 addInsertPoint(Pred, *
MI.getParent());
1452 if (It == Pred.
end())
1453 addInsertPoint(Pred,
false);
1455 addInsertPoint(*It,
false);
1463 auto REnd =
MI.getParent()->rend();
1465 for (; It != REnd && It->isTerminator(); ++It) {
1467 "copy insertion in middle of terminators not handled");
1471 addInsertPoint(*
MI.getParent()->begin(),
true);
1476 addInsertPoint(*It,
false);
1485 "Do not know where to split");
1487 MachineBasicBlock &Src = *
MI.getParent();
1488 for (
auto &Succ : Src.successors())
1489 addInsertPoint(Src, Succ);
1493void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
MachineInstr &
MI,
1495 addInsertPoint(*
new InstrInsertPoint(
MI, Before));
1498void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1500 addInsertPoint(*
new MBBInsertPoint(
MBB, Beginning));
1503void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1505 addInsertPoint(*
new EdgeInsertPoint(Src, Dst,
P, MFAM));
1508void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1509 RegBankSelectImpl::InsertPoint &Point) {
1510 CanMaterialize &= Point.canMaterialize();
1511 HasSplit |= Point.isSplit();
1512 InsertPoints.emplace_back(&Point);
1515RegBankSelectImpl::InstrInsertPoint::InstrInsertPoint(
MachineInstr &Instr,
1521 "Splitting before phis requires more points");
1522 assert((!Before || !
Instr.getNextNode() || !
Instr.getNextNode()->isPHI()) &&
1523 "Splitting between phis does not make sense");
1526void RegBankSelectImpl::InstrInsertPoint::materialize() {
1548bool RegBankSelectImpl::InstrInsertPoint::isSplit()
const {
1551 return Instr.isTerminator();
1554 return Instr.getPrevNode() &&
Instr.getPrevNode()->isTerminator();
1557uint64_t RegBankSelectImpl::InstrInsertPoint::frequency(
1568uint64_t RegBankSelectImpl::MBBInsertPoint::frequency(
1577void RegBankSelectImpl::EdgeInsertPoint::materialize() {
1583 "This point has already been split");
1585 assert(NewBB &&
"Invalid call to materialize");
1590uint64_t RegBankSelectImpl::EdgeInsertPoint::frequency(
1596 if (WasMaterialized)
1607bool RegBankSelectImpl::EdgeInsertPoint::canMaterialize()
const {
1612 "Edge is not critical");
1613 return Src.canSplitCriticalEdge(DstOrSplit);
1616RegBankSelectImpl::MappingCost::MappingCost(
BlockFrequency LocalFreq)
1617 : LocalFreq(LocalFreq.getFrequency()) {}
1619bool RegBankSelectImpl::MappingCost::addLocalCost(
uint64_t Cost) {
1621 if (LocalCost +
Cost < LocalCost) {
1626 return isSaturated();
1629bool RegBankSelectImpl::MappingCost::addNonLocalCost(
uint64_t Cost) {
1631 if (NonLocalCost +
Cost < NonLocalCost) {
1635 NonLocalCost +=
Cost;
1636 return isSaturated();
1639bool RegBankSelectImpl::MappingCost::isSaturated()
const {
1644void RegBankSelectImpl::MappingCost::saturate() {
1645 *
this = ImpossibleCost();
1649RegBankSelectImpl::MappingCost
1650RegBankSelectImpl::MappingCost::ImpossibleCost() {
1654bool RegBankSelectImpl::MappingCost::operator<(
const MappingCost &
Cost)
const {
1660 if ((*
this == ImpossibleCost()) || (
Cost == ImpossibleCost()))
1661 return (*
this == ImpossibleCost()) < (
Cost == ImpossibleCost());
1664 if (isSaturated() ||
Cost.isSaturated())
1665 return isSaturated() <
Cost.isSaturated();
1678 if (NonLocalCost ==
Cost.NonLocalCost)
1681 return LocalCost <
Cost.LocalCost;
1685 ThisLocalAdjust = 0;
1686 OtherLocalAdjust = 0;
1687 if (LocalCost <
Cost.LocalCost)
1688 OtherLocalAdjust =
Cost.LocalCost - LocalCost;
1690 ThisLocalAdjust = LocalCost -
Cost.LocalCost;
1692 ThisLocalAdjust = LocalCost;
1693 OtherLocalAdjust =
Cost.LocalCost;
1699 if (NonLocalCost <
Cost.NonLocalCost)
1700 OtherNonLocalAdjust =
Cost.NonLocalCost - NonLocalCost;
1702 ThisNonLocalAdjust = NonLocalCost -
Cost.NonLocalCost;
1704 uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq;
1706 bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust ||
1707 ThisScaledCost < LocalFreq);
1708 uint64_t OtherScaledCost = OtherLocalAdjust *
Cost.LocalFreq;
1710 bool OtherOverflows =
1712 (OtherScaledCost < OtherLocalAdjust || OtherScaledCost <
Cost.LocalFreq);
1714 ThisOverflows |= ThisNonLocalAdjust &&
1715 ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust;
1716 ThisScaledCost += ThisNonLocalAdjust;
1717 OtherOverflows |= OtherNonLocalAdjust &&
1718 OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust;
1719 OtherScaledCost += OtherNonLocalAdjust;
1722 if (ThisOverflows && OtherOverflows)
1725 if (ThisOverflows || OtherOverflows)
1726 return ThisOverflows < OtherOverflows;
1728 return ThisScaledCost < OtherScaledCost;
1731bool RegBankSelectImpl::MappingCost::operator==(
const MappingCost &
Cost)
const {
1732 return LocalCost ==
Cost.LocalCost && NonLocalCost ==
Cost.NonLocalCost &&
1733 LocalFreq ==
Cost.LocalFreq;
1736#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1743void RegBankSelectImpl::MappingCost::print(
raw_ostream &OS)
const {
1744 if (*
this == ImpossibleCost()) {
1748 if (isSaturated()) {
1752 OS << LocalFreq <<
" * " << LocalCost <<
" + " << NonLocalCost;
1756 RegBankSelectImpl Impl(OptMode);
1757 return Impl.runOnMachineFunction(
1778 : OptMode(RunningMode) {}
1783 RegBankSelectImpl Impl(OptMode);
1784 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.
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.