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