1 //===- SIInstrInfo.h - SI Instruction Info Interface ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Interface definition for SIInstrInfo.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
15 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
16 
17 #include "AMDGPUMIRFormatter.h"
18 #include "SIRegisterInfo.h"
19 #include "Utils/AMDGPUBaseInfo.h"
20 #include "llvm/ADT/SetVector.h"
21 #include "llvm/CodeGen/TargetInstrInfo.h"
22 #include "llvm/CodeGen/TargetSchedule.h"
23 
24 #define GET_INSTRINFO_HEADER
25 #include "AMDGPUGenInstrInfo.inc"
26 
27 namespace llvm {
28 
29 class APInt;
30 class GCNSubtarget;
31 class LiveVariables;
32 class MachineDominatorTree;
33 class MachineRegisterInfo;
34 class RegScavenger;
35 class TargetRegisterClass;
36 class ScheduleHazardRecognizer;
37 
38 /// Mark the MMO of a uniform load if there are no potentially clobbering stores
39 /// on any path from the start of an entry function to this load.
40 static const MachineMemOperand::Flags MONoClobber =
41     MachineMemOperand::MOTargetFlag1;
42 
43 class SIInstrInfo final : public AMDGPUGenInstrInfo {
44 private:
45   const SIRegisterInfo RI;
46   const GCNSubtarget &ST;
47   TargetSchedModel SchedModel;
48   mutable std::unique_ptr<AMDGPUMIRFormatter> Formatter;
49 
50   // The inverse predicate should have the negative value.
51   enum BranchPredicate {
52     INVALID_BR = 0,
53     SCC_TRUE = 1,
54     SCC_FALSE = -1,
55     VCCNZ = 2,
56     VCCZ = -2,
57     EXECNZ = -3,
58     EXECZ = 3
59   };
60 
61   using SetVectorType = SmallSetVector<MachineInstr *, 32>;
62 
63   static unsigned getBranchOpcode(BranchPredicate Cond);
64   static BranchPredicate getBranchPredicate(unsigned Opcode);
65 
66 public:
67   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
68                               MachineRegisterInfo &MRI,
69                               MachineOperand &SuperReg,
70                               const TargetRegisterClass *SuperRC,
71                               unsigned SubIdx,
72                               const TargetRegisterClass *SubRC) const;
73   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
74                                          MachineRegisterInfo &MRI,
75                                          MachineOperand &SuperReg,
76                                          const TargetRegisterClass *SuperRC,
77                                          unsigned SubIdx,
78                                          const TargetRegisterClass *SubRC) const;
79 private:
80   void swapOperands(MachineInstr &Inst) const;
81 
82   std::pair<bool, MachineBasicBlock *>
83   moveScalarAddSub(SetVectorType &Worklist, MachineInstr &Inst,
84                    MachineDominatorTree *MDT = nullptr) const;
85 
86   void lowerSelect(SetVectorType &Worklist, MachineInstr &Inst,
87                    MachineDominatorTree *MDT = nullptr) const;
88 
89   void lowerScalarAbs(SetVectorType &Worklist,
90                       MachineInstr &Inst) const;
91 
92   void lowerScalarXnor(SetVectorType &Worklist,
93                        MachineInstr &Inst) const;
94 
95   void splitScalarNotBinop(SetVectorType &Worklist,
96                            MachineInstr &Inst,
97                            unsigned Opcode) const;
98 
99   void splitScalarBinOpN2(SetVectorType &Worklist,
100                           MachineInstr &Inst,
101                           unsigned Opcode) const;
102 
103   void splitScalar64BitUnaryOp(SetVectorType &Worklist,
104                                MachineInstr &Inst, unsigned Opcode,
105                                bool Swap = false) const;
106 
107   void splitScalar64BitAddSub(SetVectorType &Worklist, MachineInstr &Inst,
108                               MachineDominatorTree *MDT = nullptr) const;
109 
110   void splitScalar64BitBinaryOp(SetVectorType &Worklist, MachineInstr &Inst,
111                                 unsigned Opcode,
112                                 MachineDominatorTree *MDT = nullptr) const;
113 
114   void splitScalar64BitXnor(SetVectorType &Worklist, MachineInstr &Inst,
115                                 MachineDominatorTree *MDT = nullptr) const;
116 
117   void splitScalar64BitBCNT(SetVectorType &Worklist,
118                             MachineInstr &Inst) const;
119   void splitScalar64BitBFE(SetVectorType &Worklist,
120                            MachineInstr &Inst) const;
121   void movePackToVALU(SetVectorType &Worklist,
122                       MachineRegisterInfo &MRI,
123                       MachineInstr &Inst) const;
124 
125   void addUsersToMoveToVALUWorklist(Register Reg, MachineRegisterInfo &MRI,
126                                     SetVectorType &Worklist) const;
127 
128   void addSCCDefUsersToVALUWorklist(MachineOperand &Op,
129                                     MachineInstr &SCCDefInst,
130                                     SetVectorType &Worklist,
131                                     Register NewCond = Register()) const;
132   void addSCCDefsToVALUWorklist(MachineOperand &Op,
133                                 SetVectorType &Worklist) const;
134 
135   const TargetRegisterClass *
136   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
137 
138   bool checkInstOffsetsDoNotOverlap(const MachineInstr &MIa,
139                                     const MachineInstr &MIb) const;
140 
141   Register findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
142 
143 protected:
144   bool swapSourceModifiers(MachineInstr &MI,
145                            MachineOperand &Src0, unsigned Src0OpName,
146                            MachineOperand &Src1, unsigned Src1OpName) const;
147 
148   MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
149                                        unsigned OpIdx0,
150                                        unsigned OpIdx1) const override;
151 
152 public:
153   enum TargetOperandFlags {
154     MO_MASK = 0xf,
155 
156     MO_NONE = 0,
157     // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
158     MO_GOTPCREL = 1,
159     // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
160     MO_GOTPCREL32 = 2,
161     MO_GOTPCREL32_LO = 2,
162     // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
163     MO_GOTPCREL32_HI = 3,
164     // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
165     MO_REL32 = 4,
166     MO_REL32_LO = 4,
167     // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
168     MO_REL32_HI = 5,
169 
170     MO_FAR_BRANCH_OFFSET = 6,
171 
172     MO_ABS32_LO = 8,
173     MO_ABS32_HI = 9,
174   };
175 
176   explicit SIInstrInfo(const GCNSubtarget &ST);
177 
178   const SIRegisterInfo &getRegisterInfo() const {
179     return RI;
180   }
181 
182   const GCNSubtarget &getSubtarget() const {
183     return ST;
184   }
185 
186   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
187                                          AAResults *AA) const override;
188 
189   bool isIgnorableUse(const MachineOperand &MO) const override;
190 
191   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
192                                int64_t &Offset1,
193                                int64_t &Offset2) const override;
194 
195   bool getMemOperandsWithOffsetWidth(
196       const MachineInstr &LdSt,
197       SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
198       bool &OffsetIsScalable, unsigned &Width,
199       const TargetRegisterInfo *TRI) const final;
200 
201   bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,
202                            ArrayRef<const MachineOperand *> BaseOps2,
203                            unsigned NumLoads, unsigned NumBytes) const override;
204 
205   bool shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1, int64_t Offset0,
206                                int64_t Offset1, unsigned NumLoads) const override;
207 
208   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
209                    const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
210                    bool KillSrc) const override;
211 
212   void materializeImmediate(MachineBasicBlock &MBB,
213                             MachineBasicBlock::iterator MI,
214                             const DebugLoc &DL,
215                             unsigned DestReg,
216                             int64_t Value) const;
217 
218   const TargetRegisterClass *getPreferredSelectRegClass(
219                                unsigned Size) const;
220 
221   Register insertNE(MachineBasicBlock *MBB,
222                     MachineBasicBlock::iterator I, const DebugLoc &DL,
223                     Register SrcReg, int Value) const;
224 
225   Register insertEQ(MachineBasicBlock *MBB,
226                     MachineBasicBlock::iterator I, const DebugLoc &DL,
227                     Register SrcReg, int Value)  const;
228 
229   void storeRegToStackSlot(MachineBasicBlock &MBB,
230                            MachineBasicBlock::iterator MI, Register SrcReg,
231                            bool isKill, int FrameIndex,
232                            const TargetRegisterClass *RC,
233                            const TargetRegisterInfo *TRI) const override;
234 
235   void loadRegFromStackSlot(MachineBasicBlock &MBB,
236                             MachineBasicBlock::iterator MI, Register DestReg,
237                             int FrameIndex, const TargetRegisterClass *RC,
238                             const TargetRegisterInfo *TRI) const override;
239 
240   bool expandPostRAPseudo(MachineInstr &MI) const override;
241 
242   // Splits a V_MOV_B64_DPP_PSEUDO opcode into a pair of v_mov_b32_dpp
243   // instructions. Returns a pair of generated instructions.
244   // Can split either post-RA with physical registers or pre-RA with
245   // virtual registers. In latter case IR needs to be in SSA form and
246   // and a REG_SEQUENCE is produced to define original register.
247   std::pair<MachineInstr*, MachineInstr*>
248   expandMovDPP64(MachineInstr &MI) const;
249 
250   // Returns an opcode that can be used to move a value to a \p DstRC
251   // register.  If there is no hardware instruction that can store to \p
252   // DstRC, then AMDGPU::COPY is returned.
253   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
254 
255   const MCInstrDesc &getIndirectRegWriteMovRelPseudo(unsigned VecSize,
256                                                      unsigned EltSize,
257                                                      bool IsSGPR) const;
258 
259   const MCInstrDesc &getIndirectGPRIDXPseudo(unsigned VecSize,
260                                              bool IsIndirectSrc) const;
261   LLVM_READONLY
262   int commuteOpcode(unsigned Opc) const;
263 
264   LLVM_READONLY
265   inline int commuteOpcode(const MachineInstr &MI) const {
266     return commuteOpcode(MI.getOpcode());
267   }
268 
269   bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
270                              unsigned &SrcOpIdx2) const override;
271 
272   bool findCommutedOpIndices(MCInstrDesc Desc, unsigned & SrcOpIdx0,
273    unsigned & SrcOpIdx1) const;
274 
275   bool isBranchOffsetInRange(unsigned BranchOpc,
276                              int64_t BrOffset) const override;
277 
278   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
279 
280   void insertIndirectBranch(MachineBasicBlock &MBB,
281                             MachineBasicBlock &NewDestBB,
282                             MachineBasicBlock &RestoreBB, const DebugLoc &DL,
283                             int64_t BrOffset, RegScavenger *RS) const override;
284 
285   bool analyzeBranchImpl(MachineBasicBlock &MBB,
286                          MachineBasicBlock::iterator I,
287                          MachineBasicBlock *&TBB,
288                          MachineBasicBlock *&FBB,
289                          SmallVectorImpl<MachineOperand> &Cond,
290                          bool AllowModify) const;
291 
292   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
293                      MachineBasicBlock *&FBB,
294                      SmallVectorImpl<MachineOperand> &Cond,
295                      bool AllowModify = false) const override;
296 
297   unsigned removeBranch(MachineBasicBlock &MBB,
298                         int *BytesRemoved = nullptr) const override;
299 
300   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
301                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
302                         const DebugLoc &DL,
303                         int *BytesAdded = nullptr) const override;
304 
305   bool reverseBranchCondition(
306     SmallVectorImpl<MachineOperand> &Cond) const override;
307 
308   bool canInsertSelect(const MachineBasicBlock &MBB,
309                        ArrayRef<MachineOperand> Cond, Register DstReg,
310                        Register TrueReg, Register FalseReg, int &CondCycles,
311                        int &TrueCycles, int &FalseCycles) const override;
312 
313   void insertSelect(MachineBasicBlock &MBB,
314                     MachineBasicBlock::iterator I, const DebugLoc &DL,
315                     Register DstReg, ArrayRef<MachineOperand> Cond,
316                     Register TrueReg, Register FalseReg) const override;
317 
318   void insertVectorSelect(MachineBasicBlock &MBB,
319                           MachineBasicBlock::iterator I, const DebugLoc &DL,
320                           Register DstReg, ArrayRef<MachineOperand> Cond,
321                           Register TrueReg, Register FalseReg) const;
322 
323   bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
324                       Register &SrcReg2, int64_t &CmpMask,
325                       int64_t &CmpValue) const override;
326 
327   bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
328                             Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
329                             const MachineRegisterInfo *MRI) const override;
330 
331   unsigned getAddressSpaceForPseudoSourceKind(
332              unsigned Kind) const override;
333 
334   bool
335   areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
336                                   const MachineInstr &MIb) const override;
337 
338   static bool isFoldableCopy(const MachineInstr &MI);
339 
340   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,
341                      MachineRegisterInfo *MRI) const final;
342 
343   unsigned getMachineCSELookAheadLimit() const override { return 500; }
344 
345   MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,
346                                       LiveIntervals *LIS) const override;
347 
348   bool isSchedulingBoundary(const MachineInstr &MI,
349                             const MachineBasicBlock *MBB,
350                             const MachineFunction &MF) const override;
351 
352   static bool isSALU(const MachineInstr &MI) {
353     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
354   }
355 
356   bool isSALU(uint16_t Opcode) const {
357     return get(Opcode).TSFlags & SIInstrFlags::SALU;
358   }
359 
360   static bool isVALU(const MachineInstr &MI) {
361     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
362   }
363 
364   bool isVALU(uint16_t Opcode) const {
365     return get(Opcode).TSFlags & SIInstrFlags::VALU;
366   }
367 
368   static bool isVMEM(const MachineInstr &MI) {
369     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
370   }
371 
372   bool isVMEM(uint16_t Opcode) const {
373     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
374   }
375 
376   static bool isSOP1(const MachineInstr &MI) {
377     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
378   }
379 
380   bool isSOP1(uint16_t Opcode) const {
381     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
382   }
383 
384   static bool isSOP2(const MachineInstr &MI) {
385     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
386   }
387 
388   bool isSOP2(uint16_t Opcode) const {
389     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
390   }
391 
392   static bool isSOPC(const MachineInstr &MI) {
393     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
394   }
395 
396   bool isSOPC(uint16_t Opcode) const {
397     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
398   }
399 
400   static bool isSOPK(const MachineInstr &MI) {
401     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
402   }
403 
404   bool isSOPK(uint16_t Opcode) const {
405     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
406   }
407 
408   static bool isSOPP(const MachineInstr &MI) {
409     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
410   }
411 
412   bool isSOPP(uint16_t Opcode) const {
413     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
414   }
415 
416   static bool isPacked(const MachineInstr &MI) {
417     return MI.getDesc().TSFlags & SIInstrFlags::IsPacked;
418   }
419 
420   bool isPacked(uint16_t Opcode) const {
421     return get(Opcode).TSFlags & SIInstrFlags::IsPacked;
422   }
423 
424   static bool isVOP1(const MachineInstr &MI) {
425     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
426   }
427 
428   bool isVOP1(uint16_t Opcode) const {
429     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
430   }
431 
432   static bool isVOP2(const MachineInstr &MI) {
433     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
434   }
435 
436   bool isVOP2(uint16_t Opcode) const {
437     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
438   }
439 
440   static bool isVOP3(const MachineInstr &MI) {
441     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
442   }
443 
444   bool isVOP3(uint16_t Opcode) const {
445     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
446   }
447 
448   static bool isSDWA(const MachineInstr &MI) {
449     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
450   }
451 
452   bool isSDWA(uint16_t Opcode) const {
453     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
454   }
455 
456   static bool isVOPC(const MachineInstr &MI) {
457     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
458   }
459 
460   bool isVOPC(uint16_t Opcode) const {
461     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
462   }
463 
464   static bool isMUBUF(const MachineInstr &MI) {
465     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
466   }
467 
468   bool isMUBUF(uint16_t Opcode) const {
469     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
470   }
471 
472   static bool isMTBUF(const MachineInstr &MI) {
473     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
474   }
475 
476   bool isMTBUF(uint16_t Opcode) const {
477     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
478   }
479 
480   static bool isSMRD(const MachineInstr &MI) {
481     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
482   }
483 
484   bool isSMRD(uint16_t Opcode) const {
485     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
486   }
487 
488   bool isBufferSMRD(const MachineInstr &MI) const;
489 
490   static bool isDS(const MachineInstr &MI) {
491     return MI.getDesc().TSFlags & SIInstrFlags::DS;
492   }
493 
494   bool isDS(uint16_t Opcode) const {
495     return get(Opcode).TSFlags & SIInstrFlags::DS;
496   }
497 
498   bool isAlwaysGDS(uint16_t Opcode) const;
499 
500   static bool isMIMG(const MachineInstr &MI) {
501     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
502   }
503 
504   bool isMIMG(uint16_t Opcode) const {
505     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
506   }
507 
508   static bool isGather4(const MachineInstr &MI) {
509     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
510   }
511 
512   bool isGather4(uint16_t Opcode) const {
513     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
514   }
515 
516   static bool isFLAT(const MachineInstr &MI) {
517     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
518   }
519 
520   // Is a FLAT encoded instruction which accesses a specific segment,
521   // i.e. global_* or scratch_*.
522   static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
523     auto Flags = MI.getDesc().TSFlags;
524     return Flags & (SIInstrFlags::FlatGlobal | SIInstrFlags::FlatScratch);
525   }
526 
527   bool isSegmentSpecificFLAT(uint16_t Opcode) const {
528     auto Flags = get(Opcode).TSFlags;
529     return Flags & (SIInstrFlags::FlatGlobal | SIInstrFlags::FlatScratch);
530   }
531 
532   static bool isFLATGlobal(const MachineInstr &MI) {
533     return MI.getDesc().TSFlags & SIInstrFlags::FlatGlobal;
534   }
535 
536   bool isFLATGlobal(uint16_t Opcode) const {
537     return get(Opcode).TSFlags & SIInstrFlags::FlatGlobal;
538   }
539 
540   static bool isFLATScratch(const MachineInstr &MI) {
541     return MI.getDesc().TSFlags & SIInstrFlags::FlatScratch;
542   }
543 
544   bool isFLATScratch(uint16_t Opcode) const {
545     return get(Opcode).TSFlags & SIInstrFlags::FlatScratch;
546   }
547 
548   // Any FLAT encoded instruction, including global_* and scratch_*.
549   bool isFLAT(uint16_t Opcode) const {
550     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
551   }
552 
553   static bool isEXP(const MachineInstr &MI) {
554     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
555   }
556 
557   bool isEXP(uint16_t Opcode) const {
558     return get(Opcode).TSFlags & SIInstrFlags::EXP;
559   }
560 
561   static bool isAtomicNoRet(const MachineInstr &MI) {
562     return MI.getDesc().TSFlags & SIInstrFlags::IsAtomicNoRet;
563   }
564 
565   bool isAtomicNoRet(uint16_t Opcode) const {
566     return get(Opcode).TSFlags & SIInstrFlags::IsAtomicNoRet;
567   }
568 
569   static bool isAtomicRet(const MachineInstr &MI) {
570     return MI.getDesc().TSFlags & SIInstrFlags::IsAtomicRet;
571   }
572 
573   bool isAtomicRet(uint16_t Opcode) const {
574     return get(Opcode).TSFlags & SIInstrFlags::IsAtomicRet;
575   }
576 
577   static bool isAtomic(const MachineInstr &MI) {
578     return MI.getDesc().TSFlags & (SIInstrFlags::IsAtomicRet |
579                                    SIInstrFlags::IsAtomicNoRet);
580   }
581 
582   bool isAtomic(uint16_t Opcode) const {
583     return get(Opcode).TSFlags & (SIInstrFlags::IsAtomicRet |
584                                   SIInstrFlags::IsAtomicNoRet);
585   }
586 
587   static bool isWQM(const MachineInstr &MI) {
588     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
589   }
590 
591   bool isWQM(uint16_t Opcode) const {
592     return get(Opcode).TSFlags & SIInstrFlags::WQM;
593   }
594 
595   static bool isDisableWQM(const MachineInstr &MI) {
596     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
597   }
598 
599   bool isDisableWQM(uint16_t Opcode) const {
600     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
601   }
602 
603   static bool isVGPRSpill(const MachineInstr &MI) {
604     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
605   }
606 
607   bool isVGPRSpill(uint16_t Opcode) const {
608     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
609   }
610 
611   static bool isSGPRSpill(const MachineInstr &MI) {
612     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
613   }
614 
615   bool isSGPRSpill(uint16_t Opcode) const {
616     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
617   }
618 
619   static bool isDPP(const MachineInstr &MI) {
620     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
621   }
622 
623   bool isDPP(uint16_t Opcode) const {
624     return get(Opcode).TSFlags & SIInstrFlags::DPP;
625   }
626 
627   static bool isTRANS(const MachineInstr &MI) {
628     return MI.getDesc().TSFlags & SIInstrFlags::TRANS;
629   }
630 
631   bool isTRANS(uint16_t Opcode) const {
632     return get(Opcode).TSFlags & SIInstrFlags::TRANS;
633   }
634 
635   static bool isVOP3P(const MachineInstr &MI) {
636     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
637   }
638 
639   bool isVOP3P(uint16_t Opcode) const {
640     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
641   }
642 
643   static bool isVINTRP(const MachineInstr &MI) {
644     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
645   }
646 
647   bool isVINTRP(uint16_t Opcode) const {
648     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
649   }
650 
651   static bool isMAI(const MachineInstr &MI) {
652     return MI.getDesc().TSFlags & SIInstrFlags::IsMAI;
653   }
654 
655   bool isMAI(uint16_t Opcode) const {
656     return get(Opcode).TSFlags & SIInstrFlags::IsMAI;
657   }
658 
659   static bool isDOT(const MachineInstr &MI) {
660     return MI.getDesc().TSFlags & SIInstrFlags::IsDOT;
661   }
662 
663   bool isDOT(uint16_t Opcode) const {
664     return get(Opcode).TSFlags & SIInstrFlags::IsDOT;
665   }
666 
667   static bool isScalarUnit(const MachineInstr &MI) {
668     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
669   }
670 
671   static bool usesVM_CNT(const MachineInstr &MI) {
672     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
673   }
674 
675   static bool usesLGKM_CNT(const MachineInstr &MI) {
676     return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
677   }
678 
679   static bool sopkIsZext(const MachineInstr &MI) {
680     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
681   }
682 
683   bool sopkIsZext(uint16_t Opcode) const {
684     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
685   }
686 
687   /// \returns true if this is an s_store_dword* instruction. This is more
688   /// specific than than isSMEM && mayStore.
689   static bool isScalarStore(const MachineInstr &MI) {
690     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
691   }
692 
693   bool isScalarStore(uint16_t Opcode) const {
694     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
695   }
696 
697   static bool isFixedSize(const MachineInstr &MI) {
698     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
699   }
700 
701   bool isFixedSize(uint16_t Opcode) const {
702     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
703   }
704 
705   static bool hasFPClamp(const MachineInstr &MI) {
706     return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
707   }
708 
709   bool hasFPClamp(uint16_t Opcode) const {
710     return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
711   }
712 
713   static bool hasIntClamp(const MachineInstr &MI) {
714     return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
715   }
716 
717   uint64_t getClampMask(const MachineInstr &MI) const {
718     const uint64_t ClampFlags = SIInstrFlags::FPClamp |
719                                 SIInstrFlags::IntClamp |
720                                 SIInstrFlags::ClampLo |
721                                 SIInstrFlags::ClampHi;
722       return MI.getDesc().TSFlags & ClampFlags;
723   }
724 
725   static bool usesFPDPRounding(const MachineInstr &MI) {
726     return MI.getDesc().TSFlags & SIInstrFlags::FPDPRounding;
727   }
728 
729   bool usesFPDPRounding(uint16_t Opcode) const {
730     return get(Opcode).TSFlags & SIInstrFlags::FPDPRounding;
731   }
732 
733   static bool isFPAtomic(const MachineInstr &MI) {
734     return MI.getDesc().TSFlags & SIInstrFlags::FPAtomic;
735   }
736 
737   bool isFPAtomic(uint16_t Opcode) const {
738     return get(Opcode).TSFlags & SIInstrFlags::FPAtomic;
739   }
740 
741   bool isVGPRCopy(const MachineInstr &MI) const {
742     assert(MI.isCopy());
743     Register Dest = MI.getOperand(0).getReg();
744     const MachineFunction &MF = *MI.getParent()->getParent();
745     const MachineRegisterInfo &MRI = MF.getRegInfo();
746     return !RI.isSGPRReg(MRI, Dest);
747   }
748 
749   bool hasVGPRUses(const MachineInstr &MI) const {
750     const MachineFunction &MF = *MI.getParent()->getParent();
751     const MachineRegisterInfo &MRI = MF.getRegInfo();
752     return llvm::any_of(MI.explicit_uses(),
753                         [&MRI, this](const MachineOperand &MO) {
754       return MO.isReg() && RI.isVGPR(MRI, MO.getReg());});
755   }
756 
757   /// Return true if the instruction modifies the mode register.q
758   static bool modifiesModeRegister(const MachineInstr &MI);
759 
760   /// Whether we must prevent this instruction from executing with EXEC = 0.
761   bool hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const;
762 
763   /// Returns true if the instruction could potentially depend on the value of
764   /// exec. If false, exec dependencies may safely be ignored.
765   bool mayReadEXEC(const MachineRegisterInfo &MRI, const MachineInstr &MI) const;
766 
767   bool isInlineConstant(const APInt &Imm) const;
768 
769   bool isInlineConstant(const APFloat &Imm) const {
770     return isInlineConstant(Imm.bitcastToAPInt());
771   }
772 
773   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
774 
775   bool isInlineConstant(const MachineOperand &MO,
776                         const MCOperandInfo &OpInfo) const {
777     return isInlineConstant(MO, OpInfo.OperandType);
778   }
779 
780   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
781   /// be an inline immediate.
782   bool isInlineConstant(const MachineInstr &MI,
783                         const MachineOperand &UseMO,
784                         const MachineOperand &DefMO) const {
785     assert(UseMO.getParent() == &MI);
786     int OpIdx = MI.getOperandNo(&UseMO);
787     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
788       return false;
789     }
790 
791     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
792   }
793 
794   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
795   /// immediate.
796   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
797     const MachineOperand &MO = MI.getOperand(OpIdx);
798     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
799   }
800 
801   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
802                         const MachineOperand &MO) const {
803     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
804       return false;
805 
806     if (MI.isCopy()) {
807       unsigned Size = getOpSize(MI, OpIdx);
808       assert(Size == 8 || Size == 4);
809 
810       uint8_t OpType = (Size == 8) ?
811         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
812       return isInlineConstant(MO, OpType);
813     }
814 
815     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
816   }
817 
818   bool isInlineConstant(const MachineOperand &MO) const {
819     const MachineInstr *Parent = MO.getParent();
820     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
821   }
822 
823   bool isLiteralConstant(const MachineOperand &MO,
824                          const MCOperandInfo &OpInfo) const {
825     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
826   }
827 
828   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
829     const MachineOperand &MO = MI.getOperand(OpIdx);
830     return MO.isImm() && !isInlineConstant(MI, OpIdx);
831   }
832 
833   // Returns true if this operand could potentially require a 32-bit literal
834   // operand, but not necessarily. A FrameIndex for example could resolve to an
835   // inline immediate value that will not require an additional 4-bytes; this
836   // assumes that it will.
837   bool isLiteralConstantLike(const MachineOperand &MO,
838                              const MCOperandInfo &OpInfo) const;
839 
840   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
841                          const MachineOperand &MO) const;
842 
843   /// Return true if this 64-bit VALU instruction has a 32-bit encoding.
844   /// This function will return false if you pass it a 32-bit instruction.
845   bool hasVALU32BitEncoding(unsigned Opcode) const;
846 
847   /// Returns true if this operand uses the constant bus.
848   bool usesConstantBus(const MachineRegisterInfo &MRI,
849                        const MachineOperand &MO,
850                        const MCOperandInfo &OpInfo) const;
851 
852   /// Return true if this instruction has any modifiers.
853   ///  e.g. src[012]_mod, omod, clamp.
854   bool hasModifiers(unsigned Opcode) const;
855 
856   bool hasModifiersSet(const MachineInstr &MI,
857                        unsigned OpName) const;
858   bool hasAnyModifiersSet(const MachineInstr &MI) const;
859 
860   bool canShrink(const MachineInstr &MI,
861                  const MachineRegisterInfo &MRI) const;
862 
863   MachineInstr *buildShrunkInst(MachineInstr &MI,
864                                 unsigned NewOpcode) const;
865 
866   bool verifyInstruction(const MachineInstr &MI,
867                          StringRef &ErrInfo) const override;
868 
869   unsigned getVALUOp(const MachineInstr &MI) const;
870 
871   /// Return the correct register class for \p OpNo.  For target-specific
872   /// instructions, this will return the register class that has been defined
873   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
874   /// the register class of its machine operand.
875   /// to infer the correct register class base on the other operands.
876   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
877                                            unsigned OpNo) const;
878 
879   /// Return the size in bytes of the operand OpNo on the given
880   // instruction opcode.
881   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
882     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
883 
884     if (OpInfo.RegClass == -1) {
885       // If this is an immediate operand, this must be a 32-bit literal.
886       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
887       return 4;
888     }
889 
890     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
891   }
892 
893   /// This form should usually be preferred since it handles operands
894   /// with unknown register classes.
895   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
896     const MachineOperand &MO = MI.getOperand(OpNo);
897     if (MO.isReg()) {
898       if (unsigned SubReg = MO.getSubReg()) {
899         return RI.getSubRegIdxSize(SubReg) / 8;
900       }
901     }
902     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
903   }
904 
905   /// Legalize the \p OpIndex operand of this instruction by inserting
906   /// a MOV.  For example:
907   /// ADD_I32_e32 VGPR0, 15
908   /// to
909   /// MOV VGPR1, 15
910   /// ADD_I32_e32 VGPR0, VGPR1
911   ///
912   /// If the operand being legalized is a register, then a COPY will be used
913   /// instead of MOV.
914   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
915 
916   /// Check if \p MO is a legal operand if it was the \p OpIdx Operand
917   /// for \p MI.
918   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
919                       const MachineOperand *MO = nullptr) const;
920 
921   /// Check if \p MO would be a valid operand for the given operand
922   /// definition \p OpInfo. Note this does not attempt to validate constant bus
923   /// restrictions (e.g. literal constant usage).
924   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
925                           const MCOperandInfo &OpInfo,
926                           const MachineOperand &MO) const;
927 
928   /// Check if \p MO (a register operand) is a legal register for the
929   /// given operand description.
930   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
931                          const MCOperandInfo &OpInfo,
932                          const MachineOperand &MO) const;
933 
934   /// Legalize operands in \p MI by either commuting it or inserting a
935   /// copy of src1.
936   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
937 
938   /// Fix operands in \p MI to satisfy constant bus requirements.
939   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
940 
941   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
942   /// be used when it is know that the value in SrcReg is same across all
943   /// threads in the wave.
944   /// \returns The SGPR register that \p SrcReg was copied to.
945   Register readlaneVGPRToSGPR(Register SrcReg, MachineInstr &UseMI,
946                               MachineRegisterInfo &MRI) const;
947 
948   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
949   void legalizeOperandsFLAT(MachineRegisterInfo &MRI, MachineInstr &MI) const;
950 
951   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
952                               MachineBasicBlock::iterator I,
953                               const TargetRegisterClass *DstRC,
954                               MachineOperand &Op, MachineRegisterInfo &MRI,
955                               const DebugLoc &DL) const;
956 
957   /// Legalize all operands in this instruction.  This function may create new
958   /// instructions and control-flow around \p MI.  If present, \p MDT is
959   /// updated.
960   /// \returns A new basic block that contains \p MI if new blocks were created.
961   MachineBasicBlock *
962   legalizeOperands(MachineInstr &MI, MachineDominatorTree *MDT = nullptr) const;
963 
964   /// Change SADDR form of a FLAT \p Inst to its VADDR form if saddr operand
965   /// was moved to VGPR. \returns true if succeeded.
966   bool moveFlatAddrToVGPR(MachineInstr &Inst) const;
967 
968   /// Replace this instruction's opcode with the equivalent VALU
969   /// opcode.  This function will also move the users of \p MI to the
970   /// VALU if necessary. If present, \p MDT is updated.
971   MachineBasicBlock *moveToVALU(MachineInstr &MI,
972                                 MachineDominatorTree *MDT = nullptr) const;
973 
974   void insertNoop(MachineBasicBlock &MBB,
975                   MachineBasicBlock::iterator MI) const override;
976 
977   void insertNoops(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
978                    unsigned Quantity) const override;
979 
980   void insertReturn(MachineBasicBlock &MBB) const;
981   /// Return the number of wait states that result from executing this
982   /// instruction.
983   static unsigned getNumWaitStates(const MachineInstr &MI);
984 
985   /// Returns the operand named \p Op.  If \p MI does not have an
986   /// operand named \c Op, this function returns nullptr.
987   LLVM_READONLY
988   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
989 
990   LLVM_READONLY
991   const MachineOperand *getNamedOperand(const MachineInstr &MI,
992                                         unsigned OpName) const {
993     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
994   }
995 
996   /// Get required immediate operand
997   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
998     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
999     return MI.getOperand(Idx).getImm();
1000   }
1001 
1002   uint64_t getDefaultRsrcDataFormat() const;
1003   uint64_t getScratchRsrcWords23() const;
1004 
1005   bool isLowLatencyInstruction(const MachineInstr &MI) const;
1006   bool isHighLatencyDef(int Opc) const override;
1007 
1008   /// Return the descriptor of the target-specific machine instruction
1009   /// that corresponds to the specified pseudo or native opcode.
1010   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
1011     return get(pseudoToMCOpcode(Opcode));
1012   }
1013 
1014   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
1015   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
1016 
1017   unsigned isLoadFromStackSlot(const MachineInstr &MI,
1018                                int &FrameIndex) const override;
1019   unsigned isStoreToStackSlot(const MachineInstr &MI,
1020                               int &FrameIndex) const override;
1021 
1022   unsigned getInstBundleSize(const MachineInstr &MI) const;
1023   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
1024 
1025   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
1026 
1027   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
1028 
1029   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
1030                                  MachineBasicBlock *IfEnd) const;
1031 
1032   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
1033                                    MachineBasicBlock *LoopEnd) const;
1034 
1035   std::pair<unsigned, unsigned>
1036   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
1037 
1038   ArrayRef<std::pair<int, const char *>>
1039   getSerializableTargetIndices() const override;
1040 
1041   ArrayRef<std::pair<unsigned, const char *>>
1042   getSerializableDirectMachineOperandTargetFlags() const override;
1043 
1044   ArrayRef<std::pair<MachineMemOperand::Flags, const char *>>
1045   getSerializableMachineMemOperandTargetFlags() const override;
1046 
1047   ScheduleHazardRecognizer *
1048   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
1049                                  const ScheduleDAG *DAG) const override;
1050 
1051   ScheduleHazardRecognizer *
1052   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
1053 
1054   ScheduleHazardRecognizer *
1055   CreateTargetMIHazardRecognizer(const InstrItineraryData *II,
1056                                  const ScheduleDAGMI *DAG) const override;
1057 
1058   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
1059 
1060   MachineInstr *createPHIDestinationCopy(MachineBasicBlock &MBB,
1061                                          MachineBasicBlock::iterator InsPt,
1062                                          const DebugLoc &DL, Register Src,
1063                                          Register Dst) const override;
1064 
1065   MachineInstr *createPHISourceCopy(MachineBasicBlock &MBB,
1066                                     MachineBasicBlock::iterator InsPt,
1067                                     const DebugLoc &DL, Register Src,
1068                                     unsigned SrcSubReg,
1069                                     Register Dst) const override;
1070 
1071   bool isWave32() const;
1072 
1073   /// Return a partially built integer add instruction without carry.
1074   /// Caller must add source operands.
1075   /// For pre-GFX9 it will generate unused carry destination operand.
1076   /// TODO: After GFX9 it should return a no-carry operation.
1077   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
1078                                     MachineBasicBlock::iterator I,
1079                                     const DebugLoc &DL,
1080                                     Register DestReg) const;
1081 
1082   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
1083                                     MachineBasicBlock::iterator I,
1084                                     const DebugLoc &DL,
1085                                     Register DestReg,
1086                                     RegScavenger &RS) const;
1087 
1088   static bool isKillTerminator(unsigned Opcode);
1089   const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
1090 
1091   static bool isLegalMUBUFImmOffset(unsigned Imm) {
1092     return isUInt<12>(Imm);
1093   }
1094 
1095   /// Returns if \p Offset is legal for the subtarget as the offset to a FLAT
1096   /// encoded instruction. If \p Signed, this is for an instruction that
1097   /// interprets the offset as signed.
1098   bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
1099                          uint64_t FlatVariant) const;
1100 
1101   /// Split \p COffsetVal into {immediate offset field, remainder offset}
1102   /// values.
1103   std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal,
1104                                               unsigned AddrSpace,
1105                                               uint64_t FlatVariant) const;
1106 
1107   /// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
1108   /// Return -1 if the target-specific opcode for the pseudo instruction does
1109   /// not exist. If Opcode is not a pseudo instruction, this is identity.
1110   int pseudoToMCOpcode(int Opcode) const;
1111 
1112   /// \brief Check if this instruction should only be used by assembler.
1113   /// Return true if this opcode should not be used by codegen.
1114   bool isAsmOnlyOpcode(int MCOp) const;
1115 
1116   const TargetRegisterClass *getRegClass(const MCInstrDesc &TID, unsigned OpNum,
1117                                          const TargetRegisterInfo *TRI,
1118                                          const MachineFunction &MF)
1119     const override;
1120 
1121   void fixImplicitOperands(MachineInstr &MI) const;
1122 
1123   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
1124                                       ArrayRef<unsigned> Ops,
1125                                       MachineBasicBlock::iterator InsertPt,
1126                                       int FrameIndex,
1127                                       LiveIntervals *LIS = nullptr,
1128                                       VirtRegMap *VRM = nullptr) const override;
1129 
1130   unsigned getInstrLatency(const InstrItineraryData *ItinData,
1131                            const MachineInstr &MI,
1132                            unsigned *PredCost = nullptr) const override;
1133 
1134   const MIRFormatter *getMIRFormatter() const override {
1135     if (!Formatter.get())
1136       Formatter = std::make_unique<AMDGPUMIRFormatter>();
1137     return Formatter.get();
1138   }
1139 
1140   static unsigned getDSShaderTypeValue(const MachineFunction &MF);
1141 
1142   const TargetSchedModel &getSchedModel() const { return SchedModel; }
1143 };
1144 
1145 /// \brief Returns true if a reg:subreg pair P has a TRC class
1146 inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P,
1147                          const TargetRegisterClass &TRC,
1148                          MachineRegisterInfo &MRI) {
1149   auto *RC = MRI.getRegClass(P.Reg);
1150   if (!P.SubReg)
1151     return RC == &TRC;
1152   auto *TRI = MRI.getTargetRegisterInfo();
1153   return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg);
1154 }
1155 
1156 /// \brief Create RegSubRegPair from a register MachineOperand
1157 inline
1158 TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O) {
1159   assert(O.isReg());
1160   return TargetInstrInfo::RegSubRegPair(O.getReg(), O.getSubReg());
1161 }
1162 
1163 /// \brief Return the SubReg component from REG_SEQUENCE
1164 TargetInstrInfo::RegSubRegPair getRegSequenceSubReg(MachineInstr &MI,
1165                                                     unsigned SubReg);
1166 
1167 /// \brief Return the defining instruction for a given reg:subreg pair
1168 /// skipping copy like instructions and subreg-manipulation pseudos.
1169 /// Following another subreg of a reg:subreg isn't supported.
1170 MachineInstr *getVRegSubRegDef(const TargetInstrInfo::RegSubRegPair &P,
1171                                MachineRegisterInfo &MRI);
1172 
1173 /// \brief Return false if EXEC is not changed between the def of \p VReg at \p
1174 /// DefMI and the use at \p UseMI. Should be run on SSA. Currently does not
1175 /// attempt to track between blocks.
1176 bool execMayBeModifiedBeforeUse(const MachineRegisterInfo &MRI,
1177                                 Register VReg,
1178                                 const MachineInstr &DefMI,
1179                                 const MachineInstr &UseMI);
1180 
1181 /// \brief Return false if EXEC is not changed between the def of \p VReg at \p
1182 /// DefMI and all its uses. Should be run on SSA. Currently does not attempt to
1183 /// track between blocks.
1184 bool execMayBeModifiedBeforeAnyUse(const MachineRegisterInfo &MRI,
1185                                    Register VReg,
1186                                    const MachineInstr &DefMI);
1187 
1188 namespace AMDGPU {
1189 
1190   LLVM_READONLY
1191   int getVOPe64(uint16_t Opcode);
1192 
1193   LLVM_READONLY
1194   int getVOPe32(uint16_t Opcode);
1195 
1196   LLVM_READONLY
1197   int getSDWAOp(uint16_t Opcode);
1198 
1199   LLVM_READONLY
1200   int getDPPOp32(uint16_t Opcode);
1201 
1202   LLVM_READONLY
1203   int getBasicFromSDWAOp(uint16_t Opcode);
1204 
1205   LLVM_READONLY
1206   int getCommuteRev(uint16_t Opcode);
1207 
1208   LLVM_READONLY
1209   int getCommuteOrig(uint16_t Opcode);
1210 
1211   LLVM_READONLY
1212   int getAddr64Inst(uint16_t Opcode);
1213 
1214   /// Check if \p Opcode is an Addr64 opcode.
1215   ///
1216   /// \returns \p Opcode if it is an Addr64 opcode, otherwise -1.
1217   LLVM_READONLY
1218   int getIfAddr64Inst(uint16_t Opcode);
1219 
1220   LLVM_READONLY
1221   int getMUBUFNoLdsInst(uint16_t Opcode);
1222 
1223   LLVM_READONLY
1224   int getAtomicNoRetOp(uint16_t Opcode);
1225 
1226   LLVM_READONLY
1227   int getSOPKOp(uint16_t Opcode);
1228 
1229   /// \returns SADDR form of a FLAT Global instruction given an \p Opcode
1230   /// of a VADDR form.
1231   LLVM_READONLY
1232   int getGlobalSaddrOp(uint16_t Opcode);
1233 
1234   /// \returns VADDR form of a FLAT Global instruction given an \p Opcode
1235   /// of a SADDR form.
1236   LLVM_READONLY
1237   int getGlobalVaddrOp(uint16_t Opcode);
1238 
1239   LLVM_READONLY
1240   int getVCMPXNoSDstOp(uint16_t Opcode);
1241 
1242   /// \returns ST form with only immediate offset of a FLAT Scratch instruction
1243   /// given an \p Opcode of an SS (SADDR) form.
1244   LLVM_READONLY
1245   int getFlatScratchInstSTfromSS(uint16_t Opcode);
1246 
1247   /// \returns SV (VADDR) form of a FLAT Scratch instruction given an \p Opcode
1248   /// of an SVS (SADDR + VADDR) form.
1249   LLVM_READONLY
1250   int getFlatScratchInstSVfromSVS(uint16_t Opcode);
1251 
1252   /// \returns SS (SADDR) form of a FLAT Scratch instruction given an \p Opcode
1253   /// of an SV (VADDR) form.
1254   LLVM_READONLY
1255   int getFlatScratchInstSSfromSV(uint16_t Opcode);
1256 
1257   /// \returns SV (VADDR) form of a FLAT Scratch instruction given an \p Opcode
1258   /// of an SS (SADDR) form.
1259   LLVM_READONLY
1260   int getFlatScratchInstSVfromSS(uint16_t Opcode);
1261 
1262   /// \returns earlyclobber version of a MAC MFMA is exists.
1263   LLVM_READONLY
1264   int getMFMAEarlyClobberOp(uint16_t Opcode);
1265 
1266   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
1267   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
1268   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
1269   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
1270 
1271 } // end namespace AMDGPU
1272 
1273 namespace SI {
1274 namespace KernelInputOffsets {
1275 
1276 /// Offsets in bytes from the start of the input buffer
1277 enum Offsets {
1278   NGROUPS_X = 0,
1279   NGROUPS_Y = 4,
1280   NGROUPS_Z = 8,
1281   GLOBAL_SIZE_X = 12,
1282   GLOBAL_SIZE_Y = 16,
1283   GLOBAL_SIZE_Z = 20,
1284   LOCAL_SIZE_X = 24,
1285   LOCAL_SIZE_Y = 28,
1286   LOCAL_SIZE_Z = 32
1287 };
1288 
1289 } // end namespace KernelInputOffsets
1290 } // end namespace SI
1291 
1292 } // end namespace llvm
1293 
1294 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
1295