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