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 materializeImmediate(MachineBasicBlock &MBB,
147 MachineBasicBlock::iterator MI,
150 int64_t Value) const;
152 const TargetRegisterClass *getPreferredSelectRegClass(
153 unsigned Size) const;
155 unsigned insertNE(MachineBasicBlock *MBB,
156 MachineBasicBlock::iterator I, const DebugLoc &DL,
157 unsigned SrcReg, int Value) const;
159 unsigned insertEQ(MachineBasicBlock *MBB,
160 MachineBasicBlock::iterator I, const DebugLoc &DL,
161 unsigned SrcReg, int Value) const;
163 void storeRegToStackSlot(MachineBasicBlock &MBB,
164 MachineBasicBlock::iterator MI, unsigned SrcReg,
165 bool isKill, int FrameIndex,
166 const TargetRegisterClass *RC,
167 const TargetRegisterInfo *TRI) const override;
169 void loadRegFromStackSlot(MachineBasicBlock &MBB,
170 MachineBasicBlock::iterator MI, unsigned DestReg,
171 int FrameIndex, const TargetRegisterClass *RC,
172 const TargetRegisterInfo *TRI) const override;
174 bool expandPostRAPseudo(MachineInstr &MI) const override;
176 // \brief Returns an opcode that can be used to move a value to a \p DstRC
177 // register. If there is no hardware instruction that can store to \p
178 // DstRC, then AMDGPU::COPY is returned.
179 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
182 int commuteOpcode(unsigned Opc) const;
185 inline int commuteOpcode(const MachineInstr &MI) const {
186 return commuteOpcode(MI.getOpcode());
189 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
190 unsigned &SrcOpIdx2) const override;
192 bool isBranchOffsetInRange(unsigned BranchOpc,
193 int64_t BrOffset) const override;
195 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
197 unsigned insertIndirectBranch(MachineBasicBlock &MBB,
198 MachineBasicBlock &NewDestBB,
201 RegScavenger *RS = nullptr) const override;
203 bool analyzeBranchImpl(MachineBasicBlock &MBB,
204 MachineBasicBlock::iterator I,
205 MachineBasicBlock *&TBB,
206 MachineBasicBlock *&FBB,
207 SmallVectorImpl<MachineOperand> &Cond,
208 bool AllowModify) const;
210 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
211 MachineBasicBlock *&FBB,
212 SmallVectorImpl<MachineOperand> &Cond,
213 bool AllowModify = false) const override;
215 unsigned removeBranch(MachineBasicBlock &MBB,
216 int *BytesRemoved = nullptr) const override;
218 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
219 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
221 int *BytesAdded = nullptr) const override;
223 bool reverseBranchCondition(
224 SmallVectorImpl<MachineOperand> &Cond) const override;
227 bool canInsertSelect(const MachineBasicBlock &MBB,
228 ArrayRef<MachineOperand> Cond,
229 unsigned TrueReg, unsigned FalseReg,
231 int &TrueCycles, int &FalseCycles) const override;
233 void insertSelect(MachineBasicBlock &MBB,
234 MachineBasicBlock::iterator I, const DebugLoc &DL,
235 unsigned DstReg, ArrayRef<MachineOperand> Cond,
236 unsigned TrueReg, unsigned FalseReg) const override;
238 void insertVectorSelect(MachineBasicBlock &MBB,
239 MachineBasicBlock::iterator I, const DebugLoc &DL,
240 unsigned DstReg, ArrayRef<MachineOperand> Cond,
241 unsigned TrueReg, unsigned FalseReg) const;
244 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
245 AliasAnalysis *AA = nullptr) const override;
247 bool isFoldableCopy(const MachineInstr &MI) const;
249 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
250 MachineRegisterInfo *MRI) const final;
252 unsigned getMachineCSELookAheadLimit() const override { return 500; }
254 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
256 LiveVariables *LV) const override;
258 bool isSchedulingBoundary(const MachineInstr &MI,
259 const MachineBasicBlock *MBB,
260 const MachineFunction &MF) const override;
262 static bool isSALU(const MachineInstr &MI) {
263 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
266 bool isSALU(uint16_t Opcode) const {
267 return get(Opcode).TSFlags & SIInstrFlags::SALU;
270 static bool isVALU(const MachineInstr &MI) {
271 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
274 bool isVALU(uint16_t Opcode) const {
275 return get(Opcode).TSFlags & SIInstrFlags::VALU;
278 static bool isVMEM(const MachineInstr &MI) {
279 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
282 bool isVMEM(uint16_t Opcode) const {
283 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
286 static bool isSOP1(const MachineInstr &MI) {
287 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
290 bool isSOP1(uint16_t Opcode) const {
291 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
294 static bool isSOP2(const MachineInstr &MI) {
295 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
298 bool isSOP2(uint16_t Opcode) const {
299 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
302 static bool isSOPC(const MachineInstr &MI) {
303 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
306 bool isSOPC(uint16_t Opcode) const {
307 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
310 static bool isSOPK(const MachineInstr &MI) {
311 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
314 bool isSOPK(uint16_t Opcode) const {
315 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
318 static bool isSOPP(const MachineInstr &MI) {
319 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
322 bool isSOPP(uint16_t Opcode) const {
323 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
326 static bool isVOP1(const MachineInstr &MI) {
327 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
330 bool isVOP1(uint16_t Opcode) const {
331 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
334 static bool isVOP2(const MachineInstr &MI) {
335 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
338 bool isVOP2(uint16_t Opcode) const {
339 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
342 static bool isVOP3(const MachineInstr &MI) {
343 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
346 bool isVOP3(uint16_t Opcode) const {
347 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
350 static bool isSDWA(const MachineInstr &MI) {
351 return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
354 bool isSDWA(uint16_t Opcode) const {
355 return get(Opcode).TSFlags & SIInstrFlags::SDWA;
358 static bool isVOPC(const MachineInstr &MI) {
359 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
362 bool isVOPC(uint16_t Opcode) const {
363 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
366 static bool isMUBUF(const MachineInstr &MI) {
367 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
370 bool isMUBUF(uint16_t Opcode) const {
371 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
374 static bool isMTBUF(const MachineInstr &MI) {
375 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
378 bool isMTBUF(uint16_t Opcode) const {
379 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
382 static bool isSMRD(const MachineInstr &MI) {
383 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
386 bool isSMRD(uint16_t Opcode) const {
387 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
390 static bool isDS(const MachineInstr &MI) {
391 return MI.getDesc().TSFlags & SIInstrFlags::DS;
394 bool isDS(uint16_t Opcode) const {
395 return get(Opcode).TSFlags & SIInstrFlags::DS;
398 static bool isMIMG(const MachineInstr &MI) {
399 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
402 bool isMIMG(uint16_t Opcode) const {
403 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
406 static bool isGather4(const MachineInstr &MI) {
407 return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
410 bool isGather4(uint16_t Opcode) const {
411 return get(Opcode).TSFlags & SIInstrFlags::Gather4;
414 static bool isFLAT(const MachineInstr &MI) {
415 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
418 bool isFLAT(uint16_t Opcode) const {
419 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
422 static bool isEXP(const MachineInstr &MI) {
423 return MI.getDesc().TSFlags & SIInstrFlags::EXP;
426 bool isEXP(uint16_t Opcode) const {
427 return get(Opcode).TSFlags & SIInstrFlags::EXP;
430 static bool isWQM(const MachineInstr &MI) {
431 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
434 bool isWQM(uint16_t Opcode) const {
435 return get(Opcode).TSFlags & SIInstrFlags::WQM;
438 static bool isDisableWQM(const MachineInstr &MI) {
439 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
442 bool isDisableWQM(uint16_t Opcode) const {
443 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
446 static bool isVGPRSpill(const MachineInstr &MI) {
447 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
450 bool isVGPRSpill(uint16_t Opcode) const {
451 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
454 static bool isSGPRSpill(const MachineInstr &MI) {
455 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
458 bool isSGPRSpill(uint16_t Opcode) const {
459 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
462 static bool isDPP(const MachineInstr &MI) {
463 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
466 bool isDPP(uint16_t Opcode) const {
467 return get(Opcode).TSFlags & SIInstrFlags::DPP;
470 static bool isVOP3P(const MachineInstr &MI) {
471 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
474 bool isVOP3P(uint16_t Opcode) const {
475 return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
478 static bool isVINTRP(const MachineInstr &MI) {
479 return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
482 bool isVINTRP(uint16_t Opcode) const {
483 return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
486 static bool isScalarUnit(const MachineInstr &MI) {
487 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
490 static bool usesVM_CNT(const MachineInstr &MI) {
491 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
494 static bool sopkIsZext(const MachineInstr &MI) {
495 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
498 bool sopkIsZext(uint16_t Opcode) const {
499 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
502 /// \returns true if this is an s_store_dword* instruction. This is more
503 /// specific than than isSMEM && mayStore.
504 static bool isScalarStore(const MachineInstr &MI) {
505 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
508 bool isScalarStore(uint16_t Opcode) const {
509 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
512 static bool isFixedSize(const MachineInstr &MI) {
513 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
516 bool isFixedSize(uint16_t Opcode) const {
517 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
520 static bool hasFPClamp(const MachineInstr &MI) {
521 return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp;
524 bool hasFPClamp(uint16_t Opcode) const {
525 return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp;
528 bool isVGPRCopy(const MachineInstr &MI) const {
530 unsigned Dest = MI.getOperand(0).getReg();
531 const MachineFunction &MF = *MI.getParent()->getParent();
532 const MachineRegisterInfo &MRI = MF.getRegInfo();
533 return !RI.isSGPRReg(MRI, Dest);
536 bool isInlineConstant(const APInt &Imm) const;
538 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
540 bool isInlineConstant(const MachineOperand &MO,
541 const MCOperandInfo &OpInfo) const {
542 return isInlineConstant(MO, OpInfo.OperandType);
545 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
546 /// be an inline immediate.
547 bool isInlineConstant(const MachineInstr &MI,
548 const MachineOperand &UseMO,
549 const MachineOperand &DefMO) const {
550 assert(UseMO.getParent() == &MI);
551 int OpIdx = MI.getOperandNo(&UseMO);
552 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
556 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
559 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
561 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
562 const MachineOperand &MO = MI.getOperand(OpIdx);
563 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
566 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
567 const MachineOperand &MO) const {
568 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
572 unsigned Size = getOpSize(MI, OpIdx);
573 assert(Size == 8 || Size == 4);
575 uint8_t OpType = (Size == 8) ?
576 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
577 return isInlineConstant(MO, OpType);
580 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
583 bool isInlineConstant(const MachineOperand &MO) const {
584 const MachineInstr *Parent = MO.getParent();
585 return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
588 bool isLiteralConstant(const MachineOperand &MO,
589 const MCOperandInfo &OpInfo) const {
590 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
593 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
594 const MachineOperand &MO = MI.getOperand(OpIdx);
595 return MO.isImm() && !isInlineConstant(MI, OpIdx);
598 // Returns true if this operand could potentially require a 32-bit literal
599 // operand, but not necessarily. A FrameIndex for example could resolve to an
600 // inline immediate value that will not require an additional 4-bytes; this
601 // assumes that it will.
602 bool isLiteralConstantLike(const MachineOperand &MO,
603 const MCOperandInfo &OpInfo) const;
605 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
606 const MachineOperand &MO) const;
608 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
609 /// This function will return false if you pass it a 32-bit instruction.
610 bool hasVALU32BitEncoding(unsigned Opcode) const;
612 /// \brief Returns true if this operand uses the constant bus.
613 bool usesConstantBus(const MachineRegisterInfo &MRI,
614 const MachineOperand &MO,
615 const MCOperandInfo &OpInfo) const;
617 /// \brief Return true if this instruction has any modifiers.
618 /// e.g. src[012]_mod, omod, clamp.
619 bool hasModifiers(unsigned Opcode) const;
621 bool hasModifiersSet(const MachineInstr &MI,
622 unsigned OpName) const;
623 bool hasAnyModifiersSet(const MachineInstr &MI) const;
625 bool verifyInstruction(const MachineInstr &MI,
626 StringRef &ErrInfo) const override;
628 static unsigned getVALUOp(const MachineInstr &MI);
630 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
632 /// \brief Return the correct register class for \p OpNo. For target-specific
633 /// instructions, this will return the register class that has been defined
634 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
635 /// the register class of its machine operand.
636 /// to infer the correct register class base on the other operands.
637 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
638 unsigned OpNo) const;
640 /// \brief Return the size in bytes of the operand OpNo on the given
641 // instruction opcode.
642 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
643 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
645 if (OpInfo.RegClass == -1) {
646 // If this is an immediate operand, this must be a 32-bit literal.
647 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
651 return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
654 /// \brief This form should usually be preferred since it handles operands
655 /// with unknown register classes.
656 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
657 return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
660 /// \returns true if it is legal for the operand at index \p OpNo
662 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
664 /// \brief Legalize the \p OpIndex operand of this instruction by inserting
665 /// a MOV. For example:
666 /// ADD_I32_e32 VGPR0, 15
669 /// ADD_I32_e32 VGPR0, VGPR1
671 /// If the operand being legalized is a register, then a COPY will be used
673 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
675 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
677 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
678 const MachineOperand *MO = nullptr) const;
680 /// \brief Check if \p MO would be a valid operand for the given operand
681 /// definition \p OpInfo. Note this does not attempt to validate constant bus
682 /// restrictions (e.g. literal constant usage).
683 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
684 const MCOperandInfo &OpInfo,
685 const MachineOperand &MO) const;
687 /// \brief Check if \p MO (a register operand) is a legal register for the
688 /// given operand description.
689 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
690 const MCOperandInfo &OpInfo,
691 const MachineOperand &MO) const;
693 /// \brief Legalize operands in \p MI by either commuting it or inserting a
695 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
697 /// \brief Fix operands in \p MI to satisfy constant bus requirements.
698 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
700 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
701 /// be used when it is know that the value in SrcReg is same across all
702 /// threads in the wave.
703 /// \returns The SGPR register that \p SrcReg was copied to.
704 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
705 MachineRegisterInfo &MRI) const;
707 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
709 void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
710 MachineBasicBlock::iterator I,
711 const TargetRegisterClass *DstRC,
712 MachineOperand &Op, MachineRegisterInfo &MRI,
713 const DebugLoc &DL) const;
715 /// \brief Legalize all operands in this instruction. This function may
716 /// create new instruction and insert them before \p MI.
717 void legalizeOperands(MachineInstr &MI) const;
719 /// \brief Replace this instruction's opcode with the equivalent VALU
720 /// opcode. This function will also move the users of \p MI to the
721 /// VALU if necessary.
722 void moveToVALU(MachineInstr &MI) const;
724 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
727 void insertNoop(MachineBasicBlock &MBB,
728 MachineBasicBlock::iterator MI) const override;
730 void insertReturn(MachineBasicBlock &MBB) const;
731 /// \brief Return the number of wait states that result from executing this
733 unsigned getNumWaitStates(const MachineInstr &MI) const;
735 /// \brief Returns the operand named \p Op. If \p MI does not have an
736 /// operand named \c Op, this function returns nullptr.
738 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
741 const MachineOperand *getNamedOperand(const MachineInstr &MI,
742 unsigned OpName) const {
743 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
746 /// Get required immediate operand
747 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
748 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
749 return MI.getOperand(Idx).getImm();
752 uint64_t getDefaultRsrcDataFormat() const;
753 uint64_t getScratchRsrcWords23() const;
755 bool isLowLatencyInstruction(const MachineInstr &MI) const;
756 bool isHighLatencyInstruction(const MachineInstr &MI) const;
758 /// \brief Return the descriptor of the target-specific machine instruction
759 /// that corresponds to the specified pseudo or native opcode.
760 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
761 return get(pseudoToMCOpcode(Opcode));
764 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
765 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
767 unsigned isLoadFromStackSlot(const MachineInstr &MI,
768 int &FrameIndex) const override;
769 unsigned isStoreToStackSlot(const MachineInstr &MI,
770 int &FrameIndex) const override;
772 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
774 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
776 bool isNonUniformBranchInstr(MachineInstr &Instr) const;
778 void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
779 MachineBasicBlock *IfEnd) const;
781 void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
782 MachineBasicBlock *LoopEnd) const;
784 ArrayRef<std::pair<int, const char *>>
785 getSerializableTargetIndices() const override;
787 ScheduleHazardRecognizer *
788 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
789 const ScheduleDAG *DAG) const override;
791 ScheduleHazardRecognizer *
792 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
794 bool isBasicBlockPrologue(const MachineInstr &MI) const override;
796 /// \brief Return a partially built integer add instruction without carry.
797 /// Caller must add source operands.
798 /// For pre-GFX9 it will generate unused carry destination operand.
799 /// TODO: After GFX9 it should return a no-carry operation.
800 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
801 MachineBasicBlock::iterator I,
803 unsigned DestReg) const;
808 int getVOPe64(uint16_t Opcode);
811 int getVOPe32(uint16_t Opcode);
814 int getSDWAOp(uint16_t Opcode);
817 int getCommuteRev(uint16_t Opcode);
820 int getCommuteOrig(uint16_t Opcode);
823 int getAddr64Inst(uint16_t Opcode);
826 int getAtomicRetOp(uint16_t Opcode);
829 int getAtomicNoRetOp(uint16_t Opcode);
832 int getSOPKOp(uint16_t Opcode);
834 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
835 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
836 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
837 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
839 // For MachineOperands.
841 TF_LONG_BRANCH_FORWARD = 1 << 0,
842 TF_LONG_BRANCH_BACKWARD = 1 << 1
844 } // End namespace AMDGPU
847 namespace KernelInputOffsets {
849 /// Offsets in bytes from the start of the input buffer
862 } // End namespace KernelInputOffsets
863 } // End namespace SI
865 } // End namespace llvm