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

Generated by: LCOV version 1.13