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 "llvm/PassSupport.h"
15 #include "Hexagon.h"
16 #include "HexagonInstrInfo.h"
17 #include "HexagonMachineFunctionInfo.h"
18 #include "HexagonRegisterInfo.h"
19 #include "HexagonSubtarget.h"
20 #include "HexagonTargetMachine.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/CodeGen/MachineBasicBlock.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/MachineInstr.h"
27 #include "llvm/CodeGen/MachineInstrBuilder.h"
28 #include "llvm/CodeGen/Passes.h"
29 #include "llvm/Support/CodeGen.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Target/TargetRegisterInfo.h"
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "hexagon-copy-combine"
38 
39 static
40 cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
41                                  cl::Hidden, cl::ZeroOrMore,
42                                  cl::init(false),
43                                  cl::desc("Disable merging into combines"));
44 static
45 cl::opt<unsigned>
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 {
52   void initializeHexagonCopyToCombinePass(PassRegistry&);
53 }
54 
55 
56 namespace {
57 
58 class HexagonCopyToCombine : public MachineFunctionPass  {
59   const HexagonInstrInfo *TII;
60   const TargetRegisterInfo *TRI;
61   bool ShouldCombineAggressively;
62 
63   DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
64 public:
65   static char ID;
66 
HexagonCopyToCombine()67   HexagonCopyToCombine() : MachineFunctionPass(ID) {
68     initializeHexagonCopyToCombinePass(*PassRegistry::getPassRegistry());
69   }
70 
getAnalysisUsage(AnalysisUsage & AU) const71   void getAnalysisUsage(AnalysisUsage &AU) const override {
72     MachineFunctionPass::getAnalysisUsage(AU);
73   }
74 
getPassName() const75   const char *getPassName() const override {
76     return "Hexagon Copy-To-Combine Pass";
77   }
78 
79   bool runOnMachineFunction(MachineFunction &Fn) override;
80 
81 private:
82   MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1);
83 
84   void findPotentialNewifiableTFRs(MachineBasicBlock &);
85 
86   void combine(MachineInstr *I1, MachineInstr *I2,
87                MachineBasicBlock::iterator &MI, bool DoInsertAtI1);
88 
89   bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2,
90                             unsigned I1DestReg, unsigned I2DestReg,
91                             bool &DoInsertAtI1);
92 
93   void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
94                      MachineOperand &HiOperand, MachineOperand &LoOperand);
95 
96   void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
97                      MachineOperand &HiOperand, MachineOperand &LoOperand);
98 
99   void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
100                      MachineOperand &HiOperand, MachineOperand &LoOperand);
101 
102   void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
103                      MachineOperand &HiOperand, MachineOperand &LoOperand);
104 };
105 
106 } // End anonymous namespace.
107 
108 char HexagonCopyToCombine::ID = 0;
109 
110 INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",
111                 "Hexagon Copy-To-Combine Pass", false, false)
112 
isCombinableInstType(MachineInstr * MI,const HexagonInstrInfo * TII,bool ShouldCombineAggressively)113 static bool isCombinableInstType(MachineInstr *MI,
114                                  const HexagonInstrInfo *TII,
115                                  bool ShouldCombineAggressively) {
116   switch(MI->getOpcode()) {
117   case Hexagon::A2_tfr: {
118     // A COPY instruction can be combined if its arguments are IntRegs (32bit).
119     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg());
120 
121     unsigned DestReg = MI->getOperand(0).getReg();
122     unsigned SrcReg = MI->getOperand(1).getReg();
123     return Hexagon::IntRegsRegClass.contains(DestReg) &&
124       Hexagon::IntRegsRegClass.contains(SrcReg);
125   }
126 
127   case Hexagon::A2_tfrsi: {
128     // A transfer-immediate can be combined if its argument is a signed 8bit
129     // value.
130     const MachineOperand &Op0 = MI->getOperand(0);
131     const MachineOperand &Op1 = MI->getOperand(1);
132     assert(Op0.isReg());
133 
134     unsigned DestReg = Op0.getReg();
135     // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
136     // workaround for an ABI bug that prevents GOT relocations on combine
137     // instructions
138     if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG)
139       return false;
140 
141     // Only combine constant extended A2_tfrsi if we are in aggressive mode.
142     bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm());
143     return Hexagon::IntRegsRegClass.contains(DestReg) &&
144            (ShouldCombineAggressively || NotExt);
145   }
146 
147   case Hexagon::TFRI_V4: {
148     if (!ShouldCombineAggressively)
149       return false;
150     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal());
151 
152     // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a
153     // workaround for an ABI bug that prevents GOT relocations on combine
154     // instructions
155     if (MI->getOperand(1).getTargetFlags() != HexagonII::MO_NO_FLAG)
156       return false;
157 
158     unsigned DestReg = MI->getOperand(0).getReg();
159     return Hexagon::IntRegsRegClass.contains(DestReg);
160   }
161 
162   default:
163     break;
164   }
165 
166   return false;
167 }
168 
isGreaterThan8BitTFRI(MachineInstr * I)169 static bool isGreaterThan8BitTFRI(MachineInstr *I) {
170   return I->getOpcode() == Hexagon::A2_tfrsi &&
171     !isInt<8>(I->getOperand(1).getImm());
172 }
isGreaterThan6BitTFRI(MachineInstr * I)173 static bool isGreaterThan6BitTFRI(MachineInstr *I) {
174   return I->getOpcode() == Hexagon::A2_tfrsi &&
175     !isUInt<6>(I->getOperand(1).getImm());
176 }
177 
178 /// areCombinableOperations - Returns true if the two instruction can be merge
179 /// into a combine (ignoring register constraints).
areCombinableOperations(const TargetRegisterInfo * TRI,MachineInstr * HighRegInst,MachineInstr * LowRegInst)180 static bool areCombinableOperations(const TargetRegisterInfo *TRI,
181                                     MachineInstr *HighRegInst,
182                                     MachineInstr *LowRegInst) {
183   assert((HighRegInst->getOpcode() == Hexagon::A2_tfr ||
184           HighRegInst->getOpcode() == Hexagon::A2_tfrsi ||
185           HighRegInst->getOpcode() == Hexagon::TFRI_V4) &&
186          (LowRegInst->getOpcode() == Hexagon::A2_tfr ||
187           LowRegInst->getOpcode() == Hexagon::A2_tfrsi ||
188           LowRegInst->getOpcode() == Hexagon::TFRI_V4) &&
189          "Assume individual instructions are of a combinable type");
190 
191   // There is no combine of two constant extended values.
192   if ((HighRegInst->getOpcode() == Hexagon::TFRI_V4 ||
193        isGreaterThan8BitTFRI(HighRegInst)) &&
194       (LowRegInst->getOpcode() == Hexagon::TFRI_V4 ||
195        isGreaterThan6BitTFRI(LowRegInst)))
196     return false;
197 
198   return true;
199 }
200 
isEvenReg(unsigned Reg)201 static bool isEvenReg(unsigned Reg) {
202   assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
203          Hexagon::IntRegsRegClass.contains(Reg));
204   return (Reg - Hexagon::R0) % 2 == 0;
205 }
206 
removeKillInfo(MachineInstr * MI,unsigned RegNotKilled)207 static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) {
208   for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
209     MachineOperand &Op = MI->getOperand(I);
210     if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill())
211       continue;
212     Op.setIsKill(false);
213   }
214 }
215 
216 /// isUnsafeToMoveAcross - Returns true if it is unsafe to move a copy
217 /// instruction from \p UseReg to \p DestReg over the instruction \p I.
isUnsafeToMoveAcross(MachineInstr * I,unsigned UseReg,unsigned DestReg,const TargetRegisterInfo * TRI)218 static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg,
219                                   unsigned DestReg,
220                                   const TargetRegisterInfo *TRI) {
221   return (UseReg && (I->modifiesRegister(UseReg, TRI))) ||
222           I->modifiesRegister(DestReg, TRI) ||
223           I->readsRegister(DestReg, TRI) ||
224           I->hasUnmodeledSideEffects() ||
225           I->isInlineAsm() || I->isDebugValue();
226 }
227 
228 /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
229 /// that the two instructions can be paired in a combine.
isSafeToMoveTogether(MachineInstr * I1,MachineInstr * I2,unsigned I1DestReg,unsigned I2DestReg,bool & DoInsertAtI1)230 bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
231                                                 MachineInstr *I2,
232                                                 unsigned I1DestReg,
233                                                 unsigned I2DestReg,
234                                                 bool &DoInsertAtI1) {
235 
236   bool IsImmUseReg = I2->getOperand(1).isImm() || I2->getOperand(1).isGlobal();
237   unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg();
238 
239   // It is not safe to move I1 and I2 into one combine if I2 has a true
240   // dependence on I1.
241   if (I2UseReg && I1->modifiesRegister(I2UseReg, TRI))
242     return false;
243 
244   bool isSafe = true;
245 
246   // First try to move I2 towards I1.
247   {
248     // A reverse_iterator instantiated like below starts before I2, and I1
249     // respectively.
250     // Look at instructions I in between I2 and (excluding) I1.
251     MachineBasicBlock::reverse_iterator I(I2),
252       End = --(MachineBasicBlock::reverse_iterator(I1));
253     // At 03 we got better results (dhrystone!) by being more conservative.
254     if (!ShouldCombineAggressively)
255       End = MachineBasicBlock::reverse_iterator(I1);
256     // If I2 kills its operand and we move I2 over an instruction that also
257     // uses I2's use reg we need to modify that (first) instruction to now kill
258     // this reg.
259     unsigned KilledOperand = 0;
260     if (I2->killsRegister(I2UseReg))
261       KilledOperand = I2UseReg;
262     MachineInstr *KillingInstr = nullptr;
263 
264     for (; I != End; ++I) {
265       // If the intervening instruction I:
266       //   * modifies I2's use reg
267       //   * modifies I2's def reg
268       //   * reads I2's def reg
269       //   * or has unmodelled side effects
270       // we can't move I2 across it.
271       if (isUnsafeToMoveAcross(&*I, I2UseReg, I2DestReg, TRI)) {
272         isSafe = false;
273         break;
274       }
275 
276       // Update first use of the killed operand.
277       if (!KillingInstr && KilledOperand &&
278           I->readsRegister(KilledOperand, TRI))
279         KillingInstr = &*I;
280     }
281     if (isSafe) {
282       // Update the intermediate instruction to with the kill flag.
283       if (KillingInstr) {
284         bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
285         (void)Added; // suppress compiler warning
286         assert(Added && "Must successfully update kill flag");
287         removeKillInfo(I2, KilledOperand);
288       }
289       DoInsertAtI1 = true;
290       return true;
291     }
292   }
293 
294   // Try to move I1 towards I2.
295   {
296     // Look at instructions I in between I1 and (excluding) I2.
297     MachineBasicBlock::iterator I(I1), End(I2);
298     // At O3 we got better results (dhrystone) by being more conservative here.
299     if (!ShouldCombineAggressively)
300       End = std::next(MachineBasicBlock::iterator(I2));
301     IsImmUseReg = I1->getOperand(1).isImm() || I1->getOperand(1).isGlobal();
302     unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg();
303     // Track killed operands. If we move across an instruction that kills our
304     // operand, we need to update the kill information on the moved I1. It kills
305     // the operand now.
306     MachineInstr *KillingInstr = nullptr;
307     unsigned KilledOperand = 0;
308 
309     while(++I != End) {
310       // If the intervening instruction I:
311       //   * modifies I1's use reg
312       //   * modifies I1's def reg
313       //   * reads I1's def reg
314       //   * or has unmodelled side effects
315       //   We introduce this special case because llvm has no api to remove a
316       //   kill flag for a register (a removeRegisterKilled() analogous to
317       //   addRegisterKilled) that handles aliased register correctly.
318       //   * or has a killed aliased register use of I1's use reg
319       //           %D4<def> = TFRI64 16
320       //           %R6<def> = TFR %R9
321       //           %R8<def> = KILL %R8, %D4<imp-use,kill>
322       //      If we want to move R6 = across the KILL instruction we would have
323       //      to remove the %D4<imp-use,kill> operand. For now, we are
324       //      conservative and disallow the move.
325       // we can't move I1 across it.
326       if (isUnsafeToMoveAcross(I, I1UseReg, I1DestReg, TRI) ||
327           // Check for an aliased register kill. Bail out if we see one.
328           (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI)))
329         return false;
330 
331       // Check for an exact kill (registers match).
332       if (I1UseReg && I->killsRegister(I1UseReg)) {
333         assert(!KillingInstr && "Should only see one killing instruction");
334         KilledOperand = I1UseReg;
335         KillingInstr = &*I;
336       }
337     }
338     if (KillingInstr) {
339       removeKillInfo(KillingInstr, KilledOperand);
340       // Update I1 to set the kill flag. This flag will later be picked up by
341       // the new COMBINE instruction.
342       bool Added = I1->addRegisterKilled(KilledOperand, TRI);
343       (void)Added; // suppress compiler warning
344       assert(Added && "Must successfully update kill flag");
345     }
346     DoInsertAtI1 = false;
347   }
348 
349   return true;
350 }
351 
352 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be
353 /// newified. (A use of a 64 bit register define can not be newified)
354 void
findPotentialNewifiableTFRs(MachineBasicBlock & BB)355 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
356   DenseMap<unsigned, MachineInstr *> LastDef;
357   for (MachineBasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
358     MachineInstr *MI = I;
359     // Mark TFRs that feed a potential new value store as such.
360     if(TII->mayBeNewStore(MI)) {
361       // Look for uses of TFR instructions.
362       for (unsigned OpdIdx = 0, OpdE = MI->getNumOperands(); OpdIdx != OpdE;
363            ++OpdIdx) {
364         MachineOperand &Op = MI->getOperand(OpdIdx);
365 
366         // Skip over anything except register uses.
367         if (!Op.isReg() || !Op.isUse() || !Op.getReg())
368           continue;
369 
370         // Look for the defining instruction.
371         unsigned Reg = Op.getReg();
372         MachineInstr *DefInst = LastDef[Reg];
373         if (!DefInst)
374           continue;
375         if (!isCombinableInstType(DefInst, TII, ShouldCombineAggressively))
376           continue;
377 
378         // Only close newifiable stores should influence the decision.
379         MachineBasicBlock::iterator It(DefInst);
380         unsigned NumInstsToDef = 0;
381         while (&*It++ != MI)
382           ++NumInstsToDef;
383 
384         if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)
385           continue;
386 
387         PotentiallyNewifiableTFR.insert(DefInst);
388       }
389       // Skip to next instruction.
390       continue;
391     }
392 
393     // Put instructions that last defined integer or double registers into the
394     // map.
395     for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
396       MachineOperand &Op = MI->getOperand(I);
397       if (!Op.isReg() || !Op.isDef() || !Op.getReg())
398         continue;
399       unsigned Reg = Op.getReg();
400       if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
401         for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
402           LastDef[*SubRegs] = MI;
403         }
404       } else if (Hexagon::IntRegsRegClass.contains(Reg))
405         LastDef[Reg] = MI;
406     }
407   }
408 }
409 
runOnMachineFunction(MachineFunction & MF)410 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
411 
412   if (IsCombinesDisabled) return false;
413 
414   bool HasChanged = false;
415 
416   // Get target info.
417   TRI = MF.getSubtarget().getRegisterInfo();
418   TII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
419 
420   // Combine aggressively (for code size)
421   ShouldCombineAggressively =
422     MF.getTarget().getOptLevel() <= CodeGenOpt::Default;
423 
424   // Traverse basic blocks.
425   for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE;
426        ++BI) {
427     PotentiallyNewifiableTFR.clear();
428     findPotentialNewifiableTFRs(*BI);
429 
430     // Traverse instructions in basic block.
431     for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end();
432         MI != End;) {
433       MachineInstr *I1 = MI++;
434       // Don't combine a TFR whose user could be newified (instructions that
435       // define double registers can not be newified - Programmer's Ref Manual
436       // 5.4.2 New-value stores).
437       if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I1))
438         continue;
439 
440       // Ignore instructions that are not combinable.
441       if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
442         continue;
443 
444       // Find a second instruction that can be merged into a combine
445       // instruction.
446       bool DoInsertAtI1 = false;
447       MachineInstr *I2 = findPairable(I1, DoInsertAtI1);
448       if (I2) {
449         HasChanged = true;
450         combine(I1, I2, MI, DoInsertAtI1);
451       }
452     }
453   }
454 
455   return HasChanged;
456 }
457 
458 /// findPairable - Returns an instruction that can be merged with \p I1 into a
459 /// COMBINE instruction or 0 if no such instruction can be found. Returns true
460 /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
461 /// false if the combine must be inserted at the returned instruction.
findPairable(MachineInstr * I1,bool & DoInsertAtI1)462 MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1,
463                                                  bool &DoInsertAtI1) {
464   MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1));
465   unsigned I1DestReg = I1->getOperand(0).getReg();
466 
467   for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End;
468        ++I2) {
469     // Bail out early if we see a second definition of I1DestReg.
470     if (I2->modifiesRegister(I1DestReg, TRI))
471       break;
472 
473     // Ignore non-combinable instructions.
474     if (!isCombinableInstType(I2, TII, ShouldCombineAggressively))
475       continue;
476 
477     // Don't combine a TFR whose user could be newified.
478     if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I2))
479       continue;
480 
481     unsigned I2DestReg = I2->getOperand(0).getReg();
482 
483     // Check that registers are adjacent and that the first destination register
484     // is even.
485     bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
486     bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
487     unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
488     if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))
489       continue;
490 
491     // Check that the two instructions are combinable. V4 allows more
492     // instructions to be merged into a combine.
493     // The order matters because in a TFRI we might can encode a int8 as the
494     // hi reg operand but only a uint6 as the low reg operand.
495     if ((IsI2LowReg && !areCombinableOperations(TRI, I1, I2)) ||
496         (IsI1LowReg && !areCombinableOperations(TRI, I2, I1)))
497       break;
498 
499     if (isSafeToMoveTogether(I1, I2, I1DestReg, I2DestReg,
500                              DoInsertAtI1))
501       return I2;
502 
503     // Not safe. Stop searching.
504     break;
505   }
506   return nullptr;
507 }
508 
combine(MachineInstr * I1,MachineInstr * I2,MachineBasicBlock::iterator & MI,bool DoInsertAtI1)509 void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2,
510                                    MachineBasicBlock::iterator &MI,
511                                    bool DoInsertAtI1) {
512   // We are going to delete I2. If MI points to I2 advance it to the next
513   // instruction.
514   if ((MachineInstr *)MI == I2) ++MI;
515 
516   // Figure out whether I1 or I2 goes into the lowreg part.
517   unsigned I1DestReg = I1->getOperand(0).getReg();
518   unsigned I2DestReg = I2->getOperand(0).getReg();
519   bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
520   unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
521 
522   // Get the double word register.
523   unsigned DoubleRegDest =
524     TRI->getMatchingSuperReg(LoRegDef, Hexagon::subreg_loreg,
525                              &Hexagon::DoubleRegsRegClass);
526   assert(DoubleRegDest != 0 && "Expect a valid register");
527 
528 
529   // Setup source operands.
530   MachineOperand &LoOperand = IsI1Loreg ? I1->getOperand(1) :
531     I2->getOperand(1);
532   MachineOperand &HiOperand = IsI1Loreg ? I2->getOperand(1) :
533     I1->getOperand(1);
534 
535   // Figure out which source is a register and which a constant.
536   bool IsHiReg = HiOperand.isReg();
537   bool IsLoReg = LoOperand.isReg();
538 
539   MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);
540   // Emit combine.
541   if (IsHiReg && IsLoReg)
542     emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
543   else if (IsHiReg)
544     emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
545   else if (IsLoReg)
546     emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
547   else
548     emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
549 
550   I1->eraseFromParent();
551   I2->eraseFromParent();
552 }
553 
emitCombineII(MachineBasicBlock::iterator & InsertPt,unsigned DoubleDestReg,MachineOperand & HiOperand,MachineOperand & LoOperand)554 void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
555                                          unsigned DoubleDestReg,
556                                          MachineOperand &HiOperand,
557                                          MachineOperand &LoOperand) {
558   DebugLoc DL = InsertPt->getDebugLoc();
559   MachineBasicBlock *BB = InsertPt->getParent();
560 
561   // Handle  globals.
562   if (HiOperand.isGlobal()) {
563     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
564       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
565                         HiOperand.getTargetFlags())
566       .addImm(LoOperand.getImm());
567     return;
568   }
569   if (LoOperand.isGlobal()) {
570     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
571       .addImm(HiOperand.getImm())
572       .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
573                         LoOperand.getTargetFlags());
574     return;
575   }
576 
577   // Handle constant extended immediates.
578   if (!isInt<8>(HiOperand.getImm())) {
579     assert(isInt<8>(LoOperand.getImm()));
580     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
581       .addImm(HiOperand.getImm())
582       .addImm(LoOperand.getImm());
583     return;
584   }
585 
586   if (!isUInt<6>(LoOperand.getImm())) {
587     assert(isInt<8>(HiOperand.getImm()));
588     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
589       .addImm(HiOperand.getImm())
590       .addImm(LoOperand.getImm());
591     return;
592   }
593 
594   // Insert new combine instruction.
595   //  DoubleRegDest = combine #HiImm, #LoImm
596   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
597     .addImm(HiOperand.getImm())
598     .addImm(LoOperand.getImm());
599 }
600 
emitCombineIR(MachineBasicBlock::iterator & InsertPt,unsigned DoubleDestReg,MachineOperand & HiOperand,MachineOperand & LoOperand)601 void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
602                                          unsigned DoubleDestReg,
603                                          MachineOperand &HiOperand,
604                                          MachineOperand &LoOperand) {
605   unsigned LoReg = LoOperand.getReg();
606   unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
607 
608   DebugLoc DL = InsertPt->getDebugLoc();
609   MachineBasicBlock *BB = InsertPt->getParent();
610 
611   // Handle global.
612   if (HiOperand.isGlobal()) {
613     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
614       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
615                         HiOperand.getTargetFlags())
616       .addReg(LoReg, LoRegKillFlag);
617     return;
618   }
619   // Insert new combine instruction.
620   //  DoubleRegDest = combine #HiImm, LoReg
621   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
622     .addImm(HiOperand.getImm())
623     .addReg(LoReg, LoRegKillFlag);
624 }
625 
emitCombineRI(MachineBasicBlock::iterator & InsertPt,unsigned DoubleDestReg,MachineOperand & HiOperand,MachineOperand & LoOperand)626 void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
627                                          unsigned DoubleDestReg,
628                                          MachineOperand &HiOperand,
629                                          MachineOperand &LoOperand) {
630   unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
631   unsigned HiReg = HiOperand.getReg();
632 
633   DebugLoc DL = InsertPt->getDebugLoc();
634   MachineBasicBlock *BB = InsertPt->getParent();
635 
636   // Handle global.
637   if (LoOperand.isGlobal()) {
638     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
639       .addReg(HiReg, HiRegKillFlag)
640       .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
641                         LoOperand.getTargetFlags());
642     return;
643   }
644 
645   // Insert new combine instruction.
646   //  DoubleRegDest = combine HiReg, #LoImm
647   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
648     .addReg(HiReg, HiRegKillFlag)
649     .addImm(LoOperand.getImm());
650 }
651 
emitCombineRR(MachineBasicBlock::iterator & InsertPt,unsigned DoubleDestReg,MachineOperand & HiOperand,MachineOperand & LoOperand)652 void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
653                                          unsigned DoubleDestReg,
654                                          MachineOperand &HiOperand,
655                                          MachineOperand &LoOperand) {
656   unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());
657   unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
658   unsigned LoReg = LoOperand.getReg();
659   unsigned HiReg = HiOperand.getReg();
660 
661   DebugLoc DL = InsertPt->getDebugLoc();
662   MachineBasicBlock *BB = InsertPt->getParent();
663 
664   // Insert new combine instruction.
665   //  DoubleRegDest = combine HiReg, LoReg
666   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combinew), DoubleDestReg)
667     .addReg(HiReg, HiRegKillFlag)
668     .addReg(LoReg, LoRegKillFlag);
669 }
670 
createHexagonCopyToCombine()671 FunctionPass *llvm::createHexagonCopyToCombine() {
672   return new HexagonCopyToCombine();
673 }
674