46#define DEBUG_TYPE "hexinsert"
52 cl::desc(
"Vreg# cutoff for insert generation."));
57 cl::desc(
"Vreg distance cutoff for insert "
63 cl::desc(
"Maximum size of OrderedRegisterList"));
69 cl::desc(
"Enable timing of insert generation"));
72 cl::desc(
"Enable detailed timing of insert "
96 explicit RegisterSet(
unsigned s,
bool t =
false) : BitVector(s, t) {}
102 unsigned find_first()
const {
109 unsigned find_next(
unsigned Prev)
const {
117 unsigned Idx = v2x(R);
122 unsigned Idx = v2x(R);
135 reference operator[](
unsigned R) {
136 unsigned Idx = v2x(R);
140 bool operator[](
unsigned R)
const {
141 unsigned Idx = v2x(R);
145 bool has(
unsigned R)
const {
146 unsigned Idx = v2x(R);
156 return Rs.BitVector::subsetOf(*
this);
163 void ensure(
unsigned Idx) {
165 resize(std::max(Idx+1, 32U));
168 static inline unsigned v2x(
unsigned v) {
172 static inline unsigned x2v(
unsigned x) {
173 return Register::index2VirtReg(x);
178 PrintRegSet(
const RegisterSet &S,
const TargetRegisterInfo *RI)
181 friend raw_ostream &
operator<< (raw_ostream &OS,
182 const PrintRegSet &
P);
186 const TargetRegisterInfo *TRI;
191 for (
unsigned R =
P.RS.find_first(); R; R =
P.RS.find_next(R))
199 struct UnsignedMap :
public DenseMap<unsigned,unsigned> {
200 UnsignedMap() =
default;
203 using BaseType = DenseMap<unsigned, unsigned>;
211 struct RegisterOrdering :
public UnsignedMap {
212 RegisterOrdering() =
default;
214 unsigned operator[](
unsigned VR)
const {
215 const_iterator
F =
find(VR);
222 bool operator() (
unsigned VR1,
unsigned VR2)
const {
223 return operator[](VR1) < operator[](VR2);
233 struct BitValueOrdering {
234 BitValueOrdering(
const RegisterOrdering &RB) : BaseOrd(RB) {}
236 bool operator() (
const BitTracker::BitValue &V1,
237 const BitTracker::BitValue &V2)
const;
239 const RegisterOrdering &BaseOrd;
249 if (V1.
is(0) || V2.
is(0))
253 if (V2.
is(1) || V1.
is(1))
256 unsigned Ind1 = BaseOrd[V1.
RefI.
Reg], Ind2 = BaseOrd[V2.
RefI.
Reg];
269 struct CellMapShadow {
270 CellMapShadow(
const BitTracker &
T) :
BT(
T) {}
272 const BitTracker::RegisterCell &
lookup(
unsigned VR) {
273 unsigned RInd =
Register(VR).virtRegIndex();
275 if (RInd >= CVect.size())
276 CVect.resize(std::max(RInd+16, 32U),
nullptr);
277 const BitTracker::RegisterCell *
CP = CVect[RInd];
283 const BitTracker &
BT;
286 using CellVectType = std::vector<const BitTracker::RegisterCell *>;
293 struct RegisterCellLexCompare {
294 RegisterCellLexCompare(
const BitValueOrdering &BO, CellMapShadow &M)
295 : BitOrd(BO), CM(
M) {}
297 bool operator() (
unsigned VR1,
unsigned VR2)
const;
300 const BitValueOrdering &BitOrd;
310 struct RegisterCellBitCompareSel {
311 RegisterCellBitCompareSel(
unsigned R,
unsigned B,
unsigned N,
312 const BitValueOrdering &BO, CellMapShadow &M)
313 : SelR(
R), SelB(
B), BitN(
N), BitOrd(BO), CM(
M) {}
315 bool operator() (
unsigned VR1,
unsigned VR2)
const;
318 const unsigned SelR, SelB;
320 const BitValueOrdering &BitOrd;
326bool RegisterCellLexCompare::operator() (
unsigned VR1,
unsigned VR2)
const {
339 const BitTracker::RegisterCell &RC1 = CM.lookup(VR1), &RC2 = CM.lookup(VR2);
340 uint16_t W1 = RC1.
width(), W2 = RC2.width();
341 for (uint16_t i = 0, w = std::min(W1, W2); i < w; ++i) {
342 const BitTracker::BitValue &V1 = RC1[i], &V2 = RC2[i];
344 return BitOrd(V1, V2);
350 return BitOrd.BaseOrd[VR1] < BitOrd.BaseOrd[VR2];
353bool RegisterCellBitCompareSel::operator() (
unsigned VR1,
unsigned VR2)
const {
356 const BitTracker::RegisterCell &RC1 = CM.lookup(VR1);
357 const BitTracker::RegisterCell &RC2 = CM.lookup(VR2);
359 uint16_t Bit1 = (VR1 == SelR) ? SelB : BitN;
360 uint16_t Bit2 = (VR2 == SelR) ? SelB : BitN;
372 const BitTracker::BitValue &V1 = RC1[Bit1], V2 = RC2[Bit2];
374 return BitOrd(V1, V2);
380 class OrderedRegisterList {
381 using ListType = std::vector<unsigned>;
382 const unsigned MaxSize;
385 OrderedRegisterList(
const RegisterOrdering &RO)
388 void insert(
unsigned VR);
391 unsigned operator[](
unsigned Idx)
const {
396 unsigned size()
const {
400 using iterator = ListType::iterator;
401 using const_iterator = ListType::const_iterator;
403 iterator
begin() {
return Seq.begin(); }
404 iterator
end() {
return Seq.end(); }
405 const_iterator
begin()
const {
return Seq.begin(); }
406 const_iterator
end()
const {
return Seq.end(); }
409 unsigned idx(iterator It)
const {
return It-
begin(); }
413 const RegisterOrdering &Ord;
417 PrintORL(
const OrderedRegisterList &L,
const TargetRegisterInfo *RI)
420 friend raw_ostream &
operator<< (raw_ostream &OS,
const PrintORL &
P);
423 const OrderedRegisterList &RL;
424 const TargetRegisterInfo *
TRI;
427 raw_ostream &
operator<< (raw_ostream &OS,
const PrintORL &
P) {
429 OrderedRegisterList::const_iterator
B =
P.RL.begin(),
E =
P.RL.end();
430 for (OrderedRegisterList::const_iterator
I =
B;
I !=
E; ++
I) {
441void OrderedRegisterList::insert(
unsigned VR) {
448 unsigned S = Seq.size();
451 assert(Seq.size() <= MaxSize);
454void OrderedRegisterList::remove(
unsigned VR) {
466 IFRecord(
unsigned SR = 0,
unsigned IR = 0, uint16_t W = 0, uint16_t O = 0)
467 : SrcR(SR), InsR(
IR), Wdh(
W), Off(
O) {}
474 PrintIFR(
const IFRecord &R,
const TargetRegisterInfo *RI)
478 friend raw_ostream &
operator<< (raw_ostream &OS,
const PrintIFR &
P);
481 const TargetRegisterInfo *
TRI;
484 raw_ostream &
operator<< (raw_ostream &OS,
const PrintIFR &
P) {
485 unsigned SrcR =
P.IFR.SrcR, InsR =
P.IFR.InsR;
487 <<
",#" <<
P.IFR.Wdh <<
",#" <<
P.IFR.Off <<
')';
491 using IFRecordWithRegSet = std::pair<IFRecord, RegisterSet>;
497 class HexagonGenInsert :
public MachineFunctionPass {
501 HexagonGenInsert() : MachineFunctionPass(
ID) {}
503 StringRef getPassName()
const override {
504 return "Hexagon generate \"insert\" instructions";
507 void getAnalysisUsage(AnalysisUsage &AU)
const override {
513 bool runOnMachineFunction(MachineFunction &MF)
override;
516 using PairMapType = DenseMap<std::pair<unsigned, unsigned>,
unsigned>;
518 void buildOrderingMF(RegisterOrdering &RO)
const;
519 void buildOrderingBT(RegisterOrdering &RB, RegisterOrdering &RO)
const;
520 bool isIntClass(
const TargetRegisterClass *RC)
const;
522 bool isSmallConstant(
unsigned VR)
const;
523 bool isValidInsertForm(
unsigned DstR,
unsigned SrcR,
unsigned InsR,
524 uint16_t L, uint16_t S)
const;
525 bool findSelfReference(
unsigned VR)
const;
526 bool findNonSelfReference(
unsigned VR)
const;
527 void getInstrDefs(
const MachineInstr *
MI,
RegisterSet &Defs)
const;
529 unsigned distance(
const MachineBasicBlock *FromB,
530 const MachineBasicBlock *ToB,
const UnsignedMap &RPO,
531 PairMapType &M)
const;
534 PairMapType &M)
const;
535 bool findRecordInsertForms(
unsigned VR, OrderedRegisterList &AVs);
536 void collectInBlock(MachineBasicBlock *
B, OrderedRegisterList &AVs);
537 void findRemovableRegisters(
unsigned VR, IFRecord IF,
539 void computeRemovableRegisters();
541 void pruneEmptyLists();
542 void pruneCoveredSets(
unsigned VR);
543 void pruneUsesTooFar(
unsigned VR,
const UnsignedMap &RPO, PairMapType &M);
544 void pruneRegCopies(
unsigned VR);
545 void pruneCandidates();
546 void selectCandidates();
547 bool generateInserts();
552 using IFListType = std::vector<IFRecordWithRegSet>;
553 using IFMapType = DenseMap<unsigned, IFListType>;
555 void dump_map()
const;
557 const HexagonInstrInfo *HII =
nullptr;
558 const HexagonRegisterInfo *HRI =
nullptr;
560 MachineFunction *MFN;
561 MachineRegisterInfo *
MRI;
562 MachineDominatorTree *MDT;
565 RegisterOrdering BaseOrd;
566 RegisterOrdering CellOrd;
572char HexagonGenInsert::ID = 0;
574void HexagonGenInsert::dump_map()
const {
575 for (
const auto &
I : IFMap) {
577 const IFListType &LL =
I.second;
578 for (
const auto &J : LL)
579 dbgs() <<
" " << PrintIFR(J.first, HRI) <<
", "
580 << PrintRegSet(J.second, HRI) <<
'\n';
584void HexagonGenInsert::buildOrderingMF(RegisterOrdering &RO)
const {
587 for (
const MachineBasicBlock &
B : *MFN) {
591 for (
const MachineInstr &
MI :
B) {
592 for (
const MachineOperand &MO :
MI.operands()) {
593 if (MO.isReg() && MO.isDef()) {
595 assert(MO.getSubReg() == 0 &&
"Unexpected subregister in definition");
597 RO.insert(std::make_pair(R, Index++));
607void HexagonGenInsert::buildOrderingBT(RegisterOrdering &RB,
608 RegisterOrdering &RO)
const {
611 BitValueOrdering BVO(RB);
612 RegisterCellLexCompare LexCmp(BVO, *CMS);
614 using SortableVectorType = std::vector<unsigned>;
616 SortableVectorType VRs;
618 VRs.push_back(
I.first);
621 for (
unsigned i = 0, n = VRs.size(); i < n; ++i)
622 RO.insert(std::make_pair(VRs[i], i));
625inline bool HexagonGenInsert::isIntClass(
const TargetRegisterClass *RC)
const {
626 return RC == &Hexagon::IntRegsRegClass || RC == &Hexagon::DoubleRegsRegClass;
629bool HexagonGenInsert::isConstant(
unsigned VR)
const {
630 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
632 for (uint16_t i = 0; i <
W; ++i) {
633 const BitTracker::BitValue &BV = RC[i];
634 if (BV.
is(0) || BV.
is(1))
641bool HexagonGenInsert::isSmallConstant(
unsigned VR)
const {
642 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
646 uint64_t
V = 0,
B = 1;
647 for (uint16_t i = 0; i <
W; ++i) {
648 const BitTracker::BitValue &BV = RC[i];
664bool HexagonGenInsert::isValidInsertForm(
unsigned DstR,
unsigned SrcR,
665 unsigned InsR, uint16_t L, uint16_t S)
const {
666 const TargetRegisterClass *DstRC =
MRI->getRegClass(DstR);
667 const TargetRegisterClass *SrcRC =
MRI->getRegClass(SrcR);
668 const TargetRegisterClass *InsRC =
MRI->getRegClass(InsR);
670 if (!isIntClass(DstRC) || !isIntClass(SrcRC) || !isIntClass(InsRC))
678 if (DstRC == &Hexagon::DoubleRegsRegClass)
681 if (S < 32 && S+L > 32)
686bool HexagonGenInsert::findSelfReference(
unsigned VR)
const {
687 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
688 for (uint16_t i = 0, w = RC.
width(); i < w; ++i) {
689 const BitTracker::BitValue &
V = RC[i];
696bool HexagonGenInsert::findNonSelfReference(
unsigned VR)
const {
697 BitTracker::RegisterCell RC = CMS->lookup(VR);
698 for (uint16_t i = 0, w = RC.
width(); i < w; ++i) {
699 const BitTracker::BitValue &
V = RC[i];
706void HexagonGenInsert::getInstrDefs(
const MachineInstr *
MI,
708 for (
const MachineOperand &MO :
MI->operands()) {
709 if (!MO.isReg() || !MO.isDef())
718void HexagonGenInsert::getInstrUses(
const MachineInstr *
MI,
720 for (
const MachineOperand &MO :
MI->operands()) {
721 if (!MO.isReg() || !MO.isUse())
730unsigned HexagonGenInsert::distance(
const MachineBasicBlock *FromB,
731 const MachineBasicBlock *ToB,
const UnsignedMap &RPO,
732 PairMapType &M)
const {
739 PairMapType::iterator
F =
M.find(std::make_pair(FromN, ToN));
742 unsigned ToRPO = RPO.lookup(ToN);
750 if (
PB == FromB || RPO.lookup(
PB->getNumber()) >= ToRPO)
752 unsigned D =
PB->size() + distance(FromB,
PB, RPO, M);
758 M.insert(std::make_pair(std::make_pair(FromN, ToN), MaxD));
764 PairMapType &M)
const {
765 const MachineBasicBlock *FB = FromI->getParent(), *
TB = ToI->getParent();
767 return std::distance(FromI, ToI);
768 unsigned D1 = std::distance(
TB->begin(), ToI);
769 unsigned D2 = distance(FB, TB, RPO, M);
770 unsigned D3 = std::distance(FromI, FB->
end());
774bool HexagonGenInsert::findRecordInsertForms(
unsigned VR,
775 OrderedRegisterList &AVs) {
778 <<
" AVs: " << PrintORL(AVs, HRI) <<
"\n";
783 using iterator = OrderedRegisterList::iterator;
785 BitValueOrdering BVO(BaseOrd);
786 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
789 using RSRecord = std::pair<unsigned, uint16_t>;
790 using RSListType = std::vector<RSRecord>;
794 using LRSMapType = DenseMap<unsigned, RSListType>;
800 for (uint16_t S = 0; S <
W; ++S) {
809 for (L = 0;
L <
W-S; ++
L) {
812 RegisterCellBitCompareSel RCB(VR, S+L, L, BVO, *CMS);
813 iterator NewB = std::lower_bound(
B,
E, VR, RCB);
814 iterator NewE = std::upper_bound(NewB,
E, VR, RCB);
820 for (iterator
I =
B;
I != NewB; ++
I)
821 LM[L].push_back(std::make_pair(*
I, S));
822 for (iterator
I = NewE;
I !=
E; ++
I)
823 LM[L].push_back(std::make_pair(*
I, S));
833 for (iterator
I =
B;
I !=
E; ++
I)
834 LM[L].push_back(std::make_pair(*
I, S));
842 dbgs() <<
"Prefixes matching register " <<
printReg(VR, HRI) <<
"\n";
843 for (
const auto &
I : LM) {
844 dbgs() <<
" L=" <<
I.first <<
':';
845 const RSListType &LL =
I.second;
846 for (
const auto &J : LL)
847 dbgs() <<
" (" <<
printReg(J.first, HRI) <<
",@" << J.second <<
')';
852 bool Recorded =
false;
854 for (
unsigned SrcR : AVs) {
855 int FDi = -1, LDi = -1;
856 const BitTracker::RegisterCell &AC = CMS->lookup(SrcR);
857 uint16_t AW = AC.
width();
858 for (uint16_t i = 0, w = std::min(W, AW); i < w; ++i) {
869 uint16_t FD = FDi,
LD = LDi;
870 uint16_t MinL =
LD-FD+1;
871 for (uint16_t L = MinL;
L <
W; ++
L) {
872 LRSMapType::iterator
F = LM.find(L);
875 RSListType &LL =
F->second;
876 for (
const auto &
I : LL) {
877 uint16_t S =
I.second;
884 uint16_t EL =
L-MinL;
885 uint16_t LowS = (EL < FD) ? FD-EL : 0;
888 unsigned InsR =
I.first;
889 if (!isValidInsertForm(VR, SrcR, InsR, L, S))
893 <<
',' <<
printReg(InsR, HRI) <<
",#" <<
L <<
",#"
896 IFRecordWithRegSet RR(IFRecord(SrcR, InsR, L, S),
RegisterSet());
897 IFMap[VR].push_back(RR);
906void HexagonGenInsert::collectInBlock(MachineBasicBlock *
B,
907 OrderedRegisterList &AVs) {
921 for (MachineInstr &
MI : *
B) {
927 getInstrDefs(&
MI, InsDefs);
929 bool Skip =
MI.isCopy() ||
MI.isRegSequence();
934 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR)) {
943 if (findSelfReference(VR) || isSmallConstant(VR))
946 findRecordInsertForms(VR, AVs);
955 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR))
957 BlockDefs.insert(InsDefs);
961 MachineBasicBlock *SB = DTN->getBlock();
962 collectInBlock(SB, AVs);
965 for (
unsigned VR = BlockDefs.find_first(); VR; VR = BlockDefs.find_next(VR))
969void HexagonGenInsert::findRemovableRegisters(
unsigned VR, IFRecord IF,
980 while (!Regs[S].
empty()) {
982 unsigned OtherS = 1-S;
983 Regs[OtherS].clear();
984 for (
unsigned R = Regs[S].find_first();
R;
R = Regs[S].find_next(R)) {
986 if (R == IF.SrcR || R == IF.InsR)
998 if (!findNonSelfReference(R))
1001 const MachineInstr *DefI =
MRI->getVRegDef(R);
1008 getInstrUses(DefI, Regs[OtherS]);
1020void HexagonGenInsert::computeRemovableRegisters() {
1021 for (
auto &
I : IFMap) {
1022 IFListType &LL =
I.second;
1024 findRemovableRegisters(
I.first, J.first, J.second);
1028void HexagonGenInsert::pruneEmptyLists() {
1033 for (IFMapType::iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
1034 if (
I->second.empty())
1037 for (
const auto &It : Prune)
1041void HexagonGenInsert::pruneCoveredSets(
unsigned VR) {
1042 IFMapType::iterator
F = IFMap.find(VR);
1044 IFListType &LL =
F->second;
1053 MachineInstr *DefVR =
MRI->getVRegDef(VR);
1056 for (
const auto &
I : LL) {
1057 if (
I.second.empty())
1062 if (!DefEx || HasNE) {
1065 auto IsEmpty = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1066 return IR.second.empty();
1075 IFRecord MaxIF = LL[0].first;
1076 for (
unsigned i = 1, n = LL.size(); i < n; ++i) {
1078 const IFRecord &IF = LL[i].first;
1079 unsigned M0 = BaseOrd[MaxIF.SrcR],
M1 = BaseOrd[MaxIF.InsR];
1080 unsigned R0 = BaseOrd[IF.SrcR], R1 = BaseOrd[IF.InsR];
1087 if (MaxIF.Wdh > IF.Wdh)
1089 if (MaxIF.Wdh == IF.Wdh && MaxIF.Off >= IF.Off)
1099 LL.push_back(std::make_pair(MaxIF,
RegisterSet()));
1109 for (
unsigned i = 0, n = LL.size(); i < n; ) {
1113 if (j != i && LL[j].second.includes(RMi))
1121 LL.erase(LL.begin()+i);
1126void HexagonGenInsert::pruneUsesTooFar(
unsigned VR,
const UnsignedMap &RPO,
1128 IFMapType::iterator
F = IFMap.find(VR);
1130 IFListType &LL =
F->second;
1132 const MachineInstr *DefV =
MRI->getVRegDef(VR);
1134 for (
unsigned i = LL.size(); i > 0; --i) {
1135 unsigned SR = LL[i-1].first.SrcR,
IR = LL[i-1].first.InsR;
1136 const MachineInstr *DefS =
MRI->getVRegDef(SR);
1137 const MachineInstr *DefI =
MRI->getVRegDef(
IR);
1138 unsigned DSV = distance(DefS, DefV, RPO, M);
1140 unsigned DIV = distance(DefI, DefV, RPO, M);
1144 LL.erase(LL.begin()+(i-1));
1148void HexagonGenInsert::pruneRegCopies(
unsigned VR) {
1149 IFMapType::iterator
F = IFMap.find(VR);
1151 IFListType &LL =
F->second;
1153 auto IsCopy = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1154 return IR.first.Wdh == 32 && (
IR.first.Off == 0 ||
IR.first.Off == 32);
1159void HexagonGenInsert::pruneCandidates() {
1164 for (
const auto &
I : IFMap)
1165 pruneCoveredSets(
I.first);
1169 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
1173 for (
const auto &
I : RPOT)
1174 RPO[
I->getNumber()] = RPON++;
1178 for (
const auto &
I : IFMap)
1179 pruneUsesTooFar(
I.first, RPO, Memo);
1183 for (
const auto &
I : IFMap)
1184 pruneRegCopies(
I.first);
1198 IFOrdering(
const UnsignedMap &UC,
const RegisterOrdering &BO)
1199 : UseC(UC), BaseOrd(BO) {}
1201 bool operator() (
const IFRecordWithRegSet &
A,
1202 const IFRecordWithRegSet &
B)
const;
1206 unsigned &Sum)
const;
1208 const UnsignedMap &UseC;
1209 const RegisterOrdering &BaseOrd;
1214bool IFOrdering::operator() (
const IFRecordWithRegSet &
A,
1215 const IFRecordWithRegSet &
B)
const {
1216 unsigned SizeA = 0, ZeroA = 0, SumA = 0;
1217 unsigned SizeB = 0, ZeroB = 0, SumB = 0;
1218 stats(
A.second, SizeA, ZeroA, SumA);
1219 stats(
B.second, SizeB, ZeroB, SumB);
1223 return ZeroA > ZeroB;
1225 uint64_t AvgA = SumA*SizeB, AvgB = SumB*SizeA;
1231 unsigned OSA = BaseOrd[
A.first.SrcR], OSB = BaseOrd[
B.first.SrcR];
1234 unsigned OIA = BaseOrd[
A.first.InsR], OIB = BaseOrd[
B.first.InsR];
1237 if (
A.first.Wdh !=
B.first.Wdh)
1238 return A.first.Wdh <
B.first.Wdh;
1239 return A.first.Off <
B.first.Off;
1242void IFOrdering::stats(
const RegisterSet &Rs,
unsigned &
Size,
unsigned &Zero,
1243 unsigned &Sum)
const {
1244 for (
unsigned R = Rs.find_first(); R; R = Rs.find_next(R)) {
1245 UnsignedMap::const_iterator
F = UseC.find(R);
1247 unsigned UC =
F->second;
1255void HexagonGenInsert::selectCandidates() {
1263 UnsignedMap UseC, RemC;
1264 IFMapType::iterator End = IFMap.
end();
1266 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1267 const IFListType &LL =
I->second;
1269 for (
const auto &J : LL)
1270 TT.insert(J.second);
1271 for (
unsigned R =
TT.find_first(); R; R =
TT.find_next(R))
1276 for (
unsigned R = AllRMs.find_first(); R; R = AllRMs.find_next(R)) {
1278 using InstrSet = SmallPtrSet<const MachineInstr *, 16>;
1283 use_iterator
E =
MRI->use_nodbg_end();
1284 for (use_iterator
I =
MRI->use_nodbg_begin(R);
I !=
E; ++
I)
1285 UIs.insert(
I->getParent());
1286 unsigned C = UIs.size();
1289 unsigned D = RemC[
R];
1290 UseC[
R] = (
C >
D) ?
C-
D : 0;
1294 if (!SelectAll0 && !SelectHas0)
1302 IFOrdering IFO(UseC, BaseOrd);
1303 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1304 IFListType &LL =
I->second;
1312 assert(MinI != LL.end());
1313 IFRecordWithRegSet
M = *MinI;
1323 const MachineInstr *DefI =
MRI->getVRegDef(
I->first);
1324 getInstrUses(DefI, Us);
1325 bool Accept =
false;
1329 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1336 }
else if (SelectHas0) {
1338 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1355 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1356 const IFListType &LL =
I->second;
1358 AllRMs.insert(LL[0].second);
1360 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1361 IFListType &LL =
I->second;
1364 unsigned SR = LL[0].first.SrcR,
IR = LL[0].first.InsR;
1365 if (AllRMs[SR] || AllRMs[
IR])
1372bool HexagonGenInsert::generateInserts() {
1376 for (
auto &
I : IFMap) {
1377 unsigned VR =
I.first;
1378 const TargetRegisterClass *RC =
MRI->getRegClass(VR);
1386 for (
auto &
I : IFMap) {
1387 MachineInstr *
MI =
MRI->getVRegDef(
I.first);
1388 MachineBasicBlock &
B = *
MI->getParent();
1390 unsigned NewR = RegMap[
I.first];
1391 bool R32 =
MRI->getRegClass(NewR) == &Hexagon::IntRegsRegClass;
1392 const MCInstrDesc &
D = R32 ? HII->get(Hexagon::S2_insert)
1393 : HII->get(Hexagon::S2_insertp);
1394 IFRecord IF =
I.second[0].first;
1395 unsigned Wdh = IF.Wdh,
Off = IF.Off;
1397 if (R32 &&
MRI->getRegClass(IF.InsR) == &Hexagon::DoubleRegsRegClass) {
1398 InsS = Hexagon::isub_lo;
1400 InsS = Hexagon::isub_hi;
1408 At =
B.getFirstNonPHI();
1412 .
addReg(IF.InsR, 0, InsS)
1416 MRI->clearKillFlags(IF.SrcR);
1417 MRI->clearKillFlags(IF.InsR);
1420 for (
const auto &
I : IFMap) {
1421 MachineInstr *DefI =
MRI->getVRegDef(
I.first);
1422 MRI->replaceRegWith(
I.first, RegMap[
I.first]);
1433 Changed |= removeDeadCode(DTN);
1435 MachineBasicBlock *
B =
N->getBlock();
1436 std::vector<MachineInstr*> Instrs;
1438 Instrs.push_back(&
MI);
1440 for (MachineInstr *
MI : Instrs) {
1441 unsigned Opc =
MI->getOpcode();
1444 if (
Opc == TargetOpcode::LIFETIME_START ||
1445 Opc == TargetOpcode::LIFETIME_END)
1448 if (
MI->isInlineAsm() || !
MI->isSafeToMove(Store))
1451 bool AllDead =
true;
1452 SmallVector<unsigned,2> Regs;
1453 for (
const MachineOperand &MO :
MI->operands()) {
1454 if (!MO.isReg() || !MO.isDef())
1457 if (!
R.isVirtual() || !
MRI->use_nodbg_empty(R)) {
1467 for (
unsigned Reg : Regs)
1468 MRI->markUsesInDebugValueAsUndef(
Reg);
1475bool HexagonGenInsert::runOnMachineFunction(MachineFunction &MF) {
1490 HII =
ST.getInstrInfo();
1491 HRI =
ST.getRegisterInfo();
1494 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1503 const HexagonEvaluator HE(*HRI, *
MRI, *HII, MF);
1504 BitTracker BTLoc(HE, MF);
1507 CellMapShadow MS(BTLoc);
1510 buildOrderingMF(BaseOrd);
1511 buildOrderingBT(BaseOrd, CellOrd);
1514 dbgs() <<
"Cell ordering:\n";
1515 for (
const auto &
I : CellOrd) {
1516 unsigned VR =
I.first, Pos =
I.second;
1522 MachineBasicBlock *RootB = MDT->
getRoot();
1523 OrderedRegisterList AvailR(CellOrd);
1525 const char *
const TGName =
"hexinsert";
1526 const char *
const TGDesc =
"Generate Insert Instructions";
1529 NamedRegionTimer _T(
"collection",
"collection", TGName, TGDesc,
1531 collectInBlock(RootB, AvailR);
1533 computeRemovableRegisters();
1537 dbgs() <<
"Candidates after collection:\n";
1545 NamedRegionTimer _T(
"pruning",
"pruning", TGName, TGDesc, TimingDetail);
1550 dbgs() <<
"Candidates after pruning:\n";
1558 NamedRegionTimer _T(
"selection",
"selection", TGName, TGDesc, TimingDetail);
1563 dbgs() <<
"Candidates after selection:\n";
1574 for (IFMapType::iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
1575 unsigned Idx =
Register(
I->first).virtRegIndex();
1579 for (
const auto &It : Out)
1586 NamedRegionTimer _T(
"generation",
"generation", TGName, TGDesc,
1595 return new HexagonGenInsert();
1603 "Hexagon generate \"insert\" instructions",
false,
false)
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< ArrayRef< InsnRange >::iterator > intersects(const MachineInstr *StartMI, const MachineInstr *EndMI, ArrayRef< InsnRange > Ranges, const InstructionOrdering &Ordering)
Check if the instruction range [StartMI, EndMI] intersects any instruction range in Ranges.
This file defines the DenseMap class.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
static cl::opt< bool > OptConst("insert-const", cl::init(false), cl::Hidden)
static cl::opt< unsigned > MaxORLSize("insert-max-orl", cl::init(4096), cl::Hidden, cl::desc("Maximum size of OrderedRegisterList"))
static cl::opt< unsigned > MaxIFMSize("insert-max-ifmap", cl::init(1024), cl::Hidden, cl::desc("Maximum size of IFMap"))
static cl::opt< bool > OptTimingDetail("insert-timing-detail", cl::Hidden, cl::desc("Enable detailed timing of insert " "generation"))
static cl::opt< bool > OptTiming("insert-timing", cl::Hidden, cl::desc("Enable timing of insert generation"))
static cl::opt< unsigned > VRegDistCutoff("insert-dist-cutoff", cl::init(30U), cl::Hidden, cl::desc("Vreg distance cutoff for insert " "generation."))
static cl::opt< bool > OptSelectAll0("insert-all0", cl::init(false), cl::Hidden)
static cl::opt< unsigned > VRegIndexCutoff("insert-vreg-cutoff", cl::init(~0U), cl::Hidden, cl::desc("Vreg# cutoff for insert generation."))
static cl::opt< bool > OptSelectHas0("insert-has0", cl::init(false), cl::Hidden)
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
Legalize the Machine IR a function s Machine IR
Register const TargetRegisterInfo * TRI
Promote Memory to Register
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#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.
Remove Loads Into Fake Uses
This file defines the SmallVector class.
SmallSet< unsigned, 4 > RegisterSet
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
bool test(unsigned Idx) const
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
bool anyCommon(const BitVector &RHS) const
Test if any common bits are set.
bool any() const
any - Returns true if any bit is set.
BitVector & operator|=(const BitVector &RHS)
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
reference operator[](unsigned Idx)
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
FunctionPass class - This class is used to implement most global optimizations.
bool isConstExtended(const MachineInstr &MI) const
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
defusechain_iterator< true, false, true, true, false > use_nodbg_iterator
use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the specified register,...
SmallSet & operator=(const SmallSet &)=default
const_iterator end() const
std::pair< const_iterator, bool > insert(const unsigned &V)
void push_back(const T &Elt)
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
initializer< Ty > init(const Ty &Val)
LLVM_ABI iterator begin() const
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool includes(R1 &&Range1, R2 &&Range2)
Provide wrappers to std::includes which take ranges instead of having to pass begin/end explicitly.
auto min_element(R &&Range)
Provide wrappers to std::min_element which take ranges instead of having to pass begin/end explicitly...
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.
LLVM_ABI bool isCurrentDebugType(const char *Type, int Level=0)
isCurrentDebugType - Return true if the specified string is the debug type specified on the command l...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
unsigned M1(unsigned Val)
LLVM_ABI bool DebugFlag
This boolean is set to true if the '-debug' command line option is specified.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionPass * createHexagonGenInsert()
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
FunctionAddr VTableAddr Next
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
bool is(unsigned T) const
const RegisterCell & lookup(unsigned Reg) const
bool reached(const MachineBasicBlock *B) const