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