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