LLVM API Documentation

AMDGPUInstrInfo.h
Go to the documentation of this file.
00001 //===-- AMDGPUInstrInfo.h - AMDGPU Instruction Information ------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 /// \file
00011 /// \brief Contains the definition of a TargetInstrInfo class that is common
00012 /// to all AMD GPUs.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_LIB_TARGET_R600_AMDGPUINSTRINFO_H
00017 #define LLVM_LIB_TARGET_R600_AMDGPUINSTRINFO_H
00018 
00019 #include "AMDGPURegisterInfo.h"
00020 #include "llvm/Target/TargetInstrInfo.h"
00021 #include <map>
00022 
00023 #define GET_INSTRINFO_HEADER
00024 #define GET_INSTRINFO_ENUM
00025 #define GET_INSTRINFO_OPERAND_ENUM
00026 #include "AMDGPUGenInstrInfo.inc"
00027 
00028 #define OPCODE_IS_ZERO_INT AMDGPU::PRED_SETE_INT
00029 #define OPCODE_IS_NOT_ZERO_INT AMDGPU::PRED_SETNE_INT
00030 #define OPCODE_IS_ZERO AMDGPU::PRED_SETE
00031 #define OPCODE_IS_NOT_ZERO AMDGPU::PRED_SETNE
00032 
00033 namespace llvm {
00034 
00035 class AMDGPUSubtarget;
00036 class MachineFunction;
00037 class MachineInstr;
00038 class MachineInstrBuilder;
00039 
00040 class AMDGPUInstrInfo : public AMDGPUGenInstrInfo {
00041 private:
00042   const AMDGPURegisterInfo RI;
00043   bool getNextBranchInstr(MachineBasicBlock::iterator &iter,
00044                           MachineBasicBlock &MBB) const;
00045   virtual void anchor();
00046 protected:
00047   const AMDGPUSubtarget &ST;
00048 public:
00049   explicit AMDGPUInstrInfo(const AMDGPUSubtarget &st);
00050 
00051   virtual const AMDGPURegisterInfo &getRegisterInfo() const = 0;
00052 
00053   bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,
00054                              unsigned &DstReg, unsigned &SubIdx) const override;
00055 
00056   unsigned isLoadFromStackSlot(const MachineInstr *MI,
00057                                int &FrameIndex) const override;
00058   unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI,
00059                                      int &FrameIndex) const override;
00060   bool hasLoadFromStackSlot(const MachineInstr *MI,
00061                             const MachineMemOperand *&MMO,
00062                             int &FrameIndex) const override;
00063   unsigned isStoreFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
00064   unsigned isStoreFromStackSlotPostFE(const MachineInstr *MI,
00065                                       int &FrameIndex) const;
00066   bool hasStoreFromStackSlot(const MachineInstr *MI,
00067                              const MachineMemOperand *&MMO,
00068                              int &FrameIndex) const;
00069 
00070   MachineInstr *
00071   convertToThreeAddress(MachineFunction::iterator &MFI,
00072                         MachineBasicBlock::iterator &MBBI,
00073                         LiveVariables *LV) const override;
00074 
00075 
00076   bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
00077 
00078   void storeRegToStackSlot(MachineBasicBlock &MBB,
00079                            MachineBasicBlock::iterator MI,
00080                            unsigned SrcReg, bool isKill, int FrameIndex,
00081                            const TargetRegisterClass *RC,
00082                            const TargetRegisterInfo *TRI) const override;
00083   void loadRegFromStackSlot(MachineBasicBlock &MBB,
00084                             MachineBasicBlock::iterator MI,
00085                             unsigned DestReg, int FrameIndex,
00086                             const TargetRegisterClass *RC,
00087                             const TargetRegisterInfo *TRI) const override;
00088 
00089 protected:
00090   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
00091                                       MachineInstr *MI,
00092                                       const SmallVectorImpl<unsigned> &Ops,
00093                                       int FrameIndex) const override;
00094   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
00095                                       MachineInstr *MI,
00096                                       const SmallVectorImpl<unsigned> &Ops,
00097                                       MachineInstr *LoadMI) const override;
00098 public:
00099   /// \returns the smallest register index that will be accessed by an indirect
00100   /// read or write or -1 if indirect addressing is not used by this program.
00101   int getIndirectIndexBegin(const MachineFunction &MF) const;
00102 
00103   /// \returns the largest register index that will be accessed by an indirect
00104   /// read or write or -1 if indirect addressing is not used by this program.
00105   int getIndirectIndexEnd(const MachineFunction &MF) const;
00106 
00107   bool canFoldMemoryOperand(const MachineInstr *MI,
00108                            const SmallVectorImpl<unsigned> &Ops) const override;
00109   bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
00110                         unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
00111                         SmallVectorImpl<MachineInstr *> &NewMIs) const override;
00112   bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
00113                            SmallVectorImpl<SDNode *> &NewNodes) const override;
00114   unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
00115                                bool UnfoldLoad, bool UnfoldStore,
00116                                unsigned *LoadRegIndex = nullptr) const override;
00117 
00118   bool enableClusterLoads() const override;
00119 
00120   bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
00121                                int64_t Offset1, int64_t Offset2,
00122                                unsigned NumLoads) const override;
00123 
00124   bool
00125   ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
00126   void insertNoop(MachineBasicBlock &MBB,
00127                   MachineBasicBlock::iterator MI) const override;
00128   bool isPredicated(const MachineInstr *MI) const override;
00129   bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
00130                    const SmallVectorImpl<MachineOperand> &Pred2) const override;
00131   bool DefinesPredicate(MachineInstr *MI,
00132                         std::vector<MachineOperand> &Pred) const override;
00133   bool isPredicable(MachineInstr *MI) const override;
00134   bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override;
00135 
00136   // Helper functions that check the opcode for status information
00137   bool isRegisterStore(const MachineInstr &MI) const;
00138   bool isRegisterLoad(const MachineInstr &MI) const;
00139 
00140 //===---------------------------------------------------------------------===//
00141 // Pure virtual funtions to be implemented by sub-classes.
00142 //===---------------------------------------------------------------------===//
00143 
00144   virtual bool isMov(unsigned opcode) const = 0;
00145 
00146   /// \brief Calculate the "Indirect Address" for the given \p RegIndex and
00147   ///        \p Channel
00148   ///
00149   /// We model indirect addressing using a virtual address space that can be
00150   /// accesed with loads and stores.  The "Indirect Address" is the memory
00151   /// address in this virtual address space that maps to the given \p RegIndex
00152   /// and \p Channel.
00153   virtual unsigned calculateIndirectAddress(unsigned RegIndex,
00154                                             unsigned Channel) const = 0;
00155 
00156   /// \returns The register class to be used for loading and storing values
00157   /// from an "Indirect Address" .
00158   virtual const TargetRegisterClass *getIndirectAddrRegClass() const = 0;
00159 
00160   /// \brief Build instruction(s) for an indirect register write.
00161   ///
00162   /// \returns The instruction that performs the indirect register write
00163   virtual MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
00164                                     MachineBasicBlock::iterator I,
00165                                     unsigned ValueReg, unsigned Address,
00166                                     unsigned OffsetReg) const = 0;
00167 
00168   /// \brief Build instruction(s) for an indirect register read.
00169   ///
00170   /// \returns The instruction that performs the indirect register read
00171   virtual MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
00172                                     MachineBasicBlock::iterator I,
00173                                     unsigned ValueReg, unsigned Address,
00174                                     unsigned OffsetReg) const = 0;
00175 
00176   /// \brief Build a MOV instruction.
00177   virtual MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
00178                                       MachineBasicBlock::iterator I,
00179                                       unsigned DstReg, unsigned SrcReg) const = 0;
00180 
00181   /// \brief Given a MIMG \p Opcode that writes all 4 channels, return the
00182   /// equivalent opcode that writes \p Channels Channels.
00183   int getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const;
00184 
00185 };
00186 
00187 namespace AMDGPU {
00188   int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
00189 }  // End namespace AMDGPU
00190 
00191 } // End llvm namespace
00192 
00193 #define AMDGPU_FLAG_REGISTER_LOAD  (UINT64_C(1) << 63)
00194 #define AMDGPU_FLAG_REGISTER_STORE (UINT64_C(1) << 62)
00195 
00196 #endif