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