LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - SIInstrInfo.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 74 74 100.0 %
Date: 2018-02-18 16:14:26 Functions: 6 8 75.0 %
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             : /// \brief 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        4076 : 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    27388466 :     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             :   // \brief 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        7045 :     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       32825 :   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     6713115 :     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    12190889 :     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     2467280 :     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        8987 :     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     9986904 :     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     9986904 :     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     9134067 :     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     8101575 :     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
     376             :   }
     377             : 
     378             :   bool isVOP3(uint16_t Opcode) const {
     379       31336 :     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
     380             :   }
     381             : 
     382             :   static bool isSDWA(const MachineInstr &MI) {
     383    16786560 :     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
     384             :   }
     385             : 
     386             :   bool isSDWA(uint16_t Opcode) const {
     387        9500 :     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
     388             :   }
     389             : 
     390             :   static bool isVOPC(const MachineInstr &MI) {
     391     6580175 :     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
     392             :   }
     393             : 
     394             :   bool isVOPC(uint16_t Opcode) const {
     395       95541 :     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
     396             :   }
     397             : 
     398             :   static bool isMUBUF(const MachineInstr &MI) {
     399     3570246 :     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
     400             :   }
     401             : 
     402             :   bool isMUBUF(uint16_t Opcode) const {
     403      530534 :     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
     404             :   }
     405             : 
     406             :   static bool isMTBUF(const MachineInstr &MI) {
     407     1000118 :     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
     408             :   }
     409             : 
     410             :   bool isMTBUF(uint16_t Opcode) const {
     411       72358 :     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
     412             :   }
     413             : 
     414             :   static bool isSMRD(const MachineInstr &MI) {
     415    14524316 :     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
     416             :   }
     417             : 
     418             :   bool isSMRD(uint16_t Opcode) const {
     419      395255 :     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
     420             :   }
     421             : 
     422       20084 :   bool isBufferSMRD(const MachineInstr &MI) const {
     423       20084 :     if (!isSMRD(MI))
     424             :       return false;
     425             : 
     426             :     // Check that it is using a buffer resource.
     427       20084 :     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::sbase);
     428       20084 :     if (Idx == -1) // e.g. s_memtime
     429             :       return false;
     430             : 
     431       20073 :     const auto RCID = MI.getDesc().OpInfo[Idx].RegClass;
     432       20073 :     return RCID == AMDGPU::SReg_128RegClassID;
     433             :   }
     434             : 
     435             :   static bool isDS(const MachineInstr &MI) {
     436     2463767 :     return MI.getDesc().TSFlags & SIInstrFlags::DS;
     437             :   }
     438             : 
     439             :   bool isDS(uint16_t Opcode) const {
     440      703203 :     return get(Opcode).TSFlags & SIInstrFlags::DS;
     441             :   }
     442             : 
     443             :   static bool isMIMG(const MachineInstr &MI) {
     444      868024 :     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
     445             :   }
     446             : 
     447             :   bool isMIMG(uint16_t Opcode) const {
     448      340867 :     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
     449             :   }
     450             : 
     451             :   static bool isGather4(const MachineInstr &MI) {
     452             :     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
     453             :   }
     454             : 
     455             :   bool isGather4(uint16_t Opcode) const {
     456         574 :     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
     457             :   }
     458             : 
     459             :   static bool isD16(const MachineInstr &MI) {
     460             :     return MI.getDesc().TSFlags & SIInstrFlags::D16;
     461             :   }
     462             : 
     463             :   bool isD16(uint16_t Opcode) const {
     464         477 :     return get(Opcode).TSFlags & SIInstrFlags::D16;
     465             :   }
     466             : 
     467             :   static bool isFLAT(const MachineInstr &MI) {
     468    11120657 :     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
     469             :   }
     470             : 
     471             :   // Is a FLAT encoded instruction which accesses a specific segment,
     472             :   // i.e. global_* or scratch_*.
     473             :   static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
     474             :     auto Flags = MI.getDesc().TSFlags;
     475       37921 :     return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
     476             :   }
     477             : 
     478             :   // Any FLAT encoded instruction, including global_* and scratch_*.
     479             :   bool isFLAT(uint16_t Opcode) const {
     480             :     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
     481             :   }
     482             : 
     483             :   static bool isEXP(const MachineInstr &MI) {
     484         564 :     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
     485             :   }
     486             : 
     487             :   bool isEXP(uint16_t Opcode) const {
     488             :     return get(Opcode).TSFlags & SIInstrFlags::EXP;
     489             :   }
     490             : 
     491             :   static bool isWQM(const MachineInstr &MI) {
     492             :     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
     493             :   }
     494             : 
     495             :   bool isWQM(uint16_t Opcode) const {
     496      359580 :     return get(Opcode).TSFlags & SIInstrFlags::WQM;
     497             :   }
     498             : 
     499             :   static bool isDisableWQM(const MachineInstr &MI) {
     500      359289 :     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
     501             :   }
     502             : 
     503             :   bool isDisableWQM(uint16_t Opcode) const {
     504             :     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
     505             :   }
     506             : 
     507             :   static bool isVGPRSpill(const MachineInstr &MI) {
     508        1210 :     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
     509             :   }
     510             : 
     511             :   bool isVGPRSpill(uint16_t Opcode) const {
     512             :     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
     513             :   }
     514             : 
     515             :   static bool isSGPRSpill(const MachineInstr &MI) {
     516        6562 :     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
     517             :   }
     518             : 
     519             :   bool isSGPRSpill(uint16_t Opcode) const {
     520             :     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
     521             :   }
     522             : 
     523             :   static bool isDPP(const MachineInstr &MI) {
     524      600751 :     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
     525             :   }
     526             : 
     527             :   bool isDPP(uint16_t Opcode) const {
     528             :     return get(Opcode).TSFlags & SIInstrFlags::DPP;
     529             :   }
     530             : 
     531             :   static bool isVOP3P(const MachineInstr &MI) {
     532             :     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
     533             :   }
     534             : 
     535             :   bool isVOP3P(uint16_t Opcode) const {
     536             :     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
     537             :   }
     538             : 
     539             :   static bool isVINTRP(const MachineInstr &MI) {
     540       87114 :     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
     541             :   }
     542             : 
     543             :   bool isVINTRP(uint16_t Opcode) const {
     544             :     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
     545             :   }
     546             : 
     547             :   static bool isScalarUnit(const MachineInstr &MI) {
     548        4289 :     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
     549             :   }
     550             : 
     551             :   static bool usesVM_CNT(const MachineInstr &MI) {
     552       17630 :     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
     553             :   }
     554             : 
     555             :   static bool usesLGKM_CNT(const MachineInstr &MI) {
     556       17561 :     return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
     557             :   }
     558             : 
     559             :   static bool sopkIsZext(const MachineInstr &MI) {
     560       11475 :     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
     561             :   }
     562             : 
     563             :   bool sopkIsZext(uint16_t Opcode) const {
     564         220 :     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
     565             :   }
     566             : 
     567             :   /// \returns true if this is an s_store_dword* instruction. This is more
     568             :   /// specific than than isSMEM && mayStore.
     569             :   static bool isScalarStore(const MachineInstr &MI) {
     570      320047 :     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
     571             :   }
     572             : 
     573             :   bool isScalarStore(uint16_t Opcode) const {
     574             :     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
     575             :   }
     576             : 
     577             :   static bool isFixedSize(const MachineInstr &MI) {
     578      429729 :     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
     579             :   }
     580             : 
     581             :   bool isFixedSize(uint16_t Opcode) const {
     582             :     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
     583             :   }
     584             : 
     585             :   static bool hasFPClamp(const MachineInstr &MI) {
     586             :     return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
     587             :   }
     588             : 
     589             :   bool hasFPClamp(uint16_t Opcode) const {
     590             :     return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
     591             :   }
     592             : 
     593             :   static bool hasIntClamp(const MachineInstr &MI) {
     594             :     return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
     595             :   }
     596             : 
     597             :   uint64_t getClampMask(const MachineInstr &MI) const {
     598             :     const uint64_t ClampFlags = SIInstrFlags::FPClamp |
     599             :                                 SIInstrFlags::IntClamp |
     600             :                                 SIInstrFlags::ClampLo |
     601             :                                 SIInstrFlags::ClampHi;
     602         262 :       return MI.getDesc().TSFlags & ClampFlags;
     603             :   }
     604             : 
     605             :   bool isVGPRCopy(const MachineInstr &MI) const {
     606             :     assert(MI.isCopy());
     607             :     unsigned Dest = MI.getOperand(0).getReg();
     608             :     const MachineFunction &MF = *MI.getParent()->getParent();
     609             :     const MachineRegisterInfo &MRI = MF.getRegInfo();
     610      628786 :     return !RI.isSGPRReg(MRI, Dest);
     611             :   }
     612             : 
     613             :   bool isInlineConstant(const APInt &Imm) const;
     614             : 
     615             :   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
     616             : 
     617             :   bool isInlineConstant(const MachineOperand &MO,
     618             :                         const MCOperandInfo &OpInfo) const {
     619     2238583 :     return isInlineConstant(MO, OpInfo.OperandType);
     620             :   }
     621             : 
     622             :   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
     623             :   /// be an inline immediate.
     624         161 :   bool isInlineConstant(const MachineInstr &MI,
     625             :                         const MachineOperand &UseMO,
     626             :                         const MachineOperand &DefMO) const {
     627             :     assert(UseMO.getParent() == &MI);
     628         161 :     int OpIdx = MI.getOperandNo(&UseMO);
     629         161 :     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
     630             :       return false;
     631             :     }
     632             : 
     633         322 :     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
     634             :   }
     635             : 
     636             :   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
     637             :   /// immediate.
     638             :   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
     639             :     const MachineOperand &MO = MI.getOperand(OpIdx);
     640     2028213 :     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
     641             :   }
     642             : 
     643      144901 :   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
     644             :                         const MachineOperand &MO) const {
     645      144901 :     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
     646             :       return false;
     647             : 
     648       78406 :     if (MI.isCopy()) {
     649       12124 :       unsigned Size = getOpSize(MI, OpIdx);
     650             :       assert(Size == 8 || Size == 4);
     651             : 
     652       12124 :       uint8_t OpType = (Size == 8) ?
     653             :         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
     654       12124 :       return isInlineConstant(MO, OpType);
     655             :     }
     656             : 
     657       66282 :     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
     658             :   }
     659             : 
     660       32962 :   bool isInlineConstant(const MachineOperand &MO) const {
     661             :     const MachineInstr *Parent = MO.getParent();
     662       32962 :     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
     663             :   }
     664             : 
     665             :   bool isLiteralConstant(const MachineOperand &MO,
     666             :                          const MCOperandInfo &OpInfo) const {
     667             :     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
     668             :   }
     669             : 
     670             :   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
     671             :     const MachineOperand &MO = MI.getOperand(OpIdx);
     672             :     return MO.isImm() && !isInlineConstant(MI, OpIdx);
     673             :   }
     674             : 
     675             :   // Returns true if this operand could potentially require a 32-bit literal
     676             :   // operand, but not necessarily. A FrameIndex for example could resolve to an
     677             :   // inline immediate value that will not require an additional 4-bytes; this
     678             :   // assumes that it will.
     679             :   bool isLiteralConstantLike(const MachineOperand &MO,
     680             :                              const MCOperandInfo &OpInfo) const;
     681             : 
     682             :   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
     683             :                          const MachineOperand &MO) const;
     684             : 
     685             :   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
     686             :   /// This function will return false if you pass it a 32-bit instruction.
     687             :   bool hasVALU32BitEncoding(unsigned Opcode) const;
     688             : 
     689             :   /// \brief Returns true if this operand uses the constant bus.
     690             :   bool usesConstantBus(const MachineRegisterInfo &MRI,
     691             :                        const MachineOperand &MO,
     692             :                        const MCOperandInfo &OpInfo) const;
     693             : 
     694             :   /// \brief Return true if this instruction has any modifiers.
     695             :   ///  e.g. src[012]_mod, omod, clamp.
     696             :   bool hasModifiers(unsigned Opcode) const;
     697             : 
     698             :   bool hasModifiersSet(const MachineInstr &MI,
     699             :                        unsigned OpName) const;
     700             :   bool hasAnyModifiersSet(const MachineInstr &MI) const;
     701             : 
     702             :   bool verifyInstruction(const MachineInstr &MI,
     703             :                          StringRef &ErrInfo) const override;
     704             : 
     705             :   unsigned getVALUOp(const MachineInstr &MI) const;
     706             : 
     707             :   /// \brief Return the correct register class for \p OpNo.  For target-specific
     708             :   /// instructions, this will return the register class that has been defined
     709             :   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
     710             :   /// the register class of its machine operand.
     711             :   /// to infer the correct register class base on the other operands.
     712             :   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
     713             :                                            unsigned OpNo) const;
     714             : 
     715             :   /// \brief Return the size in bytes of the operand OpNo on the given
     716             :   // instruction opcode.
     717             :   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
     718             :     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
     719             : 
     720             :     if (OpInfo.RegClass == -1) {
     721             :       // If this is an immediate operand, this must be a 32-bit literal.
     722             :       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
     723             :       return 4;
     724             :     }
     725             : 
     726             :     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
     727             :   }
     728             : 
     729             :   /// \brief This form should usually be preferred since it handles operands
     730             :   /// with unknown register classes.
     731      262948 :   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
     732      525896 :     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
     733             :   }
     734             : 
     735             :   /// \returns true if it is legal for the operand at index \p OpNo
     736             :   /// to read a VGPR.
     737             :   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
     738             : 
     739             :   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
     740             :   /// a MOV.  For example:
     741             :   /// ADD_I32_e32 VGPR0, 15
     742             :   /// to
     743             :   /// MOV VGPR1, 15
     744             :   /// ADD_I32_e32 VGPR0, VGPR1
     745             :   ///
     746             :   /// If the operand being legalized is a register, then a COPY will be used
     747             :   /// instead of MOV.
     748             :   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
     749             : 
     750             :   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
     751             :   /// for \p MI.
     752             :   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
     753             :                       const MachineOperand *MO = nullptr) const;
     754             : 
     755             :   /// \brief Check if \p MO would be a valid operand for the given operand
     756             :   /// definition \p OpInfo. Note this does not attempt to validate constant bus
     757             :   /// restrictions (e.g. literal constant usage).
     758             :   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
     759             :                           const MCOperandInfo &OpInfo,
     760             :                           const MachineOperand &MO) const;
     761             : 
     762             :   /// \brief Check if \p MO (a register operand) is a legal register for the
     763             :   /// given operand description.
     764             :   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
     765             :                          const MCOperandInfo &OpInfo,
     766             :                          const MachineOperand &MO) const;
     767             : 
     768             :   /// \brief Legalize operands in \p MI by either commuting it or inserting a
     769             :   /// copy of src1.
     770             :   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
     771             : 
     772             :   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
     773             :   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
     774             : 
     775             :   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
     776             :   /// be used when it is know that the value in SrcReg is same across all
     777             :   /// threads in the wave.
     778             :   /// \returns The SGPR register that \p SrcReg was copied to.
     779             :   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
     780             :                               MachineRegisterInfo &MRI) const;
     781             : 
     782             :   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
     783             : 
     784             :   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
     785             :                               MachineBasicBlock::iterator I,
     786             :                               const TargetRegisterClass *DstRC,
     787             :                               MachineOperand &Op, MachineRegisterInfo &MRI,
     788             :                               const DebugLoc &DL) const;
     789             : 
     790             :   /// \brief Legalize all operands in this instruction.  This function may
     791             :   /// create new instruction and insert them before \p MI.
     792             :   void legalizeOperands(MachineInstr &MI) const;
     793             : 
     794             :   /// \brief Replace this instruction's opcode with the equivalent VALU
     795             :   /// opcode.  This function will also move the users of \p MI to the
     796             :   /// VALU if necessary.
     797             :   void moveToVALU(MachineInstr &MI) const;
     798             : 
     799             :   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
     800             :                         int Count) const;
     801             : 
     802             :   void insertNoop(MachineBasicBlock &MBB,
     803             :                   MachineBasicBlock::iterator MI) const override;
     804             : 
     805             :   void insertReturn(MachineBasicBlock &MBB) const;
     806             :   /// \brief Return the number of wait states that result from executing this
     807             :   /// instruction.
     808             :   unsigned getNumWaitStates(const MachineInstr &MI) const;
     809             : 
     810             :   /// \brief Returns the operand named \p Op.  If \p MI does not have an
     811             :   /// operand named \c Op, this function returns nullptr.
     812             :   LLVM_READONLY
     813             :   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
     814             : 
     815             :   LLVM_READONLY
     816             :   const MachineOperand *getNamedOperand(const MachineInstr &MI,
     817             :                                         unsigned OpName) const {
     818      633131 :     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
     819             :   }
     820             : 
     821             :   /// Get required immediate operand
     822             :   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
     823          59 :     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
     824          59 :     return MI.getOperand(Idx).getImm();
     825             :   }
     826             : 
     827             :   uint64_t getDefaultRsrcDataFormat() const;
     828             :   uint64_t getScratchRsrcWords23() const;
     829             : 
     830             :   bool isLowLatencyInstruction(const MachineInstr &MI) const;
     831             :   bool isHighLatencyInstruction(const MachineInstr &MI) const;
     832             : 
     833             :   /// \brief Return the descriptor of the target-specific machine instruction
     834             :   /// that corresponds to the specified pseudo or native opcode.
     835             :   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
     836      657316 :     return get(pseudoToMCOpcode(Opcode));
     837             :   }
     838             : 
     839             :   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
     840             :   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
     841             : 
     842             :   unsigned isLoadFromStackSlot(const MachineInstr &MI,
     843             :                                int &FrameIndex) const override;
     844             :   unsigned isStoreToStackSlot(const MachineInstr &MI,
     845             :                               int &FrameIndex) const override;
     846             : 
     847             :   unsigned getInstBundleSize(const MachineInstr &MI) const;
     848             :   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
     849             : 
     850             :   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
     851             : 
     852             :   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
     853             : 
     854             :   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
     855             :                                  MachineBasicBlock *IfEnd) const;
     856             : 
     857             :   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
     858             :                                    MachineBasicBlock *LoopEnd) const;
     859             : 
     860             :   std::pair<unsigned, unsigned>
     861             :   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
     862             : 
     863             :   ArrayRef<std::pair<int, const char *>>
     864             :   getSerializableTargetIndices() const override;
     865             : 
     866             :   ArrayRef<std::pair<unsigned, const char *>>
     867             :   getSerializableDirectMachineOperandTargetFlags() const override;
     868             : 
     869             :   ScheduleHazardRecognizer *
     870             :   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
     871             :                                  const ScheduleDAG *DAG) const override;
     872             : 
     873             :   ScheduleHazardRecognizer *
     874             :   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
     875             : 
     876             :   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
     877             : 
     878             :   /// \brief Return a partially built integer add instruction without carry.
     879             :   /// Caller must add source operands.
     880             :   /// For pre-GFX9 it will generate unused carry destination operand.
     881             :   /// TODO: After GFX9 it should return a no-carry operation.
     882             :   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
     883             :                                     MachineBasicBlock::iterator I,
     884             :                                     const DebugLoc &DL,
     885             :                                     unsigned DestReg) const;
     886             : 
     887             :   static bool isKillTerminator(unsigned Opcode);
     888             :   const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
     889             : 
     890             :   static bool isLegalMUBUFImmOffset(unsigned Imm) {
     891             :     return isUInt<12>(Imm);
     892             :   }
     893             : };
     894             : 
     895             : namespace AMDGPU {
     896             : 
     897             :   LLVM_READONLY
     898             :   int getVOPe64(uint16_t Opcode);
     899             : 
     900             :   LLVM_READONLY
     901             :   int getVOPe32(uint16_t Opcode);
     902             : 
     903             :   LLVM_READONLY
     904             :   int getSDWAOp(uint16_t Opcode);
     905             : 
     906             :   LLVM_READONLY
     907             :   int getBasicFromSDWAOp(uint16_t Opcode);
     908             : 
     909             :   LLVM_READONLY
     910             :   int getCommuteRev(uint16_t Opcode);
     911             : 
     912             :   LLVM_READONLY
     913             :   int getCommuteOrig(uint16_t Opcode);
     914             : 
     915             :   LLVM_READONLY
     916             :   int getAddr64Inst(uint16_t Opcode);
     917             : 
     918             :   LLVM_READONLY
     919             :   int getAtomicRetOp(uint16_t Opcode);
     920             : 
     921             :   LLVM_READONLY
     922             :   int getAtomicNoRetOp(uint16_t Opcode);
     923             : 
     924             :   LLVM_READONLY
     925             :   int getSOPKOp(uint16_t Opcode);
     926             : 
     927             :   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
     928             :   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
     929             :   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
     930             :   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
     931             : 
     932             :   // For MachineOperands.
     933             :   enum TargetFlags {
     934             :     TF_LONG_BRANCH_FORWARD = 1 << 0,
     935             :     TF_LONG_BRANCH_BACKWARD = 1 << 1
     936             :   };
     937             : 
     938             : } // end namespace AMDGPU
     939             : 
     940             : namespace SI {
     941             : namespace KernelInputOffsets {
     942             : 
     943             : /// Offsets in bytes from the start of the input buffer
     944             : enum Offsets {
     945             :   NGROUPS_X = 0,
     946             :   NGROUPS_Y = 4,
     947             :   NGROUPS_Z = 8,
     948             :   GLOBAL_SIZE_X = 12,
     949             :   GLOBAL_SIZE_Y = 16,
     950             :   GLOBAL_SIZE_Z = 20,
     951             :   LOCAL_SIZE_X = 24,
     952             :   LOCAL_SIZE_Y = 28,
     953             :   LOCAL_SIZE_Z = 32
     954             : };
     955             : 
     956             : } // end namespace KernelInputOffsets
     957             : } // end namespace SI
     958             : 
     959             : } // end namespace llvm
     960             : 
     961             : #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H

Generated by: LCOV version 1.13