xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
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 
14 #include "HexagonInstrInfo.h"
15 #include "HexagonSubtarget.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/CodeGen/MachineBasicBlock.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstr.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/CodeGen/TargetRegisterInfo.h"
25 #include "llvm/Pass.h"
26 #include "llvm/Support/CodeGen.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/Target/TargetMachine.h"
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "hexagon-copy-combine"
35 
36 static
37 cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
38                                  cl::Hidden, cl::ZeroOrMore,
39                                  cl::init(false),
40                                  cl::desc("Disable merging into combines"));
41 static
42 cl::opt<bool> IsConst64Disabled("disable-const64",
43                                  cl::Hidden, cl::ZeroOrMore,
44                                  cl::init(false),
45                                  cl::desc("Disable generation of const64"));
46 static
47 cl::opt<unsigned>
48 MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",
49                    cl::Hidden, cl::init(4),
50                    cl::desc("Maximum distance between a tfr feeding a store we "
51                             "consider the store still to be newifiable"));
52 
53 namespace llvm {
54   FunctionPass *createHexagonCopyToCombine();
55   void initializeHexagonCopyToCombinePass(PassRegistry&);
56 }
57 
58 
59 namespace {
60 
61 class HexagonCopyToCombine : public MachineFunctionPass  {
62   const HexagonInstrInfo *TII;
63   const TargetRegisterInfo *TRI;
64   const HexagonSubtarget *ST;
65   bool ShouldCombineAggressively;
66 
67   DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
68   SmallVector<MachineInstr *, 8> DbgMItoMove;
69 
70 public:
71   static char ID;
72 
73   HexagonCopyToCombine() : MachineFunctionPass(ID) {}
74 
75   void getAnalysisUsage(AnalysisUsage &AU) const override {
76     MachineFunctionPass::getAnalysisUsage(AU);
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 {
86     return MachineFunctionProperties().set(
87         MachineFunctionProperties::Property::NoVRegs);
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).
183 static bool areCombinableOperations(const TargetRegisterInfo *TRI,
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) && !IsConst64Disabled)
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) {
229   assert(Register::isPhysicalRegister(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 (MachineOperand &Op : MI.operands())
239     if (Op.isReg() && Op.getReg() == RegNotKilled && Op.isKill())
240       Op.setIsKill(false);
241 }
242 
243 /// Returns true if it is unsafe to move a copy instruction from \p UseReg to
244 /// \p DestReg over the instruction \p MI.
245 static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg,
246                                  unsigned DestReg,
247                                  const TargetRegisterInfo *TRI) {
248   return (UseReg && (MI.modifiesRegister(UseReg, TRI))) ||
249          MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) ||
250          MI.hasUnmodeledSideEffects() || MI.isInlineAsm() ||
251          MI.isMetaInstruction();
252 }
253 
254 static Register UseReg(const MachineOperand& MO) {
255   return MO.isReg() ? MO.getReg() : Register();
256 }
257 
258 /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
259 /// that the two instructions can be paired in a combine.
260 bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
261                                                 MachineInstr &I2,
262                                                 unsigned I1DestReg,
263                                                 unsigned I2DestReg,
264                                                 bool &DoInsertAtI1) {
265   Register I2UseReg = UseReg(I2.getOperand(1));
266 
267   // It is not safe to move I1 and I2 into one combine if I2 has a true
268   // dependence on I1.
269   if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI))
270     return false;
271 
272   bool isSafe = true;
273 
274   // First try to move I2 towards I1.
275   {
276     // A reverse_iterator instantiated like below starts before I2, and I1
277     // respectively.
278     // Look at instructions I in between I2 and (excluding) I1.
279     MachineBasicBlock::reverse_iterator I = ++I2.getIterator().getReverse();
280     MachineBasicBlock::reverse_iterator End = I1.getIterator().getReverse();
281     // At 03 we got better results (dhrystone!) by being more conservative.
282     if (!ShouldCombineAggressively)
283       End = ++I1.getIterator().getReverse();
284     // If I2 kills its operand and we move I2 over an instruction that also
285     // uses I2's use reg we need to modify that (first) instruction to now kill
286     // this reg.
287     unsigned KilledOperand = 0;
288     if (I2.killsRegister(I2UseReg))
289       KilledOperand = I2UseReg;
290     MachineInstr *KillingInstr = nullptr;
291 
292     for (; I != End; ++I) {
293       // If the intervening instruction I:
294       //   * modifies I2's use reg
295       //   * modifies I2's def reg
296       //   * reads I2's def reg
297       //   * or has unmodelled side effects
298       // we can't move I2 across it.
299       if (I->isDebugInstr())
300         continue;
301 
302       if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) {
303         isSafe = false;
304         break;
305       }
306 
307       // Update first use of the killed operand.
308       if (!KillingInstr && KilledOperand &&
309           I->readsRegister(KilledOperand, TRI))
310         KillingInstr = &*I;
311     }
312     if (isSafe) {
313       // Update the intermediate instruction to with the kill flag.
314       if (KillingInstr) {
315         bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
316         (void)Added; // suppress compiler warning
317         assert(Added && "Must successfully update kill flag");
318         removeKillInfo(I2, KilledOperand);
319       }
320       DoInsertAtI1 = true;
321       return true;
322     }
323   }
324 
325   // Try to move I1 towards I2.
326   {
327     // Look at instructions I in between I1 and (excluding) I2.
328     MachineBasicBlock::iterator I(I1), End(I2);
329     // At O3 we got better results (dhrystone) by being more conservative here.
330     if (!ShouldCombineAggressively)
331       End = std::next(MachineBasicBlock::iterator(I2));
332     Register I1UseReg = UseReg(I1.getOperand(1));
333     // Track killed operands. If we move across an instruction that kills our
334     // operand, we need to update the kill information on the moved I1. It kills
335     // the operand now.
336     MachineInstr *KillingInstr = nullptr;
337     unsigned KilledOperand = 0;
338 
339     while(++I != End) {
340       MachineInstr &MI = *I;
341       // If the intervening instruction MI:
342       //   * modifies I1's use reg
343       //   * modifies I1's def reg
344       //   * reads I1's def reg
345       //   * or has unmodelled side effects
346       //   We introduce this special case because llvm has no api to remove a
347       //   kill flag for a register (a removeRegisterKilled() analogous to
348       //   addRegisterKilled) that handles aliased register correctly.
349       //   * or has a killed aliased register use of I1's use reg
350       //           %d4 = A2_tfrpi 16
351       //           %r6 = A2_tfr %r9
352       //           %r8 = KILL %r8, implicit killed %d4
353       //      If we want to move R6 = across the KILL instruction we would have
354       //      to remove the implicit killed %d4 operand. For now, we are
355       //      conservative and disallow the move.
356       // we can't move I1 across it.
357       if (MI.isDebugInstr()) {
358         if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2.
359           DbgMItoMove.push_back(&MI);
360         continue;
361       }
362 
363       if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) ||
364           // Check for an aliased register kill. Bail out if we see one.
365           (!MI.killsRegister(I1UseReg) && MI.killsRegister(I1UseReg, TRI)))
366         return false;
367 
368       // Check for an exact kill (registers match).
369       if (I1UseReg && MI.killsRegister(I1UseReg)) {
370         assert(!KillingInstr && "Should only see one killing instruction");
371         KilledOperand = I1UseReg;
372         KillingInstr = &MI;
373       }
374     }
375     if (KillingInstr) {
376       removeKillInfo(*KillingInstr, KilledOperand);
377       // Update I1 to set the kill flag. This flag will later be picked up by
378       // the new COMBINE instruction.
379       bool Added = I1.addRegisterKilled(KilledOperand, TRI);
380       (void)Added; // suppress compiler warning
381       assert(Added && "Must successfully update kill flag");
382     }
383     DoInsertAtI1 = false;
384   }
385 
386   return true;
387 }
388 
389 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
390 /// newified. (A use of a 64 bit register define can not be newified)
391 void
392 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
393   DenseMap<unsigned, MachineInstr *> LastDef;
394   for (MachineInstr &MI : BB) {
395     if (MI.isDebugInstr())
396       continue;
397 
398     // Mark TFRs that feed a potential new value store as such.
399     if (TII->mayBeNewStore(MI)) {
400       // Look for uses of TFR instructions.
401       for (const MachineOperand &Op : MI.operands()) {
402         // Skip over anything except register uses.
403         if (!Op.isReg() || !Op.isUse() || !Op.getReg())
404           continue;
405 
406         // Look for the defining instruction.
407         Register Reg = Op.getReg();
408         MachineInstr *DefInst = LastDef[Reg];
409         if (!DefInst)
410           continue;
411         if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))
412           continue;
413 
414         // Only close newifiable stores should influence the decision.
415         // Ignore the debug instructions in between.
416         MachineBasicBlock::iterator It(DefInst);
417         unsigned NumInstsToDef = 0;
418         while (&*It != &MI) {
419           if (!It->isDebugInstr())
420             ++NumInstsToDef;
421           ++It;
422         }
423 
424         if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
425           continue;
426 
427         PotentiallyNewifiableTFR.insert(DefInst);
428       }
429       // Skip to next instruction.
430       continue;
431     }
432 
433     // Put instructions that last defined integer or double registers into the
434     // map.
435     for (MachineOperand &Op : MI.operands()) {
436       if (Op.isReg()) {
437         if (!Op.isDef() || !Op.getReg())
438           continue;
439         Register Reg = Op.getReg();
440         if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
441           for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
442             LastDef[*SubRegs] = &MI;
443         } else if (Hexagon::IntRegsRegClass.contains(Reg))
444           LastDef[Reg] = &MI;
445       } else if (Op.isRegMask()) {
446         for (unsigned Reg : Hexagon::IntRegsRegClass)
447           if (Op.clobbersPhysReg(Reg))
448             LastDef[Reg] = &MI;
449       }
450     }
451   }
452 }
453 
454 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
455   if (skipFunction(MF.getFunction()))
456     return false;
457 
458   if (IsCombinesDisabled) return false;
459 
460   bool HasChanged = false;
461 
462   // Get target info.
463   ST = &MF.getSubtarget<HexagonSubtarget>();
464   TRI = ST->getRegisterInfo();
465   TII = ST->getInstrInfo();
466 
467   const Function &F = MF.getFunction();
468   bool OptForSize = F.hasFnAttribute(Attribute::OptimizeForSize);
469 
470   // Combine aggressively (for code size)
471   ShouldCombineAggressively =
472     MF.getTarget().getOptLevel() <= CodeGenOpt::Default;
473 
474   // Disable CONST64 for tiny core since it takes a LD resource.
475   if (!OptForSize && ST->isTinyCore())
476     IsConst64Disabled = true;
477 
478   // Traverse basic blocks.
479   for (MachineBasicBlock &MBB : MF) {
480     PotentiallyNewifiableTFR.clear();
481     findPotentialNewifiableTFRs(MBB);
482 
483     // Traverse instructions in basic block.
484     for (MachineBasicBlock::iterator MI = MBB.begin(), End = MBB.end();
485          MI != End;) {
486       MachineInstr &I1 = *MI++;
487 
488       if (I1.isDebugInstr())
489         continue;
490 
491       // Don't combine a TFR whose user could be newified (instructions that
492       // define double registers can not be newified - Programmer's Ref Manual
493       // 5.4.2 New-value stores).
494       if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))
495         continue;
496 
497       // Ignore instructions that are not combinable.
498       if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
499         continue;
500 
501       // Find a second instruction that can be merged into a combine
502       // instruction. In addition, also find all the debug instructions that
503       // need to be moved along with it.
504       bool DoInsertAtI1 = false;
505       DbgMItoMove.clear();
506       MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize);
507       if (I2) {
508         HasChanged = true;
509         combine(I1, *I2, MI, DoInsertAtI1, OptForSize);
510       }
511     }
512   }
513 
514   return HasChanged;
515 }
516 
517 /// findPairable - Returns an instruction that can be merged with \p I1 into a
518 /// COMBINE instruction or 0 if no such instruction can be found. Returns true
519 /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
520 /// false if the combine must be inserted at the returned instruction.
521 MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
522                                                  bool &DoInsertAtI1,
523                                                  bool AllowC64) {
524   MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1));
525   while (I2 != I1.getParent()->end() && I2->isDebugInstr())
526     ++I2;
527 
528   Register I1DestReg = I1.getOperand(0).getReg();
529 
530   for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End;
531        ++I2) {
532     // Bail out early if we see a second definition of I1DestReg.
533     if (I2->modifiesRegister(I1DestReg, TRI))
534       break;
535 
536     // Ignore non-combinable instructions.
537     if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))
538       continue;
539 
540     // Don't combine a TFR whose user could be newified.
541     if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))
542       continue;
543 
544     Register I2DestReg = I2->getOperand(0).getReg();
545 
546     // Check that registers are adjacent and that the first destination register
547     // is even.
548     bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
549     bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
550     unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
551     if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))
552       continue;
553 
554     // Check that the two instructions are combinable.
555     // The order matters because in a A2_tfrsi we might can encode a int8 as
556     // the hi reg operand but only a uint6 as the low reg operand.
557     if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||
558         (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))
559       break;
560 
561     if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))
562       return &*I2;
563 
564     // Not safe. Stop searching.
565     break;
566   }
567   return nullptr;
568 }
569 
570 void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,
571                                    MachineBasicBlock::iterator &MI,
572                                    bool DoInsertAtI1, bool OptForSize) {
573   // We are going to delete I2. If MI points to I2 advance it to the next
574   // instruction.
575   if (MI == I2.getIterator())
576     ++MI;
577 
578   // Figure out whether I1 or I2 goes into the lowreg part.
579   Register I1DestReg = I1.getOperand(0).getReg();
580   Register I2DestReg = I2.getOperand(0).getReg();
581   bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
582   unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
583   unsigned SubLo;
584 
585   const TargetRegisterClass *SuperRC = nullptr;
586   if (Hexagon::IntRegsRegClass.contains(LoRegDef)) {
587     SuperRC = &Hexagon::DoubleRegsRegClass;
588     SubLo = Hexagon::isub_lo;
589   } else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) {
590     assert(ST->useHVXOps());
591     SuperRC = &Hexagon::HvxWRRegClass;
592     SubLo = Hexagon::vsub_lo;
593   } else
594     llvm_unreachable("Unexpected register class");
595 
596   // Get the double word register.
597   unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC);
598   assert(DoubleRegDest != 0 && "Expect a valid register");
599 
600   // Setup source operands.
601   MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);
602   MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);
603 
604   // Figure out which source is a register and which a constant.
605   bool IsHiReg = HiOperand.isReg();
606   bool IsLoReg = LoOperand.isReg();
607 
608   // There is a combine of two constant extended values into CONST64.
609   bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&
610                isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2);
611 
612   MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
613   // Emit combine.
614   if (IsHiReg && IsLoReg)
615     emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
616   else if (IsHiReg)
617     emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
618   else if (IsLoReg)
619     emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
620   else if (IsC64 && !IsConst64Disabled)
621     emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);
622   else
623     emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
624 
625   // Move debug instructions along with I1 if it's being
626   // moved towards I2.
627   if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {
628     // Insert debug instructions at the new location before I2.
629     MachineBasicBlock *BB = InsertPt->getParent();
630     for (auto NewMI : DbgMItoMove) {
631       // If iterator MI is pointing to DEBUG_VAL, make sure
632       // MI now points to next relevant instruction.
633       if (NewMI == MI)
634         ++MI;
635       BB->splice(InsertPt, BB, NewMI);
636     }
637   }
638 
639   I1.eraseFromParent();
640   I2.eraseFromParent();
641 }
642 
643 void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,
644                                        unsigned DoubleDestReg,
645                                        MachineOperand &HiOperand,
646                                        MachineOperand &LoOperand) {
647   LLVM_DEBUG(dbgs() << "Found a CONST64\n");
648 
649   DebugLoc DL = InsertPt->getDebugLoc();
650   MachineBasicBlock *BB = InsertPt->getParent();
651   assert(LoOperand.isImm() && HiOperand.isImm() &&
652          "Both operands must be immediate");
653 
654   int64_t V = HiOperand.getImm();
655   V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());
656   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg)
657     .addImm(V);
658 }
659 
660 void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
661                                          unsigned DoubleDestReg,
662                                          MachineOperand &HiOperand,
663                                          MachineOperand &LoOperand) {
664   DebugLoc DL = InsertPt->getDebugLoc();
665   MachineBasicBlock *BB = InsertPt->getParent();
666 
667   // Handle globals.
668   if (HiOperand.isGlobal()) {
669     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
670       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
671                         HiOperand.getTargetFlags())
672       .addImm(LoOperand.getImm());
673     return;
674   }
675   if (LoOperand.isGlobal()) {
676     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
677       .addImm(HiOperand.getImm())
678       .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
679                         LoOperand.getTargetFlags());
680     return;
681   }
682 
683   // Handle block addresses.
684   if (HiOperand.isBlockAddress()) {
685     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
686       .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
687                        HiOperand.getTargetFlags())
688       .addImm(LoOperand.getImm());
689     return;
690   }
691   if (LoOperand.isBlockAddress()) {
692     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
693       .addImm(HiOperand.getImm())
694       .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
695                        LoOperand.getTargetFlags());
696     return;
697   }
698 
699   // Handle jump tables.
700   if (HiOperand.isJTI()) {
701     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
702       .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
703       .addImm(LoOperand.getImm());
704     return;
705   }
706   if (LoOperand.isJTI()) {
707     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
708       .addImm(HiOperand.getImm())
709       .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
710     return;
711   }
712 
713   // Handle constant pools.
714   if (HiOperand.isCPI()) {
715     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
716       .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
717                             HiOperand.getTargetFlags())
718       .addImm(LoOperand.getImm());
719     return;
720   }
721   if (LoOperand.isCPI()) {
722     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
723       .addImm(HiOperand.getImm())
724       .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
725                             LoOperand.getTargetFlags());
726     return;
727   }
728 
729   // First preference should be given to Hexagon::A2_combineii instruction
730   // as it can include U6 (in Hexagon::A4_combineii) as well.
731   // In this instruction, HiOperand is const extended, if required.
732   if (isInt<8>(LoOperand.getImm())) {
733     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
734       .addImm(HiOperand.getImm())
735       .addImm(LoOperand.getImm());
736       return;
737   }
738 
739   // In this instruction, LoOperand is const extended, if required.
740   if (isInt<8>(HiOperand.getImm())) {
741     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
742       .addImm(HiOperand.getImm())
743       .addImm(LoOperand.getImm());
744     return;
745   }
746 
747   // Insert new combine instruction.
748   //  DoubleRegDest = combine #HiImm, #LoImm
749   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
750     .addImm(HiOperand.getImm())
751     .addImm(LoOperand.getImm());
752 }
753 
754 void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
755                                          unsigned DoubleDestReg,
756                                          MachineOperand &HiOperand,
757                                          MachineOperand &LoOperand) {
758   Register LoReg = LoOperand.getReg();
759   unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
760 
761   DebugLoc DL = InsertPt->getDebugLoc();
762   MachineBasicBlock *BB = InsertPt->getParent();
763 
764   // Handle globals.
765   if (HiOperand.isGlobal()) {
766     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
767       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
768                         HiOperand.getTargetFlags())
769       .addReg(LoReg, LoRegKillFlag);
770     return;
771   }
772   // Handle block addresses.
773   if (HiOperand.isBlockAddress()) {
774     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
775       .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
776                        HiOperand.getTargetFlags())
777       .addReg(LoReg, LoRegKillFlag);
778     return;
779   }
780   // Handle jump tables.
781   if (HiOperand.isJTI()) {
782     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
783       .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
784       .addReg(LoReg, LoRegKillFlag);
785     return;
786   }
787   // Handle constant pools.
788   if (HiOperand.isCPI()) {
789     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
790       .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
791                             HiOperand.getTargetFlags())
792       .addReg(LoReg, LoRegKillFlag);
793     return;
794   }
795   // Insert new combine instruction.
796   //  DoubleRegDest = combine #HiImm, LoReg
797   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
798     .addImm(HiOperand.getImm())
799     .addReg(LoReg, LoRegKillFlag);
800 }
801 
802 void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
803                                          unsigned DoubleDestReg,
804                                          MachineOperand &HiOperand,
805                                          MachineOperand &LoOperand) {
806   unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
807   Register HiReg = HiOperand.getReg();
808 
809   DebugLoc DL = InsertPt->getDebugLoc();
810   MachineBasicBlock *BB = InsertPt->getParent();
811 
812   // Handle global.
813   if (LoOperand.isGlobal()) {
814     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
815       .addReg(HiReg, HiRegKillFlag)
816       .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
817                         LoOperand.getTargetFlags());
818     return;
819   }
820   // Handle block addresses.
821   if (LoOperand.isBlockAddress()) {
822     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
823       .addReg(HiReg, HiRegKillFlag)
824       .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
825                        LoOperand.getTargetFlags());
826     return;
827   }
828   // Handle jump tables.
829   if (LoOperand.isJTI()) {
830     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
831       .addReg(HiOperand.getReg(), HiRegKillFlag)
832       .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
833     return;
834   }
835   // Handle constant pools.
836   if (LoOperand.isCPI()) {
837     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
838       .addReg(HiOperand.getReg(), HiRegKillFlag)
839       .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
840                             LoOperand.getTargetFlags());
841     return;
842   }
843 
844   // Insert new combine instruction.
845   //  DoubleRegDest = combine HiReg, #LoImm
846   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
847     .addReg(HiReg, HiRegKillFlag)
848     .addImm(LoOperand.getImm());
849 }
850 
851 void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
852                                          unsigned DoubleDestReg,
853                                          MachineOperand &HiOperand,
854                                          MachineOperand &LoOperand) {
855   unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
856   unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
857   Register LoReg = LoOperand.getReg();
858   Register HiReg = HiOperand.getReg();
859 
860   DebugLoc DL = InsertPt->getDebugLoc();
861   MachineBasicBlock *BB = InsertPt->getParent();
862 
863   // Insert new combine instruction.
864   //  DoubleRegDest = combine HiReg, LoReg
865   unsigned NewOpc;
866   if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) {
867     NewOpc = Hexagon::A2_combinew;
868   } else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) {
869     assert(ST->useHVXOps());
870     NewOpc = Hexagon::V6_vcombine;
871   } else
872     llvm_unreachable("Unexpected register");
873 
874   BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)
875     .addReg(HiReg, HiRegKillFlag)
876     .addReg(LoReg, LoRegKillFlag);
877 }
878 
879 FunctionPass *llvm::createHexagonCopyToCombine() {
880   return new HexagonCopyToCombine();
881 }
882