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   MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
90                                        unsigned OpIdx0,
91                                        unsigned OpIdx1) const override;
92 
93 public:
94 
95   enum TargetOperandFlags {
96     MO_NONE = 0,
97     MO_GOTPCREL = 1
98   };
99 
100   explicit SIInstrInfo(const SISubtarget &);
101 
getRegisterInfo()102   const SIRegisterInfo &getRegisterInfo() const {
103     return RI;
104   }
105 
106   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
107                                          AliasAnalysis *AA) const override;
108 
109   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
110                                int64_t &Offset1,
111                                int64_t &Offset2) const override;
112 
113   bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
114                              int64_t &Offset,
115                              const TargetRegisterInfo *TRI) const final;
116 
117   bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
118                            unsigned NumLoads) const final;
119 
120   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
121                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
122                    bool KillSrc) const override;
123 
124   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
125                                     RegScavenger *RS, unsigned TmpReg,
126                                     unsigned Offset, unsigned Size) const;
127 
128   void storeRegToStackSlot(MachineBasicBlock &MBB,
129                            MachineBasicBlock::iterator MI, unsigned SrcReg,
130                            bool isKill, int FrameIndex,
131                            const TargetRegisterClass *RC,
132                            const TargetRegisterInfo *TRI) const override;
133 
134   void loadRegFromStackSlot(MachineBasicBlock &MBB,
135                             MachineBasicBlock::iterator MI, unsigned DestReg,
136                             int FrameIndex, const TargetRegisterClass *RC,
137                             const TargetRegisterInfo *TRI) const override;
138 
139   bool expandPostRAPseudo(MachineInstr &MI) const override;
140 
141   // \brief Returns an opcode that can be used to move a value to a \p DstRC
142   // register.  If there is no hardware instruction that can store to \p
143   // DstRC, then AMDGPU::COPY is returned.
144   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
145 
146   LLVM_READONLY
147   int commuteOpcode(const MachineInstr &MI) const;
148 
149   bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
150                              unsigned &SrcOpIdx2) const override;
151 
152   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
153                      MachineBasicBlock *&FBB,
154                      SmallVectorImpl<MachineOperand> &Cond,
155                      bool AllowModify) const override;
156 
157   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
158 
159   unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
160                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
161                         const DebugLoc &DL) const override;
162 
163   bool ReverseBranchCondition(
164     SmallVectorImpl<MachineOperand> &Cond) const override;
165 
166   bool
167   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
168                                   AliasAnalysis *AA = nullptr) const override;
169 
170   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
171                      MachineRegisterInfo *MRI) const final;
172 
getMachineCSELookAheadLimit()173   unsigned getMachineCSELookAheadLimit() const override { return 500; }
174 
175   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
176                                       MachineInstr &MI,
177                                       LiveVariables *LV) const override;
178 
179   bool isSchedulingBoundary(const MachineInstr &MI,
180                             const MachineBasicBlock *MBB,
181                             const MachineFunction &MF) const override;
182 
isSALU(const MachineInstr & MI)183   static bool isSALU(const MachineInstr &MI) {
184     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
185   }
186 
isSALU(uint16_t Opcode)187   bool isSALU(uint16_t Opcode) const {
188     return get(Opcode).TSFlags & SIInstrFlags::SALU;
189   }
190 
isVALU(const MachineInstr & MI)191   static bool isVALU(const MachineInstr &MI) {
192     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
193   }
194 
isVALU(uint16_t Opcode)195   bool isVALU(uint16_t Opcode) const {
196     return get(Opcode).TSFlags & SIInstrFlags::VALU;
197   }
198 
isVMEM(const MachineInstr & MI)199   static bool isVMEM(const MachineInstr &MI) {
200     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
201   }
202 
isVMEM(uint16_t Opcode)203   bool isVMEM(uint16_t Opcode) const {
204     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
205   }
206 
isSOP1(const MachineInstr & MI)207   static bool isSOP1(const MachineInstr &MI) {
208     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
209   }
210 
isSOP1(uint16_t Opcode)211   bool isSOP1(uint16_t Opcode) const {
212     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
213   }
214 
isSOP2(const MachineInstr & MI)215   static bool isSOP2(const MachineInstr &MI) {
216     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
217   }
218 
isSOP2(uint16_t Opcode)219   bool isSOP2(uint16_t Opcode) const {
220     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
221   }
222 
isSOPC(const MachineInstr & MI)223   static bool isSOPC(const MachineInstr &MI) {
224     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
225   }
226 
isSOPC(uint16_t Opcode)227   bool isSOPC(uint16_t Opcode) const {
228     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
229   }
230 
isSOPK(const MachineInstr & MI)231   static bool isSOPK(const MachineInstr &MI) {
232     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
233   }
234 
isSOPK(uint16_t Opcode)235   bool isSOPK(uint16_t Opcode) const {
236     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
237   }
238 
isSOPP(const MachineInstr & MI)239   static bool isSOPP(const MachineInstr &MI) {
240     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
241   }
242 
isSOPP(uint16_t Opcode)243   bool isSOPP(uint16_t Opcode) const {
244     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
245   }
246 
isVOP1(const MachineInstr & MI)247   static bool isVOP1(const MachineInstr &MI) {
248     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
249   }
250 
isVOP1(uint16_t Opcode)251   bool isVOP1(uint16_t Opcode) const {
252     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
253   }
254 
isVOP2(const MachineInstr & MI)255   static bool isVOP2(const MachineInstr &MI) {
256     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
257   }
258 
isVOP2(uint16_t Opcode)259   bool isVOP2(uint16_t Opcode) const {
260     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
261   }
262 
isVOP3(const MachineInstr & MI)263   static bool isVOP3(const MachineInstr &MI) {
264     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
265   }
266 
isVOP3(uint16_t Opcode)267   bool isVOP3(uint16_t Opcode) const {
268     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
269   }
270 
isVOPC(const MachineInstr & MI)271   static bool isVOPC(const MachineInstr &MI) {
272     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
273   }
274 
isVOPC(uint16_t Opcode)275   bool isVOPC(uint16_t Opcode) const {
276     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
277   }
278 
isMUBUF(const MachineInstr & MI)279   static bool isMUBUF(const MachineInstr &MI) {
280     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
281   }
282 
isMUBUF(uint16_t Opcode)283   bool isMUBUF(uint16_t Opcode) const {
284     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
285   }
286 
isMTBUF(const MachineInstr & MI)287   static bool isMTBUF(const MachineInstr &MI) {
288     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
289   }
290 
isMTBUF(uint16_t Opcode)291   bool isMTBUF(uint16_t Opcode) const {
292     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
293   }
294 
isSMRD(const MachineInstr & MI)295   static bool isSMRD(const MachineInstr &MI) {
296     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
297   }
298 
isSMRD(uint16_t Opcode)299   bool isSMRD(uint16_t Opcode) const {
300     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
301   }
302 
isDS(const MachineInstr & MI)303   static bool isDS(const MachineInstr &MI) {
304     return MI.getDesc().TSFlags & SIInstrFlags::DS;
305   }
306 
isDS(uint16_t Opcode)307   bool isDS(uint16_t Opcode) const {
308     return get(Opcode).TSFlags & SIInstrFlags::DS;
309   }
310 
isMIMG(const MachineInstr & MI)311   static bool isMIMG(const MachineInstr &MI) {
312     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
313   }
314 
isMIMG(uint16_t Opcode)315   bool isMIMG(uint16_t Opcode) const {
316     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
317   }
318 
isGather4(const MachineInstr & MI)319   static bool isGather4(const MachineInstr &MI) {
320     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
321   }
322 
isGather4(uint16_t Opcode)323   bool isGather4(uint16_t Opcode) const {
324     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
325   }
326 
isFLAT(const MachineInstr & MI)327   static bool isFLAT(const MachineInstr &MI) {
328     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
329   }
330 
isFLAT(uint16_t Opcode)331   bool isFLAT(uint16_t Opcode) const {
332     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
333   }
334 
isWQM(const MachineInstr & MI)335   static bool isWQM(const MachineInstr &MI) {
336     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
337   }
338 
isWQM(uint16_t Opcode)339   bool isWQM(uint16_t Opcode) const {
340     return get(Opcode).TSFlags & SIInstrFlags::WQM;
341   }
342 
isVGPRSpill(const MachineInstr & MI)343   static bool isVGPRSpill(const MachineInstr &MI) {
344     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
345   }
346 
isVGPRSpill(uint16_t Opcode)347   bool isVGPRSpill(uint16_t Opcode) const {
348     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
349   }
350 
isDPP(const MachineInstr & MI)351   static bool isDPP(const MachineInstr &MI) {
352     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
353   }
354 
isDPP(uint16_t Opcode)355   bool isDPP(uint16_t Opcode) const {
356     return get(Opcode).TSFlags & SIInstrFlags::DPP;
357   }
358 
isScalarUnit(const MachineInstr & MI)359   static bool isScalarUnit(const MachineInstr &MI) {
360     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
361   }
362 
usesVM_CNT(const MachineInstr & MI)363   static bool usesVM_CNT(const MachineInstr &MI) {
364     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
365   }
366 
isVGPRCopy(const MachineInstr & MI)367   bool isVGPRCopy(const MachineInstr &MI) const {
368     assert(MI.isCopy());
369     unsigned Dest = MI.getOperand(0).getReg();
370     const MachineFunction &MF = *MI.getParent()->getParent();
371     const MachineRegisterInfo &MRI = MF.getRegInfo();
372     return !RI.isSGPRReg(MRI, Dest);
373   }
374 
375   bool isInlineConstant(const APInt &Imm) const;
376   bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
377   bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
378 
379   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
380                          const MachineOperand &MO) const;
381 
382   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
383   /// This function will return false if you pass it a 32-bit instruction.
384   bool hasVALU32BitEncoding(unsigned Opcode) const;
385 
386   /// \brief Returns true if this operand uses the constant bus.
387   bool usesConstantBus(const MachineRegisterInfo &MRI,
388                        const MachineOperand &MO,
389                        unsigned OpSize) const;
390 
391   /// \brief Return true if this instruction has any modifiers.
392   ///  e.g. src[012]_mod, omod, clamp.
393   bool hasModifiers(unsigned Opcode) const;
394 
395   bool hasModifiersSet(const MachineInstr &MI,
396                        unsigned OpName) const;
397 
398   bool verifyInstruction(const MachineInstr &MI,
399                          StringRef &ErrInfo) const override;
400 
401   static unsigned getVALUOp(const MachineInstr &MI);
402 
403   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
404 
405   /// \brief Return the correct register class for \p OpNo.  For target-specific
406   /// instructions, this will return the register class that has been defined
407   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
408   /// the register class of its machine operand.
409   /// to infer the correct register class base on the other operands.
410   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
411                                            unsigned OpNo) const;
412 
413   /// \brief Return the size in bytes of the operand OpNo on the given
414   // instruction opcode.
getOpSize(uint16_t Opcode,unsigned OpNo)415   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
416     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
417 
418     if (OpInfo.RegClass == -1) {
419       // If this is an immediate operand, this must be a 32-bit literal.
420       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
421       return 4;
422     }
423 
424     return RI.getRegClass(OpInfo.RegClass)->getSize();
425   }
426 
427   /// \brief This form should usually be preferred since it handles operands
428   /// with unknown register classes.
getOpSize(const MachineInstr & MI,unsigned OpNo)429   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
430     return getOpRegClass(MI, OpNo)->getSize();
431   }
432 
433   /// \returns true if it is legal for the operand at index \p OpNo
434   /// to read a VGPR.
435   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
436 
437   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
438   /// a MOV.  For example:
439   /// ADD_I32_e32 VGPR0, 15
440   /// to
441   /// MOV VGPR1, 15
442   /// ADD_I32_e32 VGPR0, VGPR1
443   ///
444   /// If the operand being legalized is a register, then a COPY will be used
445   /// instead of MOV.
446   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
447 
448   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
449   /// for \p MI.
450   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
451                       const MachineOperand *MO = nullptr) const;
452 
453   /// \brief Check if \p MO would be a valid operand for the given operand
454   /// definition \p OpInfo. Note this does not attempt to validate constant bus
455   /// restrictions (e.g. literal constant usage).
456   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
457                           const MCOperandInfo &OpInfo,
458                           const MachineOperand &MO) const;
459 
460   /// \brief Check if \p MO (a register operand) is a legal register for the
461   /// given operand description.
462   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
463                          const MCOperandInfo &OpInfo,
464                          const MachineOperand &MO) const;
465 
466   /// \brief Legalize operands in \p MI by either commuting it or inserting a
467   /// copy of src1.
468   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
469 
470   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
471   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
472 
473   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
474   /// be used when it is know that the value in SrcReg is same across all
475   /// threads in the wave.
476   /// \returns The SGPR register that \p SrcReg was copied to.
477   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
478                               MachineRegisterInfo &MRI) const;
479 
480   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
481 
482   /// \brief Legalize all operands in this instruction.  This function may
483   /// create new instruction and insert them before \p MI.
484   void legalizeOperands(MachineInstr &MI) const;
485 
486   /// \brief Replace this instruction's opcode with the equivalent VALU
487   /// opcode.  This function will also move the users of \p MI to the
488   /// VALU if necessary.
489   void moveToVALU(MachineInstr &MI) const;
490 
491   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
492                         int Count) const;
493 
494   void insertNoop(MachineBasicBlock &MBB,
495                   MachineBasicBlock::iterator MI) const override;
496 
497   /// \brief Return the number of wait states that result from executing this
498   /// instruction.
499   unsigned getNumWaitStates(const MachineInstr &MI) const;
500 
501   /// \brief Returns the operand named \p Op.  If \p MI does not have an
502   /// operand named \c Op, this function returns nullptr.
503   LLVM_READONLY
504   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
505 
506   LLVM_READONLY
getNamedOperand(const MachineInstr & MI,unsigned OpName)507   const MachineOperand *getNamedOperand(const MachineInstr &MI,
508                                         unsigned OpName) const {
509     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
510   }
511 
512   /// Get required immediate operand
getNamedImmOperand(const MachineInstr & MI,unsigned OpName)513   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
514     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
515     return MI.getOperand(Idx).getImm();
516   }
517 
518   uint64_t getDefaultRsrcDataFormat() const;
519   uint64_t getScratchRsrcWords23() const;
520 
521   bool isLowLatencyInstruction(const MachineInstr &MI) const;
522   bool isHighLatencyInstruction(const MachineInstr &MI) const;
523 
524   /// \brief Return the descriptor of the target-specific machine instruction
525   /// that corresponds to the specified pseudo or native opcode.
getMCOpcodeFromPseudo(unsigned Opcode)526   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
527     return get(pseudoToMCOpcode(Opcode));
528   }
529 
530   unsigned getInstSizeInBytes(const MachineInstr &MI) const;
531 
532   ArrayRef<std::pair<int, const char *>>
533   getSerializableTargetIndices() const override;
534 
535   ScheduleHazardRecognizer *
536   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
537                                  const ScheduleDAG *DAG) const override;
538 
539   ScheduleHazardRecognizer *
540   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
541 };
542 
543 namespace AMDGPU {
544   LLVM_READONLY
545   int getVOPe64(uint16_t Opcode);
546 
547   LLVM_READONLY
548   int getVOPe32(uint16_t Opcode);
549 
550   LLVM_READONLY
551   int getCommuteRev(uint16_t Opcode);
552 
553   LLVM_READONLY
554   int getCommuteOrig(uint16_t Opcode);
555 
556   LLVM_READONLY
557   int getAddr64Inst(uint16_t Opcode);
558 
559   LLVM_READONLY
560   int getAtomicRetOp(uint16_t Opcode);
561 
562   LLVM_READONLY
563   int getAtomicNoRetOp(uint16_t Opcode);
564 
565   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
566   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
567   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
568   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
569 } // End namespace AMDGPU
570 
571 namespace SI {
572 namespace KernelInputOffsets {
573 
574 /// Offsets in bytes from the start of the input buffer
575 enum Offsets {
576   NGROUPS_X = 0,
577   NGROUPS_Y = 4,
578   NGROUPS_Z = 8,
579   GLOBAL_SIZE_X = 12,
580   GLOBAL_SIZE_Y = 16,
581   GLOBAL_SIZE_Z = 20,
582   LOCAL_SIZE_X = 24,
583   LOCAL_SIZE_Y = 28,
584   LOCAL_SIZE_Z = 32
585 };
586 
587 } // End namespace KernelInputOffsets
588 } // End namespace SI
589 
590 } // End namespace llvm
591 
592 #endif
593