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