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   bool
207   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
208                                   AliasAnalysis *AA = nullptr) const override;
209 
210   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
211                      MachineRegisterInfo *MRI) const final;
212 
213   unsigned getMachineCSELookAheadLimit() const override { return 500; }
214 
215   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
216                                       MachineInstr &MI,
217                                       LiveVariables *LV) const override;
218 
219   bool isSchedulingBoundary(const MachineInstr &MI,
220                             const MachineBasicBlock *MBB,
221                             const MachineFunction &MF) const override;
222 
223   static bool isSALU(const MachineInstr &MI) {
224     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
225   }
226 
227   bool isSALU(uint16_t Opcode) const {
228     return get(Opcode).TSFlags & SIInstrFlags::SALU;
229   }
230 
231   static bool isVALU(const MachineInstr &MI) {
232     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
233   }
234 
235   bool isVALU(uint16_t Opcode) const {
236     return get(Opcode).TSFlags & SIInstrFlags::VALU;
237   }
238 
239   static bool isVMEM(const MachineInstr &MI) {
240     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
241   }
242 
243   bool isVMEM(uint16_t Opcode) const {
244     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
245   }
246 
247   static bool isSOP1(const MachineInstr &MI) {
248     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
249   }
250 
251   bool isSOP1(uint16_t Opcode) const {
252     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
253   }
254 
255   static bool isSOP2(const MachineInstr &MI) {
256     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
257   }
258 
259   bool isSOP2(uint16_t Opcode) const {
260     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
261   }
262 
263   static bool isSOPC(const MachineInstr &MI) {
264     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
265   }
266 
267   bool isSOPC(uint16_t Opcode) const {
268     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
269   }
270 
271   static bool isSOPK(const MachineInstr &MI) {
272     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
273   }
274 
275   bool isSOPK(uint16_t Opcode) const {
276     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
277   }
278 
279   static bool isSOPP(const MachineInstr &MI) {
280     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
281   }
282 
283   bool isSOPP(uint16_t Opcode) const {
284     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
285   }
286 
287   static bool isVOP1(const MachineInstr &MI) {
288     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
289   }
290 
291   bool isVOP1(uint16_t Opcode) const {
292     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
293   }
294 
295   static bool isVOP2(const MachineInstr &MI) {
296     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
297   }
298 
299   bool isVOP2(uint16_t Opcode) const {
300     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
301   }
302 
303   static bool isVOP3(const MachineInstr &MI) {
304     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
305   }
306 
307   bool isVOP3(uint16_t Opcode) const {
308     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
309   }
310 
311   static bool isVOPC(const MachineInstr &MI) {
312     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
313   }
314 
315   bool isVOPC(uint16_t Opcode) const {
316     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
317   }
318 
319   static bool isMUBUF(const MachineInstr &MI) {
320     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
321   }
322 
323   bool isMUBUF(uint16_t Opcode) const {
324     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
325   }
326 
327   static bool isMTBUF(const MachineInstr &MI) {
328     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
329   }
330 
331   bool isMTBUF(uint16_t Opcode) const {
332     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
333   }
334 
335   static bool isSMRD(const MachineInstr &MI) {
336     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
337   }
338 
339   bool isSMRD(uint16_t Opcode) const {
340     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
341   }
342 
343   static bool isDS(const MachineInstr &MI) {
344     return MI.getDesc().TSFlags & SIInstrFlags::DS;
345   }
346 
347   bool isDS(uint16_t Opcode) const {
348     return get(Opcode).TSFlags & SIInstrFlags::DS;
349   }
350 
351   static bool isMIMG(const MachineInstr &MI) {
352     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
353   }
354 
355   bool isMIMG(uint16_t Opcode) const {
356     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
357   }
358 
359   static bool isGather4(const MachineInstr &MI) {
360     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
361   }
362 
363   bool isGather4(uint16_t Opcode) const {
364     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
365   }
366 
367   static bool isFLAT(const MachineInstr &MI) {
368     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
369   }
370 
371   bool isFLAT(uint16_t Opcode) const {
372     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
373   }
374 
375   static bool isWQM(const MachineInstr &MI) {
376     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
377   }
378 
379   bool isWQM(uint16_t Opcode) const {
380     return get(Opcode).TSFlags & SIInstrFlags::WQM;
381   }
382 
383   static bool isDisableWQM(const MachineInstr &MI) {
384     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
385   }
386 
387   bool isDisableWQM(uint16_t Opcode) const {
388     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
389   }
390 
391   static bool isVGPRSpill(const MachineInstr &MI) {
392     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
393   }
394 
395   bool isVGPRSpill(uint16_t Opcode) const {
396     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
397   }
398 
399   static bool isSGPRSpill(const MachineInstr &MI) {
400     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
401   }
402 
403   bool isSGPRSpill(uint16_t Opcode) const {
404     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
405   }
406 
407   static bool isDPP(const MachineInstr &MI) {
408     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
409   }
410 
411   bool isDPP(uint16_t Opcode) const {
412     return get(Opcode).TSFlags & SIInstrFlags::DPP;
413   }
414 
415   static bool isScalarUnit(const MachineInstr &MI) {
416     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
417   }
418 
419   static bool usesVM_CNT(const MachineInstr &MI) {
420     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
421   }
422 
423   static bool sopkIsZext(const MachineInstr &MI) {
424     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
425   }
426 
427   bool sopkIsZext(uint16_t Opcode) const {
428     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
429   }
430 
431   bool isVGPRCopy(const MachineInstr &MI) const {
432     assert(MI.isCopy());
433     unsigned Dest = MI.getOperand(0).getReg();
434     const MachineFunction &MF = *MI.getParent()->getParent();
435     const MachineRegisterInfo &MRI = MF.getRegInfo();
436     return !RI.isSGPRReg(MRI, Dest);
437   }
438 
439   bool isInlineConstant(const APInt &Imm) const;
440   bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
441   bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
442 
443   // Returns true if this operand could potentially require a 32-bit literal
444   // operand, but not necessarily. A FrameIndex for example could resolve to an
445   // inline immediate value that will not require an additional 4-bytes; this
446   // assumes that it will.
447   bool isLiteralConstantLike(const MachineOperand &MO, unsigned OpSize) const;
448 
449   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
450                          const MachineOperand &MO) const;
451 
452   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
453   /// This function will return false if you pass it a 32-bit instruction.
454   bool hasVALU32BitEncoding(unsigned Opcode) const;
455 
456   /// \brief Returns true if this operand uses the constant bus.
457   bool usesConstantBus(const MachineRegisterInfo &MRI,
458                        const MachineOperand &MO,
459                        unsigned OpSize) const;
460 
461   /// \brief Return true if this instruction has any modifiers.
462   ///  e.g. src[012]_mod, omod, clamp.
463   bool hasModifiers(unsigned Opcode) const;
464 
465   bool hasModifiersSet(const MachineInstr &MI,
466                        unsigned OpName) const;
467 
468   bool verifyInstruction(const MachineInstr &MI,
469                          StringRef &ErrInfo) const override;
470 
471   static unsigned getVALUOp(const MachineInstr &MI);
472 
473   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
474 
475   /// \brief Return the correct register class for \p OpNo.  For target-specific
476   /// instructions, this will return the register class that has been defined
477   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
478   /// the register class of its machine operand.
479   /// to infer the correct register class base on the other operands.
480   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
481                                            unsigned OpNo) const;
482 
483   /// \brief Return the size in bytes of the operand OpNo on the given
484   // instruction opcode.
485   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
486     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
487 
488     if (OpInfo.RegClass == -1) {
489       // If this is an immediate operand, this must be a 32-bit literal.
490       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
491       return 4;
492     }
493 
494     return RI.getRegClass(OpInfo.RegClass)->getSize();
495   }
496 
497   /// \brief This form should usually be preferred since it handles operands
498   /// with unknown register classes.
499   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
500     return getOpRegClass(MI, OpNo)->getSize();
501   }
502 
503   /// \returns true if it is legal for the operand at index \p OpNo
504   /// to read a VGPR.
505   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
506 
507   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
508   /// a MOV.  For example:
509   /// ADD_I32_e32 VGPR0, 15
510   /// to
511   /// MOV VGPR1, 15
512   /// ADD_I32_e32 VGPR0, VGPR1
513   ///
514   /// If the operand being legalized is a register, then a COPY will be used
515   /// instead of MOV.
516   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
517 
518   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
519   /// for \p MI.
520   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
521                       const MachineOperand *MO = nullptr) const;
522 
523   /// \brief Check if \p MO would be a valid operand for the given operand
524   /// definition \p OpInfo. Note this does not attempt to validate constant bus
525   /// restrictions (e.g. literal constant usage).
526   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
527                           const MCOperandInfo &OpInfo,
528                           const MachineOperand &MO) const;
529 
530   /// \brief Check if \p MO (a register operand) is a legal register for the
531   /// given operand description.
532   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
533                          const MCOperandInfo &OpInfo,
534                          const MachineOperand &MO) const;
535 
536   /// \brief Legalize operands in \p MI by either commuting it or inserting a
537   /// copy of src1.
538   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
539 
540   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
541   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
542 
543   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
544   /// be used when it is know that the value in SrcReg is same across all
545   /// threads in the wave.
546   /// \returns The SGPR register that \p SrcReg was copied to.
547   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
548                               MachineRegisterInfo &MRI) const;
549 
550   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
551 
552   /// \brief Legalize all operands in this instruction.  This function may
553   /// create new instruction and insert them before \p MI.
554   void legalizeOperands(MachineInstr &MI) const;
555 
556   /// \brief Replace this instruction's opcode with the equivalent VALU
557   /// opcode.  This function will also move the users of \p MI to the
558   /// VALU if necessary.
559   void moveToVALU(MachineInstr &MI) const;
560 
561   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
562                         int Count) const;
563 
564   void insertNoop(MachineBasicBlock &MBB,
565                   MachineBasicBlock::iterator MI) const override;
566 
567   /// \brief Return the number of wait states that result from executing this
568   /// instruction.
569   unsigned getNumWaitStates(const MachineInstr &MI) const;
570 
571   /// \brief Returns the operand named \p Op.  If \p MI does not have an
572   /// operand named \c Op, this function returns nullptr.
573   LLVM_READONLY
574   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
575 
576   LLVM_READONLY
577   const MachineOperand *getNamedOperand(const MachineInstr &MI,
578                                         unsigned OpName) const {
579     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
580   }
581 
582   /// Get required immediate operand
583   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
584     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
585     return MI.getOperand(Idx).getImm();
586   }
587 
588   uint64_t getDefaultRsrcDataFormat() const;
589   uint64_t getScratchRsrcWords23() const;
590 
591   bool isLowLatencyInstruction(const MachineInstr &MI) const;
592   bool isHighLatencyInstruction(const MachineInstr &MI) const;
593 
594   /// \brief Return the descriptor of the target-specific machine instruction
595   /// that corresponds to the specified pseudo or native opcode.
596   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
597     return get(pseudoToMCOpcode(Opcode));
598   }
599 
600   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
601   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
602 
603   unsigned isLoadFromStackSlot(const MachineInstr &MI,
604                                int &FrameIndex) const override;
605   unsigned isStoreToStackSlot(const MachineInstr &MI,
606                               int &FrameIndex) const override;
607 
608   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
609 
610   ArrayRef<std::pair<int, const char *>>
611   getSerializableTargetIndices() const override;
612 
613   ScheduleHazardRecognizer *
614   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
615                                  const ScheduleDAG *DAG) const override;
616 
617   ScheduleHazardRecognizer *
618   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
619 };
620 
621 namespace AMDGPU {
622   LLVM_READONLY
623   int getVOPe64(uint16_t Opcode);
624 
625   LLVM_READONLY
626   int getVOPe32(uint16_t Opcode);
627 
628   LLVM_READONLY
629   int getCommuteRev(uint16_t Opcode);
630 
631   LLVM_READONLY
632   int getCommuteOrig(uint16_t Opcode);
633 
634   LLVM_READONLY
635   int getAddr64Inst(uint16_t Opcode);
636 
637   LLVM_READONLY
638   int getAtomicRetOp(uint16_t Opcode);
639 
640   LLVM_READONLY
641   int getAtomicNoRetOp(uint16_t Opcode);
642 
643   LLVM_READONLY
644   int getSOPKOp(uint16_t Opcode);
645 
646   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
647   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
648   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
649   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
650 
651   // For MachineOperands.
652   enum TargetFlags {
653     TF_LONG_BRANCH_FORWARD = 1 << 0,
654     TF_LONG_BRANCH_BACKWARD = 1 << 1
655   };
656 } // End namespace AMDGPU
657 
658 namespace SI {
659 namespace KernelInputOffsets {
660 
661 /// Offsets in bytes from the start of the input buffer
662 enum Offsets {
663   NGROUPS_X = 0,
664   NGROUPS_Y = 4,
665   NGROUPS_Z = 8,
666   GLOBAL_SIZE_X = 12,
667   GLOBAL_SIZE_Y = 16,
668   GLOBAL_SIZE_Z = 20,
669   LOCAL_SIZE_X = 24,
670   LOCAL_SIZE_Y = 28,
671   LOCAL_SIZE_Z = 32
672 };
673 
674 } // End namespace KernelInputOffsets
675 } // End namespace SI
676 
677 } // End namespace llvm
678 
679 #endif
680