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