]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.h
Merge ACPICA 20170929.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AMDGPU / SIInstrInfo.h
1 //===-- SIInstrInfo.h - SI Instruction Info Interface -----------*- C++ -*-===//
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 //
10 /// \file
11 /// \brief Interface definition for SIInstrInfo.
12 //
13 //===----------------------------------------------------------------------===//
14
15
16 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
17 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
18
19 #include "AMDGPUInstrInfo.h"
20 #include "SIDefines.h"
21 #include "SIRegisterInfo.h"
22 #include "llvm/ADT/SetVector.h"
23
24 namespace llvm {
25
26 class SIInstrInfo final : public AMDGPUInstrInfo {
27 private:
28   const SIRegisterInfo RI;
29   const SISubtarget &ST;
30
31   // The the inverse predicate should have the negative value.
32   enum BranchPredicate {
33     INVALID_BR = 0,
34     SCC_TRUE = 1,
35     SCC_FALSE = -1,
36     VCCNZ = 2,
37     VCCZ = -2,
38     EXECNZ = -3,
39     EXECZ = 3
40   };
41
42   typedef SmallSetVector<MachineInstr *, 32> SetVectorType;
43
44   static unsigned getBranchOpcode(BranchPredicate Cond);
45   static BranchPredicate getBranchPredicate(unsigned Opcode);
46
47   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
48                               MachineRegisterInfo &MRI,
49                               MachineOperand &SuperReg,
50                               const TargetRegisterClass *SuperRC,
51                               unsigned SubIdx,
52                               const TargetRegisterClass *SubRC) const;
53   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
54                                          MachineRegisterInfo &MRI,
55                                          MachineOperand &SuperReg,
56                                          const TargetRegisterClass *SuperRC,
57                                          unsigned SubIdx,
58                                          const TargetRegisterClass *SubRC) const;
59
60   void swapOperands(MachineInstr &Inst) const;
61
62   void lowerScalarAbs(SetVectorType &Worklist,
63                       MachineInstr &Inst) const;
64
65   void splitScalar64BitUnaryOp(SetVectorType &Worklist,
66                                MachineInstr &Inst, unsigned Opcode) const;
67
68   void splitScalar64BitBinaryOp(SetVectorType &Worklist,
69                                 MachineInstr &Inst, unsigned Opcode) const;
70
71   void splitScalar64BitBCNT(SetVectorType &Worklist,
72                             MachineInstr &Inst) const;
73   void splitScalar64BitBFE(SetVectorType &Worklist,
74                            MachineInstr &Inst) const;
75   void movePackToVALU(SetVectorType &Worklist,
76                       MachineRegisterInfo &MRI,
77                       MachineInstr &Inst) const;
78
79   void addUsersToMoveToVALUWorklist(
80     unsigned Reg, MachineRegisterInfo &MRI,
81     SetVectorType &Worklist) const;
82
83   void
84   addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
85                                SetVectorType &Worklist) const;
86
87   const TargetRegisterClass *
88   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
89
90   bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
91
92   unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
93
94 protected:
95   bool swapSourceModifiers(MachineInstr &MI,
96                            MachineOperand &Src0, unsigned Src0OpName,
97                            MachineOperand &Src1, unsigned Src1OpName) const;
98
99   MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
100                                        unsigned OpIdx0,
101                                        unsigned OpIdx1) const override;
102
103 public:
104
105   enum TargetOperandFlags {
106     MO_MASK = 0x7,
107
108     MO_NONE = 0,
109     // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
110     MO_GOTPCREL = 1,
111     // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
112     MO_GOTPCREL32 = 2,
113     MO_GOTPCREL32_LO = 2,
114     // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
115     MO_GOTPCREL32_HI = 3,
116     // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
117     MO_REL32 = 4,
118     MO_REL32_LO = 4,
119     // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
120     MO_REL32_HI = 5
121   };
122
123   explicit SIInstrInfo(const SISubtarget &);
124
125   const SIRegisterInfo &getRegisterInfo() const {
126     return RI;
127   }
128
129   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
130                                          AliasAnalysis *AA) const override;
131
132   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
133                                int64_t &Offset1,
134                                int64_t &Offset2) const override;
135
136   bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
137                              int64_t &Offset,
138                              const TargetRegisterInfo *TRI) const final;
139
140   bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
141                            unsigned NumLoads) const final;
142
143   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
144                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
145                    bool KillSrc) const override;
146
147   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
148                                     RegScavenger *RS, unsigned TmpReg,
149                                     unsigned Offset, unsigned Size) const;
150
151   void materializeImmediate(MachineBasicBlock &MBB,
152                             MachineBasicBlock::iterator MI,
153                             const DebugLoc &DL,
154                             unsigned DestReg,
155                             int64_t Value) const;
156
157   const TargetRegisterClass *getPreferredSelectRegClass(
158                                unsigned Size) const;
159
160   unsigned insertNE(MachineBasicBlock *MBB,
161                     MachineBasicBlock::iterator I, const DebugLoc &DL,
162                     unsigned SrcReg, int Value)  const;
163
164   unsigned insertEQ(MachineBasicBlock *MBB,
165                     MachineBasicBlock::iterator I, const DebugLoc &DL,
166                     unsigned SrcReg, int Value)  const;
167
168   void storeRegToStackSlot(MachineBasicBlock &MBB,
169                            MachineBasicBlock::iterator MI, unsigned SrcReg,
170                            bool isKill, int FrameIndex,
171                            const TargetRegisterClass *RC,
172                            const TargetRegisterInfo *TRI) const override;
173
174   void loadRegFromStackSlot(MachineBasicBlock &MBB,
175                             MachineBasicBlock::iterator MI, unsigned DestReg,
176                             int FrameIndex, const TargetRegisterClass *RC,
177                             const TargetRegisterInfo *TRI) const override;
178
179   bool expandPostRAPseudo(MachineInstr &MI) const override;
180
181   // \brief Returns an opcode that can be used to move a value to a \p DstRC
182   // register.  If there is no hardware instruction that can store to \p
183   // DstRC, then AMDGPU::COPY is returned.
184   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
185
186   LLVM_READONLY
187   int commuteOpcode(unsigned Opc) const;
188
189   LLVM_READONLY
190   inline int commuteOpcode(const MachineInstr &MI) const {
191     return commuteOpcode(MI.getOpcode());
192   }
193
194   bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
195                              unsigned &SrcOpIdx2) const override;
196
197   bool isBranchOffsetInRange(unsigned BranchOpc,
198                              int64_t BrOffset) const override;
199
200   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
201
202   unsigned insertIndirectBranch(MachineBasicBlock &MBB,
203                                 MachineBasicBlock &NewDestBB,
204                                 const DebugLoc &DL,
205                                 int64_t BrOffset,
206                                 RegScavenger *RS = nullptr) const override;
207
208   bool analyzeBranchImpl(MachineBasicBlock &MBB,
209                          MachineBasicBlock::iterator I,
210                          MachineBasicBlock *&TBB,
211                          MachineBasicBlock *&FBB,
212                          SmallVectorImpl<MachineOperand> &Cond,
213                          bool AllowModify) const;
214
215   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
216                      MachineBasicBlock *&FBB,
217                      SmallVectorImpl<MachineOperand> &Cond,
218                      bool AllowModify = false) const override;
219
220   unsigned removeBranch(MachineBasicBlock &MBB,
221                         int *BytesRemoved = nullptr) const override;
222
223   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
224                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
225                         const DebugLoc &DL,
226                         int *BytesAdded = nullptr) const override;
227
228   bool reverseBranchCondition(
229     SmallVectorImpl<MachineOperand> &Cond) const override;
230
231
232   bool canInsertSelect(const MachineBasicBlock &MBB,
233                        ArrayRef<MachineOperand> Cond,
234                        unsigned TrueReg, unsigned FalseReg,
235                        int &CondCycles,
236                        int &TrueCycles, int &FalseCycles) const override;
237
238   void insertSelect(MachineBasicBlock &MBB,
239                     MachineBasicBlock::iterator I, const DebugLoc &DL,
240                     unsigned DstReg, ArrayRef<MachineOperand> Cond,
241                     unsigned TrueReg, unsigned FalseReg) const override;
242
243   void insertVectorSelect(MachineBasicBlock &MBB,
244                           MachineBasicBlock::iterator I, const DebugLoc &DL,
245                           unsigned DstReg, ArrayRef<MachineOperand> Cond,
246                           unsigned TrueReg, unsigned FalseReg) const;
247
248   bool
249   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
250                                   AliasAnalysis *AA = nullptr) const override;
251
252   bool isFoldableCopy(const MachineInstr &MI) const;
253
254   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
255                      MachineRegisterInfo *MRI) const final;
256
257   unsigned getMachineCSELookAheadLimit() const override { return 500; }
258
259   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
260                                       MachineInstr &MI,
261                                       LiveVariables *LV) const override;
262
263   bool isSchedulingBoundary(const MachineInstr &MI,
264                             const MachineBasicBlock *MBB,
265                             const MachineFunction &MF) const override;
266
267   static bool isSALU(const MachineInstr &MI) {
268     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
269   }
270
271   bool isSALU(uint16_t Opcode) const {
272     return get(Opcode).TSFlags & SIInstrFlags::SALU;
273   }
274
275   static bool isVALU(const MachineInstr &MI) {
276     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
277   }
278
279   bool isVALU(uint16_t Opcode) const {
280     return get(Opcode).TSFlags & SIInstrFlags::VALU;
281   }
282
283   static bool isVMEM(const MachineInstr &MI) {
284     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
285   }
286
287   bool isVMEM(uint16_t Opcode) const {
288     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
289   }
290
291   static bool isSOP1(const MachineInstr &MI) {
292     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
293   }
294
295   bool isSOP1(uint16_t Opcode) const {
296     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
297   }
298
299   static bool isSOP2(const MachineInstr &MI) {
300     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
301   }
302
303   bool isSOP2(uint16_t Opcode) const {
304     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
305   }
306
307   static bool isSOPC(const MachineInstr &MI) {
308     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
309   }
310
311   bool isSOPC(uint16_t Opcode) const {
312     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
313   }
314
315   static bool isSOPK(const MachineInstr &MI) {
316     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
317   }
318
319   bool isSOPK(uint16_t Opcode) const {
320     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
321   }
322
323   static bool isSOPP(const MachineInstr &MI) {
324     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
325   }
326
327   bool isSOPP(uint16_t Opcode) const {
328     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
329   }
330
331   static bool isVOP1(const MachineInstr &MI) {
332     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
333   }
334
335   bool isVOP1(uint16_t Opcode) const {
336     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
337   }
338
339   static bool isVOP2(const MachineInstr &MI) {
340     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
341   }
342
343   bool isVOP2(uint16_t Opcode) const {
344     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
345   }
346
347   static bool isVOP3(const MachineInstr &MI) {
348     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
349   }
350
351   bool isVOP3(uint16_t Opcode) const {
352     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
353   }
354
355   static bool isSDWA(const MachineInstr &MI) {
356     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
357   }
358
359   bool isSDWA(uint16_t Opcode) const {
360     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
361   }
362
363   static bool isVOPC(const MachineInstr &MI) {
364     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
365   }
366
367   bool isVOPC(uint16_t Opcode) const {
368     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
369   }
370
371   static bool isMUBUF(const MachineInstr &MI) {
372     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
373   }
374
375   bool isMUBUF(uint16_t Opcode) const {
376     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
377   }
378
379   static bool isMTBUF(const MachineInstr &MI) {
380     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
381   }
382
383   bool isMTBUF(uint16_t Opcode) const {
384     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
385   }
386
387   static bool isSMRD(const MachineInstr &MI) {
388     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
389   }
390
391   bool isSMRD(uint16_t Opcode) const {
392     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
393   }
394
395   static bool isDS(const MachineInstr &MI) {
396     return MI.getDesc().TSFlags & SIInstrFlags::DS;
397   }
398
399   bool isDS(uint16_t Opcode) const {
400     return get(Opcode).TSFlags & SIInstrFlags::DS;
401   }
402
403   static bool isMIMG(const MachineInstr &MI) {
404     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
405   }
406
407   bool isMIMG(uint16_t Opcode) const {
408     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
409   }
410
411   static bool isGather4(const MachineInstr &MI) {
412     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
413   }
414
415   bool isGather4(uint16_t Opcode) const {
416     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
417   }
418
419   static bool isFLAT(const MachineInstr &MI) {
420     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
421   }
422
423   bool isFLAT(uint16_t Opcode) const {
424     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
425   }
426
427   static bool isEXP(const MachineInstr &MI) {
428     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
429   }
430
431   bool isEXP(uint16_t Opcode) const {
432     return get(Opcode).TSFlags & SIInstrFlags::EXP;
433   }
434
435   static bool isWQM(const MachineInstr &MI) {
436     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
437   }
438
439   bool isWQM(uint16_t Opcode) const {
440     return get(Opcode).TSFlags & SIInstrFlags::WQM;
441   }
442
443   static bool isDisableWQM(const MachineInstr &MI) {
444     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
445   }
446
447   bool isDisableWQM(uint16_t Opcode) const {
448     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
449   }
450
451   static bool isVGPRSpill(const MachineInstr &MI) {
452     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
453   }
454
455   bool isVGPRSpill(uint16_t Opcode) const {
456     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
457   }
458
459   static bool isSGPRSpill(const MachineInstr &MI) {
460     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
461   }
462
463   bool isSGPRSpill(uint16_t Opcode) const {
464     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
465   }
466
467   static bool isDPP(const MachineInstr &MI) {
468     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
469   }
470
471   bool isDPP(uint16_t Opcode) const {
472     return get(Opcode).TSFlags & SIInstrFlags::DPP;
473   }
474
475   static bool isVOP3P(const MachineInstr &MI) {
476     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
477   }
478
479   bool isVOP3P(uint16_t Opcode) const {
480     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
481   }
482
483   static bool isVINTRP(const MachineInstr &MI) {
484     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
485   }
486
487   bool isVINTRP(uint16_t Opcode) const {
488     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
489   }
490
491   static bool isScalarUnit(const MachineInstr &MI) {
492     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
493   }
494
495   static bool usesVM_CNT(const MachineInstr &MI) {
496     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
497   }
498
499   static bool sopkIsZext(const MachineInstr &MI) {
500     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
501   }
502
503   bool sopkIsZext(uint16_t Opcode) const {
504     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
505   }
506
507   /// \returns true if this is an s_store_dword* instruction. This is more
508   /// specific than than isSMEM && mayStore.
509   static bool isScalarStore(const MachineInstr &MI) {
510     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
511   }
512
513   bool isScalarStore(uint16_t Opcode) const {
514     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
515   }
516
517   static bool isFixedSize(const MachineInstr &MI) {
518     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
519   }
520
521   bool isFixedSize(uint16_t Opcode) const {
522     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
523   }
524
525   static bool hasFPClamp(const MachineInstr &MI) {
526     return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp;
527   }
528
529   bool hasFPClamp(uint16_t Opcode) const {
530     return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp;
531   }
532
533   bool isVGPRCopy(const MachineInstr &MI) const {
534     assert(MI.isCopy());
535     unsigned Dest = MI.getOperand(0).getReg();
536     const MachineFunction &MF = *MI.getParent()->getParent();
537     const MachineRegisterInfo &MRI = MF.getRegInfo();
538     return !RI.isSGPRReg(MRI, Dest);
539   }
540
541   bool isInlineConstant(const APInt &Imm) const;
542
543   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
544
545   bool isInlineConstant(const MachineOperand &MO,
546                         const MCOperandInfo &OpInfo) const {
547     return isInlineConstant(MO, OpInfo.OperandType);
548   }
549
550   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
551   /// be an inline immediate.
552   bool isInlineConstant(const MachineInstr &MI,
553                         const MachineOperand &UseMO,
554                         const MachineOperand &DefMO) const {
555     assert(UseMO.getParent() == &MI);
556     int OpIdx = MI.getOperandNo(&UseMO);
557     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
558       return false;
559     }
560
561     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
562   }
563
564   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
565   /// immediate.
566   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
567     const MachineOperand &MO = MI.getOperand(OpIdx);
568     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
569   }
570
571   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
572                         const MachineOperand &MO) const {
573     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
574       return false;
575
576     if (MI.isCopy()) {
577       unsigned Size = getOpSize(MI, OpIdx);
578       assert(Size == 8 || Size == 4);
579
580       uint8_t OpType = (Size == 8) ?
581         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
582       return isInlineConstant(MO, OpType);
583     }
584
585     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
586   }
587
588   bool isInlineConstant(const MachineOperand &MO) const {
589     const MachineInstr *Parent = MO.getParent();
590     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
591   }
592
593   bool isLiteralConstant(const MachineOperand &MO,
594                          const MCOperandInfo &OpInfo) const {
595     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
596   }
597
598   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
599     const MachineOperand &MO = MI.getOperand(OpIdx);
600     return MO.isImm() && !isInlineConstant(MI, OpIdx);
601   }
602
603   // Returns true if this operand could potentially require a 32-bit literal
604   // operand, but not necessarily. A FrameIndex for example could resolve to an
605   // inline immediate value that will not require an additional 4-bytes; this
606   // assumes that it will.
607   bool isLiteralConstantLike(const MachineOperand &MO,
608                              const MCOperandInfo &OpInfo) const;
609
610   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
611                          const MachineOperand &MO) const;
612
613   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
614   /// This function will return false if you pass it a 32-bit instruction.
615   bool hasVALU32BitEncoding(unsigned Opcode) const;
616
617   /// \brief Returns true if this operand uses the constant bus.
618   bool usesConstantBus(const MachineRegisterInfo &MRI,
619                        const MachineOperand &MO,
620                        const MCOperandInfo &OpInfo) const;
621
622   /// \brief Return true if this instruction has any modifiers.
623   ///  e.g. src[012]_mod, omod, clamp.
624   bool hasModifiers(unsigned Opcode) const;
625
626   bool hasModifiersSet(const MachineInstr &MI,
627                        unsigned OpName) const;
628   bool hasAnyModifiersSet(const MachineInstr &MI) const;
629
630   bool verifyInstruction(const MachineInstr &MI,
631                          StringRef &ErrInfo) const override;
632
633   static unsigned getVALUOp(const MachineInstr &MI);
634
635   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
636
637   /// \brief Return the correct register class for \p OpNo.  For target-specific
638   /// instructions, this will return the register class that has been defined
639   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
640   /// the register class of its machine operand.
641   /// to infer the correct register class base on the other operands.
642   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
643                                            unsigned OpNo) const;
644
645   /// \brief Return the size in bytes of the operand OpNo on the given
646   // instruction opcode.
647   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
648     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
649
650     if (OpInfo.RegClass == -1) {
651       // If this is an immediate operand, this must be a 32-bit literal.
652       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
653       return 4;
654     }
655
656     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
657   }
658
659   /// \brief This form should usually be preferred since it handles operands
660   /// with unknown register classes.
661   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
662     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
663   }
664
665   /// \returns true if it is legal for the operand at index \p OpNo
666   /// to read a VGPR.
667   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
668
669   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
670   /// a MOV.  For example:
671   /// ADD_I32_e32 VGPR0, 15
672   /// to
673   /// MOV VGPR1, 15
674   /// ADD_I32_e32 VGPR0, VGPR1
675   ///
676   /// If the operand being legalized is a register, then a COPY will be used
677   /// instead of MOV.
678   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
679
680   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
681   /// for \p MI.
682   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
683                       const MachineOperand *MO = nullptr) const;
684
685   /// \brief Check if \p MO would be a valid operand for the given operand
686   /// definition \p OpInfo. Note this does not attempt to validate constant bus
687   /// restrictions (e.g. literal constant usage).
688   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
689                           const MCOperandInfo &OpInfo,
690                           const MachineOperand &MO) const;
691
692   /// \brief Check if \p MO (a register operand) is a legal register for the
693   /// given operand description.
694   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
695                          const MCOperandInfo &OpInfo,
696                          const MachineOperand &MO) const;
697
698   /// \brief Legalize operands in \p MI by either commuting it or inserting a
699   /// copy of src1.
700   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
701
702   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
703   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
704
705   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
706   /// be used when it is know that the value in SrcReg is same across all
707   /// threads in the wave.
708   /// \returns The SGPR register that \p SrcReg was copied to.
709   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
710                               MachineRegisterInfo &MRI) const;
711
712   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
713
714   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
715                               MachineBasicBlock::iterator I,
716                               const TargetRegisterClass *DstRC,
717                               MachineOperand &Op, MachineRegisterInfo &MRI,
718                               const DebugLoc &DL) const;
719
720   /// \brief Legalize all operands in this instruction.  This function may
721   /// create new instruction and insert them before \p MI.
722   void legalizeOperands(MachineInstr &MI) const;
723
724   /// \brief Replace this instruction's opcode with the equivalent VALU
725   /// opcode.  This function will also move the users of \p MI to the
726   /// VALU if necessary.
727   void moveToVALU(MachineInstr &MI) const;
728
729   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
730                         int Count) const;
731
732   void insertNoop(MachineBasicBlock &MBB,
733                   MachineBasicBlock::iterator MI) const override;
734
735   void insertReturn(MachineBasicBlock &MBB) const;
736   /// \brief Return the number of wait states that result from executing this
737   /// instruction.
738   unsigned getNumWaitStates(const MachineInstr &MI) const;
739
740   /// \brief Returns the operand named \p Op.  If \p MI does not have an
741   /// operand named \c Op, this function returns nullptr.
742   LLVM_READONLY
743   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
744
745   LLVM_READONLY
746   const MachineOperand *getNamedOperand(const MachineInstr &MI,
747                                         unsigned OpName) const {
748     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
749   }
750
751   /// Get required immediate operand
752   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
753     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
754     return MI.getOperand(Idx).getImm();
755   }
756
757   uint64_t getDefaultRsrcDataFormat() const;
758   uint64_t getScratchRsrcWords23() const;
759
760   bool isLowLatencyInstruction(const MachineInstr &MI) const;
761   bool isHighLatencyInstruction(const MachineInstr &MI) const;
762
763   /// \brief Return the descriptor of the target-specific machine instruction
764   /// that corresponds to the specified pseudo or native opcode.
765   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
766     return get(pseudoToMCOpcode(Opcode));
767   }
768
769   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
770   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
771
772   unsigned isLoadFromStackSlot(const MachineInstr &MI,
773                                int &FrameIndex) const override;
774   unsigned isStoreToStackSlot(const MachineInstr &MI,
775                               int &FrameIndex) const override;
776
777   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
778
779   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
780
781   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
782
783   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
784                                  MachineBasicBlock *IfEnd) const;
785
786   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
787                                    MachineBasicBlock *LoopEnd) const;
788
789   std::pair<unsigned, unsigned>
790   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
791
792   ArrayRef<std::pair<int, const char *>>
793   getSerializableTargetIndices() const override;
794
795   ArrayRef<std::pair<unsigned, const char *>>
796   getSerializableDirectMachineOperandTargetFlags() const override;
797
798   ScheduleHazardRecognizer *
799   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
800                                  const ScheduleDAG *DAG) const override;
801
802   ScheduleHazardRecognizer *
803   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
804
805   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
806
807   /// \brief Return a partially built integer add instruction without carry.
808   /// Caller must add source operands.
809   /// For pre-GFX9 it will generate unused carry destination operand.
810   /// TODO: After GFX9 it should return a no-carry operation.
811   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
812                                     MachineBasicBlock::iterator I,
813                                     const DebugLoc &DL,
814                                     unsigned DestReg) const;
815 };
816
817 namespace AMDGPU {
818   LLVM_READONLY
819   int getVOPe64(uint16_t Opcode);
820
821   LLVM_READONLY
822   int getVOPe32(uint16_t Opcode);
823
824   LLVM_READONLY
825   int getSDWAOp(uint16_t Opcode);
826
827   LLVM_READONLY
828   int getBasicFromSDWAOp(uint16_t Opcode);
829
830   LLVM_READONLY
831   int getCommuteRev(uint16_t Opcode);
832
833   LLVM_READONLY
834   int getCommuteOrig(uint16_t Opcode);
835
836   LLVM_READONLY
837   int getAddr64Inst(uint16_t Opcode);
838
839   LLVM_READONLY
840   int getAtomicRetOp(uint16_t Opcode);
841
842   LLVM_READONLY
843   int getAtomicNoRetOp(uint16_t Opcode);
844
845   LLVM_READONLY
846   int getSOPKOp(uint16_t Opcode);
847
848   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
849   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
850   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
851   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
852
853   // For MachineOperands.
854   enum TargetFlags {
855     TF_LONG_BRANCH_FORWARD = 1 << 0,
856     TF_LONG_BRANCH_BACKWARD = 1 << 1
857   };
858 } // End namespace AMDGPU
859
860 namespace SI {
861 namespace KernelInputOffsets {
862
863 /// Offsets in bytes from the start of the input buffer
864 enum Offsets {
865   NGROUPS_X = 0,
866   NGROUPS_Y = 4,
867   NGROUPS_Z = 8,
868   GLOBAL_SIZE_X = 12,
869   GLOBAL_SIZE_Y = 16,
870   GLOBAL_SIZE_Z = 20,
871   LOCAL_SIZE_X = 24,
872   LOCAL_SIZE_Y = 28,
873   LOCAL_SIZE_Z = 32
874 };
875
876 } // End namespace KernelInputOffsets
877 } // End namespace SI
878
879 } // End namespace llvm
880
881 #endif