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

Generated by: LCOV version 1.13