1 //===-- SIInstrInfo.h - SI Instruction Info Interface -----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Interface definition for SIInstrInfo.
13 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
17 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
19 #include "AMDGPUInstrInfo.h"
20 #include "SIDefines.h"
21 #include "SIRegisterInfo.h"
25 class SIInstrInfo final : public AMDGPUInstrInfo {
27 const SIRegisterInfo RI;
28 const SISubtarget &ST;
30 // The the inverse predicate should have the negative value.
31 enum BranchPredicate {
41 static unsigned getBranchOpcode(BranchPredicate Cond);
42 static BranchPredicate getBranchPredicate(unsigned Opcode);
44 unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
45 MachineRegisterInfo &MRI,
46 MachineOperand &SuperReg,
47 const TargetRegisterClass *SuperRC,
49 const TargetRegisterClass *SubRC) const;
50 MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
51 MachineRegisterInfo &MRI,
52 MachineOperand &SuperReg,
53 const TargetRegisterClass *SuperRC,
55 const TargetRegisterClass *SubRC) const;
57 void swapOperands(MachineInstr &Inst) const;
59 void lowerScalarAbs(SmallVectorImpl<MachineInstr *> &Worklist,
60 MachineInstr &Inst) const;
62 void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
63 MachineInstr &Inst, unsigned Opcode) const;
65 void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
66 MachineInstr &Inst, unsigned Opcode) const;
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;
76 void addUsersToMoveToVALUWorklist(
77 unsigned Reg, MachineRegisterInfo &MRI,
78 SmallVectorImpl<MachineInstr *> &Worklist) const;
81 addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
82 SmallVectorImpl<MachineInstr *> &Worklist) const;
84 const TargetRegisterClass *
85 getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
87 bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
89 unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
92 bool swapSourceModifiers(MachineInstr &MI,
93 MachineOperand &Src0, unsigned Src0OpName,
94 MachineOperand &Src1, unsigned Src1OpName) const;
96 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
98 unsigned OpIdx1) const override;
102 enum TargetOperandFlags {
104 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
106 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
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.
114 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
118 explicit SIInstrInfo(const SISubtarget &);
120 const SIRegisterInfo &getRegisterInfo() const {
124 bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
125 AliasAnalysis *AA) const override;
127 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
129 int64_t &Offset2) const override;
131 bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
133 const TargetRegisterInfo *TRI) const final;
135 bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
136 unsigned NumLoads) const final;
138 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
139 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
140 bool KillSrc) const override;
142 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
143 RegScavenger *RS, unsigned TmpReg,
144 unsigned Offset, unsigned Size) const;
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;
152 void loadRegFromStackSlot(MachineBasicBlock &MBB,
153 MachineBasicBlock::iterator MI, unsigned DestReg,
154 int FrameIndex, const TargetRegisterClass *RC,
155 const TargetRegisterInfo *TRI) const override;
157 bool expandPostRAPseudo(MachineInstr &MI) const override;
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;
165 int commuteOpcode(unsigned Opc) const;
168 inline int commuteOpcode(const MachineInstr &MI) const {
169 return commuteOpcode(MI.getOpcode());
172 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
173 unsigned &SrcOpIdx2) const override;
175 bool isBranchOffsetInRange(unsigned BranchOpc,
176 int64_t BrOffset) const override;
178 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
180 unsigned insertIndirectBranch(MachineBasicBlock &MBB,
181 MachineBasicBlock &NewDestBB,
184 RegScavenger *RS = nullptr) const override;
186 bool analyzeBranchImpl(MachineBasicBlock &MBB,
187 MachineBasicBlock::iterator I,
188 MachineBasicBlock *&TBB,
189 MachineBasicBlock *&FBB,
190 SmallVectorImpl<MachineOperand> &Cond,
191 bool AllowModify) const;
193 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
194 MachineBasicBlock *&FBB,
195 SmallVectorImpl<MachineOperand> &Cond,
196 bool AllowModify) const override;
198 unsigned removeBranch(MachineBasicBlock &MBB,
199 int *BytesRemoved = nullptr) const override;
201 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
202 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
204 int *BytesAdded = nullptr) const override;
206 bool reverseBranchCondition(
207 SmallVectorImpl<MachineOperand> &Cond) const override;
210 bool canInsertSelect(const MachineBasicBlock &MBB,
211 ArrayRef<MachineOperand> Cond,
212 unsigned TrueReg, unsigned FalseReg,
214 int &TrueCycles, int &FalseCycles) const override;
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;
222 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
223 AliasAnalysis *AA = nullptr) const override;
225 bool isFoldableCopy(const MachineInstr &MI) const;
227 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
228 MachineRegisterInfo *MRI) const final;
230 unsigned getMachineCSELookAheadLimit() const override { return 500; }
232 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
234 LiveVariables *LV) const override;
236 bool isSchedulingBoundary(const MachineInstr &MI,
237 const MachineBasicBlock *MBB,
238 const MachineFunction &MF) const override;
240 static bool isSALU(const MachineInstr &MI) {
241 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
244 bool isSALU(uint16_t Opcode) const {
245 return get(Opcode).TSFlags & SIInstrFlags::SALU;
248 static bool isVALU(const MachineInstr &MI) {
249 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
252 bool isVALU(uint16_t Opcode) const {
253 return get(Opcode).TSFlags & SIInstrFlags::VALU;
256 static bool isVMEM(const MachineInstr &MI) {
257 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
260 bool isVMEM(uint16_t Opcode) const {
261 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
264 static bool isSOP1(const MachineInstr &MI) {
265 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
268 bool isSOP1(uint16_t Opcode) const {
269 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
272 static bool isSOP2(const MachineInstr &MI) {
273 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
276 bool isSOP2(uint16_t Opcode) const {
277 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
280 static bool isSOPC(const MachineInstr &MI) {
281 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
284 bool isSOPC(uint16_t Opcode) const {
285 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
288 static bool isSOPK(const MachineInstr &MI) {
289 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
292 bool isSOPK(uint16_t Opcode) const {
293 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
296 static bool isSOPP(const MachineInstr &MI) {
297 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
300 bool isSOPP(uint16_t Opcode) const {
301 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
304 static bool isVOP1(const MachineInstr &MI) {
305 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
308 bool isVOP1(uint16_t Opcode) const {
309 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
312 static bool isVOP2(const MachineInstr &MI) {
313 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
316 bool isVOP2(uint16_t Opcode) const {
317 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
320 static bool isVOP3(const MachineInstr &MI) {
321 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
324 bool isVOP3(uint16_t Opcode) const {
325 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
328 static bool isSDWA(const MachineInstr &MI) {
329 return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
332 bool isSDWA(uint16_t Opcode) const {
333 return get(Opcode).TSFlags & SIInstrFlags::SDWA;
336 static bool isVOPC(const MachineInstr &MI) {
337 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
340 bool isVOPC(uint16_t Opcode) const {
341 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
344 static bool isMUBUF(const MachineInstr &MI) {
345 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
348 bool isMUBUF(uint16_t Opcode) const {
349 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
352 static bool isMTBUF(const MachineInstr &MI) {
353 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
356 bool isMTBUF(uint16_t Opcode) const {
357 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
360 static bool isSMRD(const MachineInstr &MI) {
361 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
364 bool isSMRD(uint16_t Opcode) const {
365 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
368 static bool isDS(const MachineInstr &MI) {
369 return MI.getDesc().TSFlags & SIInstrFlags::DS;
372 bool isDS(uint16_t Opcode) const {
373 return get(Opcode).TSFlags & SIInstrFlags::DS;
376 static bool isMIMG(const MachineInstr &MI) {
377 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
380 bool isMIMG(uint16_t Opcode) const {
381 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
384 static bool isGather4(const MachineInstr &MI) {
385 return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
388 bool isGather4(uint16_t Opcode) const {
389 return get(Opcode).TSFlags & SIInstrFlags::Gather4;
392 static bool isFLAT(const MachineInstr &MI) {
393 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
396 bool isFLAT(uint16_t Opcode) const {
397 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
400 static bool isEXP(const MachineInstr &MI) {
401 return MI.getDesc().TSFlags & SIInstrFlags::EXP;
404 bool isEXP(uint16_t Opcode) const {
405 return get(Opcode).TSFlags & SIInstrFlags::EXP;
408 static bool isWQM(const MachineInstr &MI) {
409 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
412 bool isWQM(uint16_t Opcode) const {
413 return get(Opcode).TSFlags & SIInstrFlags::WQM;
416 static bool isDisableWQM(const MachineInstr &MI) {
417 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
420 bool isDisableWQM(uint16_t Opcode) const {
421 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
424 static bool isVGPRSpill(const MachineInstr &MI) {
425 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
428 bool isVGPRSpill(uint16_t Opcode) const {
429 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
432 static bool isSGPRSpill(const MachineInstr &MI) {
433 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
436 bool isSGPRSpill(uint16_t Opcode) const {
437 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
440 static bool isDPP(const MachineInstr &MI) {
441 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
444 bool isDPP(uint16_t Opcode) const {
445 return get(Opcode).TSFlags & SIInstrFlags::DPP;
448 static bool isVOP3P(const MachineInstr &MI) {
449 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
452 bool isVOP3P(uint16_t Opcode) const {
453 return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
456 static bool isVINTRP(const MachineInstr &MI) {
457 return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
460 bool isVINTRP(uint16_t Opcode) const {
461 return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
464 static bool isScalarUnit(const MachineInstr &MI) {
465 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
468 static bool usesVM_CNT(const MachineInstr &MI) {
469 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
472 static bool sopkIsZext(const MachineInstr &MI) {
473 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
476 bool sopkIsZext(uint16_t Opcode) const {
477 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
480 /// \returns true if this is an s_store_dword* instruction. This is more
481 /// specific than than isSMEM && mayStore.
482 static bool isScalarStore(const MachineInstr &MI) {
483 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
486 bool isScalarStore(uint16_t Opcode) const {
487 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
490 static bool isFixedSize(const MachineInstr &MI) {
491 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
494 bool isFixedSize(uint16_t Opcode) const {
495 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
498 static bool hasFPClamp(const MachineInstr &MI) {
499 return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp;
502 bool hasFPClamp(uint16_t Opcode) const {
503 return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp;
506 bool isVGPRCopy(const MachineInstr &MI) const {
508 unsigned Dest = MI.getOperand(0).getReg();
509 const MachineFunction &MF = *MI.getParent()->getParent();
510 const MachineRegisterInfo &MRI = MF.getRegInfo();
511 return !RI.isSGPRReg(MRI, Dest);
514 bool isInlineConstant(const APInt &Imm) const;
516 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
518 bool isInlineConstant(const MachineOperand &MO,
519 const MCOperandInfo &OpInfo) const {
520 return isInlineConstant(MO, OpInfo.OperandType);
523 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
524 /// be an inline immediate.
525 bool isInlineConstant(const MachineInstr &MI,
526 const MachineOperand &UseMO,
527 const MachineOperand &DefMO) const {
528 assert(UseMO.getParent() == &MI);
529 int OpIdx = MI.getOperandNo(&UseMO);
530 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
534 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
537 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
539 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
540 const MachineOperand &MO = MI.getOperand(OpIdx);
541 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
544 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
545 const MachineOperand &MO) const {
546 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
550 unsigned Size = getOpSize(MI, OpIdx);
551 assert(Size == 8 || Size == 4);
553 uint8_t OpType = (Size == 8) ?
554 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
555 return isInlineConstant(MO, OpType);
558 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
561 bool isInlineConstant(const MachineOperand &MO) const {
562 const MachineInstr *Parent = MO.getParent();
563 return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
566 bool isLiteralConstant(const MachineOperand &MO,
567 const MCOperandInfo &OpInfo) const {
568 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
571 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
572 const MachineOperand &MO = MI.getOperand(OpIdx);
573 return MO.isImm() && !isInlineConstant(MI, OpIdx);
576 // Returns true if this operand could potentially require a 32-bit literal
577 // operand, but not necessarily. A FrameIndex for example could resolve to an
578 // inline immediate value that will not require an additional 4-bytes; this
579 // assumes that it will.
580 bool isLiteralConstantLike(const MachineOperand &MO,
581 const MCOperandInfo &OpInfo) const;
583 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
584 const MachineOperand &MO) const;
586 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
587 /// This function will return false if you pass it a 32-bit instruction.
588 bool hasVALU32BitEncoding(unsigned Opcode) const;
590 /// \brief Returns true if this operand uses the constant bus.
591 bool usesConstantBus(const MachineRegisterInfo &MRI,
592 const MachineOperand &MO,
593 const MCOperandInfo &OpInfo) const;
595 /// \brief Return true if this instruction has any modifiers.
596 /// e.g. src[012]_mod, omod, clamp.
597 bool hasModifiers(unsigned Opcode) const;
599 bool hasModifiersSet(const MachineInstr &MI,
600 unsigned OpName) const;
601 bool hasAnyModifiersSet(const MachineInstr &MI) const;
603 bool verifyInstruction(const MachineInstr &MI,
604 StringRef &ErrInfo) const override;
606 static unsigned getVALUOp(const MachineInstr &MI);
608 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
610 /// \brief Return the correct register class for \p OpNo. For target-specific
611 /// instructions, this will return the register class that has been defined
612 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
613 /// the register class of its machine operand.
614 /// to infer the correct register class base on the other operands.
615 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
616 unsigned OpNo) const;
618 /// \brief Return the size in bytes of the operand OpNo on the given
619 // instruction opcode.
620 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
621 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
623 if (OpInfo.RegClass == -1) {
624 // If this is an immediate operand, this must be a 32-bit literal.
625 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
629 return RI.getRegClass(OpInfo.RegClass)->getSize();
632 /// \brief This form should usually be preferred since it handles operands
633 /// with unknown register classes.
634 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
635 return getOpRegClass(MI, OpNo)->getSize();
638 /// \returns true if it is legal for the operand at index \p OpNo
640 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
642 /// \brief Legalize the \p OpIndex operand of this instruction by inserting
643 /// a MOV. For example:
644 /// ADD_I32_e32 VGPR0, 15
647 /// ADD_I32_e32 VGPR0, VGPR1
649 /// If the operand being legalized is a register, then a COPY will be used
651 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
653 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
655 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
656 const MachineOperand *MO = nullptr) const;
658 /// \brief Check if \p MO would be a valid operand for the given operand
659 /// definition \p OpInfo. Note this does not attempt to validate constant bus
660 /// restrictions (e.g. literal constant usage).
661 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
662 const MCOperandInfo &OpInfo,
663 const MachineOperand &MO) const;
665 /// \brief Check if \p MO (a register operand) is a legal register for the
666 /// given operand description.
667 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
668 const MCOperandInfo &OpInfo,
669 const MachineOperand &MO) const;
671 /// \brief Legalize operands in \p MI by either commuting it or inserting a
673 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
675 /// \brief Fix operands in \p MI to satisfy constant bus requirements.
676 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
678 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
679 /// be used when it is know that the value in SrcReg is same across all
680 /// threads in the wave.
681 /// \returns The SGPR register that \p SrcReg was copied to.
682 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
683 MachineRegisterInfo &MRI) const;
685 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
687 void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
688 MachineBasicBlock::iterator I,
689 const TargetRegisterClass *DstRC,
690 MachineOperand &Op, MachineRegisterInfo &MRI,
691 const DebugLoc &DL) const;
693 /// \brief Legalize all operands in this instruction. This function may
694 /// create new instruction and insert them before \p MI.
695 void legalizeOperands(MachineInstr &MI) const;
697 /// \brief Replace this instruction's opcode with the equivalent VALU
698 /// opcode. This function will also move the users of \p MI to the
699 /// VALU if necessary.
700 void moveToVALU(MachineInstr &MI) const;
702 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
705 void insertNoop(MachineBasicBlock &MBB,
706 MachineBasicBlock::iterator MI) const override;
708 /// \brief Return the number of wait states that result from executing this
710 unsigned getNumWaitStates(const MachineInstr &MI) const;
712 /// \brief Returns the operand named \p Op. If \p MI does not have an
713 /// operand named \c Op, this function returns nullptr.
715 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
718 const MachineOperand *getNamedOperand(const MachineInstr &MI,
719 unsigned OpName) const {
720 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
723 /// Get required immediate operand
724 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
725 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
726 return MI.getOperand(Idx).getImm();
729 uint64_t getDefaultRsrcDataFormat() const;
730 uint64_t getScratchRsrcWords23() const;
732 bool isLowLatencyInstruction(const MachineInstr &MI) const;
733 bool isHighLatencyInstruction(const MachineInstr &MI) const;
735 /// \brief Return the descriptor of the target-specific machine instruction
736 /// that corresponds to the specified pseudo or native opcode.
737 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
738 return get(pseudoToMCOpcode(Opcode));
741 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
742 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
744 unsigned isLoadFromStackSlot(const MachineInstr &MI,
745 int &FrameIndex) const override;
746 unsigned isStoreToStackSlot(const MachineInstr &MI,
747 int &FrameIndex) const override;
749 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
751 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
753 ArrayRef<std::pair<int, const char *>>
754 getSerializableTargetIndices() const override;
756 ScheduleHazardRecognizer *
757 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
758 const ScheduleDAG *DAG) const override;
760 ScheduleHazardRecognizer *
761 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
763 bool isBasicBlockPrologue(const MachineInstr &MI) const override;
765 /// \brief Return a partially built integer add instruction without carry.
766 /// Caller must add source operands.
767 /// For pre-GFX9 it will generate unused carry destination operand.
768 /// TODO: After GFX9 it should return a no-carry operation.
769 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
770 MachineBasicBlock::iterator I,
772 unsigned DestReg) const;
777 int getVOPe64(uint16_t Opcode);
780 int getVOPe32(uint16_t Opcode);
783 int getSDWAOp(uint16_t Opcode);
786 int getCommuteRev(uint16_t Opcode);
789 int getCommuteOrig(uint16_t Opcode);
792 int getAddr64Inst(uint16_t Opcode);
795 int getAtomicRetOp(uint16_t Opcode);
798 int getAtomicNoRetOp(uint16_t Opcode);
801 int getSOPKOp(uint16_t Opcode);
803 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
804 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
805 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
806 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
808 // For MachineOperands.
810 TF_LONG_BRANCH_FORWARD = 1 << 0,
811 TF_LONG_BRANCH_BACKWARD = 1 << 1
813 } // End namespace AMDGPU
816 namespace KernelInputOffsets {
818 /// Offsets in bytes from the start of the input buffer
831 } // End namespace KernelInputOffsets
832 } // End namespace SI
834 } // End namespace llvm