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