LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - SIInstrInfo.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 72 72 100.0 %
Date: 2018-06-17 00:07:59 Functions: 5 7 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- SIInstrInfo.h - SI Instruction Info Interface ------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : /// \file
      11             : /// Interface definition for SIInstrInfo.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
      16             : #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
      17             : 
      18             : #include "AMDGPUInstrInfo.h"
      19             : #include "SIDefines.h"
      20             : #include "SIRegisterInfo.h"
      21             : #include "Utils/AMDGPUBaseInfo.h"
      22             : #include "llvm/ADT/ArrayRef.h"
      23             : #include "llvm/ADT/SetVector.h"
      24             : #include "llvm/CodeGen/MachineBasicBlock.h"
      25             : #include "llvm/CodeGen/MachineFunction.h"
      26             : #include "llvm/CodeGen/MachineInstr.h"
      27             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      28             : #include "llvm/CodeGen/MachineOperand.h"
      29             : #include "llvm/MC/MCInstrDesc.h"
      30             : #include "llvm/Support/Compiler.h"
      31             : #include <cassert>
      32             : #include <cstdint>
      33             : 
      34             : namespace llvm {
      35             : 
      36             : class APInt;
      37             : class MachineRegisterInfo;
      38             : class RegScavenger;
      39             : class SISubtarget;
      40             : class TargetRegisterClass;
      41             : 
      42        4466 : class SIInstrInfo final : public AMDGPUInstrInfo {
      43             : private:
      44             :   const SIRegisterInfo RI;
      45             :   const SISubtarget &ST;
      46             : 
      47             :   // The inverse predicate should have the negative value.
      48             :   enum BranchPredicate {
      49             :     INVALID_BR = 0,
      50             :     SCC_TRUE = 1,
      51             :     SCC_FALSE = -1,
      52             :     VCCNZ = 2,
      53             :     VCCZ = -2,
      54             :     EXECNZ = -3,
      55             :     EXECZ = 3
      56             :   };
      57             : 
      58             :   using SetVectorType = SmallSetVector<MachineInstr *, 32>;
      59             : 
      60             :   static unsigned getBranchOpcode(BranchPredicate Cond);
      61             :   static BranchPredicate getBranchPredicate(unsigned Opcode);
      62             : 
      63             : public:
      64             :   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
      65             :                               MachineRegisterInfo &MRI,
      66             :                               MachineOperand &SuperReg,
      67             :                               const TargetRegisterClass *SuperRC,
      68             :                               unsigned SubIdx,
      69             :                               const TargetRegisterClass *SubRC) const;
      70             :   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
      71             :                                          MachineRegisterInfo &MRI,
      72             :                                          MachineOperand &SuperReg,
      73             :                                          const TargetRegisterClass *SuperRC,
      74             :                                          unsigned SubIdx,
      75             :                                          const TargetRegisterClass *SubRC) const;
      76             : private:
      77             :   void swapOperands(MachineInstr &Inst) const;
      78             : 
      79             :   bool moveScalarAddSub(SetVectorType &Worklist,
      80             :                         MachineInstr &Inst) const;
      81             : 
      82             :   void lowerScalarAbs(SetVectorType &Worklist,
      83             :                       MachineInstr &Inst) const;
      84             : 
      85             :   void lowerScalarXnor(SetVectorType &Worklist,
      86             :                        MachineInstr &Inst) const;
      87             : 
      88             :   void splitScalar64BitUnaryOp(SetVectorType &Worklist,
      89             :                                MachineInstr &Inst, unsigned Opcode) const;
      90             : 
      91             :   void splitScalar64BitAddSub(SetVectorType &Worklist,
      92             :                               MachineInstr &Inst) const;
      93             : 
      94             :   void splitScalar64BitBinaryOp(SetVectorType &Worklist,
      95             :                                 MachineInstr &Inst, unsigned Opcode) const;
      96             : 
      97             :   void splitScalar64BitBCNT(SetVectorType &Worklist,
      98             :                             MachineInstr &Inst) const;
      99             :   void splitScalar64BitBFE(SetVectorType &Worklist,
     100             :                            MachineInstr &Inst) const;
     101             :   void movePackToVALU(SetVectorType &Worklist,
     102             :                       MachineRegisterInfo &MRI,
     103             :                       MachineInstr &Inst) const;
     104             : 
     105             :   void addUsersToMoveToVALUWorklist(unsigned Reg, MachineRegisterInfo &MRI,
     106             :                                     SetVectorType &Worklist) const;
     107             : 
     108             :   void
     109             :   addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
     110             :                                SetVectorType &Worklist) const;
     111             : 
     112             :   const TargetRegisterClass *
     113             :   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
     114             : 
     115             :   bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
     116             : 
     117             :   unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
     118             : 
     119             : protected:
     120             :   bool swapSourceModifiers(MachineInstr &MI,
     121             :                            MachineOperand &Src0, unsigned Src0OpName,
     122             :                            MachineOperand &Src1, unsigned Src1OpName) const;
     123             : 
     124             :   MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
     125             :                                        unsigned OpIdx0,
     126             :                                        unsigned OpIdx1) const override;
     127             : 
     128             : public:
     129             :   enum TargetOperandFlags {
     130             :     MO_MASK = 0x7,
     131             : 
     132             :     MO_NONE = 0,
     133             :     // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
     134             :     MO_GOTPCREL = 1,
     135             :     // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
     136             :     MO_GOTPCREL32 = 2,
     137             :     MO_GOTPCREL32_LO = 2,
     138             :     // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
     139             :     MO_GOTPCREL32_HI = 3,
     140             :     // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
     141             :     MO_REL32 = 4,
     142             :     MO_REL32_LO = 4,
     143             :     // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
     144             :     MO_REL32_HI = 5
     145             :   };
     146             : 
     147             :   explicit SIInstrInfo(const SISubtarget &ST);
     148             : 
     149             :   const SIRegisterInfo &getRegisterInfo() const {
     150    30214399 :     return RI;
     151             :   }
     152             : 
     153             :   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
     154             :                                          AliasAnalysis *AA) const override;
     155             : 
     156             :   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
     157             :                                int64_t &Offset1,
     158             :                                int64_t &Offset2) const override;
     159             : 
     160             :   bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
     161             :                              int64_t &Offset,
     162             :                              const TargetRegisterInfo *TRI) const final;
     163             : 
     164             :   bool shouldClusterMemOps(MachineInstr &FirstLdSt, unsigned BaseReg1,
     165             :                            MachineInstr &SecondLdSt, unsigned BaseReg2,
     166             :                            unsigned NumLoads) const final;
     167             : 
     168             :   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
     169             :                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
     170             :                    bool KillSrc) const override;
     171             : 
     172             :   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
     173             :                                     RegScavenger *RS, unsigned TmpReg,
     174             :                                     unsigned Offset, unsigned Size) const;
     175             : 
     176             :   void materializeImmediate(MachineBasicBlock &MBB,
     177             :                             MachineBasicBlock::iterator MI,
     178             :                             const DebugLoc &DL,
     179             :                             unsigned DestReg,
     180             :                             int64_t Value) const;
     181             : 
     182             :   const TargetRegisterClass *getPreferredSelectRegClass(
     183             :                                unsigned Size) const;
     184             : 
     185             :   unsigned insertNE(MachineBasicBlock *MBB,
     186             :                     MachineBasicBlock::iterator I, const DebugLoc &DL,
     187             :                     unsigned SrcReg, int Value) const;
     188             : 
     189             :   unsigned insertEQ(MachineBasicBlock *MBB,
     190             :                     MachineBasicBlock::iterator I, const DebugLoc &DL,
     191             :                     unsigned SrcReg, int Value)  const;
     192             : 
     193             :   void storeRegToStackSlot(MachineBasicBlock &MBB,
     194             :                            MachineBasicBlock::iterator MI, unsigned SrcReg,
     195             :                            bool isKill, int FrameIndex,
     196             :                            const TargetRegisterClass *RC,
     197             :                            const TargetRegisterInfo *TRI) const override;
     198             : 
     199             :   void loadRegFromStackSlot(MachineBasicBlock &MBB,
     200             :                             MachineBasicBlock::iterator MI, unsigned DestReg,
     201             :                             int FrameIndex, const TargetRegisterClass *RC,
     202             :                             const TargetRegisterInfo *TRI) const override;
     203             : 
     204             :   bool expandPostRAPseudo(MachineInstr &MI) const override;
     205             : 
     206             :   // Returns an opcode that can be used to move a value to a \p DstRC
     207             :   // register.  If there is no hardware instruction that can store to \p
     208             :   // DstRC, then AMDGPU::COPY is returned.
     209             :   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
     210             : 
     211             :   LLVM_READONLY
     212             :   int commuteOpcode(unsigned Opc) const;
     213             : 
     214             :   LLVM_READONLY
     215             :   inline int commuteOpcode(const MachineInstr &MI) const {
     216       14054 :     return commuteOpcode(MI.getOpcode());
     217             :   }
     218             : 
     219             :   bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
     220             :                              unsigned &SrcOpIdx2) const override;
     221             : 
     222             :   bool isBranchOffsetInRange(unsigned BranchOpc,
     223             :                              int64_t BrOffset) const override;
     224             : 
     225             :   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
     226             : 
     227             :   unsigned insertIndirectBranch(MachineBasicBlock &MBB,
     228             :                                 MachineBasicBlock &NewDestBB,
     229             :                                 const DebugLoc &DL,
     230             :                                 int64_t BrOffset,
     231             :                                 RegScavenger *RS = nullptr) const override;
     232             : 
     233             :   bool analyzeBranchImpl(MachineBasicBlock &MBB,
     234             :                          MachineBasicBlock::iterator I,
     235             :                          MachineBasicBlock *&TBB,
     236             :                          MachineBasicBlock *&FBB,
     237             :                          SmallVectorImpl<MachineOperand> &Cond,
     238             :                          bool AllowModify) const;
     239             : 
     240             :   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
     241             :                      MachineBasicBlock *&FBB,
     242             :                      SmallVectorImpl<MachineOperand> &Cond,
     243             :                      bool AllowModify = false) const override;
     244             : 
     245             :   unsigned removeBranch(MachineBasicBlock &MBB,
     246             :                         int *BytesRemoved = nullptr) const override;
     247             : 
     248             :   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
     249             :                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
     250             :                         const DebugLoc &DL,
     251             :                         int *BytesAdded = nullptr) const override;
     252             : 
     253             :   bool reverseBranchCondition(
     254             :     SmallVectorImpl<MachineOperand> &Cond) const override;
     255             : 
     256             :   bool canInsertSelect(const MachineBasicBlock &MBB,
     257             :                        ArrayRef<MachineOperand> Cond,
     258             :                        unsigned TrueReg, unsigned FalseReg,
     259             :                        int &CondCycles,
     260             :                        int &TrueCycles, int &FalseCycles) const override;
     261             : 
     262             :   void insertSelect(MachineBasicBlock &MBB,
     263             :                     MachineBasicBlock::iterator I, const DebugLoc &DL,
     264             :                     unsigned DstReg, ArrayRef<MachineOperand> Cond,
     265             :                     unsigned TrueReg, unsigned FalseReg) const override;
     266             : 
     267             :   void insertVectorSelect(MachineBasicBlock &MBB,
     268             :                           MachineBasicBlock::iterator I, const DebugLoc &DL,
     269             :                           unsigned DstReg, ArrayRef<MachineOperand> Cond,
     270             :                           unsigned TrueReg, unsigned FalseReg) const;
     271             : 
     272             :   unsigned getAddressSpaceForPseudoSourceKind(
     273             :              PseudoSourceValue::PSVKind Kind) const override;
     274             : 
     275             :   bool
     276             :   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
     277             :                                   AliasAnalysis *AA = nullptr) const override;
     278             : 
     279             :   bool isFoldableCopy(const MachineInstr &MI) const;
     280             : 
     281             :   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
     282             :                      MachineRegisterInfo *MRI) const final;
     283             : 
     284       35241 :   unsigned getMachineCSELookAheadLimit() const override { return 500; }
     285             : 
     286             :   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
     287             :                                       MachineInstr &MI,
     288             :                                       LiveVariables *LV) const override;
     289             : 
     290             :   bool isSchedulingBoundary(const MachineInstr &MI,
     291             :                             const MachineBasicBlock *MBB,
     292             :                             const MachineFunction &MF) const override;
     293             : 
     294             :   static bool isSALU(const MachineInstr &MI) {
     295     7320096 :     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
     296             :   }
     297             : 
     298             :   bool isSALU(uint16_t Opcode) const {
     299             :     return get(Opcode).TSFlags & SIInstrFlags::SALU;
     300             :   }
     301             : 
     302             :   static bool isVALU(const MachineInstr &MI) {
     303    13122176 :     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
     304             :   }
     305             : 
     306             :   bool isVALU(uint16_t Opcode) const {
     307             :     return get(Opcode).TSFlags & SIInstrFlags::VALU;
     308             :   }
     309             : 
     310             :   static bool isVMEM(const MachineInstr &MI) {
     311     2609002 :     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
     312             :   }
     313             : 
     314             :   bool isVMEM(uint16_t Opcode) const {
     315             :     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
     316             :   }
     317             : 
     318             :   static bool isSOP1(const MachineInstr &MI) {
     319             :     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
     320             :   }
     321             : 
     322             :   bool isSOP1(uint16_t Opcode) const {
     323             :     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
     324             :   }
     325             : 
     326             :   static bool isSOP2(const MachineInstr &MI) {
     327             :     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
     328             :   }
     329             : 
     330             :   bool isSOP2(uint16_t Opcode) const {
     331             :     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
     332             :   }
     333             : 
     334             :   static bool isSOPC(const MachineInstr &MI) {
     335        8837 :     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
     336             :   }
     337             : 
     338             :   bool isSOPC(uint16_t Opcode) const {
     339             :     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
     340             :   }
     341             : 
     342             :   static bool isSOPK(const MachineInstr &MI) {
     343    10856790 :     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
     344             :   }
     345             : 
     346             :   bool isSOPK(uint16_t Opcode) const {
     347             :     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
     348             :   }
     349             : 
     350             :   static bool isSOPP(const MachineInstr &MI) {
     351             :     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
     352             :   }
     353             : 
     354             :   bool isSOPP(uint16_t Opcode) const {
     355             :     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
     356             :   }
     357             : 
     358             :   static bool isVOP1(const MachineInstr &MI) {
     359    10856110 :     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
     360             :   }
     361             : 
     362             :   bool isVOP1(uint16_t Opcode) const {
     363             :     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
     364             :   }
     365             : 
     366             :   static bool isVOP2(const MachineInstr &MI) {
     367     9940349 :     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
     368             :   }
     369             : 
     370             :   bool isVOP2(uint16_t Opcode) const {
     371             :     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
     372             :   }
     373             : 
     374             :   static bool isVOP3(const MachineInstr &MI) {
     375    12637114 :     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
     376             :   }
     377             : 
     378             :   bool isVOP3(uint16_t Opcode) const {
     379       65038 :     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
     380             :   }
     381             : 
     382             :   static bool isSDWA(const MachineInstr &MI) {
     383    18293447 :     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
     384             :   }
     385             : 
     386             :   bool isSDWA(uint16_t Opcode) const {
     387       25608 :     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
     388             :   }
     389             : 
     390             :   static bool isVOPC(const MachineInstr &MI) {
     391     7202944 :     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
     392             :   }
     393             : 
     394             :   bool isVOPC(uint16_t Opcode) const {
     395      221226 :     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
     396             :   }
     397             : 
     398             :   static bool isMUBUF(const MachineInstr &MI) {
     399     3613843 :     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
     400             :   }
     401             : 
     402             :   bool isMUBUF(uint16_t Opcode) const {
     403      511002 :     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
     404             :   }
     405             : 
     406             :   static bool isMTBUF(const MachineInstr &MI) {
     407     1053981 :     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
     408             :   }
     409             : 
     410             :   bool isMTBUF(uint16_t Opcode) const {
     411       71925 :     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
     412             :   }
     413             : 
     414             :   static bool isSMRD(const MachineInstr &MI) {
     415    15758054 :     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
     416             :   }
     417             : 
     418             :   bool isSMRD(uint16_t Opcode) const {
     419      404084 :     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
     420             :   }
     421             : 
     422             :   bool isBufferSMRD(const MachineInstr &MI) const;
     423             : 
     424             :   static bool isDS(const MachineInstr &MI) {
     425     2563081 :     return MI.getDesc().TSFlags & SIInstrFlags::DS;
     426             :   }
     427             : 
     428             :   bool isDS(uint16_t Opcode) const {
     429      344664 :     return get(Opcode).TSFlags & SIInstrFlags::DS;
     430             :   }
     431             : 
     432             :   static bool isMIMG(const MachineInstr &MI) {
     433      914489 :     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
     434             :   }
     435             : 
     436             :   bool isMIMG(uint16_t Opcode) const {
     437      726106 :     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
     438             :   }
     439             : 
     440             :   static bool isGather4(const MachineInstr &MI) {
     441             :     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
     442             :   }
     443             : 
     444             :   bool isGather4(uint16_t Opcode) const {
     445         747 :     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
     446             :   }
     447             : 
     448             :   static bool isD16(const MachineInstr &MI) {
     449             :     return MI.getDesc().TSFlags & SIInstrFlags::D16;
     450             :   }
     451             : 
     452             :   bool isD16(uint16_t Opcode) const {
     453         640 :     return get(Opcode).TSFlags & SIInstrFlags::D16;
     454             :   }
     455             : 
     456             :   static bool isFLAT(const MachineInstr &MI) {
     457    12048416 :     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
     458             :   }
     459             : 
     460             :   // Is a FLAT encoded instruction which accesses a specific segment,
     461             :   // i.e. global_* or scratch_*.
     462             :   static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
     463             :     auto Flags = MI.getDesc().TSFlags;
     464       44067 :     return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
     465             :   }
     466             : 
     467             :   // Any FLAT encoded instruction, including global_* and scratch_*.
     468             :   bool isFLAT(uint16_t Opcode) const {
     469             :     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
     470             :   }
     471             : 
     472             :   static bool isEXP(const MachineInstr &MI) {
     473         469 :     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
     474             :   }
     475             : 
     476             :   bool isEXP(uint16_t Opcode) const {
     477             :     return get(Opcode).TSFlags & SIInstrFlags::EXP;
     478             :   }
     479             : 
     480             :   static bool isWQM(const MachineInstr &MI) {
     481             :     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
     482             :   }
     483             : 
     484             :   bool isWQM(uint16_t Opcode) const {
     485      765682 :     return get(Opcode).TSFlags & SIInstrFlags::WQM;
     486             :   }
     487             : 
     488             :   static bool isDisableWQM(const MachineInstr &MI) {
     489      382502 :     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
     490             :   }
     491             : 
     492             :   bool isDisableWQM(uint16_t Opcode) const {
     493             :     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
     494             :   }
     495             : 
     496             :   static bool isVGPRSpill(const MachineInstr &MI) {
     497        1223 :     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
     498             :   }
     499             : 
     500             :   bool isVGPRSpill(uint16_t Opcode) const {
     501             :     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
     502             :   }
     503             : 
     504             :   static bool isSGPRSpill(const MachineInstr &MI) {
     505        6667 :     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
     506             :   }
     507             : 
     508             :   bool isSGPRSpill(uint16_t Opcode) const {
     509             :     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
     510             :   }
     511             : 
     512             :   static bool isDPP(const MachineInstr &MI) {
     513      633541 :     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
     514             :   }
     515             : 
     516             :   bool isDPP(uint16_t Opcode) const {
     517             :     return get(Opcode).TSFlags & SIInstrFlags::DPP;
     518             :   }
     519             : 
     520             :   static bool isVOP3P(const MachineInstr &MI) {
     521             :     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
     522             :   }
     523             : 
     524             :   bool isVOP3P(uint16_t Opcode) const {
     525             :     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
     526             :   }
     527             : 
     528             :   static bool isVINTRP(const MachineInstr &MI) {
     529      104799 :     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
     530             :   }
     531             : 
     532             :   bool isVINTRP(uint16_t Opcode) const {
     533             :     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
     534             :   }
     535             : 
     536             :   static bool isScalarUnit(const MachineInstr &MI) {
     537        5241 :     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
     538             :   }
     539             : 
     540             :   static bool usesVM_CNT(const MachineInstr &MI) {
     541       18818 :     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
     542             :   }
     543             : 
     544             :   static bool usesLGKM_CNT(const MachineInstr &MI) {
     545       19934 :     return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
     546             :   }
     547             : 
     548             :   static bool sopkIsZext(const MachineInstr &MI) {
     549       12163 :     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
     550             :   }
     551             : 
     552             :   bool sopkIsZext(uint16_t Opcode) const {
     553         316 :     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
     554             :   }
     555             : 
     556             :   /// \returns true if this is an s_store_dword* instruction. This is more
     557             :   /// specific than than isSMEM && mayStore.
     558             :   static bool isScalarStore(const MachineInstr &MI) {
     559      332627 :     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
     560             :   }
     561             : 
     562             :   bool isScalarStore(uint16_t Opcode) const {
     563             :     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
     564             :   }
     565             : 
     566             :   static bool isFixedSize(const MachineInstr &MI) {
     567      443289 :     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
     568             :   }
     569             : 
     570             :   bool isFixedSize(uint16_t Opcode) const {
     571             :     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
     572             :   }
     573             : 
     574             :   static bool hasFPClamp(const MachineInstr &MI) {
     575             :     return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
     576             :   }
     577             : 
     578             :   bool hasFPClamp(uint16_t Opcode) const {
     579             :     return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
     580             :   }
     581             : 
     582             :   static bool hasIntClamp(const MachineInstr &MI) {
     583             :     return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
     584             :   }
     585             : 
     586             :   uint64_t getClampMask(const MachineInstr &MI) const {
     587             :     const uint64_t ClampFlags = SIInstrFlags::FPClamp |
     588             :                                 SIInstrFlags::IntClamp |
     589             :                                 SIInstrFlags::ClampLo |
     590             :                                 SIInstrFlags::ClampHi;
     591         263 :       return MI.getDesc().TSFlags & ClampFlags;
     592             :   }
     593             : 
     594             :   bool isVGPRCopy(const MachineInstr &MI) const {
     595             :     assert(MI.isCopy());
     596      702854 :     unsigned Dest = MI.getOperand(0).getReg();
     597      702854 :     const MachineFunction &MF = *MI.getParent()->getParent();
     598      702854 :     const MachineRegisterInfo &MRI = MF.getRegInfo();
     599      702854 :     return !RI.isSGPRReg(MRI, Dest);
     600             :   }
     601             : 
     602             :   bool isInlineConstant(const APInt &Imm) const;
     603             : 
     604             :   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
     605             : 
     606             :   bool isInlineConstant(const MachineOperand &MO,
     607             :                         const MCOperandInfo &OpInfo) const {
     608     2408499 :     return isInlineConstant(MO, OpInfo.OperandType);
     609             :   }
     610             : 
     611             :   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
     612             :   /// be an inline immediate.
     613         184 :   bool isInlineConstant(const MachineInstr &MI,
     614             :                         const MachineOperand &UseMO,
     615             :                         const MachineOperand &DefMO) const {
     616             :     assert(UseMO.getParent() == &MI);
     617         184 :     int OpIdx = MI.getOperandNo(&UseMO);
     618         184 :     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
     619             :       return false;
     620             :     }
     621             : 
     622         368 :     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
     623             :   }
     624             : 
     625             :   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
     626             :   /// immediate.
     627             :   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
     628             :     const MachineOperand &MO = MI.getOperand(OpIdx);
     629     2120594 :     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
     630             :   }
     631             : 
     632      148494 :   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
     633             :                         const MachineOperand &MO) const {
     634      148494 :     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
     635             :       return false;
     636             : 
     637       81949 :     if (MI.isCopy()) {
     638       11823 :       unsigned Size = getOpSize(MI, OpIdx);
     639             :       assert(Size == 8 || Size == 4);
     640             : 
     641       11823 :       uint8_t OpType = (Size == 8) ?
     642             :         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
     643       11823 :       return isInlineConstant(MO, OpType);
     644             :     }
     645             : 
     646       70126 :     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
     647             :   }
     648             : 
     649       33812 :   bool isInlineConstant(const MachineOperand &MO) const {
     650       33812 :     const MachineInstr *Parent = MO.getParent();
     651       33812 :     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
     652             :   }
     653             : 
     654             :   bool isLiteralConstant(const MachineOperand &MO,
     655             :                          const MCOperandInfo &OpInfo) const {
     656             :     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
     657             :   }
     658             : 
     659             :   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
     660             :     const MachineOperand &MO = MI.getOperand(OpIdx);
     661             :     return MO.isImm() && !isInlineConstant(MI, OpIdx);
     662             :   }
     663             : 
     664             :   // Returns true if this operand could potentially require a 32-bit literal
     665             :   // operand, but not necessarily. A FrameIndex for example could resolve to an
     666             :   // inline immediate value that will not require an additional 4-bytes; this
     667             :   // assumes that it will.
     668             :   bool isLiteralConstantLike(const MachineOperand &MO,
     669             :                              const MCOperandInfo &OpInfo) const;
     670             : 
     671             :   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
     672             :                          const MachineOperand &MO) const;
     673             : 
     674             :   /// Return true if this 64-bit VALU instruction has a 32-bit encoding.
     675             :   /// This function will return false if you pass it a 32-bit instruction.
     676             :   bool hasVALU32BitEncoding(unsigned Opcode) const;
     677             : 
     678             :   /// Returns true if this operand uses the constant bus.
     679             :   bool usesConstantBus(const MachineRegisterInfo &MRI,
     680             :                        const MachineOperand &MO,
     681             :                        const MCOperandInfo &OpInfo) const;
     682             : 
     683             :   /// Return true if this instruction has any modifiers.
     684             :   ///  e.g. src[012]_mod, omod, clamp.
     685             :   bool hasModifiers(unsigned Opcode) const;
     686             : 
     687             :   bool hasModifiersSet(const MachineInstr &MI,
     688             :                        unsigned OpName) const;
     689             :   bool hasAnyModifiersSet(const MachineInstr &MI) const;
     690             : 
     691             :   bool verifyInstruction(const MachineInstr &MI,
     692             :                          StringRef &ErrInfo) const override;
     693             : 
     694             :   unsigned getVALUOp(const MachineInstr &MI) const;
     695             : 
     696             :   /// Return the correct register class for \p OpNo.  For target-specific
     697             :   /// instructions, this will return the register class that has been defined
     698             :   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
     699             :   /// the register class of its machine operand.
     700             :   /// to infer the correct register class base on the other operands.
     701             :   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
     702             :                                            unsigned OpNo) const;
     703             : 
     704             :   /// Return the size in bytes of the operand OpNo on the given
     705             :   // instruction opcode.
     706             :   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
     707             :     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
     708             : 
     709             :     if (OpInfo.RegClass == -1) {
     710             :       // If this is an immediate operand, this must be a 32-bit literal.
     711             :       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
     712             :       return 4;
     713             :     }
     714             : 
     715             :     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
     716             :   }
     717             : 
     718             :   /// This form should usually be preferred since it handles operands
     719             :   /// with unknown register classes.
     720      295778 :   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
     721      591556 :     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
     722             :   }
     723             : 
     724             :   /// \returns true if it is legal for the operand at index \p OpNo
     725             :   /// to read a VGPR.
     726             :   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
     727             : 
     728             :   /// Legalize the \p OpIndex operand of this instruction by inserting
     729             :   /// a MOV.  For example:
     730             :   /// ADD_I32_e32 VGPR0, 15
     731             :   /// to
     732             :   /// MOV VGPR1, 15
     733             :   /// ADD_I32_e32 VGPR0, VGPR1
     734             :   ///
     735             :   /// If the operand being legalized is a register, then a COPY will be used
     736             :   /// instead of MOV.
     737             :   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
     738             : 
     739             :   /// Check if \p MO is a legal operand if it was the \p OpIdx Operand
     740             :   /// for \p MI.
     741             :   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
     742             :                       const MachineOperand *MO = nullptr) const;
     743             : 
     744             :   /// Check if \p MO would be a valid operand for the given operand
     745             :   /// definition \p OpInfo. Note this does not attempt to validate constant bus
     746             :   /// restrictions (e.g. literal constant usage).
     747             :   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
     748             :                           const MCOperandInfo &OpInfo,
     749             :                           const MachineOperand &MO) const;
     750             : 
     751             :   /// Check if \p MO (a register operand) is a legal register for the
     752             :   /// given operand description.
     753             :   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
     754             :                          const MCOperandInfo &OpInfo,
     755             :                          const MachineOperand &MO) const;
     756             : 
     757             :   /// Legalize operands in \p MI by either commuting it or inserting a
     758             :   /// copy of src1.
     759             :   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
     760             : 
     761             :   /// Fix operands in \p MI to satisfy constant bus requirements.
     762             :   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
     763             : 
     764             :   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
     765             :   /// be used when it is know that the value in SrcReg is same across all
     766             :   /// threads in the wave.
     767             :   /// \returns The SGPR register that \p SrcReg was copied to.
     768             :   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
     769             :                               MachineRegisterInfo &MRI) const;
     770             : 
     771             :   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
     772             : 
     773             :   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
     774             :                               MachineBasicBlock::iterator I,
     775             :                               const TargetRegisterClass *DstRC,
     776             :                               MachineOperand &Op, MachineRegisterInfo &MRI,
     777             :                               const DebugLoc &DL) const;
     778             : 
     779             :   /// Legalize all operands in this instruction.  This function may
     780             :   /// create new instruction and insert them before \p MI.
     781             :   void legalizeOperands(MachineInstr &MI) const;
     782             : 
     783             :   /// Replace this instruction's opcode with the equivalent VALU
     784             :   /// opcode.  This function will also move the users of \p MI to the
     785             :   /// VALU if necessary.
     786             :   void moveToVALU(MachineInstr &MI) const;
     787             : 
     788             :   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
     789             :                         int Count) const;
     790             : 
     791             :   void insertNoop(MachineBasicBlock &MBB,
     792             :                   MachineBasicBlock::iterator MI) const override;
     793             : 
     794             :   void insertReturn(MachineBasicBlock &MBB) const;
     795             :   /// Return the number of wait states that result from executing this
     796             :   /// instruction.
     797             :   unsigned getNumWaitStates(const MachineInstr &MI) const;
     798             : 
     799             :   /// Returns the operand named \p Op.  If \p MI does not have an
     800             :   /// operand named \c Op, this function returns nullptr.
     801             :   LLVM_READONLY
     802             :   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
     803             : 
     804             :   LLVM_READONLY
     805             :   const MachineOperand *getNamedOperand(const MachineInstr &MI,
     806             :                                         unsigned OpName) const {
     807    11547644 :     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
     808             :   }
     809             : 
     810             :   /// Get required immediate operand
     811             :   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
     812         119 :     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
     813         126 :     return MI.getOperand(Idx).getImm();
     814             :   }
     815             : 
     816             :   uint64_t getDefaultRsrcDataFormat() const;
     817             :   uint64_t getScratchRsrcWords23() const;
     818             : 
     819             :   bool isLowLatencyInstruction(const MachineInstr &MI) const;
     820             :   bool isHighLatencyInstruction(const MachineInstr &MI) const;
     821             : 
     822             :   /// Return the descriptor of the target-specific machine instruction
     823             :   /// that corresponds to the specified pseudo or native opcode.
     824             :   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
     825      683252 :     return get(pseudoToMCOpcode(Opcode));
     826             :   }
     827             : 
     828             :   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
     829             :   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
     830             : 
     831             :   unsigned isLoadFromStackSlot(const MachineInstr &MI,
     832             :                                int &FrameIndex) const override;
     833             :   unsigned isStoreToStackSlot(const MachineInstr &MI,
     834             :                               int &FrameIndex) const override;
     835             : 
     836             :   unsigned getInstBundleSize(const MachineInstr &MI) const;
     837             :   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
     838             : 
     839             :   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
     840             : 
     841             :   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
     842             : 
     843             :   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
     844             :                                  MachineBasicBlock *IfEnd) const;
     845             : 
     846             :   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
     847             :                                    MachineBasicBlock *LoopEnd) const;
     848             : 
     849             :   std::pair<unsigned, unsigned>
     850             :   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
     851             : 
     852             :   ArrayRef<std::pair<int, const char *>>
     853             :   getSerializableTargetIndices() const override;
     854             : 
     855             :   ArrayRef<std::pair<unsigned, const char *>>
     856             :   getSerializableDirectMachineOperandTargetFlags() const override;
     857             : 
     858             :   ScheduleHazardRecognizer *
     859             :   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
     860             :                                  const ScheduleDAG *DAG) const override;
     861             : 
     862             :   ScheduleHazardRecognizer *
     863             :   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
     864             : 
     865             :   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
     866             : 
     867             :   /// Return a partially built integer add instruction without carry.
     868             :   /// Caller must add source operands.
     869             :   /// For pre-GFX9 it will generate unused carry destination operand.
     870             :   /// TODO: After GFX9 it should return a no-carry operation.
     871             :   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
     872             :                                     MachineBasicBlock::iterator I,
     873             :                                     const DebugLoc &DL,
     874             :                                     unsigned DestReg) const;
     875             : 
     876             :   static bool isKillTerminator(unsigned Opcode);
     877             :   const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
     878             : 
     879             :   static bool isLegalMUBUFImmOffset(unsigned Imm) {
     880             :     return isUInt<12>(Imm);
     881             :   }
     882             : };
     883             : 
     884             : namespace AMDGPU {
     885             : 
     886             :   LLVM_READONLY
     887             :   int getVOPe64(uint16_t Opcode);
     888             : 
     889             :   LLVM_READONLY
     890             :   int getVOPe32(uint16_t Opcode);
     891             : 
     892             :   LLVM_READONLY
     893             :   int getSDWAOp(uint16_t Opcode);
     894             : 
     895             :   LLVM_READONLY
     896             :   int getBasicFromSDWAOp(uint16_t Opcode);
     897             : 
     898             :   LLVM_READONLY
     899             :   int getCommuteRev(uint16_t Opcode);
     900             : 
     901             :   LLVM_READONLY
     902             :   int getCommuteOrig(uint16_t Opcode);
     903             : 
     904             :   LLVM_READONLY
     905             :   int getAddr64Inst(uint16_t Opcode);
     906             : 
     907             :   LLVM_READONLY
     908             :   int getMUBUFNoLdsInst(uint16_t Opcode);
     909             : 
     910             :   LLVM_READONLY
     911             :   int getAtomicRetOp(uint16_t Opcode);
     912             : 
     913             :   LLVM_READONLY
     914             :   int getAtomicNoRetOp(uint16_t Opcode);
     915             : 
     916             :   LLVM_READONLY
     917             :   int getSOPKOp(uint16_t Opcode);
     918             : 
     919             :   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
     920             :   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
     921             :   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
     922             :   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
     923             : 
     924             :   // For MachineOperands.
     925             :   enum TargetFlags {
     926             :     TF_LONG_BRANCH_FORWARD = 1 << 0,
     927             :     TF_LONG_BRANCH_BACKWARD = 1 << 1
     928             :   };
     929             : 
     930             : } // end namespace AMDGPU
     931             : 
     932             : namespace SI {
     933             : namespace KernelInputOffsets {
     934             : 
     935             : /// Offsets in bytes from the start of the input buffer
     936             : enum Offsets {
     937             :   NGROUPS_X = 0,
     938             :   NGROUPS_Y = 4,
     939             :   NGROUPS_Z = 8,
     940             :   GLOBAL_SIZE_X = 12,
     941             :   GLOBAL_SIZE_Y = 16,
     942             :   GLOBAL_SIZE_Z = 20,
     943             :   LOCAL_SIZE_X = 24,
     944             :   LOCAL_SIZE_Y = 28,
     945             :   LOCAL_SIZE_Z = 32
     946             : };
     947             : 
     948             : } // end namespace KernelInputOffsets
     949             : } // end namespace SI
     950             : 
     951             : } // end namespace llvm
     952             : 
     953             : #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H

Generated by: LCOV version 1.13