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, 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