Home | History | Annotate | Download | only in AMDGPU
      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   void swapOperands(MachineBasicBlock::iterator Inst) const;
     43 
     44   void lowerScalarAbs(SmallVectorImpl<MachineInstr *> &Worklist,
     45                       MachineInstr *Inst) const;
     46 
     47   void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
     48                                MachineInstr *Inst, unsigned Opcode) const;
     49 
     50   void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
     51                                 MachineInstr *Inst, unsigned Opcode) const;
     52 
     53   void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
     54                             MachineInstr *Inst) const;
     55   void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
     56                            MachineInstr *Inst) const;
     57 
     58   void addUsersToMoveToVALUWorklist(
     59     unsigned Reg, MachineRegisterInfo &MRI,
     60     SmallVectorImpl<MachineInstr *> &Worklist) const;
     61 
     62   const TargetRegisterClass *
     63   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
     64 
     65   bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
     66                                     MachineInstr *MIb) const;
     67 
     68   unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
     69 
     70 protected:
     71   MachineInstr *commuteInstructionImpl(MachineInstr *MI,
     72                                        bool NewMI,
     73                                        unsigned OpIdx0,
     74                                        unsigned OpIdx1) const override;
     75 
     76 public:
     77   explicit SIInstrInfo(const AMDGPUSubtarget &st);
     78 
     79   const SIRegisterInfo &getRegisterInfo() const override {
     80     return RI;
     81   }
     82 
     83   bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
     84                                          AliasAnalysis *AA) const override;
     85 
     86   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
     87                                int64_t &Offset1,
     88                                int64_t &Offset2) const override;
     89 
     90   bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
     91                              unsigned &Offset,
     92                              const TargetRegisterInfo *TRI) const final;
     93 
     94   bool shouldClusterLoads(MachineInstr *FirstLdSt,
     95                           MachineInstr *SecondLdSt,
     96                           unsigned NumLoads) const final;
     97 
     98   void copyPhysReg(MachineBasicBlock &MBB,
     99                    MachineBasicBlock::iterator MI, DebugLoc DL,
    100                    unsigned DestReg, unsigned SrcReg,
    101                    bool KillSrc) const override;
    102 
    103   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
    104                                     MachineBasicBlock::iterator MI,
    105                                     RegScavenger *RS,
    106                                     unsigned TmpReg,
    107                                     unsigned Offset,
    108                                     unsigned Size) const;
    109 
    110   void storeRegToStackSlot(MachineBasicBlock &MBB,
    111                            MachineBasicBlock::iterator MI,
    112                            unsigned SrcReg, bool isKill, int FrameIndex,
    113                            const TargetRegisterClass *RC,
    114                            const TargetRegisterInfo *TRI) const override;
    115 
    116   void loadRegFromStackSlot(MachineBasicBlock &MBB,
    117                             MachineBasicBlock::iterator MI,
    118                             unsigned DestReg, int FrameIndex,
    119                             const TargetRegisterClass *RC,
    120                             const TargetRegisterInfo *TRI) const override;
    121 
    122   bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
    123 
    124   // \brief Returns an opcode that can be used to move a value to a \p DstRC
    125   // register.  If there is no hardware instruction that can store to \p
    126   // DstRC, then AMDGPU::COPY is returned.
    127   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
    128 
    129   LLVM_READONLY
    130   int commuteOpcode(const MachineInstr &MI) const;
    131 
    132   bool findCommutedOpIndices(MachineInstr *MI,
    133                              unsigned &SrcOpIdx1,
    134                              unsigned &SrcOpIdx2) const override;
    135 
    136   bool areMemAccessesTriviallyDisjoint(
    137     MachineInstr *MIa, MachineInstr *MIb,
    138     AliasAnalysis *AA = nullptr) const override;
    139 
    140   MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
    141                               MachineBasicBlock::iterator I,
    142                               unsigned DstReg, unsigned SrcReg) const override;
    143   bool isMov(unsigned Opcode) const override;
    144 
    145   bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
    146                      unsigned Reg, MachineRegisterInfo *MRI) const final;
    147 
    148   unsigned getMachineCSELookAheadLimit() const override { return 500; }
    149 
    150   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
    151                                       MachineBasicBlock::iterator &MI,
    152                                       LiveVariables *LV) const override;
    153 
    154   static bool isSALU(const MachineInstr &MI) {
    155     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
    156   }
    157 
    158   bool isSALU(uint16_t Opcode) const {
    159     return get(Opcode).TSFlags & SIInstrFlags::SALU;
    160   }
    161 
    162   static bool isVALU(const MachineInstr &MI) {
    163     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
    164   }
    165 
    166   bool isVALU(uint16_t Opcode) const {
    167     return get(Opcode).TSFlags & SIInstrFlags::VALU;
    168   }
    169 
    170   static bool isSOP1(const MachineInstr &MI) {
    171     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
    172   }
    173 
    174   bool isSOP1(uint16_t Opcode) const {
    175     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
    176   }
    177 
    178   static bool isSOP2(const MachineInstr &MI) {
    179     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
    180   }
    181 
    182   bool isSOP2(uint16_t Opcode) const {
    183     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
    184   }
    185 
    186   static bool isSOPC(const MachineInstr &MI) {
    187     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
    188   }
    189 
    190   bool isSOPC(uint16_t Opcode) const {
    191     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
    192   }
    193 
    194   static bool isSOPK(const MachineInstr &MI) {
    195     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
    196   }
    197 
    198   bool isSOPK(uint16_t Opcode) const {
    199     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
    200   }
    201 
    202   static bool isSOPP(const MachineInstr &MI) {
    203     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
    204   }
    205 
    206   bool isSOPP(uint16_t Opcode) const {
    207     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
    208   }
    209 
    210   static bool isVOP1(const MachineInstr &MI) {
    211     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
    212   }
    213 
    214   bool isVOP1(uint16_t Opcode) const {
    215     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
    216   }
    217 
    218   static bool isVOP2(const MachineInstr &MI) {
    219     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
    220   }
    221 
    222   bool isVOP2(uint16_t Opcode) const {
    223     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
    224   }
    225 
    226   static bool isVOP3(const MachineInstr &MI) {
    227     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
    228   }
    229 
    230   bool isVOP3(uint16_t Opcode) const {
    231     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
    232   }
    233 
    234   static bool isVOPC(const MachineInstr &MI) {
    235     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
    236   }
    237 
    238   bool isVOPC(uint16_t Opcode) const {
    239     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
    240   }
    241 
    242   static bool isMUBUF(const MachineInstr &MI) {
    243     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
    244   }
    245 
    246   bool isMUBUF(uint16_t Opcode) const {
    247     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
    248   }
    249 
    250   static bool isMTBUF(const MachineInstr &MI) {
    251     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
    252   }
    253 
    254   bool isMTBUF(uint16_t Opcode) const {
    255     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
    256   }
    257 
    258   static bool isSMRD(const MachineInstr &MI) {
    259     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
    260   }
    261 
    262   bool isSMRD(uint16_t Opcode) const {
    263     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
    264   }
    265 
    266   static bool isDS(const MachineInstr &MI) {
    267     return MI.getDesc().TSFlags & SIInstrFlags::DS;
    268   }
    269 
    270   bool isDS(uint16_t Opcode) const {
    271     return get(Opcode).TSFlags & SIInstrFlags::DS;
    272   }
    273 
    274   static bool isMIMG(const MachineInstr &MI) {
    275     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
    276   }
    277 
    278   bool isMIMG(uint16_t Opcode) const {
    279     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
    280   }
    281 
    282   static bool isFLAT(const MachineInstr &MI) {
    283     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
    284   }
    285 
    286   bool isFLAT(uint16_t Opcode) const {
    287     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
    288   }
    289 
    290   static bool isWQM(const MachineInstr &MI) {
    291     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
    292   }
    293 
    294   bool isWQM(uint16_t Opcode) const {
    295     return get(Opcode).TSFlags & SIInstrFlags::WQM;
    296   }
    297 
    298   static bool isVGPRSpill(const MachineInstr &MI) {
    299     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
    300   }
    301 
    302   bool isVGPRSpill(uint16_t Opcode) const {
    303     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
    304   }
    305 
    306   bool isInlineConstant(const APInt &Imm) const;
    307   bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
    308   bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
    309 
    310   bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
    311                          const MachineOperand &MO) const;
    312 
    313   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
    314   /// This function will return false if you pass it a 32-bit instruction.
    315   bool hasVALU32BitEncoding(unsigned Opcode) const;
    316 
    317   /// \brief Returns true if this operand uses the constant bus.
    318   bool usesConstantBus(const MachineRegisterInfo &MRI,
    319                        const MachineOperand &MO,
    320                        unsigned OpSize) const;
    321 
    322   /// \brief Return true if this instruction has any modifiers.
    323   ///  e.g. src[012]_mod, omod, clamp.
    324   bool hasModifiers(unsigned Opcode) const;
    325 
    326   bool hasModifiersSet(const MachineInstr &MI,
    327                        unsigned OpName) const;
    328 
    329   bool verifyInstruction(const MachineInstr *MI,
    330                          StringRef &ErrInfo) const override;
    331 
    332   static unsigned getVALUOp(const MachineInstr &MI);
    333 
    334   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
    335 
    336   /// \brief Return the correct register class for \p OpNo.  For target-specific
    337   /// instructions, this will return the register class that has been defined
    338   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
    339   /// the register class of its machine operand.
    340   /// to infer the correct register class base on the other operands.
    341   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
    342                                            unsigned OpNo) const;
    343 
    344   /// \brief Return the size in bytes of the operand OpNo on the given
    345   // instruction opcode.
    346   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
    347     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
    348 
    349     if (OpInfo.RegClass == -1) {
    350       // If this is an immediate operand, this must be a 32-bit literal.
    351       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
    352       return 4;
    353     }
    354 
    355     return RI.getRegClass(OpInfo.RegClass)->getSize();
    356   }
    357 
    358   /// \brief This form should usually be preferred since it handles operands
    359   /// with unknown register classes.
    360   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
    361     return getOpRegClass(MI, OpNo)->getSize();
    362   }
    363 
    364   /// \returns true if it is legal for the operand at index \p OpNo
    365   /// to read a VGPR.
    366   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
    367 
    368   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
    369   /// a MOV.  For example:
    370   /// ADD_I32_e32 VGPR0, 15
    371   /// to
    372   /// MOV VGPR1, 15
    373   /// ADD_I32_e32 VGPR0, VGPR1
    374   ///
    375   /// If the operand being legalized is a register, then a COPY will be used
    376   /// instead of MOV.
    377   void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
    378 
    379   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
    380   /// for \p MI.
    381   bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
    382                       const MachineOperand *MO = nullptr) const;
    383 
    384   /// \brief Check if \p MO would be a valid operand for the given operand
    385   /// definition \p OpInfo. Note this does not attempt to validate constant bus
    386   /// restrictions (e.g. literal constant usage).
    387   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
    388                           const MCOperandInfo &OpInfo,
    389                           const MachineOperand &MO) const;
    390 
    391   /// \brief Check if \p MO (a register operand) is a legal register for the
    392   /// given operand description.
    393   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
    394                          const MCOperandInfo &OpInfo,
    395                          const MachineOperand &MO) const;
    396 
    397   /// \brief Legalize operands in \p MI by either commuting it or inserting a
    398   /// copy of src1.
    399   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr *MI) const;
    400 
    401   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
    402   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr *MI) const;
    403 
    404   /// \brief Legalize all operands in this instruction.  This function may
    405   /// create new instruction and insert them before \p MI.
    406   void legalizeOperands(MachineInstr *MI) const;
    407 
    408   /// \brief Split an SMRD instruction into two smaller loads of half the
    409   //  size storing the results in \p Lo and \p Hi.
    410   void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC,
    411                  unsigned HalfImmOp, unsigned HalfSGPROp,
    412                  MachineInstr *&Lo, MachineInstr *&Hi) const;
    413 
    414   void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI,
    415                       SmallVectorImpl<MachineInstr *> &Worklist) const;
    416 
    417   /// \brief Replace this instruction's opcode with the equivalent VALU
    418   /// opcode.  This function will also move the users of \p MI to the
    419   /// VALU if necessary.
    420   void moveToVALU(MachineInstr &MI) const;
    421 
    422   unsigned calculateIndirectAddress(unsigned RegIndex,
    423                                     unsigned Channel) const override;
    424 
    425   const TargetRegisterClass *getIndirectAddrRegClass() const override;
    426 
    427   MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
    428                                          MachineBasicBlock::iterator I,
    429                                          unsigned ValueReg,
    430                                          unsigned Address,
    431                                          unsigned OffsetReg) const override;
    432 
    433   MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
    434                                         MachineBasicBlock::iterator I,
    435                                         unsigned ValueReg,
    436                                         unsigned Address,
    437                                         unsigned OffsetReg) const override;
    438   void reserveIndirectRegisters(BitVector &Reserved,
    439                                 const MachineFunction &MF) const;
    440 
    441   void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I,
    442               unsigned SavReg, unsigned IndexReg) const;
    443 
    444   void insertWaitStates(MachineBasicBlock::iterator MI, int Count) const;
    445 
    446   /// \brief Returns the operand named \p Op.  If \p MI does not have an
    447   /// operand named \c Op, this function returns nullptr.
    448   LLVM_READONLY
    449   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
    450 
    451   LLVM_READONLY
    452   const MachineOperand *getNamedOperand(const MachineInstr &MI,
    453                                         unsigned OpName) const {
    454     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
    455   }
    456 
    457   /// Get required immediate operand
    458   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
    459     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
    460     return MI.getOperand(Idx).getImm();
    461   }
    462 
    463   uint64_t getDefaultRsrcDataFormat() const;
    464   uint64_t getScratchRsrcWords23() const;
    465 };
    466 
    467 namespace AMDGPU {
    468   LLVM_READONLY
    469   int getVOPe64(uint16_t Opcode);
    470 
    471   LLVM_READONLY
    472   int getVOPe32(uint16_t Opcode);
    473 
    474   LLVM_READONLY
    475   int getCommuteRev(uint16_t Opcode);
    476 
    477   LLVM_READONLY
    478   int getCommuteOrig(uint16_t Opcode);
    479 
    480   LLVM_READONLY
    481   int getAddr64Inst(uint16_t Opcode);
    482 
    483   LLVM_READONLY
    484   int getAtomicRetOp(uint16_t Opcode);
    485 
    486   LLVM_READONLY
    487   int getAtomicNoRetOp(uint16_t Opcode);
    488 
    489   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
    490   const uint64_t RSRC_TID_ENABLE = 1LL << 55;
    491 
    492 } // End namespace AMDGPU
    493 
    494 namespace SI {
    495 namespace KernelInputOffsets {
    496 
    497 /// Offsets in bytes from the start of the input buffer
    498 enum Offsets {
    499   NGROUPS_X = 0,
    500   NGROUPS_Y = 4,
    501   NGROUPS_Z = 8,
    502   GLOBAL_SIZE_X = 12,
    503   GLOBAL_SIZE_Y = 16,
    504   GLOBAL_SIZE_Z = 20,
    505   LOCAL_SIZE_X = 24,
    506   LOCAL_SIZE_Y = 28,
    507   LOCAL_SIZE_Z = 32
    508 };
    509 
    510 } // End namespace KernelInputOffsets
    511 } // End namespace SI
    512 
    513 } // End namespace llvm
    514 
    515 #endif
    516