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 void swapOperands(MachineBasicBlock::iterator Inst) const; 43 44 void lowerScalarAbs(SmallVectorImpl<MachineInstr *> &Worklist, 45 MachineInstr *Inst) const; 46 47 void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist, 48 MachineInstr *Inst, unsigned Opcode) const; 49 50 void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist, 51 MachineInstr *Inst, unsigned Opcode) const; 52 53 void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist, 54 MachineInstr *Inst) const; 55 void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist, 56 MachineInstr *Inst) const; 57 58 void addUsersToMoveToVALUWorklist( 59 unsigned Reg, MachineRegisterInfo &MRI, 60 SmallVectorImpl<MachineInstr *> &Worklist) const; 61 62 void addSCCDefUsersToVALUWorklist( 63 MachineInstr *SCCDefInst, SmallVectorImpl<MachineInstr *> &Worklist) const; 64 65 const TargetRegisterClass * 66 getDestEquivalentVGPRClass(const MachineInstr &Inst) const; 67 68 bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa, 69 MachineInstr *MIb) const; 70 71 unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const; 72 73 protected: 74 MachineInstr *commuteInstructionImpl(MachineInstr *MI, 75 bool NewMI, 76 unsigned OpIdx0, 77 unsigned OpIdx1) const override; 78 79 public: 80 explicit SIInstrInfo(const AMDGPUSubtarget &st); 81 82 const SIRegisterInfo &getRegisterInfo() const override { 83 return RI; 84 } 85 86 bool isReallyTriviallyReMaterializable(const MachineInstr *MI, 87 AliasAnalysis *AA) const override; 88 89 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 90 int64_t &Offset1, 91 int64_t &Offset2) const override; 92 93 bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg, 94 unsigned &Offset, 95 const TargetRegisterInfo *TRI) const final; 96 97 bool shouldClusterLoads(MachineInstr *FirstLdSt, 98 MachineInstr *SecondLdSt, 99 unsigned NumLoads) const final; 100 101 void copyPhysReg(MachineBasicBlock &MBB, 102 MachineBasicBlock::iterator MI, DebugLoc DL, 103 unsigned DestReg, unsigned SrcReg, 104 bool KillSrc) const override; 105 106 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, 107 MachineBasicBlock::iterator MI, 108 RegScavenger *RS, 109 unsigned TmpReg, 110 unsigned Offset, 111 unsigned Size) const; 112 113 void storeRegToStackSlot(MachineBasicBlock &MBB, 114 MachineBasicBlock::iterator MI, 115 unsigned SrcReg, bool isKill, int FrameIndex, 116 const TargetRegisterClass *RC, 117 const TargetRegisterInfo *TRI) const override; 118 119 void loadRegFromStackSlot(MachineBasicBlock &MBB, 120 MachineBasicBlock::iterator MI, 121 unsigned DestReg, int FrameIndex, 122 const TargetRegisterClass *RC, 123 const TargetRegisterInfo *TRI) const override; 124 125 bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override; 126 127 // \brief Returns an opcode that can be used to move a value to a \p DstRC 128 // register. If there is no hardware instruction that can store to \p 129 // DstRC, then AMDGPU::COPY is returned. 130 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const; 131 132 LLVM_READONLY 133 int commuteOpcode(const MachineInstr &MI) const; 134 135 bool findCommutedOpIndices(MachineInstr *MI, 136 unsigned &SrcOpIdx1, 137 unsigned &SrcOpIdx2) const override; 138 139 bool areMemAccessesTriviallyDisjoint( 140 MachineInstr *MIa, MachineInstr *MIb, 141 AliasAnalysis *AA = nullptr) const override; 142 143 bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 144 unsigned Reg, MachineRegisterInfo *MRI) const final; 145 146 unsigned getMachineCSELookAheadLimit() const override { return 500; } 147 148 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB, 149 MachineBasicBlock::iterator &MI, 150 LiveVariables *LV) const override; 151 152 static bool isSALU(const MachineInstr &MI) { 153 return MI.getDesc().TSFlags & SIInstrFlags::SALU; 154 } 155 156 bool isSALU(uint16_t Opcode) const { 157 return get(Opcode).TSFlags & SIInstrFlags::SALU; 158 } 159 160 static bool isVALU(const MachineInstr &MI) { 161 return MI.getDesc().TSFlags & SIInstrFlags::VALU; 162 } 163 164 bool isVALU(uint16_t Opcode) const { 165 return get(Opcode).TSFlags & SIInstrFlags::VALU; 166 } 167 168 static bool isSOP1(const MachineInstr &MI) { 169 return MI.getDesc().TSFlags & SIInstrFlags::SOP1; 170 } 171 172 bool isSOP1(uint16_t Opcode) const { 173 return get(Opcode).TSFlags & SIInstrFlags::SOP1; 174 } 175 176 static bool isSOP2(const MachineInstr &MI) { 177 return MI.getDesc().TSFlags & SIInstrFlags::SOP2; 178 } 179 180 bool isSOP2(uint16_t Opcode) const { 181 return get(Opcode).TSFlags & SIInstrFlags::SOP2; 182 } 183 184 static bool isSOPC(const MachineInstr &MI) { 185 return MI.getDesc().TSFlags & SIInstrFlags::SOPC; 186 } 187 188 bool isSOPC(uint16_t Opcode) const { 189 return get(Opcode).TSFlags & SIInstrFlags::SOPC; 190 } 191 192 static bool isSOPK(const MachineInstr &MI) { 193 return MI.getDesc().TSFlags & SIInstrFlags::SOPK; 194 } 195 196 bool isSOPK(uint16_t Opcode) const { 197 return get(Opcode).TSFlags & SIInstrFlags::SOPK; 198 } 199 200 static bool isSOPP(const MachineInstr &MI) { 201 return MI.getDesc().TSFlags & SIInstrFlags::SOPP; 202 } 203 204 bool isSOPP(uint16_t Opcode) const { 205 return get(Opcode).TSFlags & SIInstrFlags::SOPP; 206 } 207 208 static bool isVOP1(const MachineInstr &MI) { 209 return MI.getDesc().TSFlags & SIInstrFlags::VOP1; 210 } 211 212 bool isVOP1(uint16_t Opcode) const { 213 return get(Opcode).TSFlags & SIInstrFlags::VOP1; 214 } 215 216 static bool isVOP2(const MachineInstr &MI) { 217 return MI.getDesc().TSFlags & SIInstrFlags::VOP2; 218 } 219 220 bool isVOP2(uint16_t Opcode) const { 221 return get(Opcode).TSFlags & SIInstrFlags::VOP2; 222 } 223 224 static bool isVOP3(const MachineInstr &MI) { 225 return MI.getDesc().TSFlags & SIInstrFlags::VOP3; 226 } 227 228 bool isVOP3(uint16_t Opcode) const { 229 return get(Opcode).TSFlags & SIInstrFlags::VOP3; 230 } 231 232 static bool isVOPC(const MachineInstr &MI) { 233 return MI.getDesc().TSFlags & SIInstrFlags::VOPC; 234 } 235 236 bool isVOPC(uint16_t Opcode) const { 237 return get(Opcode).TSFlags & SIInstrFlags::VOPC; 238 } 239 240 static bool isMUBUF(const MachineInstr &MI) { 241 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF; 242 } 243 244 bool isMUBUF(uint16_t Opcode) const { 245 return get(Opcode).TSFlags & SIInstrFlags::MUBUF; 246 } 247 248 static bool isMTBUF(const MachineInstr &MI) { 249 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF; 250 } 251 252 bool isMTBUF(uint16_t Opcode) const { 253 return get(Opcode).TSFlags & SIInstrFlags::MTBUF; 254 } 255 256 static bool isSMRD(const MachineInstr &MI) { 257 return MI.getDesc().TSFlags & SIInstrFlags::SMRD; 258 } 259 260 bool isSMRD(uint16_t Opcode) const { 261 return get(Opcode).TSFlags & SIInstrFlags::SMRD; 262 } 263 264 static bool isDS(const MachineInstr &MI) { 265 return MI.getDesc().TSFlags & SIInstrFlags::DS; 266 } 267 268 bool isDS(uint16_t Opcode) const { 269 return get(Opcode).TSFlags & SIInstrFlags::DS; 270 } 271 272 static bool isMIMG(const MachineInstr &MI) { 273 return MI.getDesc().TSFlags & SIInstrFlags::MIMG; 274 } 275 276 bool isMIMG(uint16_t Opcode) const { 277 return get(Opcode).TSFlags & SIInstrFlags::MIMG; 278 } 279 280 static bool isFLAT(const MachineInstr &MI) { 281 return MI.getDesc().TSFlags & SIInstrFlags::FLAT; 282 } 283 284 bool isFLAT(uint16_t Opcode) const { 285 return get(Opcode).TSFlags & SIInstrFlags::FLAT; 286 } 287 288 static bool isWQM(const MachineInstr &MI) { 289 return MI.getDesc().TSFlags & SIInstrFlags::WQM; 290 } 291 292 bool isWQM(uint16_t Opcode) const { 293 return get(Opcode).TSFlags & SIInstrFlags::WQM; 294 } 295 296 static bool isVGPRSpill(const MachineInstr &MI) { 297 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill; 298 } 299 300 bool isVGPRSpill(uint16_t Opcode) const { 301 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill; 302 } 303 304 bool isInlineConstant(const APInt &Imm) const; 305 bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const; 306 bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const; 307 308 bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, 309 const MachineOperand &MO) const; 310 311 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding. 312 /// This function will return false if you pass it a 32-bit instruction. 313 bool hasVALU32BitEncoding(unsigned Opcode) const; 314 315 /// \brief Returns true if this operand uses the constant bus. 316 bool usesConstantBus(const MachineRegisterInfo &MRI, 317 const MachineOperand &MO, 318 unsigned OpSize) const; 319 320 /// \brief Return true if this instruction has any modifiers. 321 /// e.g. src[012]_mod, omod, clamp. 322 bool hasModifiers(unsigned Opcode) const; 323 324 bool hasModifiersSet(const MachineInstr &MI, 325 unsigned OpName) const; 326 327 bool verifyInstruction(const MachineInstr *MI, 328 StringRef &ErrInfo) const override; 329 330 static unsigned getVALUOp(const MachineInstr &MI); 331 332 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const; 333 334 /// \brief Return the correct register class for \p OpNo. For target-specific 335 /// instructions, this will return the register class that has been defined 336 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return 337 /// the register class of its machine operand. 338 /// to infer the correct register class base on the other operands. 339 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI, 340 unsigned OpNo) const; 341 342 /// \brief Return the size in bytes of the operand OpNo on the given 343 // instruction opcode. 344 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const { 345 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo]; 346 347 if (OpInfo.RegClass == -1) { 348 // If this is an immediate operand, this must be a 32-bit literal. 349 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE); 350 return 4; 351 } 352 353 return RI.getRegClass(OpInfo.RegClass)->getSize(); 354 } 355 356 /// \brief This form should usually be preferred since it handles operands 357 /// with unknown register classes. 358 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const { 359 return getOpRegClass(MI, OpNo)->getSize(); 360 } 361 362 /// \returns true if it is legal for the operand at index \p OpNo 363 /// to read a VGPR. 364 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const; 365 366 /// \brief Legalize the \p OpIndex operand of this instruction by inserting 367 /// a MOV. For example: 368 /// ADD_I32_e32 VGPR0, 15 369 /// to 370 /// MOV VGPR1, 15 371 /// ADD_I32_e32 VGPR0, VGPR1 372 /// 373 /// If the operand being legalized is a register, then a COPY will be used 374 /// instead of MOV. 375 void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const; 376 377 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand 378 /// for \p MI. 379 bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx, 380 const MachineOperand *MO = nullptr) const; 381 382 /// \brief Check if \p MO would be a valid operand for the given operand 383 /// definition \p OpInfo. Note this does not attempt to validate constant bus 384 /// restrictions (e.g. literal constant usage). 385 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI, 386 const MCOperandInfo &OpInfo, 387 const MachineOperand &MO) const; 388 389 /// \brief Check if \p MO (a register operand) is a legal register for the 390 /// given operand description. 391 bool isLegalRegOperand(const MachineRegisterInfo &MRI, 392 const MCOperandInfo &OpInfo, 393 const MachineOperand &MO) const; 394 395 /// \brief Legalize operands in \p MI by either commuting it or inserting a 396 /// copy of src1. 397 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr *MI) const; 398 399 /// \brief Fix operands in \p MI to satisfy constant bus requirements. 400 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr *MI) const; 401 402 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only 403 /// be used when it is know that the value in SrcReg is same across all 404 /// threads in the wave. 405 /// \returns The SGPR register that \p SrcReg was copied to. 406 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr *UseMI, 407 MachineRegisterInfo &MRI) const; 408 409 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr *MI) const; 410 411 /// \brief Legalize all operands in this instruction. This function may 412 /// create new instruction and insert them before \p MI. 413 void legalizeOperands(MachineInstr *MI) const; 414 415 /// \brief Replace this instruction's opcode with the equivalent VALU 416 /// opcode. This function will also move the users of \p MI to the 417 /// VALU if necessary. 418 void moveToVALU(MachineInstr &MI) const; 419 420 const TargetRegisterClass *getIndirectAddrRegClass() const override; 421 422 void reserveIndirectRegisters(BitVector &Reserved, 423 const MachineFunction &MF) const; 424 425 void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I, 426 unsigned SavReg, unsigned IndexReg) const; 427 428 void insertWaitStates(MachineBasicBlock::iterator MI, int Count) const; 429 430 /// \brief Returns the operand named \p Op. If \p MI does not have an 431 /// operand named \c Op, this function returns nullptr. 432 LLVM_READONLY 433 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const; 434 435 LLVM_READONLY 436 const MachineOperand *getNamedOperand(const MachineInstr &MI, 437 unsigned OpName) const { 438 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName); 439 } 440 441 /// Get required immediate operand 442 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const { 443 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName); 444 return MI.getOperand(Idx).getImm(); 445 } 446 447 uint64_t getDefaultRsrcDataFormat() const; 448 uint64_t getScratchRsrcWords23() const; 449 450 bool isLowLatencyInstruction(const MachineInstr *MI) const; 451 bool isHighLatencyInstruction(const MachineInstr *MI) const; 452 453 /// \brief Return the descriptor of the target-specific machine instruction 454 /// that corresponds to the specified pseudo or native opcode. 455 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const { 456 return get(pseudoToMCOpcode(Opcode)); 457 } 458 459 ArrayRef<std::pair<int, const char *>> 460 getSerializableTargetIndices() const override; 461 462 }; 463 464 namespace AMDGPU { 465 LLVM_READONLY 466 int getVOPe64(uint16_t Opcode); 467 468 LLVM_READONLY 469 int getVOPe32(uint16_t Opcode); 470 471 LLVM_READONLY 472 int getCommuteRev(uint16_t Opcode); 473 474 LLVM_READONLY 475 int getCommuteOrig(uint16_t Opcode); 476 477 LLVM_READONLY 478 int getAddr64Inst(uint16_t Opcode); 479 480 LLVM_READONLY 481 int getAtomicRetOp(uint16_t Opcode); 482 483 LLVM_READONLY 484 int getAtomicNoRetOp(uint16_t Opcode); 485 486 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL; 487 const uint64_t RSRC_TID_ENABLE = 1LL << 55; 488 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = 51; 489 } // End namespace AMDGPU 490 491 namespace SI { 492 namespace KernelInputOffsets { 493 494 /// Offsets in bytes from the start of the input buffer 495 enum Offsets { 496 NGROUPS_X = 0, 497 NGROUPS_Y = 4, 498 NGROUPS_Z = 8, 499 GLOBAL_SIZE_X = 12, 500 GLOBAL_SIZE_Y = 16, 501 GLOBAL_SIZE_Z = 20, 502 LOCAL_SIZE_X = 24, 503 LOCAL_SIZE_Y = 28, 504 LOCAL_SIZE_Z = 32 505 }; 506 507 } // End namespace KernelInputOffsets 508 } // End namespace SI 509 510 } // End namespace llvm 511 512 #endif 513