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