LLVM  8.0.1
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->isDebugInstr())
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.
332  MachineBasicBlock::iterator I(I1), End(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 = A2_tfrpi 16
355  // %r6 = A2_tfr %r9
356  // %r8 = KILL %r8, implicit killed %d4
357  // If we want to move R6 = across the KILL instruction we would have
358  // to remove the implicit killed %d4 operand. For now, we are
359  // conservative and disallow the move.
360  // we can't move I1 across it.
361  if (MI.isDebugInstr()) {
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.isDebugInstr())
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->isDebugInstr())
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.isDebugInstr())
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->isDebugInstr())
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.
559  // The order matters because in a A2_tfrsi we might can encode a int8 as
560  // the hi reg operand but only a uint6 as the low reg operand.
561  if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||
562  (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))
563  break;
564 
565  if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
566  return &*I2;
567 
568  // Not safe. Stop searching.
569  break;
570  }
571  return nullptr;
572 }
573 
574 void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
576  bool DoInsertAtI1, bool OptForSize) {
577  // We are going to delete I2. If MI points to I2 advance it to the next
578  // instruction.
579  if (MI == I2.getIterator())
580  ++MI;
581 
582  // Figure out whether I1 or I2 goes into the lowreg part.
583  unsigned I1DestReg = I1.getOperand(0).getReg();
584  unsigned I2DestReg = I2.getOperand(0).getReg();
585  bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
586  unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
587  unsigned SubLo;
588 
589  const TargetRegisterClass *SuperRC = nullptr;
590  if (Hexagon::IntRegsRegClass.contains(LoRegDef)) {
591  SuperRC = &Hexagon::DoubleRegsRegClass;
592  SubLo = Hexagon::isub_lo;
593  } else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) {
594  assert(ST->useHVXOps());
595  SuperRC = &Hexagon::HvxWRRegClass;
596  SubLo = Hexagon::vsub_lo;
597  } else
598  llvm_unreachable("Unexpected register class");
599 
600  // Get the double word register.
601  unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC);
602  assert(DoubleRegDest != 0 && "Expect a valid register");
603 
604  // Setup source operands.
605  MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);
606  MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);
607 
608  // Figure out which source is a register and which a constant.
609  bool IsHiReg = HiOperand.isReg();
610  bool IsLoReg = LoOperand.isReg();
611 
612  // There is a combine of two constant extended values into CONST64.
613  bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&
614  isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2);
615 
616  MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
617  // Emit combine.
618  if (IsHiReg && IsLoReg)
619  emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
620  else if (IsHiReg)
621  emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
622  else if (IsLoReg)
623  emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
624  else if (IsC64 && !IsConst64Disabled)
625  emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
626  else
627  emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
628 
629  // Move debug instructions along with I1 if it's being
630  // moved towards I2.
631  if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
632  // Insert debug instructions at the new location before I2.
633  MachineBasicBlock *BB = InsertPt->getParent();
634  for (auto NewMI : DbgMItoMove) {
635  // If iterator MI is pointing to DEBUG_VAL, make sure
636  // MI now points to next relevant instruction.
637  if (NewMI == MI)
638  ++MI;
639  BB->splice(InsertPt, BB, NewMI);
640  }
641  }
642 
643  I1.eraseFromParent();
644  I2.eraseFromParent();
645 }
646 
647 void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,
648  unsigned DoubleDestReg,
649  MachineOperand &HiOperand,
650  MachineOperand &LoOperand) {
651  LLVM_DEBUG(dbgs() << "Found a CONST64\n");
652 
653  DebugLoc DL = InsertPt->getDebugLoc();
654  MachineBasicBlock *BB = InsertPt->getParent();
655  assert(LoOperand.isImm() && HiOperand.isImm() &&
656  "Both operands must be immediate");
657 
658  int64_t V = HiOperand.getImm();
659  V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());
660  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg)
661  .addImm(V);
662 }
663 
664 void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
665  unsigned DoubleDestReg,
666  MachineOperand &HiOperand,
667  MachineOperand &LoOperand) {
668  DebugLoc DL = InsertPt->getDebugLoc();
669  MachineBasicBlock *BB = InsertPt->getParent();
670 
671  // Handle globals.
672  if (HiOperand.isGlobal()) {
673  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
674  .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
675  HiOperand.getTargetFlags())
676  .addImm(LoOperand.getImm());
677  return;
678  }
679  if (LoOperand.isGlobal()) {
680  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
681  .addImm(HiOperand.getImm())
682  .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
683  LoOperand.getTargetFlags());
684  return;
685  }
686 
687  // Handle block addresses.
688  if (HiOperand.isBlockAddress()) {
689  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
690  .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
691  HiOperand.getTargetFlags())
692  .addImm(LoOperand.getImm());
693  return;
694  }
695  if (LoOperand.isBlockAddress()) {
696  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
697  .addImm(HiOperand.getImm())
698  .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
699  LoOperand.getTargetFlags());
700  return;
701  }
702 
703  // Handle jump tables.
704  if (HiOperand.isJTI()) {
705  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
706  .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
707  .addImm(LoOperand.getImm());
708  return;
709  }
710  if (LoOperand.isJTI()) {
711  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
712  .addImm(HiOperand.getImm())
713  .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
714  return;
715  }
716 
717  // Handle constant pools.
718  if (HiOperand.isCPI()) {
719  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
720  .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
721  HiOperand.getTargetFlags())
722  .addImm(LoOperand.getImm());
723  return;
724  }
725  if (LoOperand.isCPI()) {
726  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
727  .addImm(HiOperand.getImm())
728  .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
729  LoOperand.getTargetFlags());
730  return;
731  }
732 
733  // First preference should be given to Hexagon::A2_combineii instruction
734  // as it can include U6 (in Hexagon::A4_combineii) as well.
735  // In this instruction, HiOperand is const extended, if required.
736  if (isInt<8>(LoOperand.getImm())) {
737  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
738  .addImm(HiOperand.getImm())
739  .addImm(LoOperand.getImm());
740  return;
741  }
742 
743  // In this instruction, LoOperand is const extended, if required.
744  if (isInt<8>(HiOperand.getImm())) {
745  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
746  .addImm(HiOperand.getImm())
747  .addImm(LoOperand.getImm());
748  return;
749  }
750 
751  // Insert new combine instruction.
752  // DoubleRegDest = combine #HiImm, #LoImm
753  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
754  .addImm(HiOperand.getImm())
755  .addImm(LoOperand.getImm());
756 }
757 
758 void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
759  unsigned DoubleDestReg,
760  MachineOperand &HiOperand,
761  MachineOperand &LoOperand) {
762  unsigned LoReg = LoOperand.getReg();
763  unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
764 
765  DebugLoc DL = InsertPt->getDebugLoc();
766  MachineBasicBlock *BB = InsertPt->getParent();
767 
768  // Handle globals.
769  if (HiOperand.isGlobal()) {
770  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
771  .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
772  HiOperand.getTargetFlags())
773  .addReg(LoReg, LoRegKillFlag);
774  return;
775  }
776  // Handle block addresses.
777  if (HiOperand.isBlockAddress()) {
778  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
779  .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
780  HiOperand.getTargetFlags())
781  .addReg(LoReg, LoRegKillFlag);
782  return;
783  }
784  // Handle jump tables.
785  if (HiOperand.isJTI()) {
786  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
787  .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
788  .addReg(LoReg, LoRegKillFlag);
789  return;
790  }
791  // Handle constant pools.
792  if (HiOperand.isCPI()) {
793  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
794  .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
795  HiOperand.getTargetFlags())
796  .addReg(LoReg, LoRegKillFlag);
797  return;
798  }
799  // Insert new combine instruction.
800  // DoubleRegDest = combine #HiImm, LoReg
801  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
802  .addImm(HiOperand.getImm())
803  .addReg(LoReg, LoRegKillFlag);
804 }
805 
806 void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
807  unsigned DoubleDestReg,
808  MachineOperand &HiOperand,
809  MachineOperand &LoOperand) {
810  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
811  unsigned HiReg = HiOperand.getReg();
812 
813  DebugLoc DL = InsertPt->getDebugLoc();
814  MachineBasicBlock *BB = InsertPt->getParent();
815 
816  // Handle global.
817  if (LoOperand.isGlobal()) {
818  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
819  .addReg(HiReg, HiRegKillFlag)
820  .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
821  LoOperand.getTargetFlags());
822  return;
823  }
824  // Handle block addresses.
825  if (LoOperand.isBlockAddress()) {
826  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
827  .addReg(HiReg, HiRegKillFlag)
828  .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
829  LoOperand.getTargetFlags());
830  return;
831  }
832  // Handle jump tables.
833  if (LoOperand.isJTI()) {
834  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
835  .addReg(HiOperand.getReg(), HiRegKillFlag)
836  .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
837  return;
838  }
839  // Handle constant pools.
840  if (LoOperand.isCPI()) {
841  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
842  .addReg(HiOperand.getReg(), HiRegKillFlag)
843  .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
844  LoOperand.getTargetFlags());
845  return;
846  }
847 
848  // Insert new combine instruction.
849  // DoubleRegDest = combine HiReg, #LoImm
850  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
851  .addReg(HiReg, HiRegKillFlag)
852  .addImm(LoOperand.getImm());
853 }
854 
855 void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
856  unsigned DoubleDestReg,
857  MachineOperand &HiOperand,
858  MachineOperand &LoOperand) {
859  unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
860  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
861  unsigned LoReg = LoOperand.getReg();
862  unsigned HiReg = HiOperand.getReg();
863 
864  DebugLoc DL = InsertPt->getDebugLoc();
865  MachineBasicBlock *BB = InsertPt->getParent();
866 
867  // Insert new combine instruction.
868  // DoubleRegDest = combine HiReg, LoReg
869  unsigned NewOpc;
870  if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) {
871  NewOpc = Hexagon::A2_combinew;
872  } else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) {
873  assert(ST->useHVXOps());
874  NewOpc = Hexagon::V6_vcombine;
875  } else
876  llvm_unreachable("Unexpected register");
877 
878  BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)
879  .addReg(HiReg, HiRegKillFlag)
880  .addReg(LoReg, LoRegKillFlag);
881 }
882 
884  return new HexagonCopyToCombine();
885 }
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...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:24
Implements a dense probed hash-table based set.
Definition: DenseSet.h:250
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
bool isInlineAsm() const
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:303
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:321
unsigned const TargetRegisterInfo * TRI
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...
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
Retuns the total number of operands.
Definition: MachineInstr.h:412
const HexagonRegisterInfo * getRegisterInfo() const override
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
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:423
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.
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.
size_t size() const
Definition: SmallVector.h:53
bool isDebugInstr() const
Definition: MachineInstr.h:999
#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.
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:847
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.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
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.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
MachineFunctionProperties & set(Property P)
const HexagonInstrInfo bool ShouldCombineAggressively
Representation of each machine instruction.
Definition: MachineInstr.h:64
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.
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:92
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static bool isEvenReg(unsigned Reg)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
const HexagonInstrInfo * getInstrInfo() const override
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
#define LLVM_DEBUG(X)
Definition: Debug.h:123
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
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"))