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_AMDGPU_SIINSTRINFO_H 17 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H 18 19 #include "AMDGPUInstrInfo.h" 20 #include "SIDefines.h" 21 #include "SIRegisterInfo.h" 22 23 namespace llvm { 24 25 class SIInstrInfo final : 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 int64_t &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 bool isSchedulingBoundary(const MachineInstr *MI, 153 const MachineBasicBlock *MBB, 154 const MachineFunction &MF) const override; 155 156 static bool isSALU(const MachineInstr &MI) { 157 return MI.getDesc().TSFlags & SIInstrFlags::SALU; 158 } 159 160 bool isSALU(uint16_t Opcode) const { 161 return get(Opcode).TSFlags & SIInstrFlags::SALU; 162 } 163 164 static bool isVALU(const MachineInstr &MI) { 165 return MI.getDesc().TSFlags & SIInstrFlags::VALU; 166 } 167 168 bool isVALU(uint16_t Opcode) const { 169 return get(Opcode).TSFlags & SIInstrFlags::VALU; 170 } 171 172 static bool isSOP1(const MachineInstr &MI) { 173 return MI.getDesc().TSFlags & SIInstrFlags::SOP1; 174 } 175 176 bool isSOP1(uint16_t Opcode) const { 177 return get(Opcode).TSFlags & SIInstrFlags::SOP1; 178 } 179 180 static bool isSOP2(const MachineInstr &MI) { 181 return MI.getDesc().TSFlags & SIInstrFlags::SOP2; 182 } 183 184 bool isSOP2(uint16_t Opcode) const { 185 return get(Opcode).TSFlags & SIInstrFlags::SOP2; 186 } 187 188 static bool isSOPC(const MachineInstr &MI) { 189 return MI.getDesc().TSFlags & SIInstrFlags::SOPC; 190 } 191 192 bool isSOPC(uint16_t Opcode) const { 193 return get(Opcode).TSFlags & SIInstrFlags::SOPC; 194 } 195 196 static bool isSOPK(const MachineInstr &MI) { 197 return MI.getDesc().TSFlags & SIInstrFlags::SOPK; 198 } 199 200 bool isSOPK(uint16_t Opcode) const { 201 return get(Opcode).TSFlags & SIInstrFlags::SOPK; 202 } 203 204 static bool isSOPP(const MachineInstr &MI) { 205 return MI.getDesc().TSFlags & SIInstrFlags::SOPP; 206 } 207 208 bool isSOPP(uint16_t Opcode) const { 209 return get(Opcode).TSFlags & SIInstrFlags::SOPP; 210 } 211 212 static bool isVOP1(const MachineInstr &MI) { 213 return MI.getDesc().TSFlags & SIInstrFlags::VOP1; 214 } 215 216 bool isVOP1(uint16_t Opcode) const { 217 return get(Opcode).TSFlags & SIInstrFlags::VOP1; 218 } 219 220 static bool isVOP2(const MachineInstr &MI) { 221 return MI.getDesc().TSFlags & SIInstrFlags::VOP2; 222 } 223 224 bool isVOP2(uint16_t Opcode) const { 225 return get(Opcode).TSFlags & SIInstrFlags::VOP2; 226 } 227 228 static bool isVOP3(const MachineInstr &MI) { 229 return MI.getDesc().TSFlags & SIInstrFlags::VOP3; 230 } 231 232 bool isVOP3(uint16_t Opcode) const { 233 return get(Opcode).TSFlags & SIInstrFlags::VOP3; 234 } 235 236 static bool isVOPC(const MachineInstr &MI) { 237 return MI.getDesc().TSFlags & SIInstrFlags::VOPC; 238 } 239 240 bool isVOPC(uint16_t Opcode) const { 241 return get(Opcode).TSFlags & SIInstrFlags::VOPC; 242 } 243 244 static bool isMUBUF(const MachineInstr &MI) { 245 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF; 246 } 247 248 bool isMUBUF(uint16_t Opcode) const { 249 return get(Opcode).TSFlags & SIInstrFlags::MUBUF; 250 } 251 252 static bool isMTBUF(const MachineInstr &MI) { 253 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF; 254 } 255 256 bool isMTBUF(uint16_t Opcode) const { 257 return get(Opcode).TSFlags & SIInstrFlags::MTBUF; 258 } 259 260 static bool isSMRD(const MachineInstr &MI) { 261 return MI.getDesc().TSFlags & SIInstrFlags::SMRD; 262 } 263 264 bool isSMRD(uint16_t Opcode) const { 265 return get(Opcode).TSFlags & SIInstrFlags::SMRD; 266 } 267 268 static bool isDS(const MachineInstr &MI) { 269 return MI.getDesc().TSFlags & SIInstrFlags::DS; 270 } 271 272 bool isDS(uint16_t Opcode) const { 273 return get(Opcode).TSFlags & SIInstrFlags::DS; 274 } 275 276 static bool isMIMG(const MachineInstr &MI) { 277 return MI.getDesc().TSFlags & SIInstrFlags::MIMG; 278 } 279 280 bool isMIMG(uint16_t Opcode) const { 281 return get(Opcode).TSFlags & SIInstrFlags::MIMG; 282 } 283 284 static bool isFLAT(const MachineInstr &MI) { 285 return MI.getDesc().TSFlags & SIInstrFlags::FLAT; 286 } 287 288 bool isFLAT(uint16_t Opcode) const { 289 return get(Opcode).TSFlags & SIInstrFlags::FLAT; 290 } 291 292 static bool isWQM(const MachineInstr &MI) { 293 return MI.getDesc().TSFlags & SIInstrFlags::WQM; 294 } 295 296 bool isWQM(uint16_t Opcode) const { 297 return get(Opcode).TSFlags & SIInstrFlags::WQM; 298 } 299 300 static bool isVGPRSpill(const MachineInstr &MI) { 301 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill; 302 } 303 304 bool isVGPRSpill(uint16_t Opcode) const { 305 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill; 306 } 307 308 static bool isDPP(const MachineInstr &MI) { 309 return MI.getDesc().TSFlags & SIInstrFlags::DPP; 310 } 311 312 bool isDPP(uint16_t Opcode) const { 313 return get(Opcode).TSFlags & SIInstrFlags::DPP; 314 } 315 316 bool isInlineConstant(const APInt &Imm) const; 317 bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const; 318 bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const; 319 320 bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, 321 const MachineOperand &MO) const; 322 323 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding. 324 /// This function will return false if you pass it a 32-bit instruction. 325 bool hasVALU32BitEncoding(unsigned Opcode) const; 326 327 /// \brief Returns true if this operand uses the constant bus. 328 bool usesConstantBus(const MachineRegisterInfo &MRI, 329 const MachineOperand &MO, 330 unsigned OpSize) const; 331 332 /// \brief Return true if this instruction has any modifiers. 333 /// e.g. src[012]_mod, omod, clamp. 334 bool hasModifiers(unsigned Opcode) const; 335 336 bool hasModifiersSet(const MachineInstr &MI, 337 unsigned OpName) const; 338 339 bool verifyInstruction(const MachineInstr *MI, 340 StringRef &ErrInfo) const override; 341 342 static unsigned getVALUOp(const MachineInstr &MI); 343 344 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const; 345 346 /// \brief Return the correct register class for \p OpNo. For target-specific 347 /// instructions, this will return the register class that has been defined 348 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return 349 /// the register class of its machine operand. 350 /// to infer the correct register class base on the other operands. 351 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI, 352 unsigned OpNo) const; 353 354 /// \brief Return the size in bytes of the operand OpNo on the given 355 // instruction opcode. 356 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const { 357 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo]; 358 359 if (OpInfo.RegClass == -1) { 360 // If this is an immediate operand, this must be a 32-bit literal. 361 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE); 362 return 4; 363 } 364 365 return RI.getRegClass(OpInfo.RegClass)->getSize(); 366 } 367 368 /// \brief This form should usually be preferred since it handles operands 369 /// with unknown register classes. 370 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const { 371 return getOpRegClass(MI, OpNo)->getSize(); 372 } 373 374 /// \returns true if it is legal for the operand at index \p OpNo 375 /// to read a VGPR. 376 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const; 377 378 /// \brief Legalize the \p OpIndex operand of this instruction by inserting 379 /// a MOV. For example: 380 /// ADD_I32_e32 VGPR0, 15 381 /// to 382 /// MOV VGPR1, 15 383 /// ADD_I32_e32 VGPR0, VGPR1 384 /// 385 /// If the operand being legalized is a register, then a COPY will be used 386 /// instead of MOV. 387 void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const; 388 389 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand 390 /// for \p MI. 391 bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx, 392 const MachineOperand *MO = nullptr) const; 393 394 /// \brief Check if \p MO would be a valid operand for the given operand 395 /// definition \p OpInfo. Note this does not attempt to validate constant bus 396 /// restrictions (e.g. literal constant usage). 397 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI, 398 const MCOperandInfo &OpInfo, 399 const MachineOperand &MO) const; 400 401 /// \brief Check if \p MO (a register operand) is a legal register for the 402 /// given operand description. 403 bool isLegalRegOperand(const MachineRegisterInfo &MRI, 404 const MCOperandInfo &OpInfo, 405 const MachineOperand &MO) const; 406 407 /// \brief Legalize operands in \p MI by either commuting it or inserting a 408 /// copy of src1. 409 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr *MI) const; 410 411 /// \brief Fix operands in \p MI to satisfy constant bus requirements. 412 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr *MI) const; 413 414 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only 415 /// be used when it is know that the value in SrcReg is same across all 416 /// threads in the wave. 417 /// \returns The SGPR register that \p SrcReg was copied to. 418 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr *UseMI, 419 MachineRegisterInfo &MRI) const; 420 421 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr *MI) const; 422 423 /// \brief Legalize all operands in this instruction. This function may 424 /// create new instruction and insert them before \p MI. 425 void legalizeOperands(MachineInstr *MI) const; 426 427 /// \brief Replace this instruction's opcode with the equivalent VALU 428 /// opcode. This function will also move the users of \p MI to the 429 /// VALU if necessary. 430 void moveToVALU(MachineInstr &MI) const; 431 432 const TargetRegisterClass *getIndirectAddrRegClass() const override; 433 434 void reserveIndirectRegisters(BitVector &Reserved, 435 const MachineFunction &MF) const; 436 437 void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I, 438 unsigned SavReg, unsigned IndexReg) const; 439 440 void insertWaitStates(MachineBasicBlock::iterator MI, int Count) const; 441 442 /// \brief Returns the operand named \p Op. If \p MI does not have an 443 /// operand named \c Op, this function returns nullptr. 444 LLVM_READONLY 445 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const; 446 447 LLVM_READONLY 448 const MachineOperand *getNamedOperand(const MachineInstr &MI, 449 unsigned OpName) const { 450 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName); 451 } 452 453 /// Get required immediate operand 454 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const { 455 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName); 456 return MI.getOperand(Idx).getImm(); 457 } 458 459 uint64_t getDefaultRsrcDataFormat() const; 460 uint64_t getScratchRsrcWords23() const; 461 462 bool isLowLatencyInstruction(const MachineInstr *MI) const; 463 bool isHighLatencyInstruction(const MachineInstr *MI) const; 464 465 /// \brief Return the descriptor of the target-specific machine instruction 466 /// that corresponds to the specified pseudo or native opcode. 467 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const { 468 return get(pseudoToMCOpcode(Opcode)); 469 } 470 471 ArrayRef<std::pair<int, const char *>> 472 getSerializableTargetIndices() const override; 473 474 }; 475 476 namespace AMDGPU { 477 LLVM_READONLY 478 int getVOPe64(uint16_t Opcode); 479 480 LLVM_READONLY 481 int getVOPe32(uint16_t Opcode); 482 483 LLVM_READONLY 484 int getCommuteRev(uint16_t Opcode); 485 486 LLVM_READONLY 487 int getCommuteOrig(uint16_t Opcode); 488 489 LLVM_READONLY 490 int getAddr64Inst(uint16_t Opcode); 491 492 LLVM_READONLY 493 int getAtomicRetOp(uint16_t Opcode); 494 495 LLVM_READONLY 496 int getAtomicNoRetOp(uint16_t Opcode); 497 498 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL; 499 const uint64_t RSRC_TID_ENABLE = 1LL << 55; 500 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = 51; 501 } // End namespace AMDGPU 502 503 namespace SI { 504 namespace KernelInputOffsets { 505 506 /// Offsets in bytes from the start of the input buffer 507 enum Offsets { 508 NGROUPS_X = 0, 509 NGROUPS_Y = 4, 510 NGROUPS_Z = 8, 511 GLOBAL_SIZE_X = 12, 512 GLOBAL_SIZE_Y = 16, 513 GLOBAL_SIZE_Z = 20, 514 LOCAL_SIZE_X = 24, 515 LOCAL_SIZE_Y = 28, 516 LOCAL_SIZE_Z = 32 517 }; 518 519 } // End namespace KernelInputOffsets 520 } // End namespace SI 521 522 } // End namespace llvm 523 524 #endif 525