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