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(MachineInstr &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 void movePackToVALU(SmallVectorImpl<MachineInstr *> &Worklist, 73 MachineRegisterInfo &MRI, 74 MachineInstr &Inst) const; 75 76 void addUsersToMoveToVALUWorklist( 77 unsigned Reg, MachineRegisterInfo &MRI, 78 SmallVectorImpl<MachineInstr *> &Worklist) const; 79 80 void 81 addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst, 82 SmallVectorImpl<MachineInstr *> &Worklist) const; 83 84 const TargetRegisterClass * 85 getDestEquivalentVGPRClass(const MachineInstr &Inst) const; 86 87 bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const; 88 89 unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const; 90 91 protected: 92 bool swapSourceModifiers(MachineInstr &MI, 93 MachineOperand &Src0, unsigned Src0OpName, 94 MachineOperand &Src1, unsigned Src1OpName) const; 95 96 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 97 unsigned OpIdx0, 98 unsigned OpIdx1) const override; 99 100 public: 101 102 enum TargetOperandFlags { 103 MO_NONE = 0, 104 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL. 105 MO_GOTPCREL = 1, 106 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO. 107 MO_GOTPCREL32 = 2, 108 MO_GOTPCREL32_LO = 2, 109 // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI. 110 MO_GOTPCREL32_HI = 3, 111 // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO. 112 MO_REL32 = 4, 113 MO_REL32_LO = 4, 114 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI. 115 MO_REL32_HI = 5 116 }; 117 118 explicit SIInstrInfo(const SISubtarget &); 119 120 const SIRegisterInfo &getRegisterInfo() const { 121 return RI; 122 } 123 124 bool isReallyTriviallyReMaterializable(const MachineInstr &MI, 125 AliasAnalysis *AA) const override; 126 127 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 128 int64_t &Offset1, 129 int64_t &Offset2) const override; 130 131 bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg, 132 int64_t &Offset, 133 const TargetRegisterInfo *TRI) const final; 134 135 bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt, 136 unsigned NumLoads) const final; 137 138 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 139 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 140 bool KillSrc) const override; 141 142 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI, 143 RegScavenger *RS, unsigned TmpReg, 144 unsigned Offset, unsigned Size) const; 145 146 void storeRegToStackSlot(MachineBasicBlock &MBB, 147 MachineBasicBlock::iterator MI, unsigned SrcReg, 148 bool isKill, int FrameIndex, 149 const TargetRegisterClass *RC, 150 const TargetRegisterInfo *TRI) const override; 151 152 void loadRegFromStackSlot(MachineBasicBlock &MBB, 153 MachineBasicBlock::iterator MI, unsigned DestReg, 154 int FrameIndex, const TargetRegisterClass *RC, 155 const TargetRegisterInfo *TRI) const override; 156 157 bool expandPostRAPseudo(MachineInstr &MI) const override; 158 159 // \brief Returns an opcode that can be used to move a value to a \p DstRC 160 // register. If there is no hardware instruction that can store to \p 161 // DstRC, then AMDGPU::COPY is returned. 162 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const; 163 164 LLVM_READONLY 165 int commuteOpcode(unsigned Opc) const; 166 167 LLVM_READONLY 168 inline int commuteOpcode(const MachineInstr &MI) const { 169 return commuteOpcode(MI.getOpcode()); 170 } 171 172 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, 173 unsigned &SrcOpIdx2) const override; 174 175 bool isBranchOffsetInRange(unsigned BranchOpc, 176 int64_t BrOffset) const override; 177 178 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 179 180 unsigned insertIndirectBranch(MachineBasicBlock &MBB, 181 MachineBasicBlock &NewDestBB, 182 const DebugLoc &DL, 183 int64_t BrOffset, 184 RegScavenger *RS = nullptr) const override; 185 186 bool analyzeBranchImpl(MachineBasicBlock &MBB, 187 MachineBasicBlock::iterator I, 188 MachineBasicBlock *&TBB, 189 MachineBasicBlock *&FBB, 190 SmallVectorImpl<MachineOperand> &Cond, 191 bool AllowModify) const; 192 193 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 194 MachineBasicBlock *&FBB, 195 SmallVectorImpl<MachineOperand> &Cond, 196 bool AllowModify) const override; 197 198 unsigned removeBranch(MachineBasicBlock &MBB, 199 int *BytesRemoved = nullptr) const override; 200 201 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 202 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 203 const DebugLoc &DL, 204 int *BytesAdded = nullptr) const override; 205 206 bool reverseBranchCondition( 207 SmallVectorImpl<MachineOperand> &Cond) const override; 208 209 210 bool canInsertSelect(const MachineBasicBlock &MBB, 211 ArrayRef<MachineOperand> Cond, 212 unsigned TrueReg, unsigned FalseReg, 213 int &CondCycles, 214 int &TrueCycles, int &FalseCycles) const override; 215 216 void insertSelect(MachineBasicBlock &MBB, 217 MachineBasicBlock::iterator I, const DebugLoc &DL, 218 unsigned DstReg, ArrayRef<MachineOperand> Cond, 219 unsigned TrueReg, unsigned FalseReg) const override; 220 221 bool 222 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb, 223 AliasAnalysis *AA = nullptr) const override; 224 225 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg, 226 MachineRegisterInfo *MRI) const final; 227 228 unsigned getMachineCSELookAheadLimit() const override { return 500; } 229 230 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB, 231 MachineInstr &MI, 232 LiveVariables *LV) const override; 233 234 bool isSchedulingBoundary(const MachineInstr &MI, 235 const MachineBasicBlock *MBB, 236 const MachineFunction &MF) const override; 237 238 static bool isSALU(const MachineInstr &MI) { 239 return MI.getDesc().TSFlags & SIInstrFlags::SALU; 240 } 241 242 bool isSALU(uint16_t Opcode) const { 243 return get(Opcode).TSFlags & SIInstrFlags::SALU; 244 } 245 246 static bool isVALU(const MachineInstr &MI) { 247 return MI.getDesc().TSFlags & SIInstrFlags::VALU; 248 } 249 250 bool isVALU(uint16_t Opcode) const { 251 return get(Opcode).TSFlags & SIInstrFlags::VALU; 252 } 253 254 static bool isVMEM(const MachineInstr &MI) { 255 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI); 256 } 257 258 bool isVMEM(uint16_t Opcode) const { 259 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode); 260 } 261 262 static bool isSOP1(const MachineInstr &MI) { 263 return MI.getDesc().TSFlags & SIInstrFlags::SOP1; 264 } 265 266 bool isSOP1(uint16_t Opcode) const { 267 return get(Opcode).TSFlags & SIInstrFlags::SOP1; 268 } 269 270 static bool isSOP2(const MachineInstr &MI) { 271 return MI.getDesc().TSFlags & SIInstrFlags::SOP2; 272 } 273 274 bool isSOP2(uint16_t Opcode) const { 275 return get(Opcode).TSFlags & SIInstrFlags::SOP2; 276 } 277 278 static bool isSOPC(const MachineInstr &MI) { 279 return MI.getDesc().TSFlags & SIInstrFlags::SOPC; 280 } 281 282 bool isSOPC(uint16_t Opcode) const { 283 return get(Opcode).TSFlags & SIInstrFlags::SOPC; 284 } 285 286 static bool isSOPK(const MachineInstr &MI) { 287 return MI.getDesc().TSFlags & SIInstrFlags::SOPK; 288 } 289 290 bool isSOPK(uint16_t Opcode) const { 291 return get(Opcode).TSFlags & SIInstrFlags::SOPK; 292 } 293 294 static bool isSOPP(const MachineInstr &MI) { 295 return MI.getDesc().TSFlags & SIInstrFlags::SOPP; 296 } 297 298 bool isSOPP(uint16_t Opcode) const { 299 return get(Opcode).TSFlags & SIInstrFlags::SOPP; 300 } 301 302 static bool isVOP1(const MachineInstr &MI) { 303 return MI.getDesc().TSFlags & SIInstrFlags::VOP1; 304 } 305 306 bool isVOP1(uint16_t Opcode) const { 307 return get(Opcode).TSFlags & SIInstrFlags::VOP1; 308 } 309 310 static bool isVOP2(const MachineInstr &MI) { 311 return MI.getDesc().TSFlags & SIInstrFlags::VOP2; 312 } 313 314 bool isVOP2(uint16_t Opcode) const { 315 return get(Opcode).TSFlags & SIInstrFlags::VOP2; 316 } 317 318 static bool isVOP3(const MachineInstr &MI) { 319 return MI.getDesc().TSFlags & SIInstrFlags::VOP3; 320 } 321 322 bool isVOP3(uint16_t Opcode) const { 323 return get(Opcode).TSFlags & SIInstrFlags::VOP3; 324 } 325 326 static bool isSDWA(const MachineInstr &MI) { 327 return MI.getDesc().TSFlags & SIInstrFlags::SDWA; 328 } 329 330 bool isSDWA(uint16_t Opcode) const { 331 return get(Opcode).TSFlags & SIInstrFlags::SDWA; 332 } 333 334 static bool isVOPC(const MachineInstr &MI) { 335 return MI.getDesc().TSFlags & SIInstrFlags::VOPC; 336 } 337 338 bool isVOPC(uint16_t Opcode) const { 339 return get(Opcode).TSFlags & SIInstrFlags::VOPC; 340 } 341 342 static bool isMUBUF(const MachineInstr &MI) { 343 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF; 344 } 345 346 bool isMUBUF(uint16_t Opcode) const { 347 return get(Opcode).TSFlags & SIInstrFlags::MUBUF; 348 } 349 350 static bool isMTBUF(const MachineInstr &MI) { 351 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF; 352 } 353 354 bool isMTBUF(uint16_t Opcode) const { 355 return get(Opcode).TSFlags & SIInstrFlags::MTBUF; 356 } 357 358 static bool isSMRD(const MachineInstr &MI) { 359 return MI.getDesc().TSFlags & SIInstrFlags::SMRD; 360 } 361 362 bool isSMRD(uint16_t Opcode) const { 363 return get(Opcode).TSFlags & SIInstrFlags::SMRD; 364 } 365 366 static bool isDS(const MachineInstr &MI) { 367 return MI.getDesc().TSFlags & SIInstrFlags::DS; 368 } 369 370 bool isDS(uint16_t Opcode) const { 371 return get(Opcode).TSFlags & SIInstrFlags::DS; 372 } 373 374 static bool isMIMG(const MachineInstr &MI) { 375 return MI.getDesc().TSFlags & SIInstrFlags::MIMG; 376 } 377 378 bool isMIMG(uint16_t Opcode) const { 379 return get(Opcode).TSFlags & SIInstrFlags::MIMG; 380 } 381 382 static bool isGather4(const MachineInstr &MI) { 383 return MI.getDesc().TSFlags & SIInstrFlags::Gather4; 384 } 385 386 bool isGather4(uint16_t Opcode) const { 387 return get(Opcode).TSFlags & SIInstrFlags::Gather4; 388 } 389 390 static bool isFLAT(const MachineInstr &MI) { 391 return MI.getDesc().TSFlags & SIInstrFlags::FLAT; 392 } 393 394 bool isFLAT(uint16_t Opcode) const { 395 return get(Opcode).TSFlags & SIInstrFlags::FLAT; 396 } 397 398 static bool isEXP(const MachineInstr &MI) { 399 return MI.getDesc().TSFlags & SIInstrFlags::EXP; 400 } 401 402 bool isEXP(uint16_t Opcode) const { 403 return get(Opcode).TSFlags & SIInstrFlags::EXP; 404 } 405 406 static bool isWQM(const MachineInstr &MI) { 407 return MI.getDesc().TSFlags & SIInstrFlags::WQM; 408 } 409 410 bool isWQM(uint16_t Opcode) const { 411 return get(Opcode).TSFlags & SIInstrFlags::WQM; 412 } 413 414 static bool isDisableWQM(const MachineInstr &MI) { 415 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM; 416 } 417 418 bool isDisableWQM(uint16_t Opcode) const { 419 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM; 420 } 421 422 static bool isVGPRSpill(const MachineInstr &MI) { 423 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill; 424 } 425 426 bool isVGPRSpill(uint16_t Opcode) const { 427 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill; 428 } 429 430 static bool isSGPRSpill(const MachineInstr &MI) { 431 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill; 432 } 433 434 bool isSGPRSpill(uint16_t Opcode) const { 435 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill; 436 } 437 438 static bool isDPP(const MachineInstr &MI) { 439 return MI.getDesc().TSFlags & SIInstrFlags::DPP; 440 } 441 442 bool isDPP(uint16_t Opcode) const { 443 return get(Opcode).TSFlags & SIInstrFlags::DPP; 444 } 445 446 static bool isVOP3P(const MachineInstr &MI) { 447 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P; 448 } 449 450 bool isVOP3P(uint16_t Opcode) const { 451 return get(Opcode).TSFlags & SIInstrFlags::VOP3P; 452 } 453 454 static bool isScalarUnit(const MachineInstr &MI) { 455 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD); 456 } 457 458 static bool usesVM_CNT(const MachineInstr &MI) { 459 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT; 460 } 461 462 static bool sopkIsZext(const MachineInstr &MI) { 463 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT; 464 } 465 466 bool sopkIsZext(uint16_t Opcode) const { 467 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT; 468 } 469 470 /// \returns true if this is an s_store_dword* instruction. This is more 471 /// specific than than isSMEM && mayStore. 472 static bool isScalarStore(const MachineInstr &MI) { 473 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE; 474 } 475 476 bool isScalarStore(uint16_t Opcode) const { 477 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE; 478 } 479 480 static bool isFixedSize(const MachineInstr &MI) { 481 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE; 482 } 483 484 bool isFixedSize(uint16_t Opcode) const { 485 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE; 486 } 487 488 static bool hasFPClamp(const MachineInstr &MI) { 489 return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp; 490 } 491 492 bool hasFPClamp(uint16_t Opcode) const { 493 return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp; 494 } 495 496 bool isVGPRCopy(const MachineInstr &MI) const { 497 assert(MI.isCopy()); 498 unsigned Dest = MI.getOperand(0).getReg(); 499 const MachineFunction &MF = *MI.getParent()->getParent(); 500 const MachineRegisterInfo &MRI = MF.getRegInfo(); 501 return !RI.isSGPRReg(MRI, Dest); 502 } 503 504 bool isInlineConstant(const APInt &Imm) const; 505 506 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const; 507 508 bool isInlineConstant(const MachineOperand &MO, 509 const MCOperandInfo &OpInfo) const { 510 return isInlineConstant(MO, OpInfo.OperandType); 511 } 512 513 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would 514 /// be an inline immediate. 515 bool isInlineConstant(const MachineInstr &MI, 516 const MachineOperand &UseMO, 517 const MachineOperand &DefMO) const { 518 assert(UseMO.getParent() == &MI); 519 int OpIdx = MI.getOperandNo(&UseMO); 520 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) { 521 return false; 522 } 523 524 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]); 525 } 526 527 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline 528 /// immediate. 529 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const { 530 const MachineOperand &MO = MI.getOperand(OpIdx); 531 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType); 532 } 533 534 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx, 535 const MachineOperand &MO) const { 536 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) 537 return false; 538 539 if (MI.isCopy()) { 540 unsigned Size = getOpSize(MI, OpIdx); 541 assert(Size == 8 || Size == 4); 542 543 uint8_t OpType = (Size == 8) ? 544 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32; 545 return isInlineConstant(MO, OpType); 546 } 547 548 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType); 549 } 550 551 bool isInlineConstant(const MachineOperand &MO) const { 552 const MachineInstr *Parent = MO.getParent(); 553 return isInlineConstant(*Parent, Parent->getOperandNo(&MO)); 554 } 555 556 bool isLiteralConstant(const MachineOperand &MO, 557 const MCOperandInfo &OpInfo) const { 558 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType); 559 } 560 561 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const { 562 const MachineOperand &MO = MI.getOperand(OpIdx); 563 return MO.isImm() && !isInlineConstant(MI, OpIdx); 564 } 565 566 // Returns true if this operand could potentially require a 32-bit literal 567 // operand, but not necessarily. A FrameIndex for example could resolve to an 568 // inline immediate value that will not require an additional 4-bytes; this 569 // assumes that it will. 570 bool isLiteralConstantLike(const MachineOperand &MO, 571 const MCOperandInfo &OpInfo) const; 572 573 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo, 574 const MachineOperand &MO) const; 575 576 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding. 577 /// This function will return false if you pass it a 32-bit instruction. 578 bool hasVALU32BitEncoding(unsigned Opcode) const; 579 580 /// \brief Returns true if this operand uses the constant bus. 581 bool usesConstantBus(const MachineRegisterInfo &MRI, 582 const MachineOperand &MO, 583 const MCOperandInfo &OpInfo) const; 584 585 /// \brief Return true if this instruction has any modifiers. 586 /// e.g. src[012]_mod, omod, clamp. 587 bool hasModifiers(unsigned Opcode) const; 588 589 bool hasModifiersSet(const MachineInstr &MI, 590 unsigned OpName) const; 591 bool hasAnyModifiersSet(const MachineInstr &MI) const; 592 593 bool verifyInstruction(const MachineInstr &MI, 594 StringRef &ErrInfo) const override; 595 596 static unsigned getVALUOp(const MachineInstr &MI); 597 598 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const; 599 600 /// \brief Return the correct register class for \p OpNo. For target-specific 601 /// instructions, this will return the register class that has been defined 602 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return 603 /// the register class of its machine operand. 604 /// to infer the correct register class base on the other operands. 605 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI, 606 unsigned OpNo) const; 607 608 /// \brief Return the size in bytes of the operand OpNo on the given 609 // instruction opcode. 610 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const { 611 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo]; 612 613 if (OpInfo.RegClass == -1) { 614 // If this is an immediate operand, this must be a 32-bit literal. 615 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE); 616 return 4; 617 } 618 619 return RI.getRegClass(OpInfo.RegClass)->getSize(); 620 } 621 622 /// \brief This form should usually be preferred since it handles operands 623 /// with unknown register classes. 624 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const { 625 return getOpRegClass(MI, OpNo)->getSize(); 626 } 627 628 /// \returns true if it is legal for the operand at index \p OpNo 629 /// to read a VGPR. 630 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const; 631 632 /// \brief Legalize the \p OpIndex operand of this instruction by inserting 633 /// a MOV. For example: 634 /// ADD_I32_e32 VGPR0, 15 635 /// to 636 /// MOV VGPR1, 15 637 /// ADD_I32_e32 VGPR0, VGPR1 638 /// 639 /// If the operand being legalized is a register, then a COPY will be used 640 /// instead of MOV. 641 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const; 642 643 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand 644 /// for \p MI. 645 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx, 646 const MachineOperand *MO = nullptr) const; 647 648 /// \brief Check if \p MO would be a valid operand for the given operand 649 /// definition \p OpInfo. Note this does not attempt to validate constant bus 650 /// restrictions (e.g. literal constant usage). 651 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI, 652 const MCOperandInfo &OpInfo, 653 const MachineOperand &MO) const; 654 655 /// \brief Check if \p MO (a register operand) is a legal register for the 656 /// given operand description. 657 bool isLegalRegOperand(const MachineRegisterInfo &MRI, 658 const MCOperandInfo &OpInfo, 659 const MachineOperand &MO) const; 660 661 /// \brief Legalize operands in \p MI by either commuting it or inserting a 662 /// copy of src1. 663 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const; 664 665 /// \brief Fix operands in \p MI to satisfy constant bus requirements. 666 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const; 667 668 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only 669 /// be used when it is know that the value in SrcReg is same across all 670 /// threads in the wave. 671 /// \returns The SGPR register that \p SrcReg was copied to. 672 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI, 673 MachineRegisterInfo &MRI) const; 674 675 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const; 676 677 void legalizeGenericOperand(MachineBasicBlock &InsertMBB, 678 MachineBasicBlock::iterator I, 679 const TargetRegisterClass *DstRC, 680 MachineOperand &Op, MachineRegisterInfo &MRI, 681 const DebugLoc &DL) const; 682 683 /// \brief Legalize all operands in this instruction. This function may 684 /// create new instruction and insert them before \p MI. 685 void legalizeOperands(MachineInstr &MI) const; 686 687 /// \brief Replace this instruction's opcode with the equivalent VALU 688 /// opcode. This function will also move the users of \p MI to the 689 /// VALU if necessary. 690 void moveToVALU(MachineInstr &MI) const; 691 692 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI, 693 int Count) const; 694 695 void insertNoop(MachineBasicBlock &MBB, 696 MachineBasicBlock::iterator MI) const override; 697 698 /// \brief Return the number of wait states that result from executing this 699 /// instruction. 700 unsigned getNumWaitStates(const MachineInstr &MI) const; 701 702 /// \brief Returns the operand named \p Op. If \p MI does not have an 703 /// operand named \c Op, this function returns nullptr. 704 LLVM_READONLY 705 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const; 706 707 LLVM_READONLY 708 const MachineOperand *getNamedOperand(const MachineInstr &MI, 709 unsigned OpName) const { 710 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName); 711 } 712 713 /// Get required immediate operand 714 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const { 715 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName); 716 return MI.getOperand(Idx).getImm(); 717 } 718 719 uint64_t getDefaultRsrcDataFormat() const; 720 uint64_t getScratchRsrcWords23() const; 721 722 bool isLowLatencyInstruction(const MachineInstr &MI) const; 723 bool isHighLatencyInstruction(const MachineInstr &MI) const; 724 725 /// \brief Return the descriptor of the target-specific machine instruction 726 /// that corresponds to the specified pseudo or native opcode. 727 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const { 728 return get(pseudoToMCOpcode(Opcode)); 729 } 730 731 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const; 732 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const; 733 734 unsigned isLoadFromStackSlot(const MachineInstr &MI, 735 int &FrameIndex) const override; 736 unsigned isStoreToStackSlot(const MachineInstr &MI, 737 int &FrameIndex) const override; 738 739 unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 740 741 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const; 742 743 ArrayRef<std::pair<int, const char *>> 744 getSerializableTargetIndices() const override; 745 746 ScheduleHazardRecognizer * 747 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 748 const ScheduleDAG *DAG) const override; 749 750 ScheduleHazardRecognizer * 751 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override; 752 753 bool isBasicBlockPrologue(const MachineInstr &MI) const override; 754 }; 755 756 namespace AMDGPU { 757 LLVM_READONLY 758 int getVOPe64(uint16_t Opcode); 759 760 LLVM_READONLY 761 int getVOPe32(uint16_t Opcode); 762 763 LLVM_READONLY 764 int getCommuteRev(uint16_t Opcode); 765 766 LLVM_READONLY 767 int getCommuteOrig(uint16_t Opcode); 768 769 LLVM_READONLY 770 int getAddr64Inst(uint16_t Opcode); 771 772 LLVM_READONLY 773 int getAtomicRetOp(uint16_t Opcode); 774 775 LLVM_READONLY 776 int getAtomicNoRetOp(uint16_t Opcode); 777 778 LLVM_READONLY 779 int getSOPKOp(uint16_t Opcode); 780 781 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL; 782 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19); 783 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21); 784 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23); 785 786 // For MachineOperands. 787 enum TargetFlags { 788 TF_LONG_BRANCH_FORWARD = 1 << 0, 789 TF_LONG_BRANCH_BACKWARD = 1 << 1 790 }; 791 } // End namespace AMDGPU 792 793 namespace SI { 794 namespace KernelInputOffsets { 795 796 /// Offsets in bytes from the start of the input buffer 797 enum Offsets { 798 NGROUPS_X = 0, 799 NGROUPS_Y = 4, 800 NGROUPS_Z = 8, 801 GLOBAL_SIZE_X = 12, 802 GLOBAL_SIZE_Y = 16, 803 GLOBAL_SIZE_Z = 20, 804 LOCAL_SIZE_X = 24, 805 LOCAL_SIZE_Y = 28, 806 LOCAL_SIZE_Z = 32 807 }; 808 809 } // End namespace KernelInputOffsets 810 } // End namespace SI 811 812 } // End namespace llvm 813 814 #endif 815