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