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;
73 void addUsersToMoveToVALUWorklist(
74 unsigned Reg, MachineRegisterInfo &MRI,
75 SmallVectorImpl<MachineInstr *> &Worklist) const;
78 addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
79 SmallVectorImpl<MachineInstr *> &Worklist) const;
81 const TargetRegisterClass *
82 getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
84 bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
86 unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
89 bool swapSourceModifiers(MachineInstr &MI,
90 MachineOperand &Src0, unsigned Src0OpName,
91 MachineOperand &Src1, unsigned Src1OpName) const;
93 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
95 unsigned OpIdx1) const override;
99 enum TargetOperandFlags {
101 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
103 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
105 MO_GOTPCREL32_LO = 2,
106 // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
107 MO_GOTPCREL32_HI = 3,
108 // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
111 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
115 explicit SIInstrInfo(const SISubtarget &);
117 const SIRegisterInfo &getRegisterInfo() const {
121 bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
122 AliasAnalysis *AA) const override;
124 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
126 int64_t &Offset2) const override;
128 bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
130 const TargetRegisterInfo *TRI) const final;
132 bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
133 unsigned NumLoads) const final;
135 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
136 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
137 bool KillSrc) const override;
139 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
140 RegScavenger *RS, unsigned TmpReg,
141 unsigned Offset, unsigned Size) const;
143 void storeRegToStackSlot(MachineBasicBlock &MBB,
144 MachineBasicBlock::iterator MI, unsigned SrcReg,
145 bool isKill, int FrameIndex,
146 const TargetRegisterClass *RC,
147 const TargetRegisterInfo *TRI) const override;
149 void loadRegFromStackSlot(MachineBasicBlock &MBB,
150 MachineBasicBlock::iterator MI, unsigned DestReg,
151 int FrameIndex, const TargetRegisterClass *RC,
152 const TargetRegisterInfo *TRI) const override;
154 bool expandPostRAPseudo(MachineInstr &MI) const override;
156 // \brief Returns an opcode that can be used to move a value to a \p DstRC
157 // register. If there is no hardware instruction that can store to \p
158 // DstRC, then AMDGPU::COPY is returned.
159 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
162 int commuteOpcode(unsigned Opc) const;
165 inline int commuteOpcode(const MachineInstr &MI) const {
166 return commuteOpcode(MI.getOpcode());
169 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
170 unsigned &SrcOpIdx2) const override;
172 bool isBranchOffsetInRange(unsigned BranchOpc,
173 int64_t BrOffset) const override;
175 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
177 unsigned insertIndirectBranch(MachineBasicBlock &MBB,
178 MachineBasicBlock &NewDestBB,
181 RegScavenger *RS = nullptr) const override;
183 bool analyzeBranchImpl(MachineBasicBlock &MBB,
184 MachineBasicBlock::iterator I,
185 MachineBasicBlock *&TBB,
186 MachineBasicBlock *&FBB,
187 SmallVectorImpl<MachineOperand> &Cond,
188 bool AllowModify) const;
190 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
191 MachineBasicBlock *&FBB,
192 SmallVectorImpl<MachineOperand> &Cond,
193 bool AllowModify) const override;
195 unsigned removeBranch(MachineBasicBlock &MBB,
196 int *BytesRemoved = nullptr) const override;
198 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
199 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
201 int *BytesAdded = nullptr) const override;
203 bool reverseBranchCondition(
204 SmallVectorImpl<MachineOperand> &Cond) const override;
207 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
208 AliasAnalysis *AA = nullptr) const override;
210 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
211 MachineRegisterInfo *MRI) const final;
213 unsigned getMachineCSELookAheadLimit() const override { return 500; }
215 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
217 LiveVariables *LV) const override;
219 bool isSchedulingBoundary(const MachineInstr &MI,
220 const MachineBasicBlock *MBB,
221 const MachineFunction &MF) const override;
223 static bool isSALU(const MachineInstr &MI) {
224 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
227 bool isSALU(uint16_t Opcode) const {
228 return get(Opcode).TSFlags & SIInstrFlags::SALU;
231 static bool isVALU(const MachineInstr &MI) {
232 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
235 bool isVALU(uint16_t Opcode) const {
236 return get(Opcode).TSFlags & SIInstrFlags::VALU;
239 static bool isVMEM(const MachineInstr &MI) {
240 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
243 bool isVMEM(uint16_t Opcode) const {
244 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
247 static bool isSOP1(const MachineInstr &MI) {
248 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
251 bool isSOP1(uint16_t Opcode) const {
252 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
255 static bool isSOP2(const MachineInstr &MI) {
256 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
259 bool isSOP2(uint16_t Opcode) const {
260 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
263 static bool isSOPC(const MachineInstr &MI) {
264 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
267 bool isSOPC(uint16_t Opcode) const {
268 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
271 static bool isSOPK(const MachineInstr &MI) {
272 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
275 bool isSOPK(uint16_t Opcode) const {
276 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
279 static bool isSOPP(const MachineInstr &MI) {
280 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
283 bool isSOPP(uint16_t Opcode) const {
284 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
287 static bool isVOP1(const MachineInstr &MI) {
288 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
291 bool isVOP1(uint16_t Opcode) const {
292 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
295 static bool isVOP2(const MachineInstr &MI) {
296 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
299 bool isVOP2(uint16_t Opcode) const {
300 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
303 static bool isVOP3(const MachineInstr &MI) {
304 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
307 bool isVOP3(uint16_t Opcode) const {
308 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
311 static bool isVOPC(const MachineInstr &MI) {
312 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
315 bool isVOPC(uint16_t Opcode) const {
316 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
319 static bool isMUBUF(const MachineInstr &MI) {
320 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
323 bool isMUBUF(uint16_t Opcode) const {
324 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
327 static bool isMTBUF(const MachineInstr &MI) {
328 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
331 bool isMTBUF(uint16_t Opcode) const {
332 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
335 static bool isSMRD(const MachineInstr &MI) {
336 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
339 bool isSMRD(uint16_t Opcode) const {
340 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
343 static bool isDS(const MachineInstr &MI) {
344 return MI.getDesc().TSFlags & SIInstrFlags::DS;
347 bool isDS(uint16_t Opcode) const {
348 return get(Opcode).TSFlags & SIInstrFlags::DS;
351 static bool isMIMG(const MachineInstr &MI) {
352 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
355 bool isMIMG(uint16_t Opcode) const {
356 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
359 static bool isGather4(const MachineInstr &MI) {
360 return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
363 bool isGather4(uint16_t Opcode) const {
364 return get(Opcode).TSFlags & SIInstrFlags::Gather4;
367 static bool isFLAT(const MachineInstr &MI) {
368 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
371 bool isFLAT(uint16_t Opcode) const {
372 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
375 static bool isEXP(const MachineInstr &MI) {
376 return MI.getDesc().TSFlags & SIInstrFlags::EXP;
379 bool isEXP(uint16_t Opcode) const {
380 return get(Opcode).TSFlags & SIInstrFlags::EXP;
383 static bool isWQM(const MachineInstr &MI) {
384 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
387 bool isWQM(uint16_t Opcode) const {
388 return get(Opcode).TSFlags & SIInstrFlags::WQM;
391 static bool isDisableWQM(const MachineInstr &MI) {
392 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
395 bool isDisableWQM(uint16_t Opcode) const {
396 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
399 static bool isVGPRSpill(const MachineInstr &MI) {
400 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
403 bool isVGPRSpill(uint16_t Opcode) const {
404 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
407 static bool isSGPRSpill(const MachineInstr &MI) {
408 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
411 bool isSGPRSpill(uint16_t Opcode) const {
412 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
415 static bool isDPP(const MachineInstr &MI) {
416 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
419 bool isDPP(uint16_t Opcode) const {
420 return get(Opcode).TSFlags & SIInstrFlags::DPP;
423 static bool isScalarUnit(const MachineInstr &MI) {
424 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
427 static bool usesVM_CNT(const MachineInstr &MI) {
428 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
431 static bool sopkIsZext(const MachineInstr &MI) {
432 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
435 bool sopkIsZext(uint16_t Opcode) const {
436 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
439 /// \returns true if this is an s_store_dword* instruction. This is more
440 /// specific than than isSMEM && mayStore.
441 static bool isScalarStore(const MachineInstr &MI) {
442 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
445 bool isScalarStore(uint16_t Opcode) const {
446 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
449 static bool isFixedSize(const MachineInstr &MI) {
450 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
453 bool isFixedSize(uint16_t Opcode) const {
454 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
457 bool isVGPRCopy(const MachineInstr &MI) const {
459 unsigned Dest = MI.getOperand(0).getReg();
460 const MachineFunction &MF = *MI.getParent()->getParent();
461 const MachineRegisterInfo &MRI = MF.getRegInfo();
462 return !RI.isSGPRReg(MRI, Dest);
465 static int operandBitWidth(uint8_t OperandType) {
466 switch (OperandType) {
467 case AMDGPU::OPERAND_REG_IMM_INT32:
468 case AMDGPU::OPERAND_REG_IMM_FP32:
469 case AMDGPU::OPERAND_REG_INLINE_C_INT32:
470 case AMDGPU::OPERAND_REG_INLINE_C_FP32:
472 case AMDGPU::OPERAND_REG_IMM_INT64:
473 case AMDGPU::OPERAND_REG_IMM_FP64:
474 case AMDGPU::OPERAND_REG_INLINE_C_INT64:
475 case AMDGPU::OPERAND_REG_INLINE_C_FP64:
477 case AMDGPU::OPERAND_REG_INLINE_C_INT16:
478 case AMDGPU::OPERAND_REG_INLINE_C_FP16:
479 case AMDGPU::OPERAND_REG_IMM_INT16:
480 case AMDGPU::OPERAND_REG_IMM_FP16:
483 llvm_unreachable("unexpected operand type");
487 bool isInlineConstant(const APInt &Imm) const;
489 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
491 bool isInlineConstant(const MachineOperand &MO,
492 const MCOperandInfo &OpInfo) const {
493 return isInlineConstant(MO, OpInfo.OperandType);
496 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
497 /// be an inline immediate.
498 bool isInlineConstant(const MachineInstr &MI,
499 const MachineOperand &UseMO,
500 const MachineOperand &DefMO) const {
501 assert(UseMO.getParent() == &MI);
502 int OpIdx = MI.getOperandNo(&UseMO);
503 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
507 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
510 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
512 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
513 const MachineOperand &MO = MI.getOperand(OpIdx);
514 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
517 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
518 const MachineOperand &MO) const {
519 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
523 unsigned Size = getOpSize(MI, OpIdx);
524 assert(Size == 8 || Size == 4);
526 uint8_t OpType = (Size == 8) ?
527 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
528 return isInlineConstant(MO, OpType);
531 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
534 bool isInlineConstant(const MachineOperand &MO) const {
535 const MachineInstr *Parent = MO.getParent();
536 return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
539 bool isLiteralConstant(const MachineOperand &MO,
540 const MCOperandInfo &OpInfo) const {
541 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
544 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
545 const MachineOperand &MO = MI.getOperand(OpIdx);
546 return MO.isImm() && !isInlineConstant(MI, OpIdx);
549 // Returns true if this operand could potentially require a 32-bit literal
550 // operand, but not necessarily. A FrameIndex for example could resolve to an
551 // inline immediate value that will not require an additional 4-bytes; this
552 // assumes that it will.
553 bool isLiteralConstantLike(const MachineOperand &MO,
554 const MCOperandInfo &OpInfo) const;
556 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
557 const MachineOperand &MO) const;
559 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
560 /// This function will return false if you pass it a 32-bit instruction.
561 bool hasVALU32BitEncoding(unsigned Opcode) const;
563 /// \brief Returns true if this operand uses the constant bus.
564 bool usesConstantBus(const MachineRegisterInfo &MRI,
565 const MachineOperand &MO,
566 const MCOperandInfo &OpInfo) const;
568 /// \brief Return true if this instruction has any modifiers.
569 /// e.g. src[012]_mod, omod, clamp.
570 bool hasModifiers(unsigned Opcode) const;
572 bool hasModifiersSet(const MachineInstr &MI,
573 unsigned OpName) const;
575 bool verifyInstruction(const MachineInstr &MI,
576 StringRef &ErrInfo) const override;
578 static unsigned getVALUOp(const MachineInstr &MI);
580 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
582 /// \brief Return the correct register class for \p OpNo. For target-specific
583 /// instructions, this will return the register class that has been defined
584 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
585 /// the register class of its machine operand.
586 /// to infer the correct register class base on the other operands.
587 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
588 unsigned OpNo) const;
590 /// \brief Return the size in bytes of the operand OpNo on the given
591 // instruction opcode.
592 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
593 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
595 if (OpInfo.RegClass == -1) {
596 // If this is an immediate operand, this must be a 32-bit literal.
597 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
601 return RI.getRegClass(OpInfo.RegClass)->getSize();
604 /// \brief This form should usually be preferred since it handles operands
605 /// with unknown register classes.
606 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
607 return getOpRegClass(MI, OpNo)->getSize();
610 /// \returns true if it is legal for the operand at index \p OpNo
612 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
614 /// \brief Legalize the \p OpIndex operand of this instruction by inserting
615 /// a MOV. For example:
616 /// ADD_I32_e32 VGPR0, 15
619 /// ADD_I32_e32 VGPR0, VGPR1
621 /// If the operand being legalized is a register, then a COPY will be used
623 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
625 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
627 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
628 const MachineOperand *MO = nullptr) const;
630 /// \brief Check if \p MO would be a valid operand for the given operand
631 /// definition \p OpInfo. Note this does not attempt to validate constant bus
632 /// restrictions (e.g. literal constant usage).
633 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
634 const MCOperandInfo &OpInfo,
635 const MachineOperand &MO) const;
637 /// \brief Check if \p MO (a register operand) is a legal register for the
638 /// given operand description.
639 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
640 const MCOperandInfo &OpInfo,
641 const MachineOperand &MO) const;
643 /// \brief Legalize operands in \p MI by either commuting it or inserting a
645 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
647 /// \brief Fix operands in \p MI to satisfy constant bus requirements.
648 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
650 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
651 /// be used when it is know that the value in SrcReg is same across all
652 /// threads in the wave.
653 /// \returns The SGPR register that \p SrcReg was copied to.
654 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
655 MachineRegisterInfo &MRI) const;
657 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
659 void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
660 MachineBasicBlock::iterator I,
661 const TargetRegisterClass *DstRC,
662 MachineOperand &Op, MachineRegisterInfo &MRI,
663 const DebugLoc &DL) const;
665 /// \brief Legalize all operands in this instruction. This function may
666 /// create new instruction and insert them before \p MI.
667 void legalizeOperands(MachineInstr &MI) const;
669 /// \brief Replace this instruction's opcode with the equivalent VALU
670 /// opcode. This function will also move the users of \p MI to the
671 /// VALU if necessary.
672 void moveToVALU(MachineInstr &MI) const;
674 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
677 void insertNoop(MachineBasicBlock &MBB,
678 MachineBasicBlock::iterator MI) const override;
680 /// \brief Return the number of wait states that result from executing this
682 unsigned getNumWaitStates(const MachineInstr &MI) const;
684 /// \brief Returns the operand named \p Op. If \p MI does not have an
685 /// operand named \c Op, this function returns nullptr.
687 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
690 const MachineOperand *getNamedOperand(const MachineInstr &MI,
691 unsigned OpName) const {
692 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
695 /// Get required immediate operand
696 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
697 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
698 return MI.getOperand(Idx).getImm();
701 uint64_t getDefaultRsrcDataFormat() const;
702 uint64_t getScratchRsrcWords23() const;
704 bool isLowLatencyInstruction(const MachineInstr &MI) const;
705 bool isHighLatencyInstruction(const MachineInstr &MI) const;
707 /// \brief Return the descriptor of the target-specific machine instruction
708 /// that corresponds to the specified pseudo or native opcode.
709 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
710 return get(pseudoToMCOpcode(Opcode));
713 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
714 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
716 unsigned isLoadFromStackSlot(const MachineInstr &MI,
717 int &FrameIndex) const override;
718 unsigned isStoreToStackSlot(const MachineInstr &MI,
719 int &FrameIndex) const override;
721 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
723 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
725 ArrayRef<std::pair<int, const char *>>
726 getSerializableTargetIndices() const override;
728 ScheduleHazardRecognizer *
729 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
730 const ScheduleDAG *DAG) const override;
732 ScheduleHazardRecognizer *
733 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
738 int getVOPe64(uint16_t Opcode);
741 int getVOPe32(uint16_t Opcode);
744 int getCommuteRev(uint16_t Opcode);
747 int getCommuteOrig(uint16_t Opcode);
750 int getAddr64Inst(uint16_t Opcode);
753 int getAtomicRetOp(uint16_t Opcode);
756 int getAtomicNoRetOp(uint16_t Opcode);
759 int getSOPKOp(uint16_t Opcode);
761 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
762 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
763 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
764 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
766 // For MachineOperands.
768 TF_LONG_BRANCH_FORWARD = 1 << 0,
769 TF_LONG_BRANCH_BACKWARD = 1 << 1
771 } // End namespace AMDGPU
774 namespace KernelInputOffsets {
776 /// Offsets in bytes from the start of the input buffer
789 } // End namespace KernelInputOffsets
790 } // End namespace SI
792 } // End namespace llvm