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 unsigned split64BitImm(SmallVectorImpl<MachineInstr *> &Worklist, 43 MachineBasicBlock::iterator MI, 44 MachineRegisterInfo &MRI, 45 const TargetRegisterClass *RC, 46 const MachineOperand &Op) const; 47 48 void swapOperands(MachineBasicBlock::iterator Inst) const; 49 50 void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist, 51 MachineInstr *Inst, unsigned Opcode) const; 52 53 void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist, 54 MachineInstr *Inst, unsigned Opcode) const; 55 56 void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist, 57 MachineInstr *Inst) const; 58 void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist, 59 MachineInstr *Inst) const; 60 61 void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const; 62 63 bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa, 64 MachineInstr *MIb) const; 65 66 unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const; 67 68 public: 69 explicit SIInstrInfo(const AMDGPUSubtarget &st); 70 getRegisterInfo()71 const SIRegisterInfo &getRegisterInfo() const override { 72 return RI; 73 } 74 75 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 76 int64_t &Offset1, 77 int64_t &Offset2) const override; 78 79 bool getLdStBaseRegImmOfs(MachineInstr *LdSt, 80 unsigned &BaseReg, unsigned &Offset, 81 const TargetRegisterInfo *TRI) const final; 82 83 bool shouldClusterLoads(MachineInstr *FirstLdSt, 84 MachineInstr *SecondLdSt, 85 unsigned NumLoads) const final; 86 87 void copyPhysReg(MachineBasicBlock &MBB, 88 MachineBasicBlock::iterator MI, DebugLoc DL, 89 unsigned DestReg, unsigned SrcReg, 90 bool KillSrc) const override; 91 92 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, 93 MachineBasicBlock::iterator MI, 94 RegScavenger *RS, 95 unsigned TmpReg, 96 unsigned Offset, 97 unsigned Size) const; 98 99 void storeRegToStackSlot(MachineBasicBlock &MBB, 100 MachineBasicBlock::iterator MI, 101 unsigned SrcReg, bool isKill, int FrameIndex, 102 const TargetRegisterClass *RC, 103 const TargetRegisterInfo *TRI) const override; 104 105 void loadRegFromStackSlot(MachineBasicBlock &MBB, 106 MachineBasicBlock::iterator MI, 107 unsigned DestReg, int FrameIndex, 108 const TargetRegisterClass *RC, 109 const TargetRegisterInfo *TRI) const override; 110 111 bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override; 112 113 // \brief Returns an opcode that can be used to move a value to a \p DstRC 114 // register. If there is no hardware instruction that can store to \p 115 // DstRC, then AMDGPU::COPY is returned. 116 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const; 117 unsigned commuteOpcode(const MachineInstr &MI) const; 118 119 MachineInstr *commuteInstruction(MachineInstr *MI, 120 bool NewMI = false) const override; 121 bool findCommutedOpIndices(MachineInstr *MI, 122 unsigned &SrcOpIdx1, 123 unsigned &SrcOpIdx2) const override; 124 125 bool isTriviallyReMaterializable(const MachineInstr *MI, 126 AliasAnalysis *AA = nullptr) const; 127 128 bool areMemAccessesTriviallyDisjoint( 129 MachineInstr *MIa, MachineInstr *MIb, 130 AliasAnalysis *AA = nullptr) const override; 131 132 MachineInstr *buildMovInstr(MachineBasicBlock *MBB, 133 MachineBasicBlock::iterator I, 134 unsigned DstReg, unsigned SrcReg) const override; 135 bool isMov(unsigned Opcode) const override; 136 137 bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override; 138 139 bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 140 unsigned Reg, MachineRegisterInfo *MRI) const final; 141 isSALU(uint16_t Opcode)142 bool isSALU(uint16_t Opcode) const { 143 return get(Opcode).TSFlags & SIInstrFlags::SALU; 144 } 145 isVALU(uint16_t Opcode)146 bool isVALU(uint16_t Opcode) const { 147 return get(Opcode).TSFlags & SIInstrFlags::VALU; 148 } 149 isSOP1(uint16_t Opcode)150 bool isSOP1(uint16_t Opcode) const { 151 return get(Opcode).TSFlags & SIInstrFlags::SOP1; 152 } 153 isSOP2(uint16_t Opcode)154 bool isSOP2(uint16_t Opcode) const { 155 return get(Opcode).TSFlags & SIInstrFlags::SOP2; 156 } 157 isSOPC(uint16_t Opcode)158 bool isSOPC(uint16_t Opcode) const { 159 return get(Opcode).TSFlags & SIInstrFlags::SOPC; 160 } 161 isSOPK(uint16_t Opcode)162 bool isSOPK(uint16_t Opcode) const { 163 return get(Opcode).TSFlags & SIInstrFlags::SOPK; 164 } 165 isSOPP(uint16_t Opcode)166 bool isSOPP(uint16_t Opcode) const { 167 return get(Opcode).TSFlags & SIInstrFlags::SOPP; 168 } 169 isVOP1(uint16_t Opcode)170 bool isVOP1(uint16_t Opcode) const { 171 return get(Opcode).TSFlags & SIInstrFlags::VOP1; 172 } 173 isVOP2(uint16_t Opcode)174 bool isVOP2(uint16_t Opcode) const { 175 return get(Opcode).TSFlags & SIInstrFlags::VOP2; 176 } 177 isVOP3(uint16_t Opcode)178 bool isVOP3(uint16_t Opcode) const { 179 return get(Opcode).TSFlags & SIInstrFlags::VOP3; 180 } 181 isVOPC(uint16_t Opcode)182 bool isVOPC(uint16_t Opcode) const { 183 return get(Opcode).TSFlags & SIInstrFlags::VOPC; 184 } 185 isMUBUF(uint16_t Opcode)186 bool isMUBUF(uint16_t Opcode) const { 187 return get(Opcode).TSFlags & SIInstrFlags::MUBUF; 188 } 189 isMTBUF(uint16_t Opcode)190 bool isMTBUF(uint16_t Opcode) const { 191 return get(Opcode).TSFlags & SIInstrFlags::MTBUF; 192 } 193 isSMRD(uint16_t Opcode)194 bool isSMRD(uint16_t Opcode) const { 195 return get(Opcode).TSFlags & SIInstrFlags::SMRD; 196 } 197 isDS(uint16_t Opcode)198 bool isDS(uint16_t Opcode) const { 199 return get(Opcode).TSFlags & SIInstrFlags::DS; 200 } 201 isMIMG(uint16_t Opcode)202 bool isMIMG(uint16_t Opcode) const { 203 return get(Opcode).TSFlags & SIInstrFlags::MIMG; 204 } 205 isFLAT(uint16_t Opcode)206 bool isFLAT(uint16_t Opcode) const { 207 return get(Opcode).TSFlags & SIInstrFlags::FLAT; 208 } 209 isWQM(uint16_t Opcode)210 bool isWQM(uint16_t Opcode) const { 211 return get(Opcode).TSFlags & SIInstrFlags::WQM; 212 } 213 214 bool isInlineConstant(const APInt &Imm) const; 215 bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const; 216 bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const; 217 218 bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, 219 const MachineOperand &MO) const; 220 221 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding. 222 /// This function will return false if you pass it a 32-bit instruction. 223 bool hasVALU32BitEncoding(unsigned Opcode) const; 224 225 /// \brief Returns true if this operand uses the constant bus. 226 bool usesConstantBus(const MachineRegisterInfo &MRI, 227 const MachineOperand &MO, 228 unsigned OpSize) const; 229 230 /// \brief Return true if this instruction has any modifiers. 231 /// e.g. src[012]_mod, omod, clamp. 232 bool hasModifiers(unsigned Opcode) const; 233 234 bool hasModifiersSet(const MachineInstr &MI, 235 unsigned OpName) const; 236 237 bool verifyInstruction(const MachineInstr *MI, 238 StringRef &ErrInfo) const override; 239 240 static unsigned getVALUOp(const MachineInstr &MI); 241 242 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const; 243 244 /// \brief Return the correct register class for \p OpNo. For target-specific 245 /// instructions, this will return the register class that has been defined 246 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return 247 /// the register class of its machine operand. 248 /// to infer the correct register class base on the other operands. 249 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI, 250 unsigned OpNo) const; 251 252 /// \brief Return the size in bytes of the operand OpNo on the given 253 // instruction opcode. getOpSize(uint16_t Opcode,unsigned OpNo)254 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const { 255 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo]; 256 257 if (OpInfo.RegClass == -1) { 258 // If this is an immediate operand, this must be a 32-bit literal. 259 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE); 260 return 4; 261 } 262 263 return RI.getRegClass(OpInfo.RegClass)->getSize(); 264 } 265 266 /// \brief This form should usually be preferred since it handles operands 267 /// with unknown register classes. getOpSize(const MachineInstr & MI,unsigned OpNo)268 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const { 269 return getOpRegClass(MI, OpNo)->getSize(); 270 } 271 272 /// \returns true if it is legal for the operand at index \p OpNo 273 /// to read a VGPR. 274 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const; 275 276 /// \brief Legalize the \p OpIndex operand of this instruction by inserting 277 /// a MOV. For example: 278 /// ADD_I32_e32 VGPR0, 15 279 /// to 280 /// MOV VGPR1, 15 281 /// ADD_I32_e32 VGPR0, VGPR1 282 /// 283 /// If the operand being legalized is a register, then a COPY will be used 284 /// instead of MOV. 285 void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const; 286 287 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand 288 /// for \p MI. 289 bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx, 290 const MachineOperand *MO = nullptr) const; 291 292 /// \brief Legalize all operands in this instruction. This function may 293 /// create new instruction and insert them before \p MI. 294 void legalizeOperands(MachineInstr *MI) const; 295 296 /// \brief Split an SMRD instruction into two smaller loads of half the 297 // size storing the results in \p Lo and \p Hi. 298 void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC, 299 unsigned HalfImmOp, unsigned HalfSGPROp, 300 MachineInstr *&Lo, MachineInstr *&Hi) const; 301 302 void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI) const; 303 304 /// \brief Replace this instruction's opcode with the equivalent VALU 305 /// opcode. This function will also move the users of \p MI to the 306 /// VALU if necessary. 307 void moveToVALU(MachineInstr &MI) const; 308 309 unsigned calculateIndirectAddress(unsigned RegIndex, 310 unsigned Channel) const override; 311 312 const TargetRegisterClass *getIndirectAddrRegClass() const override; 313 314 MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, 315 MachineBasicBlock::iterator I, 316 unsigned ValueReg, 317 unsigned Address, 318 unsigned OffsetReg) const override; 319 320 MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, 321 MachineBasicBlock::iterator I, 322 unsigned ValueReg, 323 unsigned Address, 324 unsigned OffsetReg) const override; 325 void reserveIndirectRegisters(BitVector &Reserved, 326 const MachineFunction &MF) const; 327 328 void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I, 329 unsigned SavReg, unsigned IndexReg) const; 330 331 void insertNOPs(MachineBasicBlock::iterator MI, int Count) const; 332 333 /// \brief Returns the operand named \p Op. If \p MI does not have an 334 /// operand named \c Op, this function returns nullptr. 335 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const; 336 getNamedOperand(const MachineInstr & MI,unsigned OpName)337 const MachineOperand *getNamedOperand(const MachineInstr &MI, 338 unsigned OpName) const { 339 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName); 340 } 341 342 uint64_t getDefaultRsrcDataFormat() const; 343 344 }; 345 346 namespace AMDGPU { 347 348 int getVOPe64(uint16_t Opcode); 349 int getVOPe32(uint16_t Opcode); 350 int getCommuteRev(uint16_t Opcode); 351 int getCommuteOrig(uint16_t Opcode); 352 int getAddr64Inst(uint16_t Opcode); 353 int getAtomicRetOp(uint16_t Opcode); 354 int getAtomicNoRetOp(uint16_t Opcode); 355 356 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL; 357 const uint64_t RSRC_TID_ENABLE = 1LL << 55; 358 359 } // End namespace AMDGPU 360 361 namespace SI { 362 namespace KernelInputOffsets { 363 364 /// Offsets in bytes from the start of the input buffer 365 enum Offsets { 366 NGROUPS_X = 0, 367 NGROUPS_Y = 4, 368 NGROUPS_Z = 8, 369 GLOBAL_SIZE_X = 12, 370 GLOBAL_SIZE_Y = 16, 371 GLOBAL_SIZE_Z = 20, 372 LOCAL_SIZE_X = 24, 373 LOCAL_SIZE_Y = 28, 374 LOCAL_SIZE_Z = 32 375 }; 376 377 } // End namespace KernelInputOffsets 378 } // End namespace SI 379 380 } // End namespace llvm 381 382 #endif 383