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 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 MBBInsertPoint :
public InsertPoint {
238 MachineBasicBlock &MBB;
243 void materialize()
override { }
246 return Beginning ? MBB.begin() : MBB.end();
249 MachineBasicBlock &getInsertMBBImpl()
override {
return MBB; }
252 MBBInsertPoint(MachineBasicBlock &MBB,
bool Beginning =
true)
253 : MBB(MBB), Beginning(Beginning) {
256 assert((!Beginning || MBB.getFirstNonPHI() == MBB.begin()) &&
257 "Invalid beginning point");
260 assert((Beginning || MBB.getFirstTerminator() == MBB.end()) &&
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 EdgeInsertPoint :
public InsertPoint {
276 MachineBasicBlock &Src;
281 MachineBasicBlock *DstOrSplit;
288 void materialize()
override;
294 assert(DstOrSplit && DstOrSplit->isPredecessor(&Src) &&
295 DstOrSplit->pred_size() == 1 && DstOrSplit->succ_size() == 1 &&
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 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 void addInsertPoint(MachineBasicBlock &
MBB,
bool Beginning);
381 void addInsertPoint(MachineInstr &
MI,
bool Before);
383 void addInsertPoint(MachineBasicBlock &Src, MachineBasicBlock &Dst);
386 void addInsertPoint(InsertPoint &Point);
391 insertpt_iterator
begin() {
return InsertPoints.begin(); }
392 insertpt_iterator
end() {
return InsertPoints.end(); }
394 const_insertpt_iterator
begin()
const {
return InsertPoints.begin(); }
395 const_insertpt_iterator
end()
const {
return InsertPoints.end(); }
397 unsigned getNumInsertPoints()
const {
return InsertPoints.size(); }
407 void switchTo(RepairingKind NewKind) {
408 assert(NewKind != Kind &&
"Already of the right Kind");
410 InsertPoints.clear();
411 CanMaterialize = NewKind != RepairingKind::Impossible;
413 assert(NewKind != RepairingKind::Insert &&
414 "We would need more MI to switch to Insert");
442 : LocalCost(LocalCost), NonLocalCost(NonLocalCost),
443 LocalFreq(LocalFreq) {}
446 bool isSaturated()
const;
451 MappingCost(BlockFrequency LocalFreq);
467 static MappingCost ImpossibleCost();
477 return *
this !=
Cost &&
Cost < *
this;
484 void print(raw_ostream &OS)
const;
487 [[maybe_unused]]
friend raw_ostream &
operator<<(raw_ostream &OS,
488 const MappingCost &
Cost) {
496 const RegisterBankInfo *RBI =
nullptr;
500 MachineRegisterInfo *MRI =
nullptr;
503 const TargetRegisterInfo *TRI =
nullptr;
507 MachineBlockFrequencyInfo *MBFI =
nullptr;
511 MachineBranchProbabilityInfo *MBPI =
nullptr;
514 std::unique_ptr<MachineOptimizationRemarkEmitter> MORE;
517 MachineIRBuilder MIRBuilder;
529 assignInstr(MachineInstr &
MI,
530 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
531 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
535 function_ref<MachineBlockFrequencyInfo *()> GetMBFI,
536 function_ref<MachineBranchProbabilityInfo *()> GetMBPI);
543 const RegisterBankInfo::ValueMapping &ValMapping,
544 bool &OnlyAssign)
const;
578 bool repairReg(MachineOperand &MO,
579 const RegisterBankInfo::ValueMapping &ValMapping,
580 RegBankSelectImpl::RepairingPlacement &RepairPt,
590 getRepairCost(
const MachineOperand &MO,
591 const RegisterBankInfo::ValueMapping &ValMapping)
const;
595 const RegisterBankInfo::InstructionMapping &
596 findBestMapping(MachineInstr &
MI,
598 SmallVectorImpl<RepairingPlacement> &RepairPts,
599 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
600 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
610 computeMapping(MachineInstr &
MI,
611 const RegisterBankInfo::InstructionMapping &InstrMapping,
612 SmallVectorImpl<RepairingPlacement> &RepairPts,
613 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
614 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI,
615 const MappingCost *BestCost =
nullptr);
624 void tryAvoidingSplit(RegBankSelectImpl::RepairingPlacement &RepairPt,
625 const MachineInstr &
MI,
626 const RegisterBankInfo::ValueMapping &ValMapping)
const;
632 bool applyMapping(MachineInstr &
MI,
633 const RegisterBankInfo::InstructionMapping &InstrMapping,
634 SmallVectorImpl<RepairingPlacement> &RepairPts);
669 bool assignRegisterBanks(
671 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
672 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
674 bool runOnMachineFunction(
677 function_ref<MachineBlockFrequencyInfo *()> GetMBFI,
678 function_ref<MachineBranchProbabilityInfo *()> GetMBPI,
679 function_ref<MachineBlockFrequencyInfo *()> GetCachedMBFI,
680 function_ref<MachineBranchProbabilityInfo *()> GetCachedMBPI);
686 : OptMode(RunningMode) {}
691void RegBankSelectImpl::init(
695 assert(RBI &&
"Cannot work without RegisterBankInfo");
705 MIRBuilder.
setMF(MF);
706 MORE = std::make_unique<MachineOptimizationRemarkEmitter>(MF, MBFI);
721bool RegBankSelectImpl::assignmentMatch(
723 bool &OnlyAssign)
const {
735 OnlyAssign = CurRegBank ==
nullptr;
737 if (CurRegBank)
dbgs() << *CurRegBank;
else dbgs() <<
"none";
738 dbgs() <<
" against ";
739 assert(DesiredRegBank &&
"The mapping must be valid");
740 dbgs() << *DesiredRegBank <<
'\n';);
741 return CurRegBank == DesiredRegBank;
744bool RegBankSelectImpl::repairReg(
746 RegBankSelectImpl::RepairingPlacement &RepairPt,
750 "need new vreg for each breakdown");
753 assert(!NewVRegs.empty() &&
"We should not have to repair");
767 assert((RepairPt.getNumInsertPoints() == 1 || Dst.isPhysical()) &&
768 "We are about to create several defs for Dst");
790 MergeOp = TargetOpcode::G_BUILD_VECTOR;
797 "don't understand this value breakdown");
799 MergeOp = TargetOpcode::G_CONCAT_VECTORS;
802 MergeOp = TargetOpcode::G_MERGE_VALUES;
809 MergeBuilder.
addUse(SrcReg);
816 UnMergeBuilder.
addDef(DefReg);
823 if (RepairPt.getNumInsertPoints() != 1)
829 std::unique_ptr<MachineInstr *[]> NewInstrs(
833 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
838 CurMI = MIRBuilder.
getMF().CloneMachineInstr(
MI);
840 NewInstrs[Idx++] = CurMI;
848uint64_t RegBankSelectImpl::getRepairCost(
851 assert(MO.
isReg() &&
"We should only repair register operand");
873 if (IsSameNumOfValues) {
890 unsigned Cost = RBI->
copyCost(*DesiredRegBank, *CurRegBank,
905 "Do not know how to map this instruction");
908 MappingCost
Cost = MappingCost::ImpossibleCost();
912 MappingCost CurCost = computeMapping(
MI, *CurMapping, LocalRepairPts,
913 GetCachedMBFI, GetCachedMBPI, &
Cost);
914 if (CurCost <
Cost) {
917 BestMapping = CurMapping;
919 for (RepairingPlacement &RepairPt : LocalRepairPts)
923 if (!BestMapping &&
MI.getMF()->getTarget().Options.GlobalISelAbort !=
928 BestMapping = *PossibleMappings.begin();
930 RepairingPlacement::Impossible));
932 assert(BestMapping &&
"No suitable mapping for instruction");
936void RegBankSelectImpl::tryAvoidingSplit(
937 RegBankSelectImpl::RepairingPlacement &RepairPt,
const MachineInstr &
MI,
940 assert(RepairPt.hasSplit() &&
"We should not have to adjust for split");
943 assert((
MI.isPHI() ||
MI.isTerminator()) &&
"Why do we split?");
949 assert((!
MI.isPHI() || !MO.
isDef()) &&
"Need split for phi def?");
953 if (
MI.isTerminator()) {
954 assert(&
MI != &(*
MI.getParent()->getFirstTerminator()) &&
955 "Need to split for the first terminator?!");
962 RepairPt.switchTo(RepairingPlacement::RepairingKind::Reassign);
977 "This code is for the def of a terminator");
1024 assert(&
MI == &(*
MI.getParent()->getFirstTerminator()) &&
1025 "Do not know which outgoing edges are relevant");
1028 "Do not know where each terminator ends up");
1034 "Need to split between terminators");
1043 assert(
false &&
"Repairing cost may not be accurate");
1048 RepairPt.switchTo(RepairingPlacement::RepairingKind::Impossible);
1053RegBankSelectImpl::MappingCost RegBankSelectImpl::computeMapping(
1058 const RegBankSelectImpl::MappingCost *BestCost) {
1059 assert((MBFI || !BestCost) &&
"Costs comparison require MBFI");
1062 return MappingCost::ImpossibleCost();
1067 bool Saturated =
Cost.addLocalCost(InstrMapping.
getCost());
1068 assert(!Saturated &&
"Possible mapping saturated the cost");
1072 if (BestCost &&
Cost > *BestCost) {
1073 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive from the start\n");
1082 for (
unsigned OpIdx = 0, EndOpIdx = InstrMapping.
getNumOperands();
1083 OpIdx != EndOpIdx; ++OpIdx) {
1096 InstrMapping.getOperandMapping(OpIdx);
1099 if (assignmentMatch(
Reg, ValMapping, Assign)) {
1106 RepairingPlacement::Reassign));
1112 RepairingPlacement::Insert));
1113 RepairingPlacement &RepairPt = RepairPts.
back();
1118 if (RepairPt.hasSplit())
1119 tryAvoidingSplit(RepairPt,
MI, ValMapping);
1122 if (!RepairPt.canMaterialize()) {
1124 return MappingCost::ImpossibleCost();
1129 if (!BestCost || Saturated)
1134 assert(MBFI && MBPI &&
"Cost computation requires MBFI and MBPI");
1146 uint64_t RepairCost = getRepairCost(MO, ValMapping);
1150 return MappingCost::ImpossibleCost();
1153 const uint64_t PercentageForBias = 5;
1154 uint64_t Bias = (RepairCost * PercentageForBias + 99) / 100;
1159 assert(((RepairCost < RepairCost * PercentageForBias) &&
1160 (RepairCost * PercentageForBias <
1161 RepairCost * PercentageForBias + 99)) &&
1162 "Repairing involves more than a billion of instructions?!");
1163 for (
const std::unique_ptr<InsertPoint> &InsertPt : RepairPt) {
1164 assert(InsertPt->canMaterialize() &&
"We should not have made it here");
1166 if (!InsertPt->isSplit())
1167 Saturated =
Cost.addLocalCost(RepairCost);
1169 uint64_t CostForInsertPt = RepairCost;
1172 assert(CostForInsertPt + Bias > CostForInsertPt &&
1173 "Repairing + split bias overflows");
1174 CostForInsertPt += Bias;
1176 InsertPt->frequency(GetCachedMBFI, GetCachedMBPI) * CostForInsertPt;
1178 if ((Saturated = PtCost < CostForInsertPt))
1181 Saturated =
Cost.addNonLocalCost(PtCost);
1186 if (BestCost &&
Cost > *BestCost) {
1187 LLVM_DEBUG(
dbgs() <<
"Mapping is too expensive, stop processing\n");
1201bool RegBankSelectImpl::applyMapping(
1205 std::optional<RegisterBankInfo::OperandsMapper> OpdMapper;
1208 for (RepairingPlacement &RepairPt : RepairPts) {
1209 if (!RepairPt.canMaterialize() ||
1210 RepairPt.getKind() == RepairingPlacement::Impossible)
1212 assert(RepairPt.getKind() != RepairingPlacement::None &&
1213 "This should not make its way in the list");
1214 unsigned OpIdx = RepairPt.getOpIdx();
1217 InstrMapping.getOperandMapping(OpIdx);
1220 switch (RepairPt.getKind()) {
1221 case RepairingPlacement::Reassign:
1223 "Reassignment should only be for simple mapping");
1226 case RepairingPlacement::Insert:
1228 if (
MI.isDebugInstr())
1231 OpdMapper.emplace(
MI, InstrMapping, *MRI);
1232 OpdMapper->createVRegs(OpIdx);
1233 if (!repairReg(MO, ValMapping, RepairPt, OpdMapper->getVRegs(OpIdx)))
1246 OpdMapper.emplace(
MI, InstrMapping, *MRI);
1248 LLVM_DEBUG(
dbgs() <<
"Actual mapping of the operands: " << *OpdMapper
1255bool RegBankSelectImpl::assignInstr(
1260 unsigned Opc =
MI.getOpcode();
1262 assert((
Opc == TargetOpcode::G_ASSERT_ZEXT ||
1263 Opc == TargetOpcode::G_ASSERT_SEXT ||
1264 Opc == TargetOpcode::G_ASSERT_ALIGN) &&
1265 "Unexpected hint opcode!");
1272 assert(RB &&
"Expected source register to have a register bank?");
1273 LLVM_DEBUG(
dbgs() <<
"... Hint always uses source's register bank.\n");
1284 MappingCost DefaultCost = computeMapping(
MI, *BestMapping, RepairPts,
1285 GetCachedMBFI, GetCachedMBPI);
1287 if (DefaultCost == MappingCost::ImpossibleCost())
1292 if (PossibleMappings.
empty())
1294 BestMapping = &findBestMapping(
MI, PossibleMappings, RepairPts,
1295 GetCachedMBFI, GetCachedMBPI);
1298 assert(BestMapping->
verify(
MI) &&
"Invalid instruction mapping");
1304 return applyMapping(
MI, *BestMapping, RepairPts);
1307bool RegBankSelectImpl::assignRegisterBanks(
1322 while (!WorkList.empty()) {
1332 if (
MI.isInlineAsm())
1336 if (
MI.isImplicitDef())
1339 if (!assignInstr(
MI, GetCachedMBFI, GetCachedMBPI)) {
1341 "unable to map instruction",
MI);
1350bool RegBankSelectImpl::checkFunctionIsLegal(
MachineFunction &MF)
const {
1355 "instruction is not legal", *
MI);
1363bool RegBankSelectImpl::runOnMachineFunction(
1381 init(MF, GetMBFI, GetMBPI);
1384 if (!checkFunctionIsLegal(MF))
1388 assignRegisterBanks(MF, GetCachedMBFI, GetCachedMBPI);
1390 OptMode = SaveOptMode;
1397RegBankSelectImpl::RepairingPlacement::RepairingPlacement(
1400 RepairingPlacement::RepairingKind Kind)
1403 CanMaterialize(
Kind != RepairingKind::Impossible),
P(
P) {
1404 const MachineOperand &MO =
MI.getOperand(OpIdx);
1405 assert(MO.
isReg() &&
"Trying to repair a non-reg operand");
1407 if (Kind != RepairingKind::Insert)
1411 bool Before = !MO.
isDef();
1414 if (!
MI.isPHI() && !
MI.isTerminator()) {
1415 addInsertPoint(
MI, Before);
1427 if (It !=
MI.getParent()->end())
1428 addInsertPoint(*It,
true);
1430 addInsertPoint(*(--It),
false);
1434 MachineBasicBlock &Pred = *
MI.getOperand(OpIdx + 1).getMBB();
1439 for (
auto Begin = Pred.
begin(); It != Begin && It->isTerminator(); --It)
1440 if (It->modifiesRegister(
Reg, &
TRI)) {
1443 addInsertPoint(Pred, *
MI.getParent());
1451 if (It == Pred.
end())
1452 addInsertPoint(Pred,
false);
1454 addInsertPoint(*It,
false);
1462 auto REnd =
MI.getParent()->rend();
1464 for (; It != REnd && It->isTerminator(); ++It) {
1466 "copy insertion in middle of terminators not handled");
1470 addInsertPoint(*
MI.getParent()->begin(),
true);
1475 addInsertPoint(*It,
false);
1484 "Do not know where to split");
1486 MachineBasicBlock &Src = *
MI.getParent();
1487 for (
auto &Succ : Src.successors())
1488 addInsertPoint(Src, Succ);
1492void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
MachineInstr &
MI,
1494 addInsertPoint(*
new InstrInsertPoint(
MI, Before));
1497void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1499 addInsertPoint(*
new MBBInsertPoint(
MBB, Beginning));
1502void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1504 addInsertPoint(*
new EdgeInsertPoint(Src, Dst,
P, MFAM));
1507void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
1508 RegBankSelectImpl::InsertPoint &Point) {
1509 CanMaterialize &= Point.canMaterialize();
1510 HasSplit |= Point.isSplit();
1511 InsertPoints.emplace_back(&Point);
1514RegBankSelectImpl::InstrInsertPoint::InstrInsertPoint(
MachineInstr &Instr,
1520 "Splitting before phis requires more points");
1521 assert((!Before || !
Instr.getNextNode() || !
Instr.getNextNode()->isPHI()) &&
1522 "Splitting between phis does not make sense");
1525void RegBankSelectImpl::InstrInsertPoint::materialize() {
1547bool RegBankSelectImpl::InstrInsertPoint::isSplit()
const {
1550 return Instr.isTerminator();
1553 return Instr.getPrevNode() &&
Instr.getPrevNode()->isTerminator();
1556uint64_t RegBankSelectImpl::InstrInsertPoint::frequency(
1567uint64_t RegBankSelectImpl::MBBInsertPoint::frequency(
1576void RegBankSelectImpl::EdgeInsertPoint::materialize() {
1582 "This point has already been split");
1584 assert(NewBB &&
"Invalid call to materialize");
1589uint64_t RegBankSelectImpl::EdgeInsertPoint::frequency(
1595 if (WasMaterialized)
1606bool RegBankSelectImpl::EdgeInsertPoint::canMaterialize()
const {
1611 "Edge is not critical");
1612 return Src.canSplitCriticalEdge(DstOrSplit);
1615RegBankSelectImpl::MappingCost::MappingCost(
BlockFrequency LocalFreq)
1616 : LocalFreq(LocalFreq.getFrequency()) {}
1618bool RegBankSelectImpl::MappingCost::addLocalCost(
uint64_t Cost) {
1620 if (LocalCost +
Cost < LocalCost) {
1625 return isSaturated();
1628bool RegBankSelectImpl::MappingCost::addNonLocalCost(
uint64_t Cost) {
1630 if (NonLocalCost +
Cost < NonLocalCost) {
1634 NonLocalCost +=
Cost;
1635 return isSaturated();
1638bool RegBankSelectImpl::MappingCost::isSaturated()
const {
1643void RegBankSelectImpl::MappingCost::saturate() {
1644 *
this = ImpossibleCost();
1648RegBankSelectImpl::MappingCost
1649RegBankSelectImpl::MappingCost::ImpossibleCost() {
1653bool RegBankSelectImpl::MappingCost::operator<(
const MappingCost &
Cost)
const {
1659 if ((*
this == ImpossibleCost()) || (
Cost == ImpossibleCost()))
1660 return (*
this == ImpossibleCost()) < (
Cost == ImpossibleCost());
1663 if (isSaturated() ||
Cost.isSaturated())
1664 return isSaturated() <
Cost.isSaturated();
1677 if (NonLocalCost ==
Cost.NonLocalCost)
1680 return LocalCost <
Cost.LocalCost;
1684 ThisLocalAdjust = 0;
1685 OtherLocalAdjust = 0;
1686 if (LocalCost <
Cost.LocalCost)
1687 OtherLocalAdjust =
Cost.LocalCost - LocalCost;
1689 ThisLocalAdjust = LocalCost -
Cost.LocalCost;
1691 ThisLocalAdjust = LocalCost;
1692 OtherLocalAdjust =
Cost.LocalCost;
1698 if (NonLocalCost <
Cost.NonLocalCost)
1699 OtherNonLocalAdjust =
Cost.NonLocalCost - NonLocalCost;
1701 ThisNonLocalAdjust = NonLocalCost -
Cost.NonLocalCost;
1703 uint64_t ThisScaledCost = ThisLocalAdjust * LocalFreq;
1705 bool ThisOverflows = ThisLocalAdjust && (ThisScaledCost < ThisLocalAdjust ||
1706 ThisScaledCost < LocalFreq);
1707 uint64_t OtherScaledCost = OtherLocalAdjust *
Cost.LocalFreq;
1709 bool OtherOverflows =
1711 (OtherScaledCost < OtherLocalAdjust || OtherScaledCost <
Cost.LocalFreq);
1713 ThisOverflows |= ThisNonLocalAdjust &&
1714 ThisScaledCost + ThisNonLocalAdjust < ThisNonLocalAdjust;
1715 ThisScaledCost += ThisNonLocalAdjust;
1716 OtherOverflows |= OtherNonLocalAdjust &&
1717 OtherScaledCost + OtherNonLocalAdjust < OtherNonLocalAdjust;
1718 OtherScaledCost += OtherNonLocalAdjust;
1721 if (ThisOverflows && OtherOverflows)
1724 if (ThisOverflows || OtherOverflows)
1725 return ThisOverflows < OtherOverflows;
1727 return ThisScaledCost < OtherScaledCost;
1730bool RegBankSelectImpl::MappingCost::operator==(
const MappingCost &
Cost)
const {
1731 return LocalCost ==
Cost.LocalCost && NonLocalCost ==
Cost.NonLocalCost &&
1732 LocalFreq ==
Cost.LocalFreq;
1735#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1742void RegBankSelectImpl::MappingCost::print(
raw_ostream &OS)
const {
1743 if (*
this == ImpossibleCost()) {
1747 if (isSaturated()) {
1751 OS << LocalFreq <<
" * " << LocalCost <<
" + " << NonLocalCost;
1755 RegBankSelectImpl Impl(OptMode);
1756 return Impl.runOnMachineFunction(
1777 : OptMode(RunningMode) {}
1782 RegBankSelectImpl Impl(OptMode);
1783 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 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.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI 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.