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