Home | History | Annotate | Download | only in AMDGPU
      1 //===-- R600InstrInfo.h - R600 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 R600InstrInfo
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H
     16 #define LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H
     17 
     18 #include "AMDGPUInstrInfo.h"
     19 #include "R600RegisterInfo.h"
     20 
     21 namespace llvm {
     22 class AMDGPUTargetMachine;
     23 class DFAPacketizer;
     24 class MachineFunction;
     25 class MachineInstr;
     26 class MachineInstrBuilder;
     27 class R600Subtarget;
     28 
     29 class R600InstrInfo final : public AMDGPUInstrInfo {
     30 private:
     31   const R600RegisterInfo RI;
     32   const R600Subtarget &ST;
     33 
     34   std::vector<std::pair<int, unsigned>>
     35   ExtractSrcs(MachineInstr &MI, const DenseMap<unsigned, unsigned> &PV,
     36               unsigned &ConstCount) const;
     37 
     38   MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
     39                                         MachineBasicBlock::iterator I,
     40                                         unsigned ValueReg, unsigned Address,
     41                                         unsigned OffsetReg,
     42                                         unsigned AddrChan) const;
     43 
     44   MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
     45                                          MachineBasicBlock::iterator I,
     46                                          unsigned ValueReg, unsigned Address,
     47                                          unsigned OffsetReg,
     48                                          unsigned AddrChan) const;
     49 public:
     50   enum BankSwizzle {
     51     ALU_VEC_012_SCL_210 = 0,
     52     ALU_VEC_021_SCL_122,
     53     ALU_VEC_120_SCL_212,
     54     ALU_VEC_102_SCL_221,
     55     ALU_VEC_201,
     56     ALU_VEC_210
     57   };
     58 
     59   explicit R600InstrInfo(const R600Subtarget &);
     60 
     61   const R600RegisterInfo &getRegisterInfo() const {
     62     return RI;
     63   }
     64 
     65   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
     66                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
     67                    bool KillSrc) const override;
     68   bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
     69                            MachineBasicBlock::iterator MBBI) const override;
     70 
     71   bool isTrig(const MachineInstr &MI) const;
     72   bool isPlaceHolderOpcode(unsigned opcode) const;
     73   bool isReductionOp(unsigned opcode) const;
     74   bool isCubeOp(unsigned opcode) const;
     75 
     76   /// \returns true if this \p Opcode represents an ALU instruction.
     77   bool isALUInstr(unsigned Opcode) const;
     78   bool hasInstrModifiers(unsigned Opcode) const;
     79   bool isLDSInstr(unsigned Opcode) const;
     80   bool isLDSNoRetInstr(unsigned Opcode) const;
     81   bool isLDSRetInstr(unsigned Opcode) const;
     82 
     83   /// \returns true if this \p Opcode represents an ALU instruction or an
     84   /// instruction that will be lowered in ExpandSpecialInstrs Pass.
     85   bool canBeConsideredALU(const MachineInstr &MI) const;
     86 
     87   bool isTransOnly(unsigned Opcode) const;
     88   bool isTransOnly(const MachineInstr &MI) const;
     89   bool isVectorOnly(unsigned Opcode) const;
     90   bool isVectorOnly(const MachineInstr &MI) const;
     91   bool isExport(unsigned Opcode) const;
     92 
     93   bool usesVertexCache(unsigned Opcode) const;
     94   bool usesVertexCache(const MachineInstr &MI) const;
     95   bool usesTextureCache(unsigned Opcode) const;
     96   bool usesTextureCache(const MachineInstr &MI) const;
     97 
     98   bool mustBeLastInClause(unsigned Opcode) const;
     99   bool usesAddressRegister(MachineInstr &MI) const;
    100   bool definesAddressRegister(MachineInstr &MI) const;
    101   bool readsLDSSrcReg(const MachineInstr &MI) const;
    102 
    103   /// \returns The operand index for the given source number.  Legal values
    104   /// for SrcNum are 0, 1, and 2.
    105   int getSrcIdx(unsigned Opcode, unsigned SrcNum) const;
    106   /// \returns The operand Index for the Sel operand given an index to one
    107   /// of the instruction's src operands.
    108   int getSelIdx(unsigned Opcode, unsigned SrcIdx) const;
    109 
    110   /// \returns a pair for each src of an ALU instructions.
    111   /// The first member of a pair is the register id.
    112   /// If register is ALU_CONST, second member is SEL.
    113   /// If register is ALU_LITERAL, second member is IMM.
    114   /// Otherwise, second member value is undefined.
    115   SmallVector<std::pair<MachineOperand *, int64_t>, 3>
    116   getSrcs(MachineInstr &MI) const;
    117 
    118   unsigned  isLegalUpTo(
    119     const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
    120     const std::vector<R600InstrInfo::BankSwizzle> &Swz,
    121     const std::vector<std::pair<int, unsigned> > &TransSrcs,
    122     R600InstrInfo::BankSwizzle TransSwz) const;
    123 
    124   bool FindSwizzleForVectorSlot(
    125     const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs,
    126     std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate,
    127     const std::vector<std::pair<int, unsigned> > &TransSrcs,
    128     R600InstrInfo::BankSwizzle TransSwz) const;
    129 
    130   /// Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210
    131   /// returns true and the first (in lexical order) BankSwizzle affectation
    132   /// starting from the one already provided in the Instruction Group MIs that
    133   /// fits Read Port limitations in BS if available. Otherwise returns false
    134   /// and undefined content in BS.
    135   /// isLastAluTrans should be set if the last Alu of MIs will be executed on
    136   /// Trans ALU. In this case, ValidTSwizzle returns the BankSwizzle value to
    137   /// apply to the last instruction.
    138   /// PV holds GPR to PV registers in the Instruction Group MIs.
    139   bool fitsReadPortLimitations(const std::vector<MachineInstr *> &MIs,
    140                                const DenseMap<unsigned, unsigned> &PV,
    141                                std::vector<BankSwizzle> &BS,
    142                                bool isLastAluTrans) const;
    143 
    144   /// An instruction group can only access 2 channel pair (either [XY] or [ZW])
    145   /// from KCache bank on R700+. This function check if MI set in input meet
    146   /// this limitations
    147   bool fitsConstReadLimitations(const std::vector<MachineInstr *> &) const;
    148   /// Same but using const index set instead of MI set.
    149   bool fitsConstReadLimitations(const std::vector<unsigned>&) const;
    150 
    151   /// \brief Vector instructions are instructions that must fill all
    152   /// instruction slots within an instruction group.
    153   bool isVector(const MachineInstr &MI) const;
    154 
    155   bool isMov(unsigned Opcode) const;
    156 
    157   DFAPacketizer *
    158   CreateTargetScheduleState(const TargetSubtargetInfo &) const override;
    159 
    160   bool ReverseBranchCondition(
    161     SmallVectorImpl<MachineOperand> &Cond) const override;
    162 
    163   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
    164                      MachineBasicBlock *&FBB,
    165                      SmallVectorImpl<MachineOperand> &Cond,
    166                      bool AllowModify) const override;
    167 
    168   unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    169                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
    170                         const DebugLoc &DL) const override;
    171 
    172   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
    173 
    174   bool isPredicated(const MachineInstr &MI) const override;
    175 
    176   bool isPredicable(MachineInstr &MI) const override;
    177 
    178   bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
    179                                  BranchProbability Probability) const override;
    180 
    181   bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
    182                            unsigned ExtraPredCycles,
    183                            BranchProbability Probability) const override ;
    184 
    185   bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
    186                            unsigned NumTCycles, unsigned ExtraTCycles,
    187                            MachineBasicBlock &FMBB,
    188                            unsigned NumFCycles, unsigned ExtraFCycles,
    189                            BranchProbability Probability) const override;
    190 
    191   bool DefinesPredicate(MachineInstr &MI,
    192                         std::vector<MachineOperand> &Pred) const override;
    193 
    194   bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
    195                          ArrayRef<MachineOperand> Pred2) const override;
    196 
    197   bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
    198                                  MachineBasicBlock &FMBB) const override;
    199 
    200   bool PredicateInstruction(MachineInstr &MI,
    201                             ArrayRef<MachineOperand> Pred) const override;
    202 
    203   unsigned int getPredicationCost(const MachineInstr &) const override;
    204 
    205   unsigned int getInstrLatency(const InstrItineraryData *ItinData,
    206                                const MachineInstr &MI,
    207                                unsigned *PredCost = nullptr) const override;
    208 
    209   int getInstrLatency(const InstrItineraryData *ItinData,
    210                       SDNode *Node) const override { return 1;}
    211 
    212   bool expandPostRAPseudo(MachineInstr &MI) const override;
    213 
    214   /// \brief Reserve the registers that may be accesed using indirect addressing.
    215   void reserveIndirectRegisters(BitVector &Reserved,
    216                                 const MachineFunction &MF) const;
    217 
    218   /// Calculate the "Indirect Address" for the given \p RegIndex and
    219   /// \p Channel
    220   ///
    221   /// We model indirect addressing using a virtual address space that can be
    222   /// accesed with loads and stores.  The "Indirect Address" is the memory
    223   /// address in this virtual address space that maps to the given \p RegIndex
    224   /// and \p Channel.
    225   unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const;
    226 
    227 
    228   /// \returns The register class to be used for loading and storing values
    229   /// from an "Indirect Address" .
    230   const TargetRegisterClass *getIndirectAddrRegClass() const;
    231 
    232   /// \returns the smallest register index that will be accessed by an indirect
    233   /// read or write or -1 if indirect addressing is not used by this program.
    234   int getIndirectIndexBegin(const MachineFunction &MF) const;
    235 
    236   /// \returns the largest register index that will be accessed by an indirect
    237   /// read or write or -1 if indirect addressing is not used by this program.
    238   int getIndirectIndexEnd(const MachineFunction &MF) const;
    239 
    240   /// \brief Build instruction(s) for an indirect register write.
    241   ///
    242   /// \returns The instruction that performs the indirect register write
    243   MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
    244                                          MachineBasicBlock::iterator I,
    245                                          unsigned ValueReg, unsigned Address,
    246                                          unsigned OffsetReg) const;
    247 
    248   /// \brief Build instruction(s) for an indirect register read.
    249   ///
    250   /// \returns The instruction that performs the indirect register read
    251   MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
    252                                         MachineBasicBlock::iterator I,
    253                                         unsigned ValueReg, unsigned Address,
    254                                         unsigned OffsetReg) const;
    255 
    256   unsigned getMaxAlusPerClause() const;
    257 
    258   /// buildDefaultInstruction - This function returns a MachineInstr with all
    259   /// the instruction modifiers initialized to their default values.  You can
    260   /// use this function to avoid manually specifying each instruction modifier
    261   /// operand when building a new instruction.
    262   ///
    263   /// \returns a MachineInstr with all the instruction modifiers initialized
    264   /// to their default values.
    265   MachineInstrBuilder buildDefaultInstruction(MachineBasicBlock &MBB,
    266                                               MachineBasicBlock::iterator I,
    267                                               unsigned Opcode,
    268                                               unsigned DstReg,
    269                                               unsigned Src0Reg,
    270                                               unsigned Src1Reg = 0) const;
    271 
    272   MachineInstr *buildSlotOfVectorInstruction(MachineBasicBlock &MBB,
    273                                              MachineInstr *MI,
    274                                              unsigned Slot,
    275                                              unsigned DstReg) const;
    276 
    277   MachineInstr *buildMovImm(MachineBasicBlock &BB,
    278                             MachineBasicBlock::iterator I,
    279                             unsigned DstReg,
    280                             uint64_t Imm) const;
    281 
    282   MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
    283                               MachineBasicBlock::iterator I,
    284                               unsigned DstReg, unsigned SrcReg) const;
    285 
    286   /// \brief Get the index of Op in the MachineInstr.
    287   ///
    288   /// \returns -1 if the Instruction does not contain the specified \p Op.
    289   int getOperandIdx(const MachineInstr &MI, unsigned Op) const;
    290 
    291   /// \brief Get the index of \p Op for the given Opcode.
    292   ///
    293   /// \returns -1 if the Instruction does not contain the specified \p Op.
    294   int getOperandIdx(unsigned Opcode, unsigned Op) const;
    295 
    296   /// \brief Helper function for setting instruction flag values.
    297   void setImmOperand(MachineInstr &MI, unsigned Op, int64_t Imm) const;
    298 
    299   /// \returns true if this instruction has an operand for storing target flags.
    300   bool hasFlagOperand(const MachineInstr &MI) const;
    301 
    302   ///\brief Add one of the MO_FLAG* flags to the specified \p Operand.
    303   void addFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const;
    304 
    305   ///\brief Determine if the specified \p Flag is set on this \p Operand.
    306   bool isFlagSet(const MachineInstr &MI, unsigned Operand, unsigned Flag) const;
    307 
    308   /// \param SrcIdx The register source to set the flag on (e.g src0, src1, src2)
    309   /// \param Flag The flag being set.
    310   ///
    311   /// \returns the operand containing the flags for this instruction.
    312   MachineOperand &getFlagOp(MachineInstr &MI, unsigned SrcIdx = 0,
    313                             unsigned Flag = 0) const;
    314 
    315   /// \brief Clear the specified flag on the instruction.
    316   void clearFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const;
    317 
    318   // Helper functions that check the opcode for status information
    319   bool isRegisterStore(const MachineInstr &MI) const;
    320   bool isRegisterLoad(const MachineInstr &MI) const;
    321 };
    322 
    323 namespace AMDGPU {
    324 
    325 int getLDSNoRetOp(uint16_t Opcode);
    326 
    327 } //End namespace AMDGPU
    328 
    329 } // End llvm namespace
    330 
    331 #endif
    332