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);
157 return !Rs.BitVector::test(*
this);
164 void ensure(
unsigned Idx) {
166 resize(std::max(Idx+1, 32U));
169 static inline unsigned v2x(
unsigned v) {
173 static inline unsigned x2v(
unsigned x) {
174 return Register::index2VirtReg(x);
179 PrintRegSet(
const RegisterSet &S,
const TargetRegisterInfo *RI)
182 friend raw_ostream &
operator<< (raw_ostream &OS,
183 const PrintRegSet &
P);
187 const TargetRegisterInfo *TRI;
192 for (
unsigned R =
P.RS.find_first(); R; R =
P.RS.find_next(R))
200 struct UnsignedMap :
public DenseMap<unsigned,unsigned> {
201 UnsignedMap() =
default;
204 using BaseType = DenseMap<unsigned, unsigned>;
212 struct RegisterOrdering :
public UnsignedMap {
213 RegisterOrdering() =
default;
215 unsigned operator[](
unsigned VR)
const {
216 const_iterator
F =
find(VR);
223 bool operator() (
unsigned VR1,
unsigned VR2)
const {
224 return operator[](VR1) < operator[](VR2);
234 struct BitValueOrdering {
235 BitValueOrdering(
const RegisterOrdering &RB) : BaseOrd(RB) {}
237 bool operator() (
const BitTracker::BitValue &V1,
238 const BitTracker::BitValue &V2)
const;
240 const RegisterOrdering &BaseOrd;
250 if (V1.
is(0) || V2.
is(0))
254 if (V2.
is(1) || V1.
is(1))
257 unsigned Ind1 = BaseOrd[V1.
RefI.
Reg], Ind2 = BaseOrd[V2.
RefI.
Reg];
270 struct CellMapShadow {
271 CellMapShadow(
const BitTracker &
T) :
BT(
T) {}
273 const BitTracker::RegisterCell &
lookup(
unsigned VR) {
274 unsigned RInd =
Register(VR).virtRegIndex();
276 if (RInd >= CVect.size())
277 CVect.resize(std::max(RInd+16, 32U),
nullptr);
278 const BitTracker::RegisterCell *
CP = CVect[RInd];
284 const BitTracker &
BT;
287 using CellVectType = std::vector<const BitTracker::RegisterCell *>;
294 struct RegisterCellLexCompare {
295 RegisterCellLexCompare(
const BitValueOrdering &BO, CellMapShadow &M)
296 : BitOrd(BO), CM(
M) {}
298 bool operator() (
unsigned VR1,
unsigned VR2)
const;
301 const BitValueOrdering &BitOrd;
311 struct RegisterCellBitCompareSel {
312 RegisterCellBitCompareSel(
unsigned R,
unsigned B,
unsigned N,
313 const BitValueOrdering &BO, CellMapShadow &M)
314 : SelR(
R), SelB(
B), BitN(
N), BitOrd(BO), CM(
M) {}
316 bool operator() (
unsigned VR1,
unsigned VR2)
const;
319 const unsigned SelR, SelB;
321 const BitValueOrdering &BitOrd;
327bool RegisterCellLexCompare::operator() (
unsigned VR1,
unsigned VR2)
const {
340 const BitTracker::RegisterCell &RC1 = CM.lookup(VR1), &RC2 = CM.lookup(VR2);
341 uint16_t W1 = RC1.
width(), W2 = RC2.width();
342 for (uint16_t i = 0, w = std::min(W1, W2); i < w; ++i) {
343 const BitTracker::BitValue &V1 = RC1[i], &V2 = RC2[i];
345 return BitOrd(V1, V2);
351 return BitOrd.BaseOrd[VR1] < BitOrd.BaseOrd[VR2];
354bool RegisterCellBitCompareSel::operator() (
unsigned VR1,
unsigned VR2)
const {
357 const BitTracker::RegisterCell &RC1 = CM.lookup(VR1);
358 const BitTracker::RegisterCell &RC2 = CM.lookup(VR2);
360 uint16_t Bit1 = (VR1 == SelR) ? SelB : BitN;
361 uint16_t Bit2 = (VR2 == SelR) ? SelB : BitN;
373 const BitTracker::BitValue &V1 = RC1[Bit1], V2 = RC2[Bit2];
375 return BitOrd(V1, V2);
381 class OrderedRegisterList {
382 using ListType = std::vector<unsigned>;
383 const unsigned MaxSize;
386 OrderedRegisterList(
const RegisterOrdering &RO)
389 void insert(
unsigned VR);
392 unsigned operator[](
unsigned Idx)
const {
397 unsigned size()
const {
401 using iterator = ListType::iterator;
402 using const_iterator = ListType::const_iterator;
404 iterator
begin() {
return Seq.begin(); }
405 iterator
end() {
return Seq.end(); }
406 const_iterator
begin()
const {
return Seq.begin(); }
407 const_iterator
end()
const {
return Seq.end(); }
410 unsigned idx(iterator It)
const {
return It-
begin(); }
414 const RegisterOrdering &Ord;
418 PrintORL(
const OrderedRegisterList &L,
const TargetRegisterInfo *RI)
421 friend raw_ostream &
operator<< (raw_ostream &OS,
const PrintORL &
P);
424 const OrderedRegisterList &RL;
425 const TargetRegisterInfo *
TRI;
428 raw_ostream &
operator<< (raw_ostream &OS,
const PrintORL &
P) {
430 OrderedRegisterList::const_iterator
B =
P.RL.begin(),
E =
P.RL.end();
431 for (OrderedRegisterList::const_iterator
I =
B;
I !=
E; ++
I) {
442void OrderedRegisterList::insert(
unsigned VR) {
449 unsigned S = Seq.size();
452 assert(Seq.size() <= MaxSize);
455void OrderedRegisterList::remove(
unsigned VR) {
467 IFRecord(
unsigned SR = 0,
unsigned IR = 0, uint16_t W = 0, uint16_t O = 0)
468 : SrcR(SR), InsR(
IR), Wdh(
W), Off(
O) {}
475 PrintIFR(
const IFRecord &R,
const TargetRegisterInfo *RI)
479 friend raw_ostream &
operator<< (raw_ostream &OS,
const PrintIFR &
P);
482 const TargetRegisterInfo *
TRI;
485 raw_ostream &
operator<< (raw_ostream &OS,
const PrintIFR &
P) {
486 unsigned SrcR =
P.IFR.SrcR, InsR =
P.IFR.InsR;
488 <<
",#" <<
P.IFR.Wdh <<
",#" <<
P.IFR.Off <<
')';
492 using IFRecordWithRegSet = std::pair<IFRecord, RegisterSet>;
498 class HexagonGenInsert :
public MachineFunctionPass {
502 HexagonGenInsert() : MachineFunctionPass(
ID) {}
504 StringRef getPassName()
const override {
505 return "Hexagon generate \"insert\" instructions";
508 void getAnalysisUsage(AnalysisUsage &AU)
const override {
514 bool runOnMachineFunction(MachineFunction &MF)
override;
517 using PairMapType = DenseMap<std::pair<unsigned, unsigned>,
unsigned>;
519 void buildOrderingMF(RegisterOrdering &RO)
const;
520 void buildOrderingBT(RegisterOrdering &RB, RegisterOrdering &RO)
const;
521 bool isIntClass(
const TargetRegisterClass *RC)
const;
523 bool isSmallConstant(
unsigned VR)
const;
524 bool isValidInsertForm(
unsigned DstR,
unsigned SrcR,
unsigned InsR,
525 uint16_t L, uint16_t S)
const;
526 bool findSelfReference(
unsigned VR)
const;
527 bool findNonSelfReference(
unsigned VR)
const;
528 void getInstrDefs(
const MachineInstr *
MI,
RegisterSet &Defs)
const;
530 unsigned distance(
const MachineBasicBlock *FromB,
531 const MachineBasicBlock *ToB,
const UnsignedMap &RPO,
532 PairMapType &M)
const;
535 PairMapType &M)
const;
536 bool findRecordInsertForms(
unsigned VR, OrderedRegisterList &AVs);
537 void collectInBlock(MachineBasicBlock *
B, OrderedRegisterList &AVs);
538 void findRemovableRegisters(
unsigned VR, IFRecord IF,
540 void computeRemovableRegisters();
542 void pruneEmptyLists();
543 void pruneCoveredSets(
unsigned VR);
544 void pruneUsesTooFar(
unsigned VR,
const UnsignedMap &RPO, PairMapType &M);
545 void pruneRegCopies(
unsigned VR);
546 void pruneCandidates();
547 void selectCandidates();
548 bool generateInserts();
553 using IFListType = std::vector<IFRecordWithRegSet>;
554 using IFMapType = DenseMap<unsigned, IFListType>;
556 void dump_map()
const;
558 const HexagonInstrInfo *HII =
nullptr;
559 const HexagonRegisterInfo *HRI =
nullptr;
561 MachineFunction *MFN;
562 MachineRegisterInfo *
MRI;
563 MachineDominatorTree *MDT;
566 RegisterOrdering BaseOrd;
567 RegisterOrdering CellOrd;
573char HexagonGenInsert::ID = 0;
575void HexagonGenInsert::dump_map()
const {
576 for (
const auto &
I : IFMap) {
578 const IFListType &LL =
I.second;
579 for (
const auto &J : LL)
580 dbgs() <<
" " << PrintIFR(J.first, HRI) <<
", "
581 << PrintRegSet(J.second, HRI) <<
'\n';
585void HexagonGenInsert::buildOrderingMF(RegisterOrdering &RO)
const {
588 for (
const MachineBasicBlock &
B : *MFN) {
592 for (
const MachineInstr &
MI :
B) {
593 for (
const MachineOperand &MO :
MI.operands()) {
594 if (MO.isReg() && MO.isDef()) {
596 assert(MO.getSubReg() == 0 &&
"Unexpected subregister in definition");
598 RO.insert(std::make_pair(R, Index++));
608void HexagonGenInsert::buildOrderingBT(RegisterOrdering &RB,
609 RegisterOrdering &RO)
const {
612 BitValueOrdering BVO(RB);
613 RegisterCellLexCompare LexCmp(BVO, *CMS);
615 using SortableVectorType = std::vector<unsigned>;
617 SortableVectorType VRs;
619 VRs.push_back(
I.first);
622 for (
unsigned i = 0, n = VRs.size(); i < n; ++i)
623 RO.insert(std::make_pair(VRs[i], i));
626inline bool HexagonGenInsert::isIntClass(
const TargetRegisterClass *RC)
const {
627 return RC == &Hexagon::IntRegsRegClass || RC == &Hexagon::DoubleRegsRegClass;
630bool HexagonGenInsert::isConstant(
unsigned VR)
const {
631 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
633 for (uint16_t i = 0; i <
W; ++i) {
634 const BitTracker::BitValue &BV = RC[i];
635 if (BV.
is(0) || BV.
is(1))
642bool HexagonGenInsert::isSmallConstant(
unsigned VR)
const {
643 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
647 uint64_t
V = 0,
B = 1;
648 for (uint16_t i = 0; i <
W; ++i) {
649 const BitTracker::BitValue &BV = RC[i];
665bool HexagonGenInsert::isValidInsertForm(
unsigned DstR,
unsigned SrcR,
666 unsigned InsR, uint16_t L, uint16_t S)
const {
667 const TargetRegisterClass *DstRC =
MRI->getRegClass(DstR);
668 const TargetRegisterClass *SrcRC =
MRI->getRegClass(SrcR);
669 const TargetRegisterClass *InsRC =
MRI->getRegClass(InsR);
671 if (!isIntClass(DstRC) || !isIntClass(SrcRC) || !isIntClass(InsRC))
679 if (DstRC == &Hexagon::DoubleRegsRegClass)
682 if (S < 32 && S+L > 32)
687bool HexagonGenInsert::findSelfReference(
unsigned VR)
const {
688 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
689 for (uint16_t i = 0, w = RC.
width(); i < w; ++i) {
690 const BitTracker::BitValue &
V = RC[i];
697bool HexagonGenInsert::findNonSelfReference(
unsigned VR)
const {
698 BitTracker::RegisterCell RC = CMS->lookup(VR);
699 for (uint16_t i = 0, w = RC.
width(); i < w; ++i) {
700 const BitTracker::BitValue &
V = RC[i];
707void HexagonGenInsert::getInstrDefs(
const MachineInstr *
MI,
709 for (
const MachineOperand &MO :
MI->operands()) {
710 if (!MO.isReg() || !MO.isDef())
719void HexagonGenInsert::getInstrUses(
const MachineInstr *
MI,
721 for (
const MachineOperand &MO :
MI->operands()) {
722 if (!MO.isReg() || !MO.isUse())
731unsigned HexagonGenInsert::distance(
const MachineBasicBlock *FromB,
732 const MachineBasicBlock *ToB,
const UnsignedMap &RPO,
733 PairMapType &M)
const {
740 PairMapType::iterator
F =
M.find(std::make_pair(FromN, ToN));
743 unsigned ToRPO = RPO.lookup(ToN);
751 if (
PB == FromB || RPO.lookup(
PB->getNumber()) >= ToRPO)
753 unsigned D =
PB->size() + distance(FromB,
PB, RPO, M);
759 M.insert(std::make_pair(std::make_pair(FromN, ToN), MaxD));
765 PairMapType &M)
const {
766 const MachineBasicBlock *FB = FromI->getParent(), *
TB = ToI->getParent();
768 return std::distance(FromI, ToI);
769 unsigned D1 = std::distance(
TB->begin(), ToI);
770 unsigned D2 = distance(FB, TB, RPO, M);
771 unsigned D3 = std::distance(FromI, FB->
end());
775bool HexagonGenInsert::findRecordInsertForms(
unsigned VR,
776 OrderedRegisterList &AVs) {
779 <<
" AVs: " << PrintORL(AVs, HRI) <<
"\n";
784 using iterator = OrderedRegisterList::iterator;
786 BitValueOrdering BVO(BaseOrd);
787 const BitTracker::RegisterCell &RC = CMS->lookup(VR);
790 using RSRecord = std::pair<unsigned, uint16_t>;
791 using RSListType = std::vector<RSRecord>;
795 using LRSMapType = DenseMap<unsigned, RSListType>;
801 for (uint16_t S = 0; S <
W; ++S) {
810 for (L = 0;
L <
W-S; ++
L) {
813 RegisterCellBitCompareSel RCB(VR, S+L, L, BVO, *CMS);
814 iterator NewB = std::lower_bound(
B,
E, VR, RCB);
815 iterator NewE = std::upper_bound(NewB,
E, VR, RCB);
821 for (iterator
I =
B;
I != NewB; ++
I)
822 LM[L].push_back(std::make_pair(*
I, S));
823 for (iterator
I = NewE;
I !=
E; ++
I)
824 LM[L].push_back(std::make_pair(*
I, S));
834 for (iterator
I =
B;
I !=
E; ++
I)
835 LM[L].push_back(std::make_pair(*
I, S));
843 dbgs() <<
"Prefixes matching register " <<
printReg(VR, HRI) <<
"\n";
844 for (
const auto &
I : LM) {
845 dbgs() <<
" L=" <<
I.first <<
':';
846 const RSListType &LL =
I.second;
847 for (
const auto &J : LL)
848 dbgs() <<
" (" <<
printReg(J.first, HRI) <<
",@" << J.second <<
')';
853 bool Recorded =
false;
855 for (
unsigned SrcR : AVs) {
856 int FDi = -1, LDi = -1;
857 const BitTracker::RegisterCell &AC = CMS->lookup(SrcR);
858 uint16_t AW = AC.
width();
859 for (uint16_t i = 0, w = std::min(W, AW); i < w; ++i) {
870 uint16_t FD = FDi,
LD = LDi;
871 uint16_t MinL =
LD-FD+1;
872 for (uint16_t L = MinL;
L <
W; ++
L) {
873 LRSMapType::iterator
F = LM.find(L);
876 RSListType &LL =
F->second;
877 for (
const auto &
I : LL) {
878 uint16_t S =
I.second;
885 uint16_t EL =
L-MinL;
886 uint16_t LowS = (EL < FD) ? FD-EL : 0;
889 unsigned InsR =
I.first;
890 if (!isValidInsertForm(VR, SrcR, InsR, L, S))
894 <<
',' <<
printReg(InsR, HRI) <<
",#" <<
L <<
",#"
897 IFRecordWithRegSet RR(IFRecord(SrcR, InsR, L, S),
RegisterSet());
898 IFMap[VR].push_back(RR);
907void HexagonGenInsert::collectInBlock(MachineBasicBlock *
B,
908 OrderedRegisterList &AVs) {
922 for (MachineInstr &
MI : *
B) {
924 getInstrDefs(&
MI, InsDefs);
926 bool Skip =
MI.isCopy() ||
MI.isRegSequence();
931 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR)) {
940 if (findSelfReference(VR) || isSmallConstant(VR))
943 findRecordInsertForms(VR, AVs);
952 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR))
954 BlockDefs.insert(InsDefs);
958 MachineBasicBlock *SB = DTN->getBlock();
959 collectInBlock(SB, AVs);
962 for (
unsigned VR = BlockDefs.find_first(); VR; VR = BlockDefs.find_next(VR))
966void HexagonGenInsert::findRemovableRegisters(
unsigned VR, IFRecord IF,
977 while (!Regs[S].
empty()) {
979 unsigned OtherS = 1-S;
980 Regs[OtherS].clear();
981 for (
unsigned R = Regs[S].find_first();
R;
R = Regs[S].find_next(R)) {
983 if (R ==
IF.SrcR || R ==
IF.InsR)
995 if (!findNonSelfReference(R))
998 const MachineInstr *DefI =
MRI->getVRegDef(R);
1005 getInstrUses(DefI, Regs[OtherS]);
1017void HexagonGenInsert::computeRemovableRegisters() {
1018 for (
auto &
I : IFMap) {
1019 IFListType &LL =
I.second;
1021 findRemovableRegisters(
I.first, J.first, J.second);
1025void HexagonGenInsert::pruneEmptyLists() {
1030 for (IFMapType::iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
1031 if (
I->second.empty())
1034 for (
const auto &It : Prune)
1038void HexagonGenInsert::pruneCoveredSets(
unsigned VR) {
1039 IFMapType::iterator
F = IFMap.find(VR);
1041 IFListType &LL =
F->second;
1050 MachineInstr *DefVR =
MRI->getVRegDef(VR);
1053 for (
const auto &
I : LL) {
1054 if (
I.second.empty())
1059 if (!DefEx || HasNE) {
1062 auto IsEmpty = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1063 return IR.second.empty();
1072 IFRecord MaxIF = LL[0].first;
1073 for (
unsigned i = 1, n = LL.size(); i < n; ++i) {
1075 const IFRecord &
IF = LL[i].first;
1076 unsigned M0 = BaseOrd[MaxIF.SrcR],
M1 = BaseOrd[MaxIF.InsR];
1077 unsigned R0 = BaseOrd[
IF.SrcR], R1 = BaseOrd[
IF.InsR];
1084 if (MaxIF.Wdh >
IF.Wdh)
1086 if (MaxIF.Wdh ==
IF.Wdh && MaxIF.Off >=
IF.Off)
1096 LL.push_back(std::make_pair(MaxIF,
RegisterSet()));
1106 for (
unsigned i = 0, n = LL.size(); i < n; ) {
1110 if (j != i && LL[j].second.includes(RMi))
1118 LL.erase(LL.begin()+i);
1123void HexagonGenInsert::pruneUsesTooFar(
unsigned VR,
const UnsignedMap &RPO,
1125 IFMapType::iterator
F = IFMap.find(VR);
1127 IFListType &LL =
F->second;
1129 const MachineInstr *DefV =
MRI->getVRegDef(VR);
1131 for (
unsigned i = LL.size(); i > 0; --i) {
1132 unsigned SR = LL[i-1].first.SrcR,
IR = LL[i-1].first.InsR;
1133 const MachineInstr *DefS =
MRI->getVRegDef(SR);
1134 const MachineInstr *DefI =
MRI->getVRegDef(
IR);
1135 unsigned DSV = distance(DefS, DefV, RPO, M);
1137 unsigned DIV = distance(DefI, DefV, RPO, M);
1141 LL.erase(LL.begin()+(i-1));
1145void HexagonGenInsert::pruneRegCopies(
unsigned VR) {
1146 IFMapType::iterator
F = IFMap.find(VR);
1148 IFListType &LL =
F->second;
1150 auto IsCopy = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1151 return IR.first.Wdh == 32 && (
IR.first.Off == 0 ||
IR.first.Off == 32);
1156void HexagonGenInsert::pruneCandidates() {
1161 for (
const auto &
I : IFMap)
1162 pruneCoveredSets(
I.first);
1166 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
1170 for (
const auto &
I : RPOT)
1171 RPO[
I->getNumber()] = RPON++;
1175 for (
const auto &
I : IFMap)
1176 pruneUsesTooFar(
I.first, RPO, Memo);
1180 for (
const auto &
I : IFMap)
1181 pruneRegCopies(
I.first);
1195 IFOrdering(
const UnsignedMap &UC,
const RegisterOrdering &BO)
1196 : UseC(UC), BaseOrd(BO) {}
1198 bool operator() (
const IFRecordWithRegSet &
A,
1199 const IFRecordWithRegSet &
B)
const;
1203 unsigned &Sum)
const;
1205 const UnsignedMap &UseC;
1206 const RegisterOrdering &BaseOrd;
1211bool IFOrdering::operator() (
const IFRecordWithRegSet &
A,
1212 const IFRecordWithRegSet &
B)
const {
1213 unsigned SizeA = 0, ZeroA = 0, SumA = 0;
1214 unsigned SizeB = 0, ZeroB = 0, SumB = 0;
1215 stats(
A.second, SizeA, ZeroA, SumA);
1216 stats(
B.second, SizeB, ZeroB, SumB);
1220 return ZeroA > ZeroB;
1222 uint64_t AvgA = SumA*SizeB, AvgB = SumB*SizeA;
1228 unsigned OSA = BaseOrd[
A.first.SrcR], OSB = BaseOrd[
B.first.SrcR];
1231 unsigned OIA = BaseOrd[
A.first.InsR], OIB = BaseOrd[
B.first.InsR];
1234 if (
A.first.Wdh !=
B.first.Wdh)
1235 return A.first.Wdh <
B.first.Wdh;
1236 return A.first.Off <
B.first.Off;
1239void IFOrdering::stats(
const RegisterSet &Rs,
unsigned &
Size,
unsigned &Zero,
1240 unsigned &Sum)
const {
1241 for (
unsigned R = Rs.find_first(); R; R = Rs.find_next(R)) {
1242 UnsignedMap::const_iterator
F = UseC.find(R);
1244 unsigned UC =
F->second;
1252void HexagonGenInsert::selectCandidates() {
1260 UnsignedMap UseC, RemC;
1261 IFMapType::iterator End = IFMap.
end();
1263 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1264 const IFListType &LL =
I->second;
1266 for (
const auto &J : LL)
1267 TT.insert(J.second);
1268 for (
unsigned R =
TT.find_first(); R; R =
TT.find_next(R))
1273 for (
unsigned R = AllRMs.find_first(); R; R = AllRMs.find_next(R)) {
1275 using InstrSet = SmallPtrSet<const MachineInstr *, 16>;
1280 use_iterator
E =
MRI->use_nodbg_end();
1281 for (use_iterator
I =
MRI->use_nodbg_begin(R);
I !=
E; ++
I)
1282 UIs.insert(
I->getParent());
1283 unsigned C = UIs.size();
1286 unsigned D = RemC[
R];
1287 UseC[
R] = (
C >
D) ?
C-
D : 0;
1291 if (!SelectAll0 && !SelectHas0)
1299 IFOrdering IFO(UseC, BaseOrd);
1300 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1301 IFListType &LL =
I->second;
1309 assert(MinI != LL.end());
1310 IFRecordWithRegSet
M = *MinI;
1320 const MachineInstr *DefI =
MRI->getVRegDef(
I->first);
1321 getInstrUses(DefI, Us);
1322 bool Accept =
false;
1326 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1333 }
else if (SelectHas0) {
1335 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1352 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1353 const IFListType &LL =
I->second;
1355 AllRMs.insert(LL[0].second);
1357 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1358 IFListType &LL =
I->second;
1361 unsigned SR = LL[0].first.SrcR,
IR = LL[0].first.InsR;
1362 if (AllRMs[SR] || AllRMs[
IR])
1369bool HexagonGenInsert::generateInserts() {
1373 for (
auto &
I : IFMap) {
1374 unsigned VR =
I.first;
1375 const TargetRegisterClass *RC =
MRI->getRegClass(VR);
1383 for (
auto &
I : IFMap) {
1384 MachineInstr *
MI =
MRI->getVRegDef(
I.first);
1385 MachineBasicBlock &
B = *
MI->getParent();
1387 unsigned NewR = RegMap[
I.first];
1388 bool R32 =
MRI->getRegClass(NewR) == &Hexagon::IntRegsRegClass;
1389 const MCInstrDesc &
D = R32 ? HII->get(Hexagon::S2_insert)
1390 : HII->get(Hexagon::S2_insertp);
1391 IFRecord
IF =
I.second[0].first;
1392 unsigned Wdh =
IF.Wdh,
Off =
IF.Off;
1394 if (R32 &&
MRI->getRegClass(
IF.InsR) == &Hexagon::DoubleRegsRegClass) {
1395 InsS = Hexagon::isub_lo;
1397 InsS = Hexagon::isub_hi;
1405 At =
B.getFirstNonPHI();
1413 MRI->clearKillFlags(
IF.SrcR);
1414 MRI->clearKillFlags(
IF.InsR);
1417 for (
const auto &
I : IFMap) {
1418 MachineInstr *DefI =
MRI->getVRegDef(
I.first);
1419 MRI->replaceRegWith(
I.first, RegMap[
I.first]);
1430 Changed |= removeDeadCode(DTN);
1432 MachineBasicBlock *
B =
N->getBlock();
1433 std::vector<MachineInstr*> Instrs;
1435 Instrs.push_back(&
MI);
1437 for (MachineInstr *
MI : Instrs) {
1438 unsigned Opc =
MI->getOpcode();
1441 if (
Opc == TargetOpcode::LIFETIME_START ||
1442 Opc == TargetOpcode::LIFETIME_END)
1445 if (
MI->isInlineAsm() || !
MI->isSafeToMove(Store))
1448 bool AllDead =
true;
1449 SmallVector<unsigned,2> Regs;
1450 for (
const MachineOperand &MO :
MI->operands()) {
1451 if (!MO.isReg() || !MO.isDef())
1454 if (!
R.isVirtual() || !
MRI->use_nodbg_empty(R)) {
1464 for (
unsigned Reg : Regs)
1465 MRI->markUsesInDebugValueAsUndef(
Reg);
1472bool HexagonGenInsert::runOnMachineFunction(MachineFunction &MF) {
1487 HII =
ST.getInstrInfo();
1488 HRI =
ST.getRegisterInfo();
1491 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1500 const HexagonEvaluator HE(*HRI, *
MRI, *HII, MF);
1501 BitTracker BTLoc(HE, MF);
1504 CellMapShadow MS(BTLoc);
1507 buildOrderingMF(BaseOrd);
1508 buildOrderingBT(BaseOrd, CellOrd);
1511 dbgs() <<
"Cell ordering:\n";
1512 for (
const auto &
I : CellOrd) {
1513 unsigned VR =
I.first, Pos =
I.second;
1519 MachineBasicBlock *RootB = MDT->
getRoot();
1520 OrderedRegisterList AvailR(CellOrd);
1522 const char *
const TGName =
"hexinsert";
1523 const char *
const TGDesc =
"Generate Insert Instructions";
1526 NamedRegionTimer _T(
"collection",
"collection", TGName, TGDesc,
1528 collectInBlock(RootB, AvailR);
1530 computeRemovableRegisters();
1534 dbgs() <<
"Candidates after collection:\n";
1542 NamedRegionTimer _T(
"pruning",
"pruning", TGName, TGDesc, TimingDetail);
1547 dbgs() <<
"Candidates after pruning:\n";
1555 NamedRegionTimer _T(
"selection",
"selection", TGName, TGDesc, TimingDetail);
1560 dbgs() <<
"Candidates after selection:\n";
1571 for (IFMapType::iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
1572 unsigned Idx =
Register(
I->first).virtRegIndex();
1576 for (
const auto &It : Out)
1583 NamedRegionTimer _T(
"generation",
"generation", TGName, TGDesc,
1592 return new HexagonGenInsert();
1600 "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, const 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