Home | History | Annotate | Download | only in Hexagon
      1 //===- HexagonSplitDouble.cpp ---------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #define DEBUG_TYPE "hsdr"
     11 
     12 #include "HexagonInstrInfo.h"
     13 #include "HexagonRegisterInfo.h"
     14 #include "HexagonSubtarget.h"
     15 #include "llvm/ADT/BitVector.h"
     16 #include "llvm/ADT/STLExtras.h"
     17 #include "llvm/ADT/SmallVector.h"
     18 #include "llvm/ADT/StringRef.h"
     19 #include "llvm/CodeGen/MachineBasicBlock.h"
     20 #include "llvm/CodeGen/MachineFunction.h"
     21 #include "llvm/CodeGen/MachineFunctionPass.h"
     22 #include "llvm/CodeGen/MachineInstr.h"
     23 #include "llvm/CodeGen/MachineInstrBuilder.h"
     24 #include "llvm/CodeGen/MachineLoopInfo.h"
     25 #include "llvm/CodeGen/MachineMemOperand.h"
     26 #include "llvm/CodeGen/MachineOperand.h"
     27 #include "llvm/CodeGen/MachineRegisterInfo.h"
     28 #include "llvm/CodeGen/TargetRegisterInfo.h"
     29 #include "llvm/Config/llvm-config.h"
     30 #include "llvm/IR/DebugLoc.h"
     31 #include "llvm/Pass.h"
     32 #include "llvm/Support/CommandLine.h"
     33 #include "llvm/Support/Compiler.h"
     34 #include "llvm/Support/Debug.h"
     35 #include "llvm/Support/ErrorHandling.h"
     36 #include "llvm/Support/raw_ostream.h"
     37 #include <algorithm>
     38 #include <cassert>
     39 #include <cstdint>
     40 #include <limits>
     41 #include <map>
     42 #include <set>
     43 #include <utility>
     44 #include <vector>
     45 
     46 using namespace llvm;
     47 
     48 namespace llvm {
     49 
     50   FunctionPass *createHexagonSplitDoubleRegs();
     51   void initializeHexagonSplitDoubleRegsPass(PassRegistry&);
     52 
     53 } // end namespace llvm
     54 
     55 static cl::opt<int> MaxHSDR("max-hsdr", cl::Hidden, cl::init(-1),
     56     cl::desc("Maximum number of split partitions"));
     57 static cl::opt<bool> MemRefsFixed("hsdr-no-mem", cl::Hidden, cl::init(true),
     58     cl::desc("Do not split loads or stores"));
     59   static cl::opt<bool> SplitAll("hsdr-split-all", cl::Hidden, cl::init(false),
     60       cl::desc("Split all partitions"));
     61 
     62 namespace {
     63 
     64   class HexagonSplitDoubleRegs : public MachineFunctionPass {
     65   public:
     66     static char ID;
     67 
     68     HexagonSplitDoubleRegs() : MachineFunctionPass(ID) {}
     69 
     70     StringRef getPassName() const override {
     71       return "Hexagon Split Double Registers";
     72     }
     73 
     74     void getAnalysisUsage(AnalysisUsage &AU) const override {
     75       AU.addRequired<MachineLoopInfo>();
     76       AU.addPreserved<MachineLoopInfo>();
     77       MachineFunctionPass::getAnalysisUsage(AU);
     78     }
     79 
     80     bool runOnMachineFunction(MachineFunction &MF) override;
     81 
     82   private:
     83     static const TargetRegisterClass *const DoubleRC;
     84 
     85     const HexagonRegisterInfo *TRI = nullptr;
     86     const HexagonInstrInfo *TII = nullptr;
     87     const MachineLoopInfo *MLI;
     88     MachineRegisterInfo *MRI;
     89 
     90     using USet = std::set<unsigned>;
     91     using UUSetMap = std::map<unsigned, USet>;
     92     using UUPair = std::pair<unsigned, unsigned>;
     93     using UUPairMap = std::map<unsigned, UUPair>;
     94     using LoopRegMap = std::map<const MachineLoop *, USet>;
     95 
     96     bool isInduction(unsigned Reg, LoopRegMap &IRM) const;
     97     bool isVolatileInstr(const MachineInstr *MI) const;
     98     bool isFixedInstr(const MachineInstr *MI) const;
     99     void partitionRegisters(UUSetMap &P2Rs);
    100     int32_t profit(const MachineInstr *MI) const;
    101     int32_t profit(unsigned Reg) const;
    102     bool isProfitable(const USet &Part, LoopRegMap &IRM) const;
    103 
    104     void collectIndRegsForLoop(const MachineLoop *L, USet &Rs);
    105     void collectIndRegs(LoopRegMap &IRM);
    106 
    107     void createHalfInstr(unsigned Opc, MachineInstr *MI,
    108         const UUPairMap &PairMap, unsigned SubR);
    109     void splitMemRef(MachineInstr *MI, const UUPairMap &PairMap);
    110     void splitImmediate(MachineInstr *MI, const UUPairMap &PairMap);
    111     void splitCombine(MachineInstr *MI, const UUPairMap &PairMap);
    112     void splitExt(MachineInstr *MI, const UUPairMap &PairMap);
    113     void splitShift(MachineInstr *MI, const UUPairMap &PairMap);
    114     void splitAslOr(MachineInstr *MI, const UUPairMap &PairMap);
    115     bool splitInstr(MachineInstr *MI, const UUPairMap &PairMap);
    116     void replaceSubregUses(MachineInstr *MI, const UUPairMap &PairMap);
    117     void collapseRegPairs(MachineInstr *MI, const UUPairMap &PairMap);
    118     bool splitPartition(const USet &Part);
    119 
    120     static int Counter;
    121 
    122     static void dump_partition(raw_ostream&, const USet&,
    123        const TargetRegisterInfo&);
    124   };
    125 
    126 } // end anonymous namespace
    127 
    128 char HexagonSplitDoubleRegs::ID;
    129 int HexagonSplitDoubleRegs::Counter = 0;
    130 const TargetRegisterClass *const HexagonSplitDoubleRegs::DoubleRC =
    131     &Hexagon::DoubleRegsRegClass;
    132 
    133 INITIALIZE_PASS(HexagonSplitDoubleRegs, "hexagon-split-double",
    134   "Hexagon Split Double Registers", false, false)
    135 
    136 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    137 LLVM_DUMP_METHOD void HexagonSplitDoubleRegs::dump_partition(raw_ostream &os,
    138       const USet &Part, const TargetRegisterInfo &TRI) {
    139   dbgs() << '{';
    140   for (auto I : Part)
    141     dbgs() << ' ' << printReg(I, &TRI);
    142   dbgs() << " }";
    143 }
    144 #endif
    145 
    146 bool HexagonSplitDoubleRegs::isInduction(unsigned Reg, LoopRegMap &IRM) const {
    147   for (auto I : IRM) {
    148     const USet &Rs = I.second;
    149     if (Rs.find(Reg) != Rs.end())
    150       return true;
    151   }
    152   return false;
    153 }
    154 
    155 bool HexagonSplitDoubleRegs::isVolatileInstr(const MachineInstr *MI) const {
    156   for (auto &I : MI->memoperands())
    157     if (I->isVolatile())
    158       return true;
    159   return false;
    160 }
    161 
    162 bool HexagonSplitDoubleRegs::isFixedInstr(const MachineInstr *MI) const {
    163   if (MI->mayLoad() || MI->mayStore())
    164     if (MemRefsFixed || isVolatileInstr(MI))
    165       return true;
    166   if (MI->isDebugInstr())
    167     return false;
    168 
    169   unsigned Opc = MI->getOpcode();
    170   switch (Opc) {
    171     default:
    172       return true;
    173 
    174     case TargetOpcode::PHI:
    175     case TargetOpcode::COPY:
    176       break;
    177 
    178     case Hexagon::L2_loadrd_io:
    179       // Not handling stack stores (only reg-based addresses).
    180       if (MI->getOperand(1).isReg())
    181         break;
    182       return true;
    183     case Hexagon::S2_storerd_io:
    184       // Not handling stack stores (only reg-based addresses).
    185       if (MI->getOperand(0).isReg())
    186         break;
    187       return true;
    188     case Hexagon::L2_loadrd_pi:
    189     case Hexagon::S2_storerd_pi:
    190 
    191     case Hexagon::A2_tfrpi:
    192     case Hexagon::A2_combineii:
    193     case Hexagon::A4_combineir:
    194     case Hexagon::A4_combineii:
    195     case Hexagon::A4_combineri:
    196     case Hexagon::A2_combinew:
    197     case Hexagon::CONST64:
    198 
    199     case Hexagon::A2_sxtw:
    200 
    201     case Hexagon::A2_andp:
    202     case Hexagon::A2_orp:
    203     case Hexagon::A2_xorp:
    204     case Hexagon::S2_asl_i_p_or:
    205     case Hexagon::S2_asl_i_p:
    206     case Hexagon::S2_asr_i_p:
    207     case Hexagon::S2_lsr_i_p:
    208       break;
    209   }
    210 
    211   for (auto &Op : MI->operands()) {
    212     if (!Op.isReg())
    213       continue;
    214     unsigned R = Op.getReg();
    215     if (!TargetRegisterInfo::isVirtualRegister(R))
    216       return true;
    217   }
    218   return false;
    219 }
    220 
    221 void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) {
    222   using UUMap = std::map<unsigned, unsigned>;
    223   using UVect = std::vector<unsigned>;
    224 
    225   unsigned NumRegs = MRI->getNumVirtRegs();
    226   BitVector DoubleRegs(NumRegs);
    227   for (unsigned i = 0; i < NumRegs; ++i) {
    228     unsigned R = TargetRegisterInfo::index2VirtReg(i);
    229     if (MRI->getRegClass(R) == DoubleRC)
    230       DoubleRegs.set(i);
    231   }
    232 
    233   BitVector FixedRegs(NumRegs);
    234   for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) {
    235     unsigned R = TargetRegisterInfo::index2VirtReg(x);
    236     MachineInstr *DefI = MRI->getVRegDef(R);
    237     // In some cases a register may exist, but never be defined or used.
    238     // It should never appear anywhere, but mark it as "fixed", just to be
    239     // safe.
    240     if (!DefI || isFixedInstr(DefI))
    241       FixedRegs.set(x);
    242   }
    243 
    244   UUSetMap AssocMap;
    245   for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) {
    246     if (FixedRegs[x])
    247       continue;
    248     unsigned R = TargetRegisterInfo::index2VirtReg(x);
    249     LLVM_DEBUG(dbgs() << printReg(R, TRI) << " ~~");
    250     USet &Asc = AssocMap[R];
    251     for (auto U = MRI->use_nodbg_begin(R), Z = MRI->use_nodbg_end();
    252          U != Z; ++U) {
    253       MachineOperand &Op = *U;
    254       MachineInstr *UseI = Op.getParent();
    255       if (isFixedInstr(UseI))
    256         continue;
    257       for (unsigned i = 0, n = UseI->getNumOperands(); i < n; ++i) {
    258         MachineOperand &MO = UseI->getOperand(i);
    259         // Skip non-registers or registers with subregisters.
    260         if (&MO == &Op || !MO.isReg() || MO.getSubReg())
    261           continue;
    262         unsigned T = MO.getReg();
    263         if (!TargetRegisterInfo::isVirtualRegister(T)) {
    264           FixedRegs.set(x);
    265           continue;
    266         }
    267         if (MRI->getRegClass(T) != DoubleRC)
    268           continue;
    269         unsigned u = TargetRegisterInfo::virtReg2Index(T);
    270         if (FixedRegs[u])
    271           continue;
    272         LLVM_DEBUG(dbgs() << ' ' << printReg(T, TRI));
    273         Asc.insert(T);
    274         // Make it symmetric.
    275         AssocMap[T].insert(R);
    276       }
    277     }
    278     LLVM_DEBUG(dbgs() << '\n');
    279   }
    280 
    281   UUMap R2P;
    282   unsigned NextP = 1;
    283   USet Visited;
    284   for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) {
    285     unsigned R = TargetRegisterInfo::index2VirtReg(x);
    286     if (Visited.count(R))
    287       continue;
    288     // Create a new partition for R.
    289     unsigned ThisP = FixedRegs[x] ? 0 : NextP++;
    290     UVect WorkQ;
    291     WorkQ.push_back(R);
    292     for (unsigned i = 0; i < WorkQ.size(); ++i) {
    293       unsigned T = WorkQ[i];
    294       if (Visited.count(T))
    295         continue;
    296       R2P[T] = ThisP;
    297       Visited.insert(T);
    298       // Add all registers associated with T.
    299       USet &Asc = AssocMap[T];
    300       for (USet::iterator J = Asc.begin(), F = Asc.end(); J != F; ++J)
    301         WorkQ.push_back(*J);
    302     }
    303   }
    304 
    305   for (auto I : R2P)
    306     P2Rs[I.second].insert(I.first);
    307 }
    308 
    309 static inline int32_t profitImm(unsigned Imm) {
    310   int32_t P = 0;
    311   if (Imm == 0 || Imm == 0xFFFFFFFF)
    312     P += 10;
    313   return P;
    314 }
    315 
    316 int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const {
    317   unsigned ImmX = 0;
    318   unsigned Opc = MI->getOpcode();
    319   switch (Opc) {
    320     case TargetOpcode::PHI:
    321       for (const auto &Op : MI->operands())
    322         if (!Op.getSubReg())
    323           return 0;
    324       return 10;
    325     case TargetOpcode::COPY:
    326       if (MI->getOperand(1).getSubReg() != 0)
    327         return 10;
    328       return 0;
    329 
    330     case Hexagon::L2_loadrd_io:
    331     case Hexagon::S2_storerd_io:
    332       return -1;
    333     case Hexagon::L2_loadrd_pi:
    334     case Hexagon::S2_storerd_pi:
    335       return 2;
    336 
    337     case Hexagon::A2_tfrpi:
    338     case Hexagon::CONST64: {
    339       uint64_t D = MI->getOperand(1).getImm();
    340       unsigned Lo = D & 0xFFFFFFFFULL;
    341       unsigned Hi = D >> 32;
    342       return profitImm(Lo) + profitImm(Hi);
    343     }
    344     case Hexagon::A2_combineii:
    345     case Hexagon::A4_combineii: {
    346       const MachineOperand &Op1 = MI->getOperand(1);
    347       const MachineOperand &Op2 = MI->getOperand(2);
    348       int32_t Prof1 = Op1.isImm() ? profitImm(Op1.getImm()) : 0;
    349       int32_t Prof2 = Op2.isImm() ? profitImm(Op2.getImm()) : 0;
    350       return Prof1 + Prof2;
    351     }
    352     case Hexagon::A4_combineri:
    353       ImmX++;
    354       // Fall through into A4_combineir.
    355       LLVM_FALLTHROUGH;
    356     case Hexagon::A4_combineir: {
    357       ImmX++;
    358       const MachineOperand &OpX = MI->getOperand(ImmX);
    359       if (OpX.isImm()) {
    360         int64_t V = OpX.getImm();
    361         if (V == 0 || V == -1)
    362           return 10;
    363       }
    364       // Fall through into A2_combinew.
    365       LLVM_FALLTHROUGH;
    366     }
    367     case Hexagon::A2_combinew:
    368       return 2;
    369 
    370     case Hexagon::A2_sxtw:
    371       return 3;
    372 
    373     case Hexagon::A2_andp:
    374     case Hexagon::A2_orp:
    375     case Hexagon::A2_xorp: {
    376       unsigned Rs = MI->getOperand(1).getReg();
    377       unsigned Rt = MI->getOperand(2).getReg();
    378       return profit(Rs) + profit(Rt);
    379     }
    380 
    381     case Hexagon::S2_asl_i_p_or: {
    382       unsigned S = MI->getOperand(3).getImm();
    383       if (S == 0 || S == 32)
    384         return 10;
    385       return -1;
    386     }
    387     case Hexagon::S2_asl_i_p:
    388     case Hexagon::S2_asr_i_p:
    389     case Hexagon::S2_lsr_i_p:
    390       unsigned S = MI->getOperand(2).getImm();
    391       if (S == 0 || S == 32)
    392         return 10;
    393       if (S == 16)
    394         return 5;
    395       if (S == 48)
    396         return 7;
    397       return -10;
    398   }
    399 
    400   return 0;
    401 }
    402 
    403 int32_t HexagonSplitDoubleRegs::profit(unsigned Reg) const {
    404   assert(TargetRegisterInfo::isVirtualRegister(Reg));
    405 
    406   const MachineInstr *DefI = MRI->getVRegDef(Reg);
    407   switch (DefI->getOpcode()) {
    408     case Hexagon::A2_tfrpi:
    409     case Hexagon::CONST64:
    410     case Hexagon::A2_combineii:
    411     case Hexagon::A4_combineii:
    412     case Hexagon::A4_combineri:
    413     case Hexagon::A4_combineir:
    414     case Hexagon::A2_combinew:
    415       return profit(DefI);
    416     default:
    417       break;
    418   }
    419   return 0;
    420 }
    421 
    422 bool HexagonSplitDoubleRegs::isProfitable(const USet &Part, LoopRegMap &IRM)
    423       const {
    424   unsigned FixedNum = 0, LoopPhiNum = 0;
    425   int32_t TotalP = 0;
    426 
    427   for (unsigned DR : Part) {
    428     MachineInstr *DefI = MRI->getVRegDef(DR);
    429     int32_t P = profit(DefI);
    430     if (P == std::numeric_limits<int>::min())
    431       return false;
    432     TotalP += P;
    433     // Reduce the profitability of splitting induction registers.
    434     if (isInduction(DR, IRM))
    435       TotalP -= 30;
    436 
    437     for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end();
    438          U != W; ++U) {
    439       MachineInstr *UseI = U->getParent();
    440       if (isFixedInstr(UseI)) {
    441         FixedNum++;
    442         // Calculate the cost of generating REG_SEQUENCE instructions.
    443         for (auto &Op : UseI->operands()) {
    444           if (Op.isReg() && Part.count(Op.getReg()))
    445             if (Op.getSubReg())
    446               TotalP -= 2;
    447         }
    448         continue;
    449       }
    450       // If a register from this partition is used in a fixed instruction,
    451       // and there is also a register in this partition that is used in
    452       // a loop phi node, then decrease the splitting profit as this can
    453       // confuse the modulo scheduler.
    454       if (UseI->isPHI()) {
    455         const MachineBasicBlock *PB = UseI->getParent();
    456         const MachineLoop *L = MLI->getLoopFor(PB);
    457         if (L && L->getHeader() == PB)
    458           LoopPhiNum++;
    459       }
    460       // Splittable instruction.
    461       int32_t P = profit(UseI);
    462       if (P == std::numeric_limits<int>::min())
    463         return false;
    464       TotalP += P;
    465     }
    466   }
    467 
    468   if (FixedNum > 0 && LoopPhiNum > 0)
    469     TotalP -= 20*LoopPhiNum;
    470 
    471   LLVM_DEBUG(dbgs() << "Partition profit: " << TotalP << '\n');
    472   if (SplitAll)
    473     return true;
    474   return TotalP > 0;
    475 }
    476 
    477 void HexagonSplitDoubleRegs::collectIndRegsForLoop(const MachineLoop *L,
    478       USet &Rs) {
    479   const MachineBasicBlock *HB = L->getHeader();
    480   const MachineBasicBlock *LB = L->getLoopLatch();
    481   if (!HB || !LB)
    482     return;
    483 
    484   // Examine the latch branch. Expect it to be a conditional branch to
    485   // the header (either "br-cond header" or "br-cond exit; br header").
    486   MachineBasicBlock *TB = nullptr, *FB = nullptr;
    487   MachineBasicBlock *TmpLB = const_cast<MachineBasicBlock*>(LB);
    488   SmallVector<MachineOperand,2> Cond;
    489   bool BadLB = TII->analyzeBranch(*TmpLB, TB, FB, Cond, false);
    490   // Only analyzable conditional branches. HII::analyzeBranch will put
    491   // the branch opcode as the first element of Cond, and the predicate
    492   // operand as the second.
    493   if (BadLB || Cond.size() != 2)
    494     return;
    495   // Only simple jump-conditional (with or without negation).
    496   if (!TII->PredOpcodeHasJMP_c(Cond[0].getImm()))
    497     return;
    498   // Must go to the header.
    499   if (TB != HB && FB != HB)
    500     return;
    501   assert(Cond[1].isReg() && "Unexpected Cond vector from analyzeBranch");
    502   // Expect a predicate register.
    503   unsigned PR = Cond[1].getReg();
    504   assert(MRI->getRegClass(PR) == &Hexagon::PredRegsRegClass);
    505 
    506   // Get the registers on which the loop controlling compare instruction
    507   // depends.
    508   unsigned CmpR1 = 0, CmpR2 = 0;
    509   const MachineInstr *CmpI = MRI->getVRegDef(PR);
    510   while (CmpI->getOpcode() == Hexagon::C2_not)
    511     CmpI = MRI->getVRegDef(CmpI->getOperand(1).getReg());
    512 
    513   int Mask = 0, Val = 0;
    514   bool OkCI = TII->analyzeCompare(*CmpI, CmpR1, CmpR2, Mask, Val);
    515   if (!OkCI)
    516     return;
    517   // Eliminate non-double input registers.
    518   if (CmpR1 && MRI->getRegClass(CmpR1) != DoubleRC)
    519     CmpR1 = 0;
    520   if (CmpR2 && MRI->getRegClass(CmpR2) != DoubleRC)
    521     CmpR2 = 0;
    522   if (!CmpR1 && !CmpR2)
    523     return;
    524 
    525   // Now examine the top of the loop: the phi nodes that could poten-
    526   // tially define loop induction registers. The registers defined by
    527   // such a phi node would be used in a 64-bit add, which then would
    528   // be used in the loop compare instruction.
    529 
    530   // Get the set of all double registers defined by phi nodes in the
    531   // loop header.
    532   using UVect = std::vector<unsigned>;
    533 
    534   UVect DP;
    535   for (auto &MI : *HB) {
    536     if (!MI.isPHI())
    537       break;
    538     const MachineOperand &MD = MI.getOperand(0);
    539     unsigned R = MD.getReg();
    540     if (MRI->getRegClass(R) == DoubleRC)
    541       DP.push_back(R);
    542   }
    543   if (DP.empty())
    544     return;
    545 
    546   auto NoIndOp = [this, CmpR1, CmpR2] (unsigned R) -> bool {
    547     for (auto I = MRI->use_nodbg_begin(R), E = MRI->use_nodbg_end();
    548          I != E; ++I) {
    549       const MachineInstr *UseI = I->getParent();
    550       if (UseI->getOpcode() != Hexagon::A2_addp)
    551         continue;
    552       // Get the output from the add. If it is one of the inputs to the
    553       // loop-controlling compare instruction, then R is likely an induc-
    554       // tion register.
    555       unsigned T = UseI->getOperand(0).getReg();
    556       if (T == CmpR1 || T == CmpR2)
    557         return false;
    558     }
    559     return true;
    560   };
    561   UVect::iterator End = llvm::remove_if(DP, NoIndOp);
    562   Rs.insert(DP.begin(), End);
    563   Rs.insert(CmpR1);
    564   Rs.insert(CmpR2);
    565 
    566   LLVM_DEBUG({
    567     dbgs() << "For loop at " << printMBBReference(*HB) << " ind regs: ";
    568     dump_partition(dbgs(), Rs, *TRI);
    569     dbgs() << '\n';
    570   });
    571 }
    572 
    573 void HexagonSplitDoubleRegs::collectIndRegs(LoopRegMap &IRM) {
    574   using LoopVector = std::vector<MachineLoop *>;
    575 
    576   LoopVector WorkQ;
    577 
    578   for (auto I : *MLI)
    579     WorkQ.push_back(I);
    580   for (unsigned i = 0; i < WorkQ.size(); ++i) {
    581     for (auto I : *WorkQ[i])
    582       WorkQ.push_back(I);
    583   }
    584 
    585   USet Rs;
    586   for (unsigned i = 0, n = WorkQ.size(); i < n; ++i) {
    587     MachineLoop *L = WorkQ[i];
    588     Rs.clear();
    589     collectIndRegsForLoop(L, Rs);
    590     if (!Rs.empty())
    591       IRM.insert(std::make_pair(L, Rs));
    592   }
    593 }
    594 
    595 void HexagonSplitDoubleRegs::createHalfInstr(unsigned Opc, MachineInstr *MI,
    596       const UUPairMap &PairMap, unsigned SubR) {
    597   MachineBasicBlock &B = *MI->getParent();
    598   DebugLoc DL = MI->getDebugLoc();
    599   MachineInstr *NewI = BuildMI(B, MI, DL, TII->get(Opc));
    600 
    601   for (auto &Op : MI->operands()) {
    602     if (!Op.isReg()) {
    603       NewI->addOperand(Op);
    604       continue;
    605     }
    606     // For register operands, set the subregister.
    607     unsigned R = Op.getReg();
    608     unsigned SR = Op.getSubReg();
    609     bool isVirtReg = TargetRegisterInfo::isVirtualRegister(R);
    610     bool isKill = Op.isKill();
    611     if (isVirtReg && MRI->getRegClass(R) == DoubleRC) {
    612       isKill = false;
    613       UUPairMap::const_iterator F = PairMap.find(R);
    614       if (F == PairMap.end()) {
    615         SR = SubR;
    616       } else {
    617         const UUPair &P = F->second;
    618         R = (SubR == Hexagon::isub_lo) ? P.first : P.second;
    619         SR = 0;
    620       }
    621     }
    622     auto CO = MachineOperand::CreateReg(R, Op.isDef(), Op.isImplicit(), isKill,
    623           Op.isDead(), Op.isUndef(), Op.isEarlyClobber(), SR, Op.isDebug(),
    624           Op.isInternalRead());
    625     NewI->addOperand(CO);
    626   }
    627 }
    628 
    629 void HexagonSplitDoubleRegs::splitMemRef(MachineInstr *MI,
    630       const UUPairMap &PairMap) {
    631   bool Load = MI->mayLoad();
    632   unsigned OrigOpc = MI->getOpcode();
    633   bool PostInc = (OrigOpc == Hexagon::L2_loadrd_pi ||
    634                   OrigOpc == Hexagon::S2_storerd_pi);
    635   MachineInstr *LowI, *HighI;
    636   MachineBasicBlock &B = *MI->getParent();
    637   DebugLoc DL = MI->getDebugLoc();
    638 
    639   // Index of the base-address-register operand.
    640   unsigned AdrX = PostInc ? (Load ? 2 : 1)
    641                           : (Load ? 1 : 0);
    642   MachineOperand &AdrOp = MI->getOperand(AdrX);
    643   unsigned RSA = getRegState(AdrOp);
    644   MachineOperand &ValOp = Load ? MI->getOperand(0)
    645                                : (PostInc ? MI->getOperand(3)
    646                                           : MI->getOperand(2));
    647   UUPairMap::const_iterator F = PairMap.find(ValOp.getReg());
    648   assert(F != PairMap.end());
    649 
    650   if (Load) {
    651     const UUPair &P = F->second;
    652     int64_t Off = PostInc ? 0 : MI->getOperand(2).getImm();
    653     LowI = BuildMI(B, MI, DL, TII->get(Hexagon::L2_loadri_io), P.first)
    654              .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg())
    655              .addImm(Off);
    656     HighI = BuildMI(B, MI, DL, TII->get(Hexagon::L2_loadri_io), P.second)
    657               .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg())
    658               .addImm(Off+4);
    659   } else {
    660     const UUPair &P = F->second;
    661     int64_t Off = PostInc ? 0 : MI->getOperand(1).getImm();
    662     LowI = BuildMI(B, MI, DL, TII->get(Hexagon::S2_storeri_io))
    663              .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg())
    664              .addImm(Off)
    665              .addReg(P.first);
    666     HighI = BuildMI(B, MI, DL, TII->get(Hexagon::S2_storeri_io))
    667               .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg())
    668               .addImm(Off+4)
    669               .addReg(P.second);
    670   }
    671 
    672   if (PostInc) {
    673     // Create the increment of the address register.
    674     int64_t Inc = Load ? MI->getOperand(3).getImm()
    675                        : MI->getOperand(2).getImm();
    676     MachineOperand &UpdOp = Load ? MI->getOperand(1) : MI->getOperand(0);
    677     const TargetRegisterClass *RC = MRI->getRegClass(UpdOp.getReg());
    678     unsigned NewR = MRI->createVirtualRegister(RC);
    679     assert(!UpdOp.getSubReg() && "Def operand with subreg");
    680     BuildMI(B, MI, DL, TII->get(Hexagon::A2_addi), NewR)
    681       .addReg(AdrOp.getReg(), RSA)
    682       .addImm(Inc);
    683     MRI->replaceRegWith(UpdOp.getReg(), NewR);
    684     // The original instruction will be deleted later.
    685   }
    686 
    687   // Generate a new pair of memory-operands.
    688   MachineFunction &MF = *B.getParent();
    689   for (auto &MO : MI->memoperands()) {
    690     const MachinePointerInfo &Ptr = MO->getPointerInfo();
    691     MachineMemOperand::Flags F = MO->getFlags();
    692     int A = MO->getAlignment();
    693 
    694     auto *Tmp1 = MF.getMachineMemOperand(Ptr, F, 4/*size*/, A);
    695     LowI->addMemOperand(MF, Tmp1);
    696     auto *Tmp2 = MF.getMachineMemOperand(Ptr, F, 4/*size*/, std::min(A, 4));
    697     HighI->addMemOperand(MF, Tmp2);
    698   }
    699 }
    700 
    701 void HexagonSplitDoubleRegs::splitImmediate(MachineInstr *MI,
    702       const UUPairMap &PairMap) {
    703   MachineOperand &Op0 = MI->getOperand(0);
    704   MachineOperand &Op1 = MI->getOperand(1);
    705   assert(Op0.isReg() && Op1.isImm());
    706   uint64_t V = Op1.getImm();
    707 
    708   MachineBasicBlock &B = *MI->getParent();
    709   DebugLoc DL = MI->getDebugLoc();
    710   UUPairMap::const_iterator F = PairMap.find(Op0.getReg());
    711   assert(F != PairMap.end());
    712   const UUPair &P = F->second;
    713 
    714   // The operand to A2_tfrsi can only have 32 significant bits. Immediate
    715   // values in MachineOperand are stored as 64-bit integers, and so the
    716   // value -1 may be represented either as 64-bit -1, or 4294967295. Both
    717   // will have the 32 higher bits truncated in the end, but -1 will remain
    718   // as -1, while the latter may appear to be a large unsigned value
    719   // requiring a constant extender. The casting to int32_t will select the
    720   // former representation. (The same reasoning applies to all 32-bit
    721   // values.)
    722   BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first)
    723     .addImm(int32_t(V & 0xFFFFFFFFULL));
    724   BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second)
    725     .addImm(int32_t(V >> 32));
    726 }
    727 
    728 void HexagonSplitDoubleRegs::splitCombine(MachineInstr *MI,
    729       const UUPairMap &PairMap) {
    730   MachineOperand &Op0 = MI->getOperand(0);
    731   MachineOperand &Op1 = MI->getOperand(1);
    732   MachineOperand &Op2 = MI->getOperand(2);
    733   assert(Op0.isReg());
    734 
    735   MachineBasicBlock &B = *MI->getParent();
    736   DebugLoc DL = MI->getDebugLoc();
    737   UUPairMap::const_iterator F = PairMap.find(Op0.getReg());
    738   assert(F != PairMap.end());
    739   const UUPair &P = F->second;
    740 
    741   if (!Op1.isReg()) {
    742     BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second)
    743       .add(Op1);
    744   } else {
    745     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second)
    746       .addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg());
    747   }
    748 
    749   if (!Op2.isReg()) {
    750     BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first)
    751       .add(Op2);
    752   } else {
    753     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first)
    754       .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg());
    755   }
    756 }
    757 
    758 void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI,
    759       const UUPairMap &PairMap) {
    760   MachineOperand &Op0 = MI->getOperand(0);
    761   MachineOperand &Op1 = MI->getOperand(1);
    762   assert(Op0.isReg() && Op1.isReg());
    763 
    764   MachineBasicBlock &B = *MI->getParent();
    765   DebugLoc DL = MI->getDebugLoc();
    766   UUPairMap::const_iterator F = PairMap.find(Op0.getReg());
    767   assert(F != PairMap.end());
    768   const UUPair &P = F->second;
    769   unsigned RS = getRegState(Op1);
    770 
    771   BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first)
    772     .addReg(Op1.getReg(), RS & ~RegState::Kill, Op1.getSubReg());
    773   BuildMI(B, MI, DL, TII->get(Hexagon::S2_asr_i_r), P.second)
    774     .addReg(Op1.getReg(), RS, Op1.getSubReg())
    775     .addImm(31);
    776 }
    777 
    778 void HexagonSplitDoubleRegs::splitShift(MachineInstr *MI,
    779       const UUPairMap &PairMap) {
    780   using namespace Hexagon;
    781 
    782   MachineOperand &Op0 = MI->getOperand(0);
    783   MachineOperand &Op1 = MI->getOperand(1);
    784   MachineOperand &Op2 = MI->getOperand(2);
    785   assert(Op0.isReg() && Op1.isReg() && Op2.isImm());
    786   int64_t Sh64 = Op2.getImm();
    787   assert(Sh64 >= 0 && Sh64 < 64);
    788   unsigned S = Sh64;
    789 
    790   UUPairMap::const_iterator F = PairMap.find(Op0.getReg());
    791   assert(F != PairMap.end());
    792   const UUPair &P = F->second;
    793   unsigned LoR = P.first;
    794   unsigned HiR = P.second;
    795 
    796   unsigned Opc = MI->getOpcode();
    797   bool Right = (Opc == S2_lsr_i_p || Opc == S2_asr_i_p);
    798   bool Left = !Right;
    799   bool Signed = (Opc == S2_asr_i_p);
    800 
    801   MachineBasicBlock &B = *MI->getParent();
    802   DebugLoc DL = MI->getDebugLoc();
    803   unsigned RS = getRegState(Op1);
    804   unsigned ShiftOpc = Left ? S2_asl_i_r
    805                            : (Signed ? S2_asr_i_r : S2_lsr_i_r);
    806   unsigned LoSR = isub_lo;
    807   unsigned HiSR = isub_hi;
    808 
    809   if (S == 0) {
    810     // No shift, subregister copy.
    811     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR)
    812       .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR);
    813     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), HiR)
    814       .addReg(Op1.getReg(), RS, HiSR);
    815   } else if (S < 32) {
    816     const TargetRegisterClass *IntRC = &IntRegsRegClass;
    817     unsigned TmpR = MRI->createVirtualRegister(IntRC);
    818     // Expansion:
    819     // Shift left:    DR = shl R, #s
    820     //   LoR  = shl R.lo, #s
    821     //   TmpR = extractu R.lo, #s, #32-s
    822     //   HiR  = or (TmpR, asl(R.hi, #s))
    823     // Shift right:   DR = shr R, #s
    824     //   HiR  = shr R.hi, #s
    825     //   TmpR = shr R.lo, #s
    826     //   LoR  = insert TmpR, R.hi, #s, #32-s
    827 
    828     // Shift left:
    829     //   LoR  = shl R.lo, #s
    830     // Shift right:
    831     //   TmpR = shr R.lo, #s
    832 
    833     // Make a special case for A2_aslh and A2_asrh (they are predicable as
    834     // opposed to S2_asl_i_r/S2_asr_i_r).
    835     if (S == 16 && Left)
    836       BuildMI(B, MI, DL, TII->get(A2_aslh), LoR)
    837         .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR);
    838     else if (S == 16 && Signed)
    839       BuildMI(B, MI, DL, TII->get(A2_asrh), TmpR)
    840         .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR);
    841     else
    842       BuildMI(B, MI, DL, TII->get(ShiftOpc), (Left ? LoR : TmpR))
    843         .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR)
    844         .addImm(S);
    845 
    846     if (Left) {
    847       // TmpR = extractu R.lo, #s, #32-s
    848       BuildMI(B, MI, DL, TII->get(S2_extractu), TmpR)
    849         .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR)
    850         .addImm(S)
    851         .addImm(32-S);
    852       // HiR  = or (TmpR, asl(R.hi, #s))
    853       BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR)
    854         .addReg(TmpR)
    855         .addReg(Op1.getReg(), RS, HiSR)
    856         .addImm(S);
    857     } else {
    858       // HiR  = shr R.hi, #s
    859       BuildMI(B, MI, DL, TII->get(ShiftOpc), HiR)
    860         .addReg(Op1.getReg(), RS & ~RegState::Kill, HiSR)
    861         .addImm(S);
    862       // LoR  = insert TmpR, R.hi, #s, #32-s
    863       BuildMI(B, MI, DL, TII->get(S2_insert), LoR)
    864         .addReg(TmpR)
    865         .addReg(Op1.getReg(), RS, HiSR)
    866         .addImm(S)
    867         .addImm(32-S);
    868     }
    869   } else if (S == 32) {
    870     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), (Left ? HiR : LoR))
    871       .addReg(Op1.getReg(), RS & ~RegState::Kill, (Left ? LoSR : HiSR));
    872     if (!Signed)
    873       BuildMI(B, MI, DL, TII->get(A2_tfrsi), (Left ? LoR : HiR))
    874         .addImm(0);
    875     else  // Must be right shift.
    876       BuildMI(B, MI, DL, TII->get(S2_asr_i_r), HiR)
    877         .addReg(Op1.getReg(), RS, HiSR)
    878         .addImm(31);
    879   } else if (S < 64) {
    880     S -= 32;
    881     if (S == 16 && Left)
    882       BuildMI(B, MI, DL, TII->get(A2_aslh), HiR)
    883         .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR);
    884     else if (S == 16 && Signed)
    885       BuildMI(B, MI, DL, TII->get(A2_asrh), LoR)
    886         .addReg(Op1.getReg(), RS & ~RegState::Kill, HiSR);
    887     else
    888       BuildMI(B, MI, DL, TII->get(ShiftOpc), (Left ? HiR : LoR))
    889         .addReg(Op1.getReg(), RS & ~RegState::Kill, (Left ? LoSR : HiSR))
    890         .addImm(S);
    891 
    892     if (Signed)
    893       BuildMI(B, MI, DL, TII->get(S2_asr_i_r), HiR)
    894         .addReg(Op1.getReg(), RS, HiSR)
    895         .addImm(31);
    896     else
    897       BuildMI(B, MI, DL, TII->get(A2_tfrsi), (Left ? LoR : HiR))
    898         .addImm(0);
    899   }
    900 }
    901 
    902 void HexagonSplitDoubleRegs::splitAslOr(MachineInstr *MI,
    903       const UUPairMap &PairMap) {
    904   using namespace Hexagon;
    905 
    906   MachineOperand &Op0 = MI->getOperand(0);
    907   MachineOperand &Op1 = MI->getOperand(1);
    908   MachineOperand &Op2 = MI->getOperand(2);
    909   MachineOperand &Op3 = MI->getOperand(3);
    910   assert(Op0.isReg() && Op1.isReg() && Op2.isReg() && Op3.isImm());
    911   int64_t Sh64 = Op3.getImm();
    912   assert(Sh64 >= 0 && Sh64 < 64);
    913   unsigned S = Sh64;
    914 
    915   UUPairMap::const_iterator F = PairMap.find(Op0.getReg());
    916   assert(F != PairMap.end());
    917   const UUPair &P = F->second;
    918   unsigned LoR = P.first;
    919   unsigned HiR = P.second;
    920 
    921   MachineBasicBlock &B = *MI->getParent();
    922   DebugLoc DL = MI->getDebugLoc();
    923   unsigned RS1 = getRegState(Op1);
    924   unsigned RS2 = getRegState(Op2);
    925   const TargetRegisterClass *IntRC = &IntRegsRegClass;
    926 
    927   unsigned LoSR = isub_lo;
    928   unsigned HiSR = isub_hi;
    929 
    930   // Op0 = S2_asl_i_p_or Op1, Op2, Op3
    931   // means:  Op0 = or (Op1, asl(Op2, Op3))
    932 
    933   // Expansion of
    934   //   DR = or (R1, asl(R2, #s))
    935   //
    936   //   LoR  = or (R1.lo, asl(R2.lo, #s))
    937   //   Tmp1 = extractu R2.lo, #s, #32-s
    938   //   Tmp2 = or R1.hi, Tmp1
    939   //   HiR  = or (Tmp2, asl(R2.hi, #s))
    940 
    941   if (S == 0) {
    942     // DR  = or (R1, asl(R2, #0))
    943     //    -> or (R1, R2)
    944     // i.e. LoR = or R1.lo, R2.lo
    945     //      HiR = or R1.hi, R2.hi
    946     BuildMI(B, MI, DL, TII->get(A2_or), LoR)
    947       .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR)
    948       .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR);
    949     BuildMI(B, MI, DL, TII->get(A2_or), HiR)
    950       .addReg(Op1.getReg(), RS1, HiSR)
    951       .addReg(Op2.getReg(), RS2, HiSR);
    952   } else if (S < 32) {
    953     BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), LoR)
    954       .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR)
    955       .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR)
    956       .addImm(S);
    957     unsigned TmpR1 = MRI->createVirtualRegister(IntRC);
    958     BuildMI(B, MI, DL, TII->get(S2_extractu), TmpR1)
    959       .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR)
    960       .addImm(S)
    961       .addImm(32-S);
    962     unsigned TmpR2 = MRI->createVirtualRegister(IntRC);
    963     BuildMI(B, MI, DL, TII->get(A2_or), TmpR2)
    964       .addReg(Op1.getReg(), RS1, HiSR)
    965       .addReg(TmpR1);
    966     BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR)
    967       .addReg(TmpR2)
    968       .addReg(Op2.getReg(), RS2, HiSR)
    969       .addImm(S);
    970   } else if (S == 32) {
    971     // DR  = or (R1, asl(R2, #32))
    972     //    -> or R1, R2.lo
    973     // LoR = R1.lo
    974     // HiR = or R1.hi, R2.lo
    975     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR)
    976       .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR);
    977     BuildMI(B, MI, DL, TII->get(A2_or), HiR)
    978       .addReg(Op1.getReg(), RS1, HiSR)
    979       .addReg(Op2.getReg(), RS2, LoSR);
    980   } else if (S < 64) {
    981     // DR  = or (R1, asl(R2, #s))
    982     //
    983     // LoR = R1:lo
    984     // HiR = or (R1:hi, asl(R2:lo, #s-32))
    985     S -= 32;
    986     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR)
    987       .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR);
    988     BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR)
    989       .addReg(Op1.getReg(), RS1, HiSR)
    990       .addReg(Op2.getReg(), RS2, LoSR)
    991       .addImm(S);
    992   }
    993 }
    994 
    995 bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *MI,
    996       const UUPairMap &PairMap) {
    997   using namespace Hexagon;
    998 
    999   LLVM_DEBUG(dbgs() << "Splitting: " << *MI);
   1000   bool Split = false;
   1001   unsigned Opc = MI->getOpcode();
   1002 
   1003   switch (Opc) {
   1004     case TargetOpcode::PHI:
   1005     case TargetOpcode::COPY: {
   1006       unsigned DstR = MI->getOperand(0).getReg();
   1007       if (MRI->getRegClass(DstR) == DoubleRC) {
   1008         createHalfInstr(Opc, MI, PairMap, isub_lo);
   1009         createHalfInstr(Opc, MI, PairMap, isub_hi);
   1010         Split = true;
   1011       }
   1012       break;
   1013     }
   1014     case A2_andp:
   1015       createHalfInstr(A2_and, MI, PairMap, isub_lo);
   1016       createHalfInstr(A2_and, MI, PairMap, isub_hi);
   1017       Split = true;
   1018       break;
   1019     case A2_orp:
   1020       createHalfInstr(A2_or, MI, PairMap, isub_lo);
   1021       createHalfInstr(A2_or, MI, PairMap, isub_hi);
   1022       Split = true;
   1023       break;
   1024     case A2_xorp:
   1025       createHalfInstr(A2_xor, MI, PairMap, isub_lo);
   1026       createHalfInstr(A2_xor, MI, PairMap, isub_hi);
   1027       Split = true;
   1028       break;
   1029 
   1030     case L2_loadrd_io:
   1031     case L2_loadrd_pi:
   1032     case S2_storerd_io:
   1033     case S2_storerd_pi:
   1034       splitMemRef(MI, PairMap);
   1035       Split = true;
   1036       break;
   1037 
   1038     case A2_tfrpi:
   1039     case CONST64:
   1040       splitImmediate(MI, PairMap);
   1041       Split = true;
   1042       break;
   1043 
   1044     case A2_combineii:
   1045     case A4_combineir:
   1046     case A4_combineii:
   1047     case A4_combineri:
   1048     case A2_combinew:
   1049       splitCombine(MI, PairMap);
   1050       Split = true;
   1051       break;
   1052 
   1053     case A2_sxtw:
   1054       splitExt(MI, PairMap);
   1055       Split = true;
   1056       break;
   1057 
   1058     case S2_asl_i_p:
   1059     case S2_asr_i_p:
   1060     case S2_lsr_i_p:
   1061       splitShift(MI, PairMap);
   1062       Split = true;
   1063       break;
   1064 
   1065     case S2_asl_i_p_or:
   1066       splitAslOr(MI, PairMap);
   1067       Split = true;
   1068       break;
   1069 
   1070     default:
   1071       llvm_unreachable("Instruction not splitable");
   1072       return false;
   1073   }
   1074 
   1075   return Split;
   1076 }
   1077 
   1078 void HexagonSplitDoubleRegs::replaceSubregUses(MachineInstr *MI,
   1079       const UUPairMap &PairMap) {
   1080   for (auto &Op : MI->operands()) {
   1081     if (!Op.isReg() || !Op.isUse() || !Op.getSubReg())
   1082       continue;
   1083     unsigned R = Op.getReg();
   1084     UUPairMap::const_iterator F = PairMap.find(R);
   1085     if (F == PairMap.end())
   1086       continue;
   1087     const UUPair &P = F->second;
   1088     switch (Op.getSubReg()) {
   1089       case Hexagon::isub_lo:
   1090         Op.setReg(P.first);
   1091         break;
   1092       case Hexagon::isub_hi:
   1093         Op.setReg(P.second);
   1094         break;
   1095     }
   1096     Op.setSubReg(0);
   1097   }
   1098 }
   1099 
   1100 void HexagonSplitDoubleRegs::collapseRegPairs(MachineInstr *MI,
   1101       const UUPairMap &PairMap) {
   1102   MachineBasicBlock &B = *MI->getParent();
   1103   DebugLoc DL = MI->getDebugLoc();
   1104 
   1105   for (auto &Op : MI->operands()) {
   1106     if (!Op.isReg() || !Op.isUse())
   1107       continue;
   1108     unsigned R = Op.getReg();
   1109     if (!TargetRegisterInfo::isVirtualRegister(R))
   1110       continue;
   1111     if (MRI->getRegClass(R) != DoubleRC || Op.getSubReg())
   1112       continue;
   1113     UUPairMap::const_iterator F = PairMap.find(R);
   1114     if (F == PairMap.end())
   1115       continue;
   1116     const UUPair &Pr = F->second;
   1117     unsigned NewDR = MRI->createVirtualRegister(DoubleRC);
   1118     BuildMI(B, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), NewDR)
   1119       .addReg(Pr.first)
   1120       .addImm(Hexagon::isub_lo)
   1121       .addReg(Pr.second)
   1122       .addImm(Hexagon::isub_hi);
   1123     Op.setReg(NewDR);
   1124   }
   1125 }
   1126 
   1127 bool HexagonSplitDoubleRegs::splitPartition(const USet &Part) {
   1128   using MISet = std::set<MachineInstr *>;
   1129 
   1130   const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass;
   1131   bool Changed = false;
   1132 
   1133   LLVM_DEBUG(dbgs() << "Splitting partition: ";
   1134              dump_partition(dbgs(), Part, *TRI); dbgs() << '\n');
   1135 
   1136   UUPairMap PairMap;
   1137 
   1138   MISet SplitIns;
   1139   for (unsigned DR : Part) {
   1140     MachineInstr *DefI = MRI->getVRegDef(DR);
   1141     SplitIns.insert(DefI);
   1142 
   1143     // Collect all instructions, including fixed ones.  We won't split them,
   1144     // but we need to visit them again to insert the REG_SEQUENCE instructions.
   1145     for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end();
   1146          U != W; ++U)
   1147       SplitIns.insert(U->getParent());
   1148 
   1149     unsigned LoR = MRI->createVirtualRegister(IntRC);
   1150     unsigned HiR = MRI->createVirtualRegister(IntRC);
   1151     LLVM_DEBUG(dbgs() << "Created mapping: " << printReg(DR, TRI) << " -> "
   1152                       << printReg(HiR, TRI) << ':' << printReg(LoR, TRI)
   1153                       << '\n');
   1154     PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR)));
   1155   }
   1156 
   1157   MISet Erase;
   1158   for (auto MI : SplitIns) {
   1159     if (isFixedInstr(MI)) {
   1160       collapseRegPairs(MI, PairMap);
   1161     } else {
   1162       bool Done = splitInstr(MI, PairMap);
   1163       if (Done)
   1164         Erase.insert(MI);
   1165       Changed |= Done;
   1166     }
   1167   }
   1168 
   1169   for (unsigned DR : Part) {
   1170     // Before erasing "double" instructions, revisit all uses of the double
   1171     // registers in this partition, and replace all uses of them with subre-
   1172     // gisters, with the corresponding single registers.
   1173     MISet Uses;
   1174     for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end();
   1175          U != W; ++U)
   1176       Uses.insert(U->getParent());
   1177     for (auto M : Uses)
   1178       replaceSubregUses(M, PairMap);
   1179   }
   1180 
   1181   for (auto MI : Erase) {
   1182     MachineBasicBlock *B = MI->getParent();
   1183     B->erase(MI);
   1184   }
   1185 
   1186   return Changed;
   1187 }
   1188 
   1189 bool HexagonSplitDoubleRegs::runOnMachineFunction(MachineFunction &MF) {
   1190   if (skipFunction(MF.getFunction()))
   1191     return false;
   1192 
   1193   LLVM_DEBUG(dbgs() << "Splitting double registers in function: "
   1194                     << MF.getName() << '\n');
   1195 
   1196   auto &ST = MF.getSubtarget<HexagonSubtarget>();
   1197   TRI = ST.getRegisterInfo();
   1198   TII = ST.getInstrInfo();
   1199   MRI = &MF.getRegInfo();
   1200   MLI = &getAnalysis<MachineLoopInfo>();
   1201 
   1202   UUSetMap P2Rs;
   1203   LoopRegMap IRM;
   1204 
   1205   collectIndRegs(IRM);
   1206   partitionRegisters(P2Rs);
   1207 
   1208   LLVM_DEBUG({
   1209     dbgs() << "Register partitioning: (partition #0 is fixed)\n";
   1210     for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) {
   1211       dbgs() << '#' << I->first << " -> ";
   1212       dump_partition(dbgs(), I->second, *TRI);
   1213       dbgs() << '\n';
   1214     }
   1215   });
   1216 
   1217   bool Changed = false;
   1218   int Limit = MaxHSDR;
   1219 
   1220   for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) {
   1221     if (I->first == 0)
   1222       continue;
   1223     if (Limit >= 0 && Counter >= Limit)
   1224       break;
   1225     USet &Part = I->second;
   1226     LLVM_DEBUG(dbgs() << "Calculating profit for partition #" << I->first
   1227                       << '\n');
   1228     if (!isProfitable(Part, IRM))
   1229       continue;
   1230     Counter++;
   1231     Changed |= splitPartition(Part);
   1232   }
   1233 
   1234   return Changed;
   1235 }
   1236 
   1237 FunctionPass *llvm::createHexagonSplitDoubleRegs() {
   1238   return new HexagonSplitDoubleRegs();
   1239 }
   1240