10 #define DEBUG_TYPE "hexinsert"
91 unsigned find_first()
const {
98 unsigned find_next(
unsigned Prev)
const {
106 unsigned Idx = v2x(R);
111 unsigned Idx = v2x(R);
124 reference operator[](
unsigned R) {
125 unsigned Idx = v2x(R);
129 bool operator[](
unsigned R)
const {
130 unsigned Idx = v2x(R);
134 bool has(
unsigned R)
const {
135 unsigned Idx = v2x(R);
146 return !Rs.BitVector::test(*
this);
153 void ensure(
unsigned Idx) {
155 resize(std::max(Idx+1, 32U));
158 static inline unsigned v2x(
unsigned v) {
162 static inline unsigned x2v(
unsigned x) {
172 const PrintRegSet &
P);
181 for (
unsigned R = P.RS.find_first(); R; R = P.RS.find_next(R))
189 struct UnsignedMap :
public DenseMap<unsigned,unsigned> {
190 UnsignedMap() =
default;
201 struct RegisterOrdering :
public UnsignedMap {
202 RegisterOrdering() =
default;
204 unsigned operator[](
unsigned VR)
const {
205 const_iterator
F =
find(VR);
212 bool operator() (
unsigned VR1,
unsigned VR2)
const {
213 return operator[](VR1) < operator[](VR2);
223 struct BitValueOrdering {
224 BitValueOrdering(
const RegisterOrdering &RB) : BaseOrd(RB) {}
229 const RegisterOrdering &BaseOrd;
239 if (V1.
is(0) || V2.
is(0))
243 if (V2.
is(1) || V1.
is(1))
246 unsigned Ind1 = BaseOrd[V1.
RefI.
Reg], Ind2 = BaseOrd[V2.
RefI.
Reg];
259 struct CellMapShadow {
265 if (RInd >= CVect.size())
266 CVect.resize(std::max(RInd+16, 32U),
nullptr);
276 typedef std::vector<const BitTracker::RegisterCell*> CellVectType;
282 struct RegisterCellLexCompare {
283 RegisterCellLexCompare(
const BitValueOrdering &BO, CellMapShadow &M)
284 : BitOrd(BO), CM(M) {}
286 bool operator() (
unsigned VR1,
unsigned VR2)
const;
289 const BitValueOrdering &BitOrd;
299 struct RegisterCellBitCompareSel {
300 RegisterCellBitCompareSel(
unsigned R,
unsigned B,
unsigned N,
301 const BitValueOrdering &BO, CellMapShadow &M)
302 : SelR(R), SelB(B), BitN(N), BitOrd(BO), CM(M) {}
304 bool operator() (
unsigned VR1,
unsigned VR2)
const;
307 const unsigned SelR, SelB;
309 const BitValueOrdering &BitOrd;
315 bool RegisterCellLexCompare::operator() (
unsigned VR1,
unsigned VR2)
const {
329 uint16_t W1 = RC1.
width(), W2 = RC2.width();
330 for (uint16_t
i = 0, w =
std::min(W1, W2);
i < w; ++
i) {
333 return BitOrd(V1, V2);
339 return BitOrd.BaseOrd[VR1] < BitOrd.BaseOrd[VR2];
342 bool RegisterCellBitCompareSel::operator() (
unsigned VR1,
unsigned VR2)
const {
348 uint16_t Bit1 = (VR1 == SelR) ? SelB : BitN;
349 uint16_t Bit2 = (VR2 == SelR) ? SelB : BitN;
363 return BitOrd(V1, V2);
369 class OrderedRegisterList {
370 typedef std::vector<unsigned> ListType;
373 OrderedRegisterList(
const RegisterOrdering &RO) : Ord(RO) {}
375 void insert(
unsigned VR);
376 void remove(
unsigned VR);
378 unsigned operator[](
unsigned Idx)
const {
383 unsigned size()
const {
387 typedef ListType::iterator iterator;
388 typedef ListType::const_iterator const_iterator;
390 iterator
end() {
return Seq.
end(); }
391 const_iterator
begin()
const {
return Seq.
begin(); }
392 const_iterator
end()
const {
return Seq.
end(); }
395 unsigned idx(iterator It)
const {
return It-
begin(); }
399 const RegisterOrdering &Ord;
409 const OrderedRegisterList &RL;
415 OrderedRegisterList::const_iterator
B = P.RL.begin(),
E = P.RL.end();
416 for (OrderedRegisterList::const_iterator
I = B;
I !=
E; ++
I) {
427 void OrderedRegisterList::insert(
unsigned VR) {
428 iterator
L = std::lower_bound(Seq.begin(), Seq.end(), VR, Ord);
436 iterator L = std::lower_bound(Seq.begin(), Seq.end(), VR, Ord);
447 IFRecord(
unsigned SR = 0,
unsigned IR = 0, uint16_t W = 0, uint16_t O = 0)
448 : SrcR(SR), InsR(
IR), Wdh(W), Off(O) {}
466 unsigned SrcR = P.IFR.SrcR, InsR = P.IFR.InsR;
468 <<
",#" << P.IFR.Wdh <<
",#" << P.IFR.Off <<
')';
472 typedef std::pair<IFRecord,RegisterSet> IFRecordWithRegSet;
494 return "Hexagon generate \"insert\" instructions";
508 void buildOrderingMF(RegisterOrdering &RO)
const;
509 void buildOrderingBT(RegisterOrdering &RB, RegisterOrdering &RO)
const;
511 bool isConstant(
unsigned VR)
const;
512 bool isSmallConstant(
unsigned VR)
const;
513 bool isValidInsertForm(
unsigned DstR,
unsigned SrcR,
unsigned InsR,
514 uint16_t L, uint16_t S)
const;
515 bool findSelfReference(
unsigned VR)
const;
516 bool findNonSelfReference(
unsigned VR)
const;
521 PairMapType &M)
const;
524 PairMapType &M)
const;
525 bool findRecordInsertForms(
unsigned VR, OrderedRegisterList &AVs);
527 void findRemovableRegisters(
unsigned VR, IFRecord IF,
529 void computeRemovableRegisters();
531 void pruneEmptyLists();
532 void pruneCoveredSets(
unsigned VR);
533 void pruneUsesTooFar(
unsigned VR,
const UnsignedMap &
RPO, PairMapType &M);
534 void pruneRegCopies(
unsigned VR);
535 void pruneCandidates();
536 void selectCandidates();
537 bool generateInserts();
542 typedef std::vector<IFRecordWithRegSet> IFListType;
545 void dump_map()
const;
555 RegisterOrdering BaseOrd;
556 RegisterOrdering CellOrd;
564 void HexagonGenInsert::dump_map()
const {
565 typedef IFMapType::const_iterator iterator;
566 for (iterator
I = IFMap.begin(),
E = IFMap.end();
I !=
E; ++
I) {
568 const IFListType &LL =
I->second;
569 for (
unsigned i = 0, n = LL.size();
i < n; ++
i)
570 dbgs() <<
" " << PrintIFR(LL[
i].first, HRI) <<
", "
571 << PrintRegSet(LL[
i].second, HRI) <<
'\n';
575 void HexagonGenInsert::buildOrderingMF(RegisterOrdering &RO)
const {
578 for (mf_iterator
A = MFN->begin(), Z = MFN->end();
A != Z; ++
A) {
580 if (!CMS->BT.reached(&B))
591 RO.insert(std::make_pair(R, Index++));
601 void HexagonGenInsert::buildOrderingBT(RegisterOrdering &RB,
602 RegisterOrdering &RO)
const {
605 BitValueOrdering BVO(RB);
606 RegisterCellLexCompare LexCmp(BVO, *CMS);
607 typedef std::vector<unsigned> SortableVectorType;
608 SortableVectorType VRs;
609 for (RegisterOrdering::iterator
I = RB.begin(),
E = RB.end();
I !=
E; ++
I)
610 VRs.push_back(
I->first);
611 std::sort(VRs.begin(), VRs.end(), LexCmp);
613 for (
unsigned i = 0, n = VRs.size();
i < n; ++
i)
614 RO.insert(std::make_pair(VRs[
i], i));
618 return RC == &Hexagon::IntRegsRegClass || RC == &Hexagon::DoubleRegsRegClass;
621 bool HexagonGenInsert::isConstant(
unsigned VR)
const {
623 uint16_t W = RC.
width();
624 for (uint16_t
i = 0;
i < W; ++
i) {
626 if (BV.
is(0) || BV.
is(1))
633 bool HexagonGenInsert::isSmallConstant(
unsigned VR)
const {
635 uint16_t W = RC.
width();
638 uint64_t V = 0, B = 1;
639 for (uint16_t
i = 0;
i < W; ++
i) {
656 bool HexagonGenInsert::isValidInsertForm(
unsigned DstR,
unsigned SrcR,
657 unsigned InsR, uint16_t L, uint16_t S)
const {
662 if (!isIntClass(DstRC) || !isIntClass(SrcRC) || !isIntClass(InsRC))
670 if (DstRC == &Hexagon::DoubleRegsRegClass)
673 if (S < 32 && S+L > 32)
678 bool HexagonGenInsert::findSelfReference(
unsigned VR)
const {
680 for (uint16_t
i = 0, w = RC.
width();
i < w; ++
i) {
688 bool HexagonGenInsert::findNonSelfReference(
unsigned VR)
const {
690 for (uint16_t
i = 0, w = RC.
width();
i < w; ++
i) {
698 void HexagonGenInsert::getInstrDefs(
const MachineInstr *MI,
711 void HexagonGenInsert::getInstrUses(
const MachineInstr *MI,
726 PairMapType &M)
const {
733 PairMapType::iterator
F = M.find(std::make_pair(FromN, ToN));
736 unsigned ToRPO = RPO.lookup(ToN);
745 if (PB == FromB || RPO.lookup(PB->
getNumber()) >= ToRPO)
747 unsigned D = PB->
size() + distance(FromB, PB, RPO, M);
753 M.insert(std::make_pair(std::make_pair(FromN, ToN), MaxD));
759 PairMapType &M)
const {
762 return std::distance(FromI, ToI);
763 unsigned D1 = std::distance(
TB->begin(), ToI);
764 unsigned D2 = distance(FB,
TB, RPO, M);
765 unsigned D3 = std::distance(FromI, FB->
end());
769 bool HexagonGenInsert::findRecordInsertForms(
unsigned VR,
770 OrderedRegisterList &AVs) {
773 <<
" AVs: " << PrintORL(AVs, HRI) <<
"\n";
778 typedef OrderedRegisterList::iterator iterator;
779 BitValueOrdering BVO(BaseOrd);
781 uint16_t W = RC.
width();
783 typedef std::pair<unsigned,uint16_t> RSRecord;
784 typedef std::vector<RSRecord> RSListType;
794 for (uint16_t S = 0; S < W; ++S) {
795 iterator B = AVs.begin(),
E = AVs.end();
803 for (L = 0; L < W-S; ++
L) {
806 RegisterCellBitCompareSel RCB(VR, S+L, L, BVO, *CMS);
807 iterator NewB = std::lower_bound(B,
E, VR, RCB);
808 iterator NewE = std::upper_bound(NewB,
E, VR, RCB);
814 for (iterator
I = B;
I != NewB; ++
I)
815 LM[L].push_back(std::make_pair(*
I, S));
816 for (iterator
I = NewE;
I !=
E; ++
I)
817 LM[L].push_back(std::make_pair(*
I, S));
825 assert(B == E || L == W-S);
827 for (iterator
I = B;
I !=
E; ++
I)
828 LM[L].push_back(std::make_pair(*
I, S));
836 dbgs() <<
"Prefixes matching register " <<
PrintReg(VR, HRI) <<
"\n";
837 for (LRSMapType::iterator
I = LM.begin(), E = LM.end();
I !=
E; ++
I) {
838 dbgs() <<
" L=" <<
I->first <<
':';
839 const RSListType &LL =
I->second;
840 for (
unsigned i = 0, n = LL.size();
i < n; ++
i)
842 << LL[
i].second <<
')';
847 bool Recorded =
false;
849 for (iterator
I = AVs.begin(), E = AVs.end();
I !=
E; ++
I) {
851 int FDi = -1, LDi = -1;
853 uint16_t AW = AC.
width();
854 for (uint16_t
i = 0, w =
std::min(W, AW);
i < w; ++
i) {
865 uint16_t FD = FDi,
LD = LDi;
866 uint16_t MinL = LD-FD+1;
867 for (uint16_t L = MinL; L < W; ++
L) {
868 LRSMapType::iterator F = LM.find(L);
871 RSListType &LL = F->second;
872 for (
unsigned i = 0, n = LL.size(); i < n; ++
i) {
873 uint16_t S = LL[
i].second;
880 uint16_t EL = L-MinL;
881 uint16_t LowS = (EL < FD) ? FD-EL : 0;
884 unsigned InsR = LL[
i].first;
885 if (!isValidInsertForm(VR, SrcR, InsR, L, S))
889 <<
',' <<
PrintReg(InsR, HRI) <<
",#" << L <<
",#"
892 IFRecordWithRegSet RR(IFRecord(SrcR, InsR, L, S),
RegisterSet());
893 IFMap[VR].push_back(RR);
903 OrderedRegisterList &AVs) {
909 if (!CMS->BT.reached(B))
920 getInstrDefs(MI, InsDefs);
927 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR)) {
930 if (!DoConst && isConstant(VR))
936 if (findSelfReference(VR) || isSmallConstant(VR))
939 findRecordInsertForms(VR, AVs);
945 for (
unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR))
947 BlockDefs.insert(InsDefs);
952 typedef GTN::ChildIteratorType ChildIter;
953 for (ChildIter
I = GTN::child_begin(N), E = GTN::child_end(N);
I !=
E; ++
I) {
955 collectInBlock(SB, AVs);
958 for (
unsigned VR = BlockDefs.find_first(); VR; VR = BlockDefs.find_next(VR))
962 void HexagonGenInsert::findRemovableRegisters(
unsigned VR, IFRecord IF,
973 while (!Regs[S].empty()) {
975 unsigned OtherS = 1-S;
976 Regs[OtherS].clear();
977 for (
unsigned R = Regs[S].find_first(); R; R = Regs[S].find_next(R)) {
979 if (R == IF.SrcR || R == IF.InsR)
991 if (!findNonSelfReference(R))
1001 getInstrUses(DefI, Regs[OtherS]);
1013 void HexagonGenInsert::computeRemovableRegisters() {
1014 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I) {
1015 IFListType &LL =
I->second;
1016 for (
unsigned i = 0, n = LL.size(); i < n; ++
i)
1017 findRemovableRegisters(
I->first, LL[i].first, LL[i].second);
1021 void HexagonGenInsert::pruneEmptyLists() {
1026 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I) {
1027 if (
I->second.empty())
1030 for (
unsigned i = 0, n = Prune.size(); i < n; ++
i)
1031 IFMap.erase(Prune[i]);
1034 void HexagonGenInsert::pruneCoveredSets(
unsigned VR) {
1035 IFMapType::iterator F = IFMap.find(VR);
1036 assert(F != IFMap.end());
1037 IFListType &LL = F->second;
1047 bool DefEx = HII->isConstExtended(*DefVR);
1049 for (
unsigned i = 0, n = LL.size(); i < n; ++
i) {
1050 if (LL[i].second.empty())
1055 if (!DefEx || HasNE) {
1058 auto IsEmpty = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1059 return IR.second.empty();
1062 if (
End != LL.end())
1063 LL.erase(
End, LL.end());
1070 IFRecord MaxIF = LL[0].first;
1071 for (
unsigned i = 1, n = LL.size(); i < n; ++
i) {
1073 const IFRecord &IF = LL[
i].first;
1074 unsigned M0 = BaseOrd[MaxIF.SrcR], M1 = BaseOrd[MaxIF.InsR];
1075 unsigned R0 = BaseOrd[IF.SrcR], R1 = BaseOrd[IF.InsR];
1082 if (MaxIF.Wdh > IF.Wdh)
1084 if (MaxIF.Wdh == IF.Wdh && MaxIF.Off >= IF.Off)
1094 LL.push_back(std::make_pair(MaxIF,
RegisterSet()));
1104 for (
unsigned i = 0, n = LL.size(); i < n; ) {
1108 if (j != i && LL[j].second.includes(RMi))
1116 LL.erase(LL.begin()+
i);
1121 void HexagonGenInsert::pruneUsesTooFar(
unsigned VR,
const UnsignedMap &RPO,
1123 IFMapType::iterator F = IFMap.find(VR);
1124 assert(F != IFMap.end());
1125 IFListType &LL = F->second;
1129 for (
unsigned i = LL.size(); i > 0; --
i) {
1130 unsigned SR = LL[i-1].first.SrcR,
IR = LL[i-1].first.InsR;
1133 unsigned DSV = distance(DefS, DefV, RPO, M);
1135 unsigned DIV = distance(DefI, DefV, RPO, M);
1139 LL.erase(LL.begin()+(i-1));
1143 void HexagonGenInsert::pruneRegCopies(
unsigned VR) {
1144 IFMapType::iterator F = IFMap.find(VR);
1145 assert(F != IFMap.end());
1146 IFListType &LL = F->second;
1148 auto IsCopy = [] (
const IFRecordWithRegSet &
IR) ->
bool {
1149 return IR.first.Wdh == 32 && (
IR.first.Off == 0 ||
IR.first.Off == 32);
1152 if (
End != LL.end())
1153 LL.erase(
End, LL.end());
1156 void HexagonGenInsert::pruneCandidates() {
1161 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I)
1162 pruneCoveredSets(
I->first);
1168 for (RPOTType::rpo_iterator
I = RPOT.begin(), E = RPOT.end();
I !=
E; ++
I)
1169 RPO[(*I)->getNumber()] = RPON++;
1173 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I)
1174 pruneUsesTooFar(
I->first, RPO, Memo);
1178 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I)
1179 pruneRegCopies(
I->first);
1193 IFOrdering(
const UnsignedMap &UC,
const RegisterOrdering &BO)
1194 : UseC(UC), BaseOrd(BO) {}
1196 bool operator() (
const IFRecordWithRegSet &
A,
1197 const IFRecordWithRegSet &B)
const;
1201 unsigned &Sum)
const;
1203 const UnsignedMap &UseC;
1204 const RegisterOrdering &BaseOrd;
1209 bool IFOrdering::operator() (
const IFRecordWithRegSet &
A,
1210 const IFRecordWithRegSet &B)
const {
1211 unsigned SizeA = 0, ZeroA = 0, SumA = 0;
1212 unsigned SizeB = 0, ZeroB = 0, SumB = 0;
1213 stats(A.second, SizeA, ZeroA, SumA);
1214 stats(B.second, SizeB, ZeroB, SumB);
1218 return ZeroA > ZeroB;
1220 uint64_t AvgA = SumA*SizeB, AvgB = SumB*SizeA;
1226 unsigned OSA = BaseOrd[A.first.SrcR], OSB = BaseOrd[B.first.SrcR];
1229 unsigned OIA = BaseOrd[A.first.InsR], OIB = BaseOrd[B.first.InsR];
1232 if (A.first.Wdh != B.first.Wdh)
1233 return A.first.Wdh < B.first.Wdh;
1234 return A.first.Off < B.first.Off;
1238 unsigned &Sum)
const {
1239 for (
unsigned R = Rs.find_first(); R; R = Rs.find_next(R)) {
1240 UnsignedMap::const_iterator F = UseC.find(R);
1242 unsigned UC = F->second;
1250 void HexagonGenInsert::selectCandidates() {
1258 UnsignedMap UseC, RemC;
1259 IFMapType::iterator
End = IFMap.end();
1261 for (IFMapType::iterator
I = IFMap.begin();
I !=
End; ++
I) {
1262 const IFListType &LL =
I->second;
1264 for (
unsigned i = 0, n = LL.size(); i < n; ++
i)
1265 TT.insert(LL[i].second);
1266 for (
unsigned R = TT.find_first(); R; R = TT.find_next(R))
1271 for (
unsigned R = AllRMs.find_first(); R; R = AllRMs.find_next(R)) {
1277 use_iterator E =
MRI->use_nodbg_end();
1278 for (use_iterator
I =
MRI->use_nodbg_begin(R);
I !=
E; ++
I)
1279 UIs.insert(
I->getParent());
1280 unsigned C = UIs.size();
1283 unsigned D = RemC[R];
1284 UseC[R] = (C >
D) ? C-D : 0;
1288 if (!SelectAll0 && !SelectHas0)
1296 IFOrdering IFO(UseC, BaseOrd);
1297 for (IFMapType::iterator
I = IFMap.begin();
I !=
End; ++
I) {
1298 IFListType &LL =
I->second;
1305 IFListType::iterator MinI = std::min_element(LL.begin(), LL.end(), IFO);
1306 assert(MinI != LL.end());
1307 IFRecordWithRegSet M = *MinI;
1318 getInstrUses(DefI, Us);
1319 bool Accept =
false;
1323 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1330 }
else if (SelectHas0) {
1332 for (
unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1349 for (IFMapType::iterator
I = IFMap.begin();
I !=
End; ++
I) {
1350 const IFListType &LL =
I->second;
1352 AllRMs.insert(LL[0].second);
1354 for (IFMapType::iterator
I = IFMap.begin();
I !=
End; ++
I) {
1355 IFListType &LL =
I->second;
1358 unsigned SR = LL[0].first.SrcR,
IR = LL[0].first.InsR;
1359 if (AllRMs[SR] || AllRMs[
IR])
1366 bool HexagonGenInsert::generateInserts() {
1370 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I) {
1371 unsigned VR =
I->first;
1373 unsigned NewVR =
MRI->createVirtualRegister(RC);
1380 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I) {
1384 unsigned NewR = RegMap[
I->first];
1385 bool R32 =
MRI->getRegClass(NewR) == &Hexagon::IntRegsRegClass;
1386 const MCInstrDesc &D = R32 ? HII->get(Hexagon::S2_insert)
1387 : HII->get(Hexagon::S2_insertp);
1388 IFRecord IF =
I->second[0].first;
1389 unsigned Wdh = IF.Wdh, Off = IF.Off;
1391 if (R32 &&
MRI->getRegClass(IF.InsR) == &Hexagon::DoubleRegsRegClass) {
1392 InsS = Hexagon::isub_lo;
1394 InsS = Hexagon::isub_hi;
1406 .
addReg(IF.InsR, 0, InsS)
1410 MRI->clearKillFlags(IF.SrcR);
1411 MRI->clearKillFlags(IF.InsR);
1414 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I) {
1416 MRI->replaceRegWith(
I->first, RegMap[
I->first]);
1424 bool Changed =
false;
1426 for (
auto I = GTN::child_begin(N), E = GTN::child_end(N);
I !=
E; ++
I)
1427 Changed |= removeDeadCode(*
I);
1430 std::vector<MachineInstr*> Instrs;
1432 Instrs.push_back(&*
I);
1434 for (
auto I = Instrs.begin(), E = Instrs.end();
I !=
E; ++
I) {
1446 bool AllDead =
true;
1451 unsigned R = MO.
getReg();
1453 !
MRI->use_nodbg_empty(R)) {
1463 for (
unsigned I = 0, N = Regs.
size();
I !=
N; ++
I)
1464 MRI->markUsesInDebugValueAsUndef(Regs[
I]);
1476 bool Changed =
false;
1486 HII =
ST.getInstrInfo();
1487 HRI =
ST.getRegisterInfo();
1490 MDT = &getAnalysis<MachineDominatorTree>();
1497 Changed = removeDeadCode(MDT->getRootNode());
1503 CellMapShadow MS(BTLoc);
1506 buildOrderingMF(BaseOrd);
1507 buildOrderingBT(BaseOrd, CellOrd);
1510 dbgs() <<
"Cell ordering:\n";
1511 for (RegisterOrdering::iterator
I = CellOrd.begin(), E = CellOrd.end();
1513 unsigned VR =
I->first, Pos =
I->second;
1520 OrderedRegisterList AvailR(CellOrd);
1522 const char *
const TGName =
"hexinsert";
1523 const char *
const TGDesc =
"Generate Insert Instructions";
1528 collectInBlock(RootB, AvailR);
1530 computeRemovableRegisters();
1534 dbgs() <<
"Candidates after collection:\n";
1547 dbgs() <<
"Candidates after pruning:\n";
1555 NamedRegionTimer _T(
"selection",
"selection", TGName, TGDesc, TimingDetail);
1560 dbgs() <<
"Candidates after selection:\n";
1569 for (IFMapType::iterator
I = IFMap.begin(), E = IFMap.end();
I !=
E; ++
I) {
1574 for (
unsigned i = 0, n = Out.size(); i < n; ++
i)
1575 IFMap.erase(Out[i]);
1590 return new HexagonGenInsert();
1598 "Hexagon generate \"insert\" instructions",
false,
false)
static cl::opt< bool > OptSelectHas0("insert-has0", cl::init(false), cl::Hidden, cl::ZeroOrMore)
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void initializeHexagonGenInsertPass(PassRegistry &)
static unsigned virtReg2Index(unsigned Reg)
Convert a virtual register number to a 0-based index.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
bool anyCommon(const BitVector &RHS) const
Test if any common bits are set.
constexpr uint32_t Lo_32(uint64_t Value)
Lo_32 - This function returns the low 32 bits of a 64 bit value.
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
Describe properties that are true of each instruction in the target description file.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Hexagon generate insert false
constexpr bool isInt< 8 >(int64_t x)
const_iterator begin(StringRef path)
Get begin iterator over path.
constexpr bool isInt< 16 >(int64_t x)
bool any() const
any - Returns true if any bit is set.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
static cl::opt< bool > OptTiming("insert-timing", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Enable timing of insert generation"))
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
void clear()
clear - Clear all bits.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
This class is basically a combination of TimeRegion and Timer.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static const uint16_t * lookup(unsigned opcode, unsigned domain, ArrayRef< uint16_t[3]> Table)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool is(unsigned T) const
BitVector & operator|=(const BitVector &RHS)
Base class for the actual dominator tree node.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
reverse_iterator rbegin()
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static cl::opt< bool > OptTimingDetail("insert-timing-detail", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Enable detailed timing of insert ""generation"))
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
This corresponds to the llvm.lifetime.
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
friend const_iterator end(StringRef path)
Get end iterator over path.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
FunctionPass class - This class is used to implement most global optimizations.
static cl::opt< unsigned > VRegDistCutoff("insert-dist-cutoff", cl::init(30U), cl::Hidden, cl::ZeroOrMore, cl::desc("Vreg distance cutoff for insert ""generation."))
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
std::vector< MachineBasicBlock * >::const_iterator const_pred_iterator
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
Iterator for intrusive lists based on ilist_node.
const RegisterCell & lookup(unsigned Reg) const
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
friend const_iterator begin(StringRef path)
Get begin iterator over path.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
reference operator[](unsigned Idx)
bool test(unsigned Idx) const
FunctionPass * createHexagonGenInsert()
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static cl::opt< bool > OptConst("insert-const", cl::init(false), cl::Hidden, cl::ZeroOrMore)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
PredIterator< BasicBlock, Value::user_iterator > pred_iterator
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
static cl::opt< unsigned > VRegIndexCutoff("insert-vreg-cutoff", cl::init(~0U), cl::Hidden, cl::ZeroOrMore, cl::desc("Vreg# cutoff for insert generation."))
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
INITIALIZE_PASS_BEGIN(HexagonGenInsert,"hexinsert","Hexagon generate \"insert\" instructions", false, false) INITIALIZE_PASS_END(HexagonGenInsert
constexpr uint32_t Hi_32(uint64_t Value)
Hi_32 - This function returns the high 32 bits of a 64 bit value.
rpo Deduce function attributes in RPO
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
inst_range instructions(Function *F)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
std::set< RegisterRef > RegisterSet
static cl::opt< bool > OptSelectAll0("insert-all0", cl::init(false), cl::Hidden, cl::ZeroOrMore)
bool isRegSequence() const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Statically lint checks LLVM IR
bool DebugFlag
DebugFlag - This boolean is set to true if the '-debug' command line option is specified.
bool isCurrentDebugType(const char *Type)
isCurrentDebugType - Return true if the specified string is the debug type specified on the command l...