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) {
928 getInstrDefs(&
MI, InsDefs);
930 bool Skip =
MI.isCopy() ||
MI.isRegSequence();
935 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR)) {
944 if (findSelfReference(VR) || isSmallConstant(VR))
947 findRecordInsertForms(VR, AVs);
956 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR))
958 BlockDefs.insert(InsDefs);
962 MachineBasicBlock *SB = DTN->getBlock();
963 collectInBlock(SB, AVs);
966 for (
unsigned VR = BlockDefs.find_first(); VR; VR = BlockDefs.find_next(VR))
970void HexagonGenInsert::findRemovableRegisters(
unsigned VR, IFRecord IF,
981 while (!Regs[S].
empty()) {
983 unsigned OtherS = 1-S;
984 Regs[OtherS].clear();
985 for (
unsigned R = Regs[S].find_first();
R;
R = Regs[S].find_next(R)) {
987 if (R ==
IF.SrcR || R ==
IF.InsR)
999 if (!findNonSelfReference(R))
1002 const MachineInstr *DefI =
MRI->getVRegDef(R);
1009 getInstrUses(DefI, Regs[OtherS]);
1021void HexagonGenInsert::computeRemovableRegisters() {
1022 for (
auto &
I : IFMap) {
1023 IFListType &LL =
I.second;
1025 findRemovableRegisters(
I.first, J.first, J.second);
1029void HexagonGenInsert::pruneEmptyLists() {
1034 for (IFMapType::iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
1035 if (
I->second.empty())
1038 for (
const auto &It : Prune)
1042void HexagonGenInsert::pruneCoveredSets(
unsigned VR) {
1043 IFMapType::iterator
F = IFMap.find(VR);
1045 IFListType &LL =
F->second;
1054 MachineInstr *DefVR =
MRI->getVRegDef(VR);
1057 for (
const auto &
I : LL) {
1058 if (
I.second.empty())
1063 if (!DefEx || HasNE) {
1066 auto IsEmpty = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1067 return IR.second.empty();
1076 IFRecord MaxIF = LL[0].first;
1077 for (
unsigned i = 1, n = LL.size(); i < n; ++i) {
1079 const IFRecord &
IF = LL[i].first;
1080 unsigned M0 = BaseOrd[MaxIF.SrcR],
M1 = BaseOrd[MaxIF.InsR];
1081 unsigned R0 = BaseOrd[
IF.SrcR], R1 = BaseOrd[
IF.InsR];
1088 if (MaxIF.Wdh >
IF.Wdh)
1090 if (MaxIF.Wdh ==
IF.Wdh && MaxIF.Off >=
IF.Off)
1100 LL.push_back(std::make_pair(MaxIF,
RegisterSet()));
1110 for (
unsigned i = 0, n = LL.size(); i < n; ) {
1114 if (j != i && LL[j].second.includes(RMi))
1122 LL.erase(LL.begin()+i);
1127void HexagonGenInsert::pruneUsesTooFar(
unsigned VR,
const UnsignedMap &RPO,
1129 IFMapType::iterator
F = IFMap.find(VR);
1131 IFListType &LL =
F->second;
1133 const MachineInstr *DefV =
MRI->getVRegDef(VR);
1135 for (
unsigned i = LL.size(); i > 0; --i) {
1136 unsigned SR = LL[i-1].first.SrcR,
IR = LL[i-1].first.InsR;
1137 const MachineInstr *DefS =
MRI->getVRegDef(SR);
1138 const MachineInstr *DefI =
MRI->getVRegDef(
IR);
1139 unsigned DSV = distance(DefS, DefV, RPO, M);
1141 unsigned DIV = distance(DefI, DefV, RPO, M);
1145 LL.erase(LL.begin()+(i-1));
1149void HexagonGenInsert::pruneRegCopies(
unsigned VR) {
1150 IFMapType::iterator
F = IFMap.find(VR);
1152 IFListType &LL =
F->second;
1154 auto IsCopy = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1155 return IR.first.Wdh == 32 && (
IR.first.Off == 0 ||
IR.first.Off == 32);
1160void HexagonGenInsert::pruneCandidates() {
1165 for (
const auto &
I : IFMap)
1166 pruneCoveredSets(
I.first);
1170 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
1174 for (
const auto &
I : RPOT)
1175 RPO[
I->getNumber()] = RPON++;
1179 for (
const auto &
I : IFMap)
1180 pruneUsesTooFar(
I.first, RPO, Memo);
1184 for (
const auto &
I : IFMap)
1185 pruneRegCopies(
I.first);
1199 IFOrdering(
const UnsignedMap &UC,
const RegisterOrdering &BO)
1200 : UseC(UC), BaseOrd(BO) {}
1202 bool operator() (
const IFRecordWithRegSet &
A,
1203 const IFRecordWithRegSet &
B)
const;
1207 unsigned &Sum)
const;
1209 const UnsignedMap &UseC;
1210 const RegisterOrdering &BaseOrd;
1215bool IFOrdering::operator() (
const IFRecordWithRegSet &
A,
1216 const IFRecordWithRegSet &
B)
const {
1217 unsigned SizeA = 0, ZeroA = 0, SumA = 0;
1218 unsigned SizeB = 0, ZeroB = 0, SumB = 0;
1219 stats(
A.second, SizeA, ZeroA, SumA);
1220 stats(
B.second, SizeB, ZeroB, SumB);
1224 return ZeroA > ZeroB;
1226 uint64_t AvgA = SumA*SizeB, AvgB = SumB*SizeA;
1232 unsigned OSA = BaseOrd[
A.first.SrcR], OSB = BaseOrd[
B.first.SrcR];
1235 unsigned OIA = BaseOrd[
A.first.InsR], OIB = BaseOrd[
B.first.InsR];
1238 if (
A.first.Wdh !=
B.first.Wdh)
1239 return A.first.Wdh <
B.first.Wdh;
1240 return A.first.Off <
B.first.Off;
1243void IFOrdering::stats(
const RegisterSet &Rs,
unsigned &
Size,
unsigned &Zero,
1244 unsigned &Sum)
const {
1245 for (
unsigned R = Rs.find_first(); R; R = Rs.find_next(R)) {
1246 UnsignedMap::const_iterator
F = UseC.find(R);
1248 unsigned UC =
F->second;
1256void HexagonGenInsert::selectCandidates() {
1264 UnsignedMap UseC, RemC;
1265 IFMapType::iterator End = IFMap.
end();
1267 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1268 const IFListType &LL =
I->second;
1270 for (
const auto &J : LL)
1271 TT.insert(J.second);
1272 for (
unsigned R =
TT.find_first(); R; R =
TT.find_next(R))
1277 for (
unsigned R = AllRMs.find_first(); R; R = AllRMs.find_next(R)) {
1279 using InstrSet = SmallPtrSet<const MachineInstr *, 16>;
1284 use_iterator
E =
MRI->use_nodbg_end();
1285 for (use_iterator
I =
MRI->use_nodbg_begin(R);
I !=
E; ++
I)
1286 UIs.insert(
I->getParent());
1287 unsigned C = UIs.size();
1290 unsigned D = RemC[
R];
1291 UseC[
R] = (
C >
D) ?
C-
D : 0;
1295 if (!SelectAll0 && !SelectHas0)
1303 IFOrdering IFO(UseC, BaseOrd);
1304 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1305 IFListType &LL =
I->second;
1313 assert(MinI != LL.end());
1314 IFRecordWithRegSet
M = *MinI;
1324 const MachineInstr *DefI =
MRI->getVRegDef(
I->first);
1325 getInstrUses(DefI, Us);
1326 bool Accept =
false;
1330 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1337 }
else if (SelectHas0) {
1339 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1356 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1357 const IFListType &LL =
I->second;
1359 AllRMs.insert(LL[0].second);
1361 for (IFMapType::iterator
I = IFMap.begin();
I != End; ++
I) {
1362 IFListType &LL =
I->second;
1365 unsigned SR = LL[0].first.SrcR,
IR = LL[0].first.InsR;
1366 if (AllRMs[SR] || AllRMs[
IR])
1373bool HexagonGenInsert::generateInserts() {
1377 for (
auto &
I : IFMap) {
1378 unsigned VR =
I.first;
1379 const TargetRegisterClass *RC =
MRI->getRegClass(VR);
1387 for (
auto &
I : IFMap) {
1388 MachineInstr *
MI =
MRI->getVRegDef(
I.first);
1389 MachineBasicBlock &
B = *
MI->getParent();
1391 unsigned NewR = RegMap[
I.first];
1392 bool R32 =
MRI->getRegClass(NewR) == &Hexagon::IntRegsRegClass;
1393 const MCInstrDesc &
D = R32 ? HII->get(Hexagon::S2_insert)
1394 : HII->get(Hexagon::S2_insertp);
1395 IFRecord
IF =
I.second[0].first;
1396 unsigned Wdh =
IF.Wdh,
Off =
IF.Off;
1398 if (R32 &&
MRI->getRegClass(
IF.InsR) == &Hexagon::DoubleRegsRegClass) {
1399 InsS = Hexagon::isub_lo;
1401 InsS = Hexagon::isub_hi;
1409 At =
B.getFirstNonPHI();
1417 MRI->clearKillFlags(
IF.SrcR);
1418 MRI->clearKillFlags(
IF.InsR);
1421 for (
const auto &
I : IFMap) {
1422 MachineInstr *DefI =
MRI->getVRegDef(
I.first);
1423 MRI->replaceRegWith(
I.first, RegMap[
I.first]);
1434 Changed |= removeDeadCode(DTN);
1436 MachineBasicBlock *
B =
N->getBlock();
1437 std::vector<MachineInstr*> Instrs;
1439 Instrs.push_back(&
MI);
1441 for (MachineInstr *
MI : Instrs) {
1442 unsigned Opc =
MI->getOpcode();
1445 if (
Opc == TargetOpcode::LIFETIME_START ||
1446 Opc == TargetOpcode::LIFETIME_END)
1449 if (
MI->isInlineAsm() || !
MI->isSafeToMove(Store))
1452 bool AllDead =
true;
1453 SmallVector<unsigned,2> Regs;
1454 for (
const MachineOperand &MO :
MI->operands()) {
1455 if (!MO.isReg() || !MO.isDef())
1458 if (!
R.isVirtual() || !
MRI->use_nodbg_empty(R)) {
1468 for (
unsigned Reg : Regs)
1469 MRI->markUsesInDebugValueAsUndef(
Reg);
1476bool HexagonGenInsert::runOnMachineFunction(MachineFunction &MF) {
1491 HII =
ST.getInstrInfo();
1492 HRI =
ST.getRegisterInfo();
1495 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1504 const HexagonEvaluator HE(*HRI, *
MRI, *HII, MF);
1505 BitTracker BTLoc(HE, MF);
1508 CellMapShadow MS(BTLoc);
1511 buildOrderingMF(BaseOrd);
1512 buildOrderingBT(BaseOrd, CellOrd);
1515 dbgs() <<
"Cell ordering:\n";
1516 for (
const auto &
I : CellOrd) {
1517 unsigned VR =
I.first, Pos =
I.second;
1523 MachineBasicBlock *RootB = MDT->
getRoot();
1524 OrderedRegisterList AvailR(CellOrd);
1526 const char *
const TGName =
"hexinsert";
1527 const char *
const TGDesc =
"Generate Insert Instructions";
1530 NamedRegionTimer _T(
"collection",
"collection", TGName, TGDesc,
1532 collectInBlock(RootB, AvailR);
1534 computeRemovableRegisters();
1538 dbgs() <<
"Candidates after collection:\n";
1546 NamedRegionTimer _T(
"pruning",
"pruning", TGName, TGDesc, TimingDetail);
1551 dbgs() <<
"Candidates after pruning:\n";
1559 NamedRegionTimer _T(
"selection",
"selection", TGName, TGDesc, TimingDetail);
1564 dbgs() <<
"Candidates after selection:\n";
1575 for (IFMapType::iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
1576 unsigned Idx =
Register(
I->first).virtRegIndex();
1580 for (
const auto &It : Out)
1587 NamedRegionTimer _T(
"generation",
"generation", TGName, TGDesc,
1596 return new HexagonGenInsert();
1604 "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