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