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