LLVM  10.0.0svn
HexagonCopyToCombine.cpp
Go to the documentation of this file.
1 //===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This pass replaces transfer instructions by combine instructions.
9 // We walk along a basic block and look for two combinable instructions and try
10 // to move them together. If we can move them next to each other we do so and
11 // replace them with a combine instruction.
12 //===----------------------------------------------------------------------===//
13 #include "HexagonInstrInfo.h"
14 #include "HexagonSubtarget.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/DenseSet.h"
22 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/PassSupport.h"
25 #include "llvm/Support/CodeGen.h"
27 #include "llvm/Support/Debug.h"
29 
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "hexagon-copy-combine"
33 
34 static
35 cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
37  cl::init(false),
38  cl::desc("Disable merging into combines"));
39 static
40 cl::opt<bool> IsConst64Disabled("disable-const64",
42  cl::init(false),
43  cl::desc("Disable generation of const64"));
44 static
46 MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
47  cl::Hidden, cl::init(4),
48  cl::desc("Maximum distance between a tfr feeding a store we "
49  "consider the store still to be newifiable"));
50 
51 namespace llvm {
54 }
55 
56 
57 namespace {
58 
59 class HexagonCopyToCombine : public MachineFunctionPass {
60  const HexagonInstrInfo *TII;
61  const TargetRegisterInfo *TRI;
62  const HexagonSubtarget *ST;
64 
65  DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
67 
68 public:
69  static char ID;
70 
71  HexagonCopyToCombine() : MachineFunctionPass(ID) {
73  }
74 
75  void getAnalysisUsage(AnalysisUsage &AU) const override {
77  }
78 
79  StringRef getPassName() const override {
80  return "Hexagon Copy-To-Combine Pass";
81  }
82 
83  bool runOnMachineFunction(MachineFunction &Fn) override;
84 
85  MachineFunctionProperties getRequiredProperties() const override {
88  }
89 
90 private:
91  MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1,
92  bool AllowC64);
93 
94  void findPotentialNewifiableTFRs(MachineBasicBlock &);
95 
96  void combine(MachineInstr &I1, MachineInstr &I2,
97  MachineBasicBlock::iterator &MI, bool DoInsertAtI1,
98  bool OptForSize);
99 
100  bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2,
101  unsigned I1DestReg, unsigned I2DestReg,
102  bool &DoInsertAtI1);
103 
104  void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
105  MachineOperand &HiOperand, MachineOperand &LoOperand);
106 
107  void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
108  MachineOperand &HiOperand, MachineOperand &LoOperand);
109 
110  void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
111  MachineOperand &HiOperand, MachineOperand &LoOperand);
112 
113  void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
114  MachineOperand &HiOperand, MachineOperand &LoOperand);
115 
116  void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg,
117  MachineOperand &HiOperand, MachineOperand &LoOperand);
118 };
119 
120 } // End anonymous namespace.
121 
122 char HexagonCopyToCombine::ID = 0;
123 
124 INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
125  "Hexagon Copy-To-Combine Pass", false, false)
126 
127 static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII,
128  bool ShouldCombineAggressively) {
129  switch (MI.getOpcode()) {
130  case Hexagon::A2_tfr: {
131  // A COPY instruction can be combined if its arguments are IntRegs (32bit).
132  const MachineOperand &Op0 = MI.getOperand(0);
133  const MachineOperand &Op1 = MI.getOperand(1);
134  assert(Op0.isReg() && Op1.isReg());
135 
136  Register DestReg = Op0.getReg();
137  Register SrcReg = Op1.getReg();
138  return Hexagon::IntRegsRegClass.contains(DestReg) &&
139  Hexagon::IntRegsRegClass.contains(SrcReg);
140  }
141 
142  case Hexagon::A2_tfrsi: {
143  // A transfer-immediate can be combined if its argument is a signed 8bit
144  // value.
145  const MachineOperand &Op0 = MI.getOperand(0);
146  const MachineOperand &Op1 = MI.getOperand(1);
147  assert(Op0.isReg());
148 
149  Register DestReg = Op0.getReg();
150  // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
151  // workaround for an ABI bug that prevents GOT relocations on combine
152  // instructions
153  if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG)
154  return false;
155 
156  // Only combine constant extended A2_tfrsi if we are in aggressive mode.
157  bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm());
158  return Hexagon::IntRegsRegClass.contains(DestReg) &&
159  (ShouldCombineAggressively || NotExt);
160  }
161 
162  case Hexagon::V6_vassign:
163  return true;
164 
165  default:
166  break;
167  }
168 
169  return false;
170 }
171 
172 template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) {
173  if (I.getOpcode() == Hexagon::TFRI64_V4 ||
174  I.getOpcode() == Hexagon::A2_tfrsi) {
175  const MachineOperand &Op = I.getOperand(1);
176  return !Op.isImm() || !isInt<N>(Op.getImm());
177  }
178  return false;
179 }
180 
181 /// areCombinableOperations - Returns true if the two instruction can be merge
182 /// into a combine (ignoring register constraints).
184  MachineInstr &HighRegInst,
185  MachineInstr &LowRegInst, bool AllowC64) {
186  unsigned HiOpc = HighRegInst.getOpcode();
187  unsigned LoOpc = LowRegInst.getOpcode();
188 
189  auto verifyOpc = [](unsigned Opc) -> void {
190  switch (Opc) {
191  case Hexagon::A2_tfr:
192  case Hexagon::A2_tfrsi:
193  case Hexagon::V6_vassign:
194  break;
195  default:
196  llvm_unreachable("Unexpected opcode");
197  }
198  };
199  verifyOpc(HiOpc);
200  verifyOpc(LoOpc);
201 
202  if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign)
203  return HiOpc == LoOpc;
204 
205  if (!AllowC64) {
206  // There is no combine of two constant extended values.
207  if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
208  isGreaterThanNBitTFRI<6>(LowRegInst))
209  return false;
210  }
211 
212  // There is a combine of two constant extended values into CONST64,
213  // provided both constants are true immediates.
214  if (isGreaterThanNBitTFRI<16>(HighRegInst) &&
215  isGreaterThanNBitTFRI<16>(LowRegInst))
216  return (HighRegInst.getOperand(1).isImm() &&
217  LowRegInst.getOperand(1).isImm());
218 
219  // There is no combine of two constant extended values, unless handled above
220  // Make both 8-bit size checks to allow both combine (#,##) and combine(##,#)
221  if (isGreaterThanNBitTFRI<8>(HighRegInst) &&
222  isGreaterThanNBitTFRI<8>(LowRegInst))
223  return false;
224 
225  return true;
226 }
227 
228 static bool isEvenReg(unsigned Reg) {
230  if (Hexagon::IntRegsRegClass.contains(Reg))
231  return (Reg - Hexagon::R0) % 2 == 0;
232  if (Hexagon::HvxVRRegClass.contains(Reg))
233  return (Reg - Hexagon::V0) % 2 == 0;
234  llvm_unreachable("Invalid register");
235 }
236 
237 static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled) {
238  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
239  MachineOperand &Op = MI.getOperand(I);
240  if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill())
241  continue;
242  Op.setIsKill(false);
243  }
244 }
245 
246 /// Returns true if it is unsafe to move a copy instruction from \p UseReg to
247 /// \p DestReg over the instruction \p MI.
249  unsigned DestReg,
250  const TargetRegisterInfo *TRI) {
251  return (UseReg && (MI.modifiesRegister(UseReg, TRI))) ||
252  MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) ||
253  MI.hasUnmodeledSideEffects() || MI.isInlineAsm() ||
254  MI.isMetaInstruction();
255 }
256 
257 static Register UseReg(const MachineOperand& MO) {
258  return MO.isReg() ? MO.getReg() : Register();
259 }
260 
261 /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
262 /// that the two instructions can be paired in a combine.
263 bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
264  MachineInstr &I2,
265  unsigned I1DestReg,
266  unsigned I2DestReg,
267  bool &DoInsertAtI1) {
268  Register I2UseReg = UseReg(I2.getOperand(1));
269 
270  // It is not safe to move I1 and I2 into one combine if I2 has a true
271  // dependence on I1.
272  if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI))
273  return false;
274 
275  bool isSafe = true;
276 
277  // First try to move I2 towards I1.
278  {
279  // A reverse_iterator instantiated like below starts before I2, and I1
280  // respectively.
281  // Look at instructions I in between I2 and (excluding) I1.
284  // At 03 we got better results (dhrystone!) by being more conservative.
285  if (!ShouldCombineAggressively)
287  // If I2 kills its operand and we move I2 over an instruction that also
288  // uses I2's use reg we need to modify that (first) instruction to now kill
289  // this reg.
290  unsigned KilledOperand = 0;
291  if (I2.killsRegister(I2UseReg))
292  KilledOperand = I2UseReg;
293  MachineInstr *KillingInstr = nullptr;
294 
295  for (; I != End; ++I) {
296  // If the intervening instruction I:
297  // * modifies I2's use reg
298  // * modifies I2's def reg
299  // * reads I2's def reg
300  // * or has unmodelled side effects
301  // we can't move I2 across it.
302  if (I->isDebugInstr())
303  continue;
304 
305  if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) {
306  isSafe = false;
307  break;
308  }
309 
310  // Update first use of the killed operand.
311  if (!KillingInstr && KilledOperand &&
312  I->readsRegister(KilledOperand, TRI))
313  KillingInstr = &*I;
314  }
315  if (isSafe) {
316  // Update the intermediate instruction to with the kill flag.
317  if (KillingInstr) {
318  bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
319  (void)Added; // suppress compiler warning
320  assert(Added && "Must successfully update kill flag");
321  removeKillInfo(I2, KilledOperand);
322  }
323  DoInsertAtI1 = true;
324  return true;
325  }
326  }
327 
328  // Try to move I1 towards I2.
329  {
330  // Look at instructions I in between I1 and (excluding) I2.
331  MachineBasicBlock::iterator I(I1), End(I2);
332  // At O3 we got better results (dhrystone) by being more conservative here.
333  if (!ShouldCombineAggressively)
334  End = std::next(MachineBasicBlock::iterator(I2));
335  Register I1UseReg = UseReg(I1.getOperand(1));
336  // Track killed operands. If we move across an instruction that kills our
337  // operand, we need to update the kill information on the moved I1. It kills
338  // the operand now.
339  MachineInstr *KillingInstr = nullptr;
340  unsigned KilledOperand = 0;
341 
342  while(++I != End) {
343  MachineInstr &MI = *I;
344  // If the intervening instruction MI:
345  // * modifies I1's use reg
346  // * modifies I1's def reg
347  // * reads I1's def reg
348  // * or has unmodelled side effects
349  // We introduce this special case because llvm has no api to remove a
350  // kill flag for a register (a removeRegisterKilled() analogous to
351  // addRegisterKilled) that handles aliased register correctly.
352  // * or has a killed aliased register use of I1's use reg
353  // %d4 = A2_tfrpi 16
354  // %r6 = A2_tfr %r9
355  // %r8 = KILL %r8, implicit killed %d4
356  // If we want to move R6 = across the KILL instruction we would have
357  // to remove the implicit killed %d4 operand. For now, we are
358  // conservative and disallow the move.
359  // we can't move I1 across it.
360  if (MI.isDebugInstr()) {
361  if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2.
362  DbgMItoMove.push_back(&MI);
363  continue;
364  }
365 
366  if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) ||
367  // Check for an aliased register kill. Bail out if we see one.
368  (!MI.killsRegister(I1UseReg) && MI.killsRegister(I1UseReg, TRI)))
369  return false;
370 
371  // Check for an exact kill (registers match).
372  if (I1UseReg && MI.killsRegister(I1UseReg)) {
373  assert(!KillingInstr && "Should only see one killing instruction");
374  KilledOperand = I1UseReg;
375  KillingInstr = &MI;
376  }
377  }
378  if (KillingInstr) {
379  removeKillInfo(*KillingInstr, KilledOperand);
380  // Update I1 to set the kill flag. This flag will later be picked up by
381  // the new COMBINE instruction.
382  bool Added = I1.addRegisterKilled(KilledOperand, TRI);
383  (void)Added; // suppress compiler warning
384  assert(Added && "Must successfully update kill flag");
385  }
386  DoInsertAtI1 = false;
387  }
388 
389  return true;
390 }
391 
392 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
393 /// newified. (A use of a 64 bit register define can not be newified)
394 void
395 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
397  for (MachineInstr &MI : BB) {
398  if (MI.isDebugInstr())
399  continue;
400 
401  // Mark TFRs that feed a potential new value store as such.
402  if (TII->mayBeNewStore(MI)) {
403  // Look for uses of TFR instructions.
404  for (unsigned OpdIdx = 0, OpdE = MI.getNumOperands(); OpdIdx != OpdE;
405  ++OpdIdx) {
406  MachineOperand &Op = MI.getOperand(OpdIdx);
407 
408  // Skip over anything except register uses.
409  if (!Op.isReg() || !Op.isUse() || !Op.getReg())
410  continue;
411 
412  // Look for the defining instruction.
413  Register Reg = Op.getReg();
414  MachineInstr *DefInst = LastDef[Reg];
415  if (!DefInst)
416  continue;
417  if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))
418  continue;
419 
420  // Only close newifiable stores should influence the decision.
421  // Ignore the debug instructions in between.
422  MachineBasicBlock::iterator It(DefInst);
423  unsigned NumInstsToDef = 0;
424  while (&*It != &MI) {
425  if (!It->isDebugInstr())
426  ++NumInstsToDef;
427  ++It;
428  }
429 
430  if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
431  continue;
432 
433  PotentiallyNewifiableTFR.insert(DefInst);
434  }
435  // Skip to next instruction.
436  continue;
437  }
438 
439  // Put instructions that last defined integer or double registers into the
440  // map.
441  for (MachineOperand &Op : MI.operands()) {
442  if (Op.isReg()) {
443  if (!Op.isDef() || !Op.getReg())
444  continue;
445  Register Reg = Op.getReg();
446  if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
447  for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
448  LastDef[*SubRegs] = &MI;
449  } else if (Hexagon::IntRegsRegClass.contains(Reg))
450  LastDef[Reg] = &MI;
451  } else if (Op.isRegMask()) {
452  for (unsigned Reg : Hexagon::IntRegsRegClass)
453  if (Op.clobbersPhysReg(Reg))
454  LastDef[Reg] = &MI;
455  }
456  }
457  }
458 }
459 
460 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
461  if (skipFunction(MF.getFunction()))
462  return false;
463 
464  if (IsCombinesDisabled) return false;
465 
466  bool HasChanged = false;
467 
468  // Get target info.
469  ST = &MF.getSubtarget<HexagonSubtarget>();
470  TRI = ST->getRegisterInfo();
471  TII = ST->getInstrInfo();
472 
473  const Function &F = MF.getFunction();
474  bool OptForSize = F.hasFnAttribute(Attribute::OptimizeForSize);
475 
476  // Combine aggressively (for code size)
477  ShouldCombineAggressively =
479 
480  // Traverse basic blocks.
481  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE;
482  ++BI) {
483  PotentiallyNewifiableTFR.clear();
484  findPotentialNewifiableTFRs(*BI);
485 
486  // Traverse instructions in basic block.
487  for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end();
488  MI != End;) {
489  MachineInstr &I1 = *MI++;
490 
491  if (I1.isDebugInstr())
492  continue;
493 
494  // Don't combine a TFR whose user could be newified (instructions that
495  // define double registers can not be newified - Programmer's Ref Manual
496  // 5.4.2 New-value stores).
497  if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))
498  continue;
499 
500  // Ignore instructions that are not combinable.
501  if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
502  continue;
503 
504  // Find a second instruction that can be merged into a combine
505  // instruction. In addition, also find all the debug instructions that
506  // need to be moved along with it.
507  bool DoInsertAtI1 = false;
508  DbgMItoMove.clear();
509  MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize);
510  if (I2) {
511  HasChanged = true;
512  combine(I1, *I2, MI, DoInsertAtI1, OptForSize);
513  }
514  }
515  }
516 
517  return HasChanged;
518 }
519 
520 /// findPairable - Returns an instruction that can be merged with \p I1 into a
521 /// COMBINE instruction or 0 if no such instruction can be found. Returns true
522 /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
523 /// false if the combine must be inserted at the returned instruction.
524 MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
525  bool &DoInsertAtI1,
526  bool AllowC64) {
528  while (I2 != I1.getParent()->end() && I2->isDebugInstr())
529  ++I2;
530 
531  Register I1DestReg = I1.getOperand(0).getReg();
532 
533  for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End;
534  ++I2) {
535  // Bail out early if we see a second definition of I1DestReg.
536  if (I2->modifiesRegister(I1DestReg, TRI))
537  break;
538 
539  // Ignore non-combinable instructions.
540  if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))
541  continue;
542 
543  // Don't combine a TFR whose user could be newified.
544  if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))
545  continue;
546 
547  Register I2DestReg = I2->getOperand(0).getReg();
548 
549  // Check that registers are adjacent and that the first destination register
550  // is even.
551  bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
552  bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
553  unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
554  if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))
555  continue;
556 
557  // Check that the two instructions are combinable.
558  // The order matters because in a A2_tfrsi we might can encode a int8 as
559  // the hi reg operand but only a uint6 as the low reg operand.
560  if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||
561  (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))
562  break;
563 
564  if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
565  return &*I2;
566 
567  // Not safe. Stop searching.
568  break;
569  }
570  return nullptr;
571 }
572 
573 void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
575  bool DoInsertAtI1, bool OptForSize) {
576  // We are going to delete I2. If MI points to I2 advance it to the next
577  // instruction.
578  if (MI == I2.getIterator())
579  ++MI;
580 
581  // Figure out whether I1 or I2 goes into the lowreg part.
582  Register I1DestReg = I1.getOperand(0).getReg();
583  Register I2DestReg = I2.getOperand(0).getReg();
584  bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
585  unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
586  unsigned SubLo;
587 
588  const TargetRegisterClass *SuperRC = nullptr;
589  if (Hexagon::IntRegsRegClass.contains(LoRegDef)) {
590  SuperRC = &Hexagon::DoubleRegsRegClass;
591  SubLo = Hexagon::isub_lo;
592  } else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) {
593  assert(ST->useHVXOps());
594  SuperRC = &Hexagon::HvxWRRegClass;
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  LLVM_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  Register 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  Register 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  Register LoReg = LoOperand.getReg();
861  Register 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::HvxWRRegClass.contains(DoubleDestReg)) {
872  assert(ST->useHVXOps());
873  NewOpc = Hexagon::V6_vcombine;
874  } else
875  llvm_unreachable("Unexpected register");
876 
877  BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)
878  .addReg(HiReg, HiRegKillFlag)
879  .addReg(LoReg, LoRegKillFlag);
880 }
881 
883  return new HexagonCopyToCombine();
884 }
unsigned getTargetFlags() const
FunctionPass * createHexagonCopyToCombine()
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:23
Implements a dense probed hash-table based set.
Definition: DenseSet.h:249
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:63
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:339
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:323
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
F(f)
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
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:413
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:410
void initializeHexagonCopyToCombinePass(PassRegistry &)
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
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:432
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr kills the specified register.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Register UseReg(const MachineOperand &MO)
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:284
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.
size_t size() const
Definition: SmallVector.h:52
bool isDebugInstr() const
#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
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
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:837
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
Promote Memory to Register
Definition: Mem2Reg.cpp:109
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:132
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:255
MachineFunctionProperties & set(Property P)
const HexagonInstrInfo bool ShouldCombineAggressively
Representation of each machine instruction.
Definition: MachineInstr.h:63
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...
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
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
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 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:48
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
const MachineInstrBuilder & addBlockAddress(const BlockAddress *BA, int64_t Offset=0, unsigned TargetFlags=0) const
static cl::opt< bool > IsConst64Disabled("disable-const64", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable generation of const64"))