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 34namespace llvm { 35 36class AMDGPUSubtarget; 37class MachineFunction; 38class MachineInstr; 39class MachineInstrBuilder; 40 41class AMDGPUInstrInfo : public AMDGPUGenInstrInfo { 42private: 43 const AMDGPURegisterInfo RI; 44 bool getNextBranchInstr(MachineBasicBlock::iterator &iter, 45 MachineBasicBlock &MBB) const; 46 virtual void anchor(); 47protected: 48 const AMDGPUSubtarget &ST; 49public: 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 95protected: 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 112public: 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 191namespace 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