1 //===-- AMDGPUInstrInfo.h - AMDGPU Instruction Information ------*- 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 Contains the definition of a TargetInstrInfo class that is common 12 /// to all AMD GPUs. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef AMDGPUINSTRUCTIONINFO_H 17 #define AMDGPUINSTRUCTIONINFO_H 18 19 #include "AMDGPUInstrInfo.h" 20 #include "AMDGPURegisterInfo.h" 21 #include "llvm/Target/TargetInstrInfo.h" 22 #include <map> 23 24 #define GET_INSTRINFO_HEADER 25 #define GET_INSTRINFO_ENUM 26 #define GET_INSTRINFO_OPERAND_ENUM 27 #include "AMDGPUGenInstrInfo.inc" 28 29 #define OPCODE_IS_ZERO_INT AMDGPU::PRED_SETE_INT 30 #define OPCODE_IS_NOT_ZERO_INT AMDGPU::PRED_SETNE_INT 31 #define OPCODE_IS_ZERO AMDGPU::PRED_SETE 32 #define OPCODE_IS_NOT_ZERO AMDGPU::PRED_SETNE 33 34 namespace llvm { 35 36 class AMDGPUSubtarget; 37 class MachineFunction; 38 class MachineInstr; 39 class MachineInstrBuilder; 40 41 class AMDGPUInstrInfo : public AMDGPUGenInstrInfo { 42 private: 43 const AMDGPURegisterInfo RI; 44 bool getNextBranchInstr(MachineBasicBlock::iterator &iter, 45 MachineBasicBlock &MBB) const; 46 virtual void anchor(); 47 protected: 48 const AMDGPUSubtarget &ST; 49 public: 50 explicit AMDGPUInstrInfo(const AMDGPUSubtarget &st); 51 52 virtual const AMDGPURegisterInfo &getRegisterInfo() const = 0; 53 54 bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, 55 unsigned &DstReg, unsigned &SubIdx) const override; 56 57 unsigned isLoadFromStackSlot(const MachineInstr *MI, 58 int &FrameIndex) const override; 59 unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, 60 int &FrameIndex) const override; 61 bool hasLoadFromStackSlot(const MachineInstr *MI, 62 const MachineMemOperand *&MMO, 63 int &FrameIndex) const override; 64 unsigned isStoreFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; 65 unsigned isStoreFromStackSlotPostFE(const MachineInstr *MI, 66 int &FrameIndex) const; 67 bool hasStoreFromStackSlot(const MachineInstr *MI, 68 const MachineMemOperand *&MMO, 69 int &FrameIndex) const; 70 71 MachineInstr * 72 convertToThreeAddress(MachineFunction::iterator &MFI, 73 MachineBasicBlock::iterator &MBBI, 74 LiveVariables *LV) const override; 75 76 77 virtual void copyPhysReg(MachineBasicBlock &MBB, 78 MachineBasicBlock::iterator MI, DebugLoc DL, 79 unsigned DestReg, unsigned SrcReg, 80 bool KillSrc) const = 0; 81 82 bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override; 83 84 void storeRegToStackSlot(MachineBasicBlock &MBB, 85 MachineBasicBlock::iterator MI, 86 unsigned SrcReg, bool isKill, int FrameIndex, 87 const TargetRegisterClass *RC, 88 const TargetRegisterInfo *TRI) const override; 89 void loadRegFromStackSlot(MachineBasicBlock &MBB, 90 MachineBasicBlock::iterator MI, 91 unsigned DestReg, int FrameIndex, 92 const TargetRegisterClass *RC, 93 const TargetRegisterInfo *TRI) const override; 94 95 protected: 96 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, 97 MachineInstr *MI, 98 const SmallVectorImpl<unsigned> &Ops, 99 int FrameIndex) const override; 100 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, 101 MachineInstr *MI, 102 const SmallVectorImpl<unsigned> &Ops, 103 MachineInstr *LoadMI) const override; 104 /// \returns the smallest register index that will be accessed by an indirect 105 /// read or write or -1 if indirect addressing is not used by this program. 106 int getIndirectIndexBegin(const MachineFunction &MF) const; 107 108 /// \returns the largest register index that will be accessed by an indirect 109 /// read or write or -1 if indirect addressing is not used by this program. 110 int getIndirectIndexEnd(const MachineFunction &MF) const; 111 112 public: 113 bool canFoldMemoryOperand(const MachineInstr *MI, 114 const SmallVectorImpl<unsigned> &Ops) const override; 115 bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, 116 unsigned Reg, bool UnfoldLoad, bool UnfoldStore, 117 SmallVectorImpl<MachineInstr *> &NewMIs) const override; 118 bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, 119 SmallVectorImpl<SDNode *> &NewNodes) const override; 120 unsigned getOpcodeAfterMemoryUnfold(unsigned Opc, 121 bool UnfoldLoad, bool UnfoldStore, 122 unsigned *LoadRegIndex = nullptr) const override; 123 bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, 124 int64_t Offset1, int64_t Offset2, 125 unsigned NumLoads) const override; 126 127 bool 128 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 129 void insertNoop(MachineBasicBlock &MBB, 130 MachineBasicBlock::iterator MI) const override; 131 bool isPredicated(const MachineInstr *MI) const override; 132 bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 133 const SmallVectorImpl<MachineOperand> &Pred2) const override; 134 bool DefinesPredicate(MachineInstr *MI, 135 std::vector<MachineOperand> &Pred) const override; 136 bool isPredicable(MachineInstr *MI) const override; 137 bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override; 138 139 // Helper functions that check the opcode for status information 140 bool isRegisterStore(const MachineInstr &MI) const; 141 bool isRegisterLoad(const MachineInstr &MI) const; 142 143 //===---------------------------------------------------------------------===// 144 // Pure virtual funtions to be implemented by sub-classes. 145 //===---------------------------------------------------------------------===// 146 147 virtual unsigned getIEQOpcode() const = 0; 148 virtual bool isMov(unsigned opcode) const = 0; 149 150 /// \brief Calculate the "Indirect Address" for the given \p RegIndex and 151 /// \p Channel 152 /// 153 /// We model indirect addressing using a virtual address space that can be 154 /// accesed with loads and stores. The "Indirect Address" is the memory 155 /// address in this virtual address space that maps to the given \p RegIndex 156 /// and \p Channel. 157 virtual unsigned calculateIndirectAddress(unsigned RegIndex, 158 unsigned Channel) const = 0; 159 160 /// \returns The register class to be used for loading and storing values 161 /// from an "Indirect Address" . 162 virtual const TargetRegisterClass *getIndirectAddrRegClass() const = 0; 163 164 /// \brief Build instruction(s) for an indirect register write. 165 /// 166 /// \returns The instruction that performs the indirect register write 167 virtual MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, 168 MachineBasicBlock::iterator I, 169 unsigned ValueReg, unsigned Address, 170 unsigned OffsetReg) const = 0; 171 172 /// \brief Build instruction(s) for an indirect register read. 173 /// 174 /// \returns The instruction that performs the indirect register read 175 virtual MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, 176 MachineBasicBlock::iterator I, 177 unsigned ValueReg, unsigned Address, 178 unsigned OffsetReg) const = 0; 179 180 /// \brief Build a MOV instruction. 181 virtual MachineInstr *buildMovInstr(MachineBasicBlock *MBB, 182 MachineBasicBlock::iterator I, 183 unsigned DstReg, unsigned SrcReg) const = 0; 184 185 /// \brief Given a MIMG \p Opcode that writes all 4 channels, return the 186 /// equivalent opcode that writes \p Channels Channels. 187 int getMaskedMIMGOp(uint16_t Opcode, unsigned Channels) const; 188 189 }; 190 191 namespace AMDGPU { 192 int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex); 193 } // End namespace AMDGPU 194 195 } // End llvm namespace 196 197 #define AMDGPU_FLAG_REGISTER_LOAD (UINT64_C(1) << 63) 198 #define AMDGPU_FLAG_REGISTER_STORE (UINT64_C(1) << 62) 199 200 #endif // AMDGPUINSTRINFO_H 201