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