Home | History | Annotate | Download | only in R600
      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 
     16 #ifndef LLVM_LIB_TARGET_R600_SIINSTRINFO_H
     17 #define LLVM_LIB_TARGET_R600_SIINSTRINFO_H
     18 
     19 #include "AMDGPUInstrInfo.h"
     20 #include "SIDefines.h"
     21 #include "SIRegisterInfo.h"
     22 
     23 namespace llvm {
     24 
     25 class SIInstrInfo : public AMDGPUInstrInfo {
     26 private:
     27   const SIRegisterInfo RI;
     28 
     29   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
     30                               MachineRegisterInfo &MRI,
     31                               MachineOperand &SuperReg,
     32                               const TargetRegisterClass *SuperRC,
     33                               unsigned SubIdx,
     34                               const TargetRegisterClass *SubRC) const;
     35   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
     36                                          MachineRegisterInfo &MRI,
     37                                          MachineOperand &SuperReg,
     38                                          const TargetRegisterClass *SuperRC,
     39                                          unsigned SubIdx,
     40                                          const TargetRegisterClass *SubRC) const;
     41 
     42   unsigned split64BitImm(SmallVectorImpl<MachineInstr *> &Worklist,
     43                          MachineBasicBlock::iterator MI,
     44                          MachineRegisterInfo &MRI,
     45                          const TargetRegisterClass *RC,
     46                          const MachineOperand &Op) const;
     47 
     48   void swapOperands(MachineBasicBlock::iterator Inst) const;
     49 
     50   void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
     51                                MachineInstr *Inst, unsigned Opcode) const;
     52 
     53   void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
     54                                 MachineInstr *Inst, unsigned Opcode) const;
     55 
     56   void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
     57                             MachineInstr *Inst) const;
     58   void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
     59                            MachineInstr *Inst) const;
     60 
     61   void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const;
     62 
     63   bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
     64                                     MachineInstr *MIb) const;
     65 
     66   unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
     67 
     68 public:
     69   explicit SIInstrInfo(const AMDGPUSubtarget &st);
     70 
     71   const SIRegisterInfo &getRegisterInfo() const override {
     72     return RI;
     73   }
     74 
     75   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
     76                                int64_t &Offset1,
     77                                int64_t &Offset2) const override;
     78 
     79   bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
     80                             unsigned &BaseReg, unsigned &Offset,
     81                             const TargetRegisterInfo *TRI) const final;
     82 
     83   bool shouldClusterLoads(MachineInstr *FirstLdSt,
     84                           MachineInstr *SecondLdSt,
     85                           unsigned NumLoads) const final;
     86 
     87   void copyPhysReg(MachineBasicBlock &MBB,
     88                    MachineBasicBlock::iterator MI, DebugLoc DL,
     89                    unsigned DestReg, unsigned SrcReg,
     90                    bool KillSrc) const override;
     91 
     92   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
     93                                     MachineBasicBlock::iterator MI,
     94                                     RegScavenger *RS,
     95                                     unsigned TmpReg,
     96                                     unsigned Offset,
     97                                     unsigned Size) const;
     98 
     99   void storeRegToStackSlot(MachineBasicBlock &MBB,
    100                            MachineBasicBlock::iterator MI,
    101                            unsigned SrcReg, bool isKill, int FrameIndex,
    102                            const TargetRegisterClass *RC,
    103                            const TargetRegisterInfo *TRI) const override;
    104 
    105   void loadRegFromStackSlot(MachineBasicBlock &MBB,
    106                             MachineBasicBlock::iterator MI,
    107                             unsigned DestReg, int FrameIndex,
    108                             const TargetRegisterClass *RC,
    109                             const TargetRegisterInfo *TRI) const override;
    110 
    111   bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
    112 
    113   // \brief Returns an opcode that can be used to move a value to a \p DstRC
    114   // register.  If there is no hardware instruction that can store to \p
    115   // DstRC, then AMDGPU::COPY is returned.
    116   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
    117   unsigned commuteOpcode(const MachineInstr &MI) const;
    118 
    119   MachineInstr *commuteInstruction(MachineInstr *MI,
    120                                    bool NewMI = false) const override;
    121   bool findCommutedOpIndices(MachineInstr *MI,
    122                              unsigned &SrcOpIdx1,
    123                              unsigned &SrcOpIdx2) const override;
    124 
    125   bool isTriviallyReMaterializable(const MachineInstr *MI,
    126                                    AliasAnalysis *AA = nullptr) const;
    127 
    128   bool areMemAccessesTriviallyDisjoint(
    129     MachineInstr *MIa, MachineInstr *MIb,
    130     AliasAnalysis *AA = nullptr) const override;
    131 
    132   MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
    133                               MachineBasicBlock::iterator I,
    134                               unsigned DstReg, unsigned SrcReg) const override;
    135   bool isMov(unsigned Opcode) const override;
    136 
    137   bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override;
    138 
    139   bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
    140                      unsigned Reg, MachineRegisterInfo *MRI) const final;
    141 
    142   bool isSALU(uint16_t Opcode) const {
    143     return get(Opcode).TSFlags & SIInstrFlags::SALU;
    144   }
    145 
    146   bool isVALU(uint16_t Opcode) const {
    147     return get(Opcode).TSFlags & SIInstrFlags::VALU;
    148   }
    149 
    150   bool isSOP1(uint16_t Opcode) const {
    151     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
    152   }
    153 
    154   bool isSOP2(uint16_t Opcode) const {
    155     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
    156   }
    157 
    158   bool isSOPC(uint16_t Opcode) const {
    159     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
    160   }
    161 
    162   bool isSOPK(uint16_t Opcode) const {
    163     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
    164   }
    165 
    166   bool isSOPP(uint16_t Opcode) const {
    167     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
    168   }
    169 
    170   bool isVOP1(uint16_t Opcode) const {
    171     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
    172   }
    173 
    174   bool isVOP2(uint16_t Opcode) const {
    175     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
    176   }
    177 
    178   bool isVOP3(uint16_t Opcode) const {
    179     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
    180   }
    181 
    182   bool isVOPC(uint16_t Opcode) const {
    183     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
    184   }
    185 
    186   bool isMUBUF(uint16_t Opcode) const {
    187     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
    188   }
    189 
    190   bool isMTBUF(uint16_t Opcode) const {
    191     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
    192   }
    193 
    194   bool isSMRD(uint16_t Opcode) const {
    195     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
    196   }
    197 
    198   bool isDS(uint16_t Opcode) const {
    199     return get(Opcode).TSFlags & SIInstrFlags::DS;
    200   }
    201 
    202   bool isMIMG(uint16_t Opcode) const {
    203     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
    204   }
    205 
    206   bool isFLAT(uint16_t Opcode) const {
    207     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
    208   }
    209 
    210   bool isWQM(uint16_t Opcode) const {
    211     return get(Opcode).TSFlags & SIInstrFlags::WQM;
    212   }
    213 
    214   bool isInlineConstant(const APInt &Imm) const;
    215   bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
    216   bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
    217 
    218   bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
    219                          const MachineOperand &MO) const;
    220 
    221   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
    222   /// This function will return false if you pass it a 32-bit instruction.
    223   bool hasVALU32BitEncoding(unsigned Opcode) const;
    224 
    225   /// \brief Returns true if this operand uses the constant bus.
    226   bool usesConstantBus(const MachineRegisterInfo &MRI,
    227                        const MachineOperand &MO,
    228                        unsigned OpSize) const;
    229 
    230   /// \brief Return true if this instruction has any modifiers.
    231   ///  e.g. src[012]_mod, omod, clamp.
    232   bool hasModifiers(unsigned Opcode) const;
    233 
    234   bool hasModifiersSet(const MachineInstr &MI,
    235                        unsigned OpName) const;
    236 
    237   bool verifyInstruction(const MachineInstr *MI,
    238                          StringRef &ErrInfo) const override;
    239 
    240   static unsigned getVALUOp(const MachineInstr &MI);
    241 
    242   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
    243 
    244   /// \brief Return the correct register class for \p OpNo.  For target-specific
    245   /// instructions, this will return the register class that has been defined
    246   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
    247   /// the register class of its machine operand.
    248   /// to infer the correct register class base on the other operands.
    249   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
    250                                            unsigned OpNo) const;
    251 
    252   /// \brief Return the size in bytes of the operand OpNo on the given
    253   // instruction opcode.
    254   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
    255     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
    256 
    257     if (OpInfo.RegClass == -1) {
    258       // If this is an immediate operand, this must be a 32-bit literal.
    259       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
    260       return 4;
    261     }
    262 
    263     return RI.getRegClass(OpInfo.RegClass)->getSize();
    264   }
    265 
    266   /// \brief This form should usually be preferred since it handles operands
    267   /// with unknown register classes.
    268   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
    269     return getOpRegClass(MI, OpNo)->getSize();
    270   }
    271 
    272   /// \returns true if it is legal for the operand at index \p OpNo
    273   /// to read a VGPR.
    274   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
    275 
    276   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
    277   /// a MOV.  For example:
    278   /// ADD_I32_e32 VGPR0, 15
    279   /// to
    280   /// MOV VGPR1, 15
    281   /// ADD_I32_e32 VGPR0, VGPR1
    282   ///
    283   /// If the operand being legalized is a register, then a COPY will be used
    284   /// instead of MOV.
    285   void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
    286 
    287   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
    288   /// for \p MI.
    289   bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
    290                       const MachineOperand *MO = nullptr) const;
    291 
    292   /// \brief Legalize all operands in this instruction.  This function may
    293   /// create new instruction and insert them before \p MI.
    294   void legalizeOperands(MachineInstr *MI) const;
    295 
    296   /// \brief Split an SMRD instruction into two smaller loads of half the
    297   //  size storing the results in \p Lo and \p Hi.
    298   void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC,
    299                  unsigned HalfImmOp, unsigned HalfSGPROp,
    300                  MachineInstr *&Lo, MachineInstr *&Hi) const;
    301 
    302   void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI) const;
    303 
    304   /// \brief Replace this instruction's opcode with the equivalent VALU
    305   /// opcode.  This function will also move the users of \p MI to the
    306   /// VALU if necessary.
    307   void moveToVALU(MachineInstr &MI) const;
    308 
    309   unsigned calculateIndirectAddress(unsigned RegIndex,
    310                                     unsigned Channel) const override;
    311 
    312   const TargetRegisterClass *getIndirectAddrRegClass() const override;
    313 
    314   MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
    315                                          MachineBasicBlock::iterator I,
    316                                          unsigned ValueReg,
    317                                          unsigned Address,
    318                                          unsigned OffsetReg) const override;
    319 
    320   MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
    321                                         MachineBasicBlock::iterator I,
    322                                         unsigned ValueReg,
    323                                         unsigned Address,
    324                                         unsigned OffsetReg) const override;
    325   void reserveIndirectRegisters(BitVector &Reserved,
    326                                 const MachineFunction &MF) const;
    327 
    328   void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I,
    329               unsigned SavReg, unsigned IndexReg) const;
    330 
    331   void insertNOPs(MachineBasicBlock::iterator MI, int Count) const;
    332 
    333   /// \brief Returns the operand named \p Op.  If \p MI does not have an
    334   /// operand named \c Op, this function returns nullptr.
    335   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
    336 
    337   const MachineOperand *getNamedOperand(const MachineInstr &MI,
    338                                         unsigned OpName) const {
    339     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
    340   }
    341 
    342   uint64_t getDefaultRsrcDataFormat() const;
    343 
    344 };
    345 
    346 namespace AMDGPU {
    347 
    348   int getVOPe64(uint16_t Opcode);
    349   int getVOPe32(uint16_t Opcode);
    350   int getCommuteRev(uint16_t Opcode);
    351   int getCommuteOrig(uint16_t Opcode);
    352   int getAddr64Inst(uint16_t Opcode);
    353   int getAtomicRetOp(uint16_t Opcode);
    354   int getAtomicNoRetOp(uint16_t Opcode);
    355 
    356   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
    357   const uint64_t RSRC_TID_ENABLE = 1LL << 55;
    358 
    359 } // End namespace AMDGPU
    360 
    361 namespace SI {
    362 namespace KernelInputOffsets {
    363 
    364 /// Offsets in bytes from the start of the input buffer
    365 enum Offsets {
    366   NGROUPS_X = 0,
    367   NGROUPS_Y = 4,
    368   NGROUPS_Z = 8,
    369   GLOBAL_SIZE_X = 12,
    370   GLOBAL_SIZE_Y = 16,
    371   GLOBAL_SIZE_Z = 20,
    372   LOCAL_SIZE_X = 24,
    373   LOCAL_SIZE_Y = 28,
    374   LOCAL_SIZE_Z = 32
    375 };
    376 
    377 } // End namespace KernelInputOffsets
    378 } // End namespace SI
    379 
    380 } // End namespace llvm
    381 
    382 #endif
    383