LLVM  4.0.0
HexagonCopyToCombine.cpp
Go to the documentation of this file.
1 //===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//
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 // This pass replaces transfer instructions by combine instructions.
10 // We walk along a basic block and look for two combinable instructions and try
11 // to move them together. If we can move them next to each other we do so and
12 // replace them with a combine instruction.
13 //===----------------------------------------------------------------------===//
14 #include "HexagonInstrInfo.h"
15 #include "HexagonSubtarget.h"
16 #include "llvm/PassSupport.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/DenseSet.h"
24 #include "llvm/CodeGen/Passes.h"
25 #include "llvm/Support/CodeGen.h"
27 #include "llvm/Support/Debug.h"
30 
31 using namespace llvm;
32 
33 #define DEBUG_TYPE "hexagon-copy-combine"
34 
35 static
36 cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
38  cl::init(false),
39  cl::desc("Disable merging into combines"));
40 static
41 cl::opt<bool> IsConst64Disabled("disable-const64",
43  cl::init(false),
44  cl::desc("Disable generation of const64"));
45 static
47 MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
48  cl::Hidden, cl::init(4),
49  cl::desc("Maximum distance between a tfr feeding a store we "
50  "consider the store still to be newifiable"));
51 
52 namespace llvm {
55 }
56 
57 
58 namespace {
59 
60 class HexagonCopyToCombine : public MachineFunctionPass {
61  const HexagonInstrInfo *TII;
62  const TargetRegisterInfo *TRI;
63  const HexagonSubtarget *ST;
64  bool ShouldCombineAggressively;
65 
66  DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
68 
69 public:
70  static char ID;
71 
72  HexagonCopyToCombine() : MachineFunctionPass(ID) {
74  }
75 
76  void getAnalysisUsage(AnalysisUsage &AU) const override {
78  }
79 
80  StringRef getPassName() const override {
81  return "Hexagon Copy-To-Combine Pass";
82  }
83 
84  bool runOnMachineFunction(MachineFunction &Fn) override;
85 
86  MachineFunctionProperties getRequiredProperties() const override {
89  }
90 
91 private:
92  MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1,
93  bool AllowC64);
94 
95  void findPotentialNewifiableTFRs(MachineBasicBlock &);
96 
97  void combine(MachineInstr &I1, MachineInstr &I2,
98  MachineBasicBlock::iterator &MI, bool DoInsertAtI1,
99  bool OptForSize);
100 
101  bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2,
102  unsigned I1DestReg, unsigned I2DestReg,
103  bool &DoInsertAtI1);
104 
105  void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
106  MachineOperand &HiOperand, MachineOperand &LoOperand);
107 
108  void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
109  MachineOperand &HiOperand, MachineOperand &LoOperand);
110 
111  void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
112  MachineOperand &HiOperand, MachineOperand &LoOperand);
113 
114  void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
115  MachineOperand &HiOperand, MachineOperand &LoOperand);
116 
117  void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg,
118  MachineOperand &HiOperand, MachineOperand &LoOperand);
119 };
120 
121 } // End anonymous namespace.
122 
123 char HexagonCopyToCombine::ID = 0;
124 
125 INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
126  "Hexagon Copy-To-Combine Pass", false, false)
127 
128 static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII,
129  bool ShouldCombineAggressively) {
130  switch (MI.getOpcode()) {
131  case Hexagon::A2_tfr: {
132  // A COPY instruction can be combined if its arguments are IntRegs (32bit).
133  const MachineOperand &Op0 = MI.getOperand(0);
134  const MachineOperand &Op1 = MI.getOperand(1);
135  assert(Op0.isReg() && Op1.isReg());
136 
137  unsigned DestReg = Op0.getReg();
138  unsigned SrcReg = Op1.getReg();
139  return Hexagon::IntRegsRegClass.contains(DestReg) &&
140  Hexagon::IntRegsRegClass.contains(SrcReg);
141  }
142 
143  case Hexagon::A2_tfrsi: {
144  // A transfer-immediate can be combined if its argument is a signed 8bit
145  // value.
146  const MachineOperand &Op0 = MI.getOperand(0);
147  const MachineOperand &Op1 = MI.getOperand(1);
148  assert(Op0.isReg());
149 
150  unsigned DestReg = Op0.getReg();
151  // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
152  // workaround for an ABI bug that prevents GOT relocations on combine
153  // instructions
154  if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG)
155  return false;
156 
157  // Only combine constant extended A2_tfrsi if we are in aggressive mode.
158  bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm());
159  return Hexagon::IntRegsRegClass.contains(DestReg) &&
160  (ShouldCombineAggressively || NotExt);
161  }
162 
163  case Hexagon::V6_vassign:
164  case Hexagon::V6_vassign_128B:
165  return true;
166 
167  default:
168  break;
169  }
170 
171  return false;
172 }
173 
174 template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) {
175  if (I.getOpcode() == Hexagon::TFRI64_V4 ||
176  I.getOpcode() == Hexagon::A2_tfrsi) {
177  const MachineOperand &Op = I.getOperand(1);
178  return !Op.isImm() || !isInt<N>(Op.getImm());
179  }
180  return false;
181 }
182 
183 /// areCombinableOperations - Returns true if the two instruction can be merge
184 /// into a combine (ignoring register constraints).
186  MachineInstr &HighRegInst,
187  MachineInstr &LowRegInst, bool AllowC64) {
188  unsigned HiOpc = HighRegInst.getOpcode();
189  unsigned LoOpc = LowRegInst.getOpcode();
190 
191  auto verifyOpc = [](unsigned Opc) -> void {
192  switch (Opc) {
193  case Hexagon::A2_tfr:
194  case Hexagon::A2_tfrsi:
195  case Hexagon::V6_vassign:
196  break;
197  default:
198  llvm_unreachable("Unexpected opcode");
199  }
200  };
201  verifyOpc(HiOpc);
202  verifyOpc(LoOpc);
203 
204  if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign)
205  return HiOpc == LoOpc;
206 
207  if (!AllowC64) {
208  // There is no combine of two constant extended values.
209  if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
210  isGreaterThanNBitTFRI<6>(LowRegInst))
211  return false;
212  }
213 
214  // There is a combine of two constant extended values into CONST64,
215  // provided both constants are true immediates.
216  if (isGreaterThanNBitTFRI<16>(HighRegInst) &&
217  isGreaterThanNBitTFRI<16>(LowRegInst))
218  return (HighRegInst.getOperand(1).isImm() &&
219  LowRegInst.getOperand(1).isImm());
220 
221  // There is no combine of two constant extended values, unless handled above
222  // Make both 8-bit size checks to allow both combine (#,##) and combine(##,#)
223  if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
224  isGreaterThanNBitTFRI<8>(LowRegInst))
225  return false;
226 
227  return true;
228 }
229 
230 static bool isEvenReg(unsigned Reg) {
232  if (Hexagon::IntRegsRegClass.contains(Reg))
233  return (Reg - Hexagon::R0) % 2 == 0;
234  if (Hexagon::VectorRegsRegClass.contains(Reg) ||
235  Hexagon::VectorRegs128BRegClass.contains(Reg))
236  return (Reg - Hexagon::V0) % 2 == 0;
237  llvm_unreachable("Invalid register");
238 }
239 
240 static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled) {
241  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
242  MachineOperand &Op = MI.getOperand(I);
243  if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill())
244  continue;
245  Op.setIsKill(false);
246  }
247 }
248 
249 /// Returns true if it is unsafe to move a copy instruction from \p UseReg to
250 /// \p DestReg over the instruction \p MI.
251 static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg,
252  unsigned DestReg,
253  const TargetRegisterInfo *TRI) {
254  return (UseReg && (MI.modifiesRegister(UseReg, TRI))) ||
255  MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) ||
256  MI.hasUnmodeledSideEffects() || MI.isInlineAsm() || MI.isDebugValue();
257 }
258 
259 static unsigned UseReg(const MachineOperand& MO) {
260  return MO.isReg() ? MO.getReg() : 0;
261 }
262 
263 /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
264 /// that the two instructions can be paired in a combine.
265 bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
266  MachineInstr &I2,
267  unsigned I1DestReg,
268  unsigned I2DestReg,
269  bool &DoInsertAtI1) {
270  unsigned I2UseReg = UseReg(I2.getOperand(1));
271 
272  // It is not safe to move I1 and I2 into one combine if I2 has a true
273  // dependence on I1.
274  if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI))
275  return false;
276 
277  bool isSafe = true;
278 
279  // First try to move I2 towards I1.
280  {
281  // A reverse_iterator instantiated like below starts before I2, and I1
282  // respectively.
283  // Look at instructions I in between I2 and (excluding) I1.
286  // At 03 we got better results (dhrystone!) by being more conservative.
287  if (!ShouldCombineAggressively)
289  // If I2 kills its operand and we move I2 over an instruction that also
290  // uses I2's use reg we need to modify that (first) instruction to now kill
291  // this reg.
292  unsigned KilledOperand = 0;
293  if (I2.killsRegister(I2UseReg))
294  KilledOperand = I2UseReg;
295  MachineInstr *KillingInstr = nullptr;
296 
297  for (; I != End; ++I) {
298  // If the intervening instruction I:
299  // * modifies I2's use reg
300  // * modifies I2's def reg
301  // * reads I2's def reg
302  // * or has unmodelled side effects
303  // we can't move I2 across it.
304  if (I->isDebugValue())
305  continue;
306 
307  if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) {
308  isSafe = false;
309  break;
310  }
311 
312  // Update first use of the killed operand.
313  if (!KillingInstr && KilledOperand &&
314  I->readsRegister(KilledOperand, TRI))
315  KillingInstr = &*I;
316  }
317  if (isSafe) {
318  // Update the intermediate instruction to with the kill flag.
319  if (KillingInstr) {
320  bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
321  (void)Added; // suppress compiler warning
322  assert(Added && "Must successfully update kill flag");
323  removeKillInfo(I2, KilledOperand);
324  }
325  DoInsertAtI1 = true;
326  return true;
327  }
328  }
329 
330  // Try to move I1 towards I2.
331  {
332  // Look at instructions I in between I1 and (excluding) I2.
334  // At O3 we got better results (dhrystone) by being more conservative here.
335  if (!ShouldCombineAggressively)
336  End = std::next(MachineBasicBlock::iterator(I2));
337  unsigned I1UseReg = UseReg(I1.getOperand(1));
338  // Track killed operands. If we move across an instruction that kills our
339  // operand, we need to update the kill information on the moved I1. It kills
340  // the operand now.
341  MachineInstr *KillingInstr = nullptr;
342  unsigned KilledOperand = 0;
343 
344  while(++I != End) {
345  MachineInstr &MI = *I;
346  // If the intervening instruction MI:
347  // * modifies I1's use reg
348  // * modifies I1's def reg
349  // * reads I1's def reg
350  // * or has unmodelled side effects
351  // We introduce this special case because llvm has no api to remove a
352  // kill flag for a register (a removeRegisterKilled() analogous to
353  // addRegisterKilled) that handles aliased register correctly.
354  // * or has a killed aliased register use of I1's use reg
355  // %D4<def> = A2_tfrpi 16
356  // %R6<def> = A2_tfr %R9
357  // %R8<def> = KILL %R8, %D4<imp-use,kill>
358  // If we want to move R6 = across the KILL instruction we would have
359  // to remove the %D4<imp-use,kill> operand. For now, we are
360  // conservative and disallow the move.
361  // we can't move I1 across it.
362  if (MI.isDebugValue()) {
363  if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2.
364  DbgMItoMove.push_back(&MI);
365  continue;
366  }
367 
368  if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) ||
369  // Check for an aliased register kill. Bail out if we see one.
370  (!MI.killsRegister(I1UseReg) && MI.killsRegister(I1UseReg, TRI)))
371  return false;
372 
373  // Check for an exact kill (registers match).
374  if (I1UseReg && MI.killsRegister(I1UseReg)) {
375  assert(!KillingInstr && "Should only see one killing instruction");
376  KilledOperand = I1UseReg;
377  KillingInstr = &MI;
378  }
379  }
380  if (KillingInstr) {
381  removeKillInfo(*KillingInstr, KilledOperand);
382  // Update I1 to set the kill flag. This flag will later be picked up by
383  // the new COMBINE instruction.
384  bool Added = I1.addRegisterKilled(KilledOperand, TRI);
385  (void)Added; // suppress compiler warning
386  assert(Added && "Must successfully update kill flag");
387  }
388  DoInsertAtI1 = false;
389  }
390 
391  return true;
392 }
393 
394 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
395 /// newified. (A use of a 64 bit register define can not be newified)
396 void
397 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
399  for (MachineInstr &MI : BB) {
400  if (MI.isDebugValue())
401  continue;
402 
403  // Mark TFRs that feed a potential new value store as such.
404  if (TII->mayBeNewStore(MI)) {
405  // Look for uses of TFR instructions.
406  for (unsigned OpdIdx = 0, OpdE = MI.getNumOperands(); OpdIdx != OpdE;
407  ++OpdIdx) {
408  MachineOperand &Op = MI.getOperand(OpdIdx);
409 
410  // Skip over anything except register uses.
411  if (!Op.isReg() || !Op.isUse() || !Op.getReg())
412  continue;
413 
414  // Look for the defining instruction.
415  unsigned Reg = Op.getReg();
416  MachineInstr *DefInst = LastDef[Reg];
417  if (!DefInst)
418  continue;
419  if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))
420  continue;
421 
422  // Only close newifiable stores should influence the decision.
423  // Ignore the debug instructions in between.
424  MachineBasicBlock::iterator It(DefInst);
425  unsigned NumInstsToDef = 0;
426  while (&*It != &MI) {
427  if (!It->isDebugValue())
428  ++NumInstsToDef;
429  ++It;
430  }
431 
432  if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
433  continue;
434 
435  PotentiallyNewifiableTFR.insert(DefInst);
436  }
437  // Skip to next instruction.
438  continue;
439  }
440 
441  // Put instructions that last defined integer or double registers into the
442  // map.
443  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
444  MachineOperand &Op = MI.getOperand(I);
445  if (!Op.isReg() || !Op.isDef() || !Op.getReg())
446  continue;
447  unsigned Reg = Op.getReg();
448  if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
449  for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
450  LastDef[*SubRegs] = &MI;
451  }
452  } else if (Hexagon::IntRegsRegClass.contains(Reg))
453  LastDef[Reg] = &MI;
454  }
455  }
456 }
457 
458 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
459 
460  if (IsCombinesDisabled) return false;
461 
462  bool HasChanged = false;
463 
464  // Get target info.
466  TRI = ST->getRegisterInfo();
467  TII = ST->getInstrInfo();
468 
469  const Function *F = MF.getFunction();
470  bool OptForSize = F->hasFnAttribute(Attribute::OptimizeForSize);
471 
472  // Combine aggressively (for code size)
473  ShouldCombineAggressively =
475 
476  // Traverse basic blocks.
477  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE;
478  ++BI) {
479  PotentiallyNewifiableTFR.clear();
480  findPotentialNewifiableTFRs(*BI);
481 
482  // Traverse instructions in basic block.
483  for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end();
484  MI != End;) {
485  MachineInstr &I1 = *MI++;
486 
487  if (I1.isDebugValue())
488  continue;
489 
490  // Don't combine a TFR whose user could be newified (instructions that
491  // define double registers can not be newified - Programmer's Ref Manual
492  // 5.4.2 New-value stores).
493  if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))
494  continue;
495 
496  // Ignore instructions that are not combinable.
497  if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
498  continue;
499 
500  // Find a second instruction that can be merged into a combine
501  // instruction. In addition, also find all the debug instructions that
502  // need to be moved along with it.
503  bool DoInsertAtI1 = false;
504  DbgMItoMove.clear();
505  MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize);
506  if (I2) {
507  HasChanged = true;
508  combine(I1, *I2, MI, DoInsertAtI1, OptForSize);
509  }
510  }
511  }
512 
513  return HasChanged;
514 }
515 
516 /// findPairable - Returns an instruction that can be merged with \p I1 into a
517 /// COMBINE instruction or 0 if no such instruction can be found. Returns true
518 /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
519 /// false if the combine must be inserted at the returned instruction.
520 MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
521  bool &DoInsertAtI1,
522  bool AllowC64) {
524  while (I2 != I1.getParent()->end() && I2->isDebugValue())
525  ++I2;
526 
527  unsigned I1DestReg = I1.getOperand(0).getReg();
528 
529  for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End;
530  ++I2) {
531  // Bail out early if we see a second definition of I1DestReg.
532  if (I2->modifiesRegister(I1DestReg, TRI))
533  break;
534 
535  // Ignore non-combinable instructions.
536  if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))
537  continue;
538 
539  // Don't combine a TFR whose user could be newified.
540  if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))
541  continue;
542 
543  unsigned I2DestReg = I2->getOperand(0).getReg();
544 
545  // Check that registers are adjacent and that the first destination register
546  // is even.
547  bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
548  bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
549  unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
550  if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))
551  continue;
552 
553  // Check that the two instructions are combinable. V4 allows more
554  // instructions to be merged into a combine.
555  // The order matters because in a A2_tfrsi we might can encode a int8 as
556  // the hi reg operand but only a uint6 as the low reg operand.
557  if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||
558  (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))
559  break;
560 
561  if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
562  return &*I2;
563 
564  // Not safe. Stop searching.
565  break;
566  }
567  return nullptr;
568 }
569 
570 void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
572  bool DoInsertAtI1, bool OptForSize) {
573  // We are going to delete I2. If MI points to I2 advance it to the next
574  // instruction.
575  if (MI == I2.getIterator())
576  ++MI;
577 
578  // Figure out whether I1 or I2 goes into the lowreg part.
579  unsigned I1DestReg = I1.getOperand(0).getReg();
580  unsigned I2DestReg = I2.getOperand(0).getReg();
581  bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
582  unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
583  unsigned SubLo;
584 
585  const TargetRegisterClass *SuperRC = nullptr;
586  if (Hexagon::IntRegsRegClass.contains(LoRegDef)) {
587  SuperRC = &Hexagon::DoubleRegsRegClass;
588  SubLo = Hexagon::isub_lo;
589  } else if (Hexagon::VectorRegsRegClass.contains(LoRegDef)) {
590  assert(ST->useHVXOps());
591  if (ST->useHVXSglOps())
592  SuperRC = &Hexagon::VecDblRegsRegClass;
593  else
594  SuperRC = &Hexagon::VecDblRegs128BRegClass;
595  SubLo = Hexagon::vsub_lo;
596  } else
597  llvm_unreachable("Unexpected register class");
598 
599  // Get the double word register.
600  unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC);
601  assert(DoubleRegDest != 0 && "Expect a valid register");
602 
603  // Setup source operands.
604  MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);
605  MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);
606 
607  // Figure out which source is a register and which a constant.
608  bool IsHiReg = HiOperand.isReg();
609  bool IsLoReg = LoOperand.isReg();
610 
611  // There is a combine of two constant extended values into CONST64.
612  bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&
613  isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2);
614 
615  MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
616  // Emit combine.
617  if (IsHiReg && IsLoReg)
618  emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
619  else if (IsHiReg)
620  emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
621  else if (IsLoReg)
622  emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
623  else if (IsC64 && !IsConst64Disabled)
624  emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
625  else
626  emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
627 
628  // Move debug instructions along with I1 if it's being
629  // moved towards I2.
630  if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
631  // Insert debug instructions at the new location before I2.
632  MachineBasicBlock *BB = InsertPt->getParent();
633  for (auto NewMI : DbgMItoMove) {
634  // If iterator MI is pointing to DEBUG_VAL, make sure
635  // MI now points to next relevant instruction.
636  if (NewMI == MI)
637  ++MI;
638  BB->splice(InsertPt, BB, NewMI);
639  }
640  }
641 
642  I1.eraseFromParent();
643  I2.eraseFromParent();
644 }
645 
646 void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,
647  unsigned DoubleDestReg,
648  MachineOperand &HiOperand,
649  MachineOperand &LoOperand) {
650  DEBUG(dbgs() << "Found a CONST64\n");
651 
652  DebugLoc DL = InsertPt->getDebugLoc();
653  MachineBasicBlock *BB = InsertPt->getParent();
654  assert(LoOperand.isImm() && HiOperand.isImm() &&
655  "Both operands must be immediate");
656 
657  int64_t V = HiOperand.getImm();
658  V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());
659  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg)
660  .addImm(V);
661 }
662 
663 void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
664  unsigned DoubleDestReg,
665  MachineOperand &HiOperand,
666  MachineOperand &LoOperand) {
667  DebugLoc DL = InsertPt->getDebugLoc();
668  MachineBasicBlock *BB = InsertPt->getParent();
669 
670  // Handle globals.
671  if (HiOperand.isGlobal()) {
672  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
673  .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
674  HiOperand.getTargetFlags())
675  .addImm(LoOperand.getImm());
676  return;
677  }
678  if (LoOperand.isGlobal()) {
679  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
680  .addImm(HiOperand.getImm())
681  .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
682  LoOperand.getTargetFlags());
683  return;
684  }
685 
686  // Handle block addresses.
687  if (HiOperand.isBlockAddress()) {
688  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
689  .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
690  HiOperand.getTargetFlags())
691  .addImm(LoOperand.getImm());
692  return;
693  }
694  if (LoOperand.isBlockAddress()) {
695  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
696  .addImm(HiOperand.getImm())
697  .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
698  LoOperand.getTargetFlags());
699  return;
700  }
701 
702  // Handle jump tables.
703  if (HiOperand.isJTI()) {
704  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
705  .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
706  .addImm(LoOperand.getImm());
707  return;
708  }
709  if (LoOperand.isJTI()) {
710  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
711  .addImm(HiOperand.getImm())
712  .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
713  return;
714  }
715 
716  // Handle constant pools.
717  if (HiOperand.isCPI()) {
718  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
719  .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
720  HiOperand.getTargetFlags())
721  .addImm(LoOperand.getImm());
722  return;
723  }
724  if (LoOperand.isCPI()) {
725  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
726  .addImm(HiOperand.getImm())
727  .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
728  LoOperand.getTargetFlags());
729  return;
730  }
731 
732  // First preference should be given to Hexagon::A2_combineii instruction
733  // as it can include U6 (in Hexagon::A4_combineii) as well.
734  // In this instruction, HiOperand is const extended, if required.
735  if (isInt<8>(LoOperand.getImm())) {
736  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
737  .addImm(HiOperand.getImm())
738  .addImm(LoOperand.getImm());
739  return;
740  }
741 
742  // In this instruction, LoOperand is const extended, if required.
743  if (isInt<8>(HiOperand.getImm())) {
744  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
745  .addImm(HiOperand.getImm())
746  .addImm(LoOperand.getImm());
747  return;
748  }
749 
750  // Insert new combine instruction.
751  // DoubleRegDest = combine #HiImm, #LoImm
752  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
753  .addImm(HiOperand.getImm())
754  .addImm(LoOperand.getImm());
755 }
756 
757 void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
758  unsigned DoubleDestReg,
759  MachineOperand &HiOperand,
760  MachineOperand &LoOperand) {
761  unsigned LoReg = LoOperand.getReg();
762  unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
763 
764  DebugLoc DL = InsertPt->getDebugLoc();
765  MachineBasicBlock *BB = InsertPt->getParent();
766 
767  // Handle globals.
768  if (HiOperand.isGlobal()) {
769  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
770  .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
771  HiOperand.getTargetFlags())
772  .addReg(LoReg, LoRegKillFlag);
773  return;
774  }
775  // Handle block addresses.
776  if (HiOperand.isBlockAddress()) {
777  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
778  .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
779  HiOperand.getTargetFlags())
780  .addReg(LoReg, LoRegKillFlag);
781  return;
782  }
783  // Handle jump tables.
784  if (HiOperand.isJTI()) {
785  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
786  .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
787  .addReg(LoReg, LoRegKillFlag);
788  return;
789  }
790  // Handle constant pools.
791  if (HiOperand.isCPI()) {
792  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
793  .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
794  HiOperand.getTargetFlags())
795  .addReg(LoReg, LoRegKillFlag);
796  return;
797  }
798  // Insert new combine instruction.
799  // DoubleRegDest = combine #HiImm, LoReg
800  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
801  .addImm(HiOperand.getImm())
802  .addReg(LoReg, LoRegKillFlag);
803 }
804 
805 void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
806  unsigned DoubleDestReg,
807  MachineOperand &HiOperand,
808  MachineOperand &LoOperand) {
809  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
810  unsigned HiReg = HiOperand.getReg();
811 
812  DebugLoc DL = InsertPt->getDebugLoc();
813  MachineBasicBlock *BB = InsertPt->getParent();
814 
815  // Handle global.
816  if (LoOperand.isGlobal()) {
817  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
818  .addReg(HiReg, HiRegKillFlag)
819  .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
820  LoOperand.getTargetFlags());
821  return;
822  }
823  // Handle block addresses.
824  if (LoOperand.isBlockAddress()) {
825  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
826  .addReg(HiReg, HiRegKillFlag)
827  .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
828  LoOperand.getTargetFlags());
829  return;
830  }
831  // Handle jump tables.
832  if (LoOperand.isJTI()) {
833  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
834  .addReg(HiOperand.getReg(), HiRegKillFlag)
835  .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
836  return;
837  }
838  // Handle constant pools.
839  if (LoOperand.isCPI()) {
840  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
841  .addReg(HiOperand.getReg(), HiRegKillFlag)
842  .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
843  LoOperand.getTargetFlags());
844  return;
845  }
846 
847  // Insert new combine instruction.
848  // DoubleRegDest = combine HiReg, #LoImm
849  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
850  .addReg(HiReg, HiRegKillFlag)
851  .addImm(LoOperand.getImm());
852 }
853 
854 void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
855  unsigned DoubleDestReg,
856  MachineOperand &HiOperand,
857  MachineOperand &LoOperand) {
858  unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
859  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
860  unsigned LoReg = LoOperand.getReg();
861  unsigned HiReg = HiOperand.getReg();
862 
863  DebugLoc DL = InsertPt->getDebugLoc();
864  MachineBasicBlock *BB = InsertPt->getParent();
865 
866  // Insert new combine instruction.
867  // DoubleRegDest = combine HiReg, LoReg
868  unsigned NewOpc;
869  if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) {
870  NewOpc = Hexagon::A2_combinew;
871  } else if (Hexagon::VecDblRegsRegClass.contains(DoubleDestReg)) {
872  assert(ST->useHVXOps());
873  if (ST->useHVXSglOps())
874  NewOpc = Hexagon::V6_vcombine;
875  else
876  NewOpc = Hexagon::V6_vcombine_128B;
877  } else
878  llvm_unreachable("Unexpected register");
879 
880  BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)
881  .addReg(HiReg, HiRegKillFlag)
882  .addReg(LoReg, LoRegKillFlag);
883 }
884 
886  return new HexagonCopyToCombine();
887 }
FunctionPass * createHexagonCopyToCombine()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const GlobalValue * getGlobal() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:202
static bool areCombinableOperations(const TargetRegisterInfo *TRI, MachineInstr &HighRegInst, MachineInstr &LowRegInst, bool AllowC64)
areCombinableOperations - Returns true if the two instruction can be merge into a combine (ignoring r...
constexpr bool isInt< 8 >(int64_t x)
Definition: MathExtras.h:268
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
A debug info location.
Definition: DebugLoc.h:34
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static bool isGreaterThanNBitTFRI(const MachineInstr &I)
static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg, unsigned DestReg, const TargetRegisterInfo *TRI)
Returns true if it is unsafe to move a copy instruction from UseReg to DestReg over the instruction M...
return AArch64::GPR64RegClass contains(Reg)
static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled)
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
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
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Reg
All possible values of the reg field in the ModR/M byte.
void initializeHexagonCopyToCombinePass(PassRegistry &)
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
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
#define F(x, y, z)
Definition: MD5.cpp:51
bool isKill() const
static cl::opt< unsigned > MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store", cl::Hidden, cl::init(4), cl::desc("Maximum distance between a tfr feeding a store we ""consider the store still to be newifiable"))
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
int64_t getImm() const
unsigned getKillRegState(bool B)
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
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
unsigned getTargetFlags() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
Represent the analysis usage information of a pass.
static const unsigned End
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
int64_t getOffset() const
Return the offset from the symbol in this operand.
self_iterator getIterator()
Definition: ilist_node.h:81
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSubRegIterator enumerates all sub-registers of Reg.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsKill(bool Val=true)
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
Definition: MachineInstr.h:865
Iterator for intrusive lists based on ilist_node.
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
bool isInlineAsm() const
Definition: MachineInstr.h:789
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
MachineFunctionProperties & set(Property P)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1132
Representation of each machine instruction.
Definition: MachineInstr.h:52
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:226
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
INITIALIZE_PASS(HexagonCopyToCombine,"hexagon-copy-combine","Hexagon Copy-To-Combine Pass", false, false) static bool isCombinableInstType(MachineInstr &MI
static unsigned UseReg(const MachineOperand &MO)
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static bool isEvenReg(unsigned Reg)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr kills the specified register.
Definition: MachineInstr.h:886
aarch64 promote const
#define DEBUG(X)
Definition: Debug.h:100
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
const BlockAddress * getBlockAddress() const
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
const MachineInstrBuilder & addBlockAddress(const BlockAddress *BA, int64_t Offset=0, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
static cl::opt< bool > IsCombinesDisabled("disable-merge-into-combines", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable merging into combines"))
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
Definition: MachineInstr.h:903
Properties which a MachineFunction may have at a given point in time.
static cl::opt< bool > IsConst64Disabled("disable-const64", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable generation of const64"))