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"
22 #include "llvm/ADT/SetVector.h"
26 class SIInstrInfo final : public AMDGPUInstrInfo {
28 const SIRegisterInfo RI;
29 const SISubtarget &ST;
31 // The the inverse predicate should have the negative value.
32 enum BranchPredicate {
42 typedef SmallSetVector<MachineInstr *, 32> SetVectorType;
44 static unsigned getBranchOpcode(BranchPredicate Cond);
45 static BranchPredicate getBranchPredicate(unsigned Opcode);
47 unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
48 MachineRegisterInfo &MRI,
49 MachineOperand &SuperReg,
50 const TargetRegisterClass *SuperRC,
52 const TargetRegisterClass *SubRC) const;
53 MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
54 MachineRegisterInfo &MRI,
55 MachineOperand &SuperReg,
56 const TargetRegisterClass *SuperRC,
58 const TargetRegisterClass *SubRC) const;
60 void swapOperands(MachineInstr &Inst) const;
62 void lowerScalarAbs(SetVectorType &Worklist,
63 MachineInstr &Inst) const;
65 void splitScalar64BitUnaryOp(SetVectorType &Worklist,
66 MachineInstr &Inst, unsigned Opcode) const;
68 void splitScalar64BitBinaryOp(SetVectorType &Worklist,
69 MachineInstr &Inst, unsigned Opcode) const;
71 void splitScalar64BitBCNT(SetVectorType &Worklist,
72 MachineInstr &Inst) const;
73 void splitScalar64BitBFE(SetVectorType &Worklist,
74 MachineInstr &Inst) const;
75 void movePackToVALU(SetVectorType &Worklist,
76 MachineRegisterInfo &MRI,
77 MachineInstr &Inst) const;
79 void addUsersToMoveToVALUWorklist(
80 unsigned Reg, MachineRegisterInfo &MRI,
81 SetVectorType &Worklist) const;
84 addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
85 SetVectorType &Worklist) const;
87 const TargetRegisterClass *
88 getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
90 bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
92 unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
95 bool swapSourceModifiers(MachineInstr &MI,
96 MachineOperand &Src0, unsigned Src0OpName,
97 MachineOperand &Src1, unsigned Src1OpName) const;
99 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
101 unsigned OpIdx1) const override;
105 enum TargetOperandFlags {
109 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
111 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
113 MO_GOTPCREL32_LO = 2,
114 // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
115 MO_GOTPCREL32_HI = 3,
116 // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
119 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
123 explicit SIInstrInfo(const SISubtarget &);
125 const SIRegisterInfo &getRegisterInfo() const {
129 bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
130 AliasAnalysis *AA) const override;
132 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
134 int64_t &Offset2) const override;
136 bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
138 const TargetRegisterInfo *TRI) const final;
140 bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
141 unsigned NumLoads) const final;
143 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
144 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
145 bool KillSrc) const override;
147 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
148 RegScavenger *RS, unsigned TmpReg,
149 unsigned Offset, unsigned Size) const;
151 void materializeImmediate(MachineBasicBlock &MBB,
152 MachineBasicBlock::iterator MI,
155 int64_t Value) const;
157 const TargetRegisterClass *getPreferredSelectRegClass(
158 unsigned Size) const;
160 unsigned insertNE(MachineBasicBlock *MBB,
161 MachineBasicBlock::iterator I, const DebugLoc &DL,
162 unsigned SrcReg, int Value) const;
164 unsigned insertEQ(MachineBasicBlock *MBB,
165 MachineBasicBlock::iterator I, const DebugLoc &DL,
166 unsigned SrcReg, int Value) const;
168 void storeRegToStackSlot(MachineBasicBlock &MBB,
169 MachineBasicBlock::iterator MI, unsigned SrcReg,
170 bool isKill, int FrameIndex,
171 const TargetRegisterClass *RC,
172 const TargetRegisterInfo *TRI) const override;
174 void loadRegFromStackSlot(MachineBasicBlock &MBB,
175 MachineBasicBlock::iterator MI, unsigned DestReg,
176 int FrameIndex, const TargetRegisterClass *RC,
177 const TargetRegisterInfo *TRI) const override;
179 bool expandPostRAPseudo(MachineInstr &MI) const override;
181 // \brief Returns an opcode that can be used to move a value to a \p DstRC
182 // register. If there is no hardware instruction that can store to \p
183 // DstRC, then AMDGPU::COPY is returned.
184 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
187 int commuteOpcode(unsigned Opc) const;
190 inline int commuteOpcode(const MachineInstr &MI) const {
191 return commuteOpcode(MI.getOpcode());
194 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
195 unsigned &SrcOpIdx2) const override;
197 bool isBranchOffsetInRange(unsigned BranchOpc,
198 int64_t BrOffset) const override;
200 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
202 unsigned insertIndirectBranch(MachineBasicBlock &MBB,
203 MachineBasicBlock &NewDestBB,
206 RegScavenger *RS = nullptr) const override;
208 bool analyzeBranchImpl(MachineBasicBlock &MBB,
209 MachineBasicBlock::iterator I,
210 MachineBasicBlock *&TBB,
211 MachineBasicBlock *&FBB,
212 SmallVectorImpl<MachineOperand> &Cond,
213 bool AllowModify) const;
215 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
216 MachineBasicBlock *&FBB,
217 SmallVectorImpl<MachineOperand> &Cond,
218 bool AllowModify = false) const override;
220 unsigned removeBranch(MachineBasicBlock &MBB,
221 int *BytesRemoved = nullptr) const override;
223 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
224 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
226 int *BytesAdded = nullptr) const override;
228 bool reverseBranchCondition(
229 SmallVectorImpl<MachineOperand> &Cond) const override;
232 bool canInsertSelect(const MachineBasicBlock &MBB,
233 ArrayRef<MachineOperand> Cond,
234 unsigned TrueReg, unsigned FalseReg,
236 int &TrueCycles, int &FalseCycles) const override;
238 void insertSelect(MachineBasicBlock &MBB,
239 MachineBasicBlock::iterator I, const DebugLoc &DL,
240 unsigned DstReg, ArrayRef<MachineOperand> Cond,
241 unsigned TrueReg, unsigned FalseReg) const override;
243 void insertVectorSelect(MachineBasicBlock &MBB,
244 MachineBasicBlock::iterator I, const DebugLoc &DL,
245 unsigned DstReg, ArrayRef<MachineOperand> Cond,
246 unsigned TrueReg, unsigned FalseReg) const;
249 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
250 AliasAnalysis *AA = nullptr) const override;
252 bool isFoldableCopy(const MachineInstr &MI) const;
254 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
255 MachineRegisterInfo *MRI) const final;
257 unsigned getMachineCSELookAheadLimit() const override { return 500; }
259 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
261 LiveVariables *LV) const override;
263 bool isSchedulingBoundary(const MachineInstr &MI,
264 const MachineBasicBlock *MBB,
265 const MachineFunction &MF) const override;
267 static bool isSALU(const MachineInstr &MI) {
268 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
271 bool isSALU(uint16_t Opcode) const {
272 return get(Opcode).TSFlags & SIInstrFlags::SALU;
275 static bool isVALU(const MachineInstr &MI) {
276 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
279 bool isVALU(uint16_t Opcode) const {
280 return get(Opcode).TSFlags & SIInstrFlags::VALU;
283 static bool isVMEM(const MachineInstr &MI) {
284 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
287 bool isVMEM(uint16_t Opcode) const {
288 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
291 static bool isSOP1(const MachineInstr &MI) {
292 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
295 bool isSOP1(uint16_t Opcode) const {
296 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
299 static bool isSOP2(const MachineInstr &MI) {
300 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
303 bool isSOP2(uint16_t Opcode) const {
304 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
307 static bool isSOPC(const MachineInstr &MI) {
308 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
311 bool isSOPC(uint16_t Opcode) const {
312 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
315 static bool isSOPK(const MachineInstr &MI) {
316 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
319 bool isSOPK(uint16_t Opcode) const {
320 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
323 static bool isSOPP(const MachineInstr &MI) {
324 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
327 bool isSOPP(uint16_t Opcode) const {
328 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
331 static bool isVOP1(const MachineInstr &MI) {
332 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
335 bool isVOP1(uint16_t Opcode) const {
336 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
339 static bool isVOP2(const MachineInstr &MI) {
340 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
343 bool isVOP2(uint16_t Opcode) const {
344 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
347 static bool isVOP3(const MachineInstr &MI) {
348 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
351 bool isVOP3(uint16_t Opcode) const {
352 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
355 static bool isSDWA(const MachineInstr &MI) {
356 return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
359 bool isSDWA(uint16_t Opcode) const {
360 return get(Opcode).TSFlags & SIInstrFlags::SDWA;
363 static bool isVOPC(const MachineInstr &MI) {
364 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
367 bool isVOPC(uint16_t Opcode) const {
368 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
371 static bool isMUBUF(const MachineInstr &MI) {
372 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
375 bool isMUBUF(uint16_t Opcode) const {
376 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
379 static bool isMTBUF(const MachineInstr &MI) {
380 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
383 bool isMTBUF(uint16_t Opcode) const {
384 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
387 static bool isSMRD(const MachineInstr &MI) {
388 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
391 bool isSMRD(uint16_t Opcode) const {
392 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
395 static bool isDS(const MachineInstr &MI) {
396 return MI.getDesc().TSFlags & SIInstrFlags::DS;
399 bool isDS(uint16_t Opcode) const {
400 return get(Opcode).TSFlags & SIInstrFlags::DS;
403 static bool isMIMG(const MachineInstr &MI) {
404 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
407 bool isMIMG(uint16_t Opcode) const {
408 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
411 static bool isGather4(const MachineInstr &MI) {
412 return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
415 bool isGather4(uint16_t Opcode) const {
416 return get(Opcode).TSFlags & SIInstrFlags::Gather4;
419 static bool isFLAT(const MachineInstr &MI) {
420 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
423 bool isFLAT(uint16_t Opcode) const {
424 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
427 static bool isEXP(const MachineInstr &MI) {
428 return MI.getDesc().TSFlags & SIInstrFlags::EXP;
431 bool isEXP(uint16_t Opcode) const {
432 return get(Opcode).TSFlags & SIInstrFlags::EXP;
435 static bool isWQM(const MachineInstr &MI) {
436 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
439 bool isWQM(uint16_t Opcode) const {
440 return get(Opcode).TSFlags & SIInstrFlags::WQM;
443 static bool isDisableWQM(const MachineInstr &MI) {
444 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
447 bool isDisableWQM(uint16_t Opcode) const {
448 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
451 static bool isVGPRSpill(const MachineInstr &MI) {
452 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
455 bool isVGPRSpill(uint16_t Opcode) const {
456 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
459 static bool isSGPRSpill(const MachineInstr &MI) {
460 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
463 bool isSGPRSpill(uint16_t Opcode) const {
464 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
467 static bool isDPP(const MachineInstr &MI) {
468 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
471 bool isDPP(uint16_t Opcode) const {
472 return get(Opcode).TSFlags & SIInstrFlags::DPP;
475 static bool isVOP3P(const MachineInstr &MI) {
476 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
479 bool isVOP3P(uint16_t Opcode) const {
480 return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
483 static bool isVINTRP(const MachineInstr &MI) {
484 return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
487 bool isVINTRP(uint16_t Opcode) const {
488 return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
491 static bool isScalarUnit(const MachineInstr &MI) {
492 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
495 static bool usesVM_CNT(const MachineInstr &MI) {
496 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
499 static bool sopkIsZext(const MachineInstr &MI) {
500 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
503 bool sopkIsZext(uint16_t Opcode) const {
504 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
507 /// \returns true if this is an s_store_dword* instruction. This is more
508 /// specific than than isSMEM && mayStore.
509 static bool isScalarStore(const MachineInstr &MI) {
510 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
513 bool isScalarStore(uint16_t Opcode) const {
514 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
517 static bool isFixedSize(const MachineInstr &MI) {
518 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
521 bool isFixedSize(uint16_t Opcode) const {
522 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
525 static bool hasFPClamp(const MachineInstr &MI) {
526 return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp;
529 bool hasFPClamp(uint16_t Opcode) const {
530 return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp;
533 bool isVGPRCopy(const MachineInstr &MI) const {
535 unsigned Dest = MI.getOperand(0).getReg();
536 const MachineFunction &MF = *MI.getParent()->getParent();
537 const MachineRegisterInfo &MRI = MF.getRegInfo();
538 return !RI.isSGPRReg(MRI, Dest);
541 bool isInlineConstant(const APInt &Imm) const;
543 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
545 bool isInlineConstant(const MachineOperand &MO,
546 const MCOperandInfo &OpInfo) const {
547 return isInlineConstant(MO, OpInfo.OperandType);
550 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
551 /// be an inline immediate.
552 bool isInlineConstant(const MachineInstr &MI,
553 const MachineOperand &UseMO,
554 const MachineOperand &DefMO) const {
555 assert(UseMO.getParent() == &MI);
556 int OpIdx = MI.getOperandNo(&UseMO);
557 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
561 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
564 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
566 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
567 const MachineOperand &MO = MI.getOperand(OpIdx);
568 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
571 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
572 const MachineOperand &MO) const {
573 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
577 unsigned Size = getOpSize(MI, OpIdx);
578 assert(Size == 8 || Size == 4);
580 uint8_t OpType = (Size == 8) ?
581 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
582 return isInlineConstant(MO, OpType);
585 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
588 bool isInlineConstant(const MachineOperand &MO) const {
589 const MachineInstr *Parent = MO.getParent();
590 return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
593 bool isLiteralConstant(const MachineOperand &MO,
594 const MCOperandInfo &OpInfo) const {
595 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
598 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
599 const MachineOperand &MO = MI.getOperand(OpIdx);
600 return MO.isImm() && !isInlineConstant(MI, OpIdx);
603 // Returns true if this operand could potentially require a 32-bit literal
604 // operand, but not necessarily. A FrameIndex for example could resolve to an
605 // inline immediate value that will not require an additional 4-bytes; this
606 // assumes that it will.
607 bool isLiteralConstantLike(const MachineOperand &MO,
608 const MCOperandInfo &OpInfo) const;
610 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
611 const MachineOperand &MO) const;
613 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
614 /// This function will return false if you pass it a 32-bit instruction.
615 bool hasVALU32BitEncoding(unsigned Opcode) const;
617 /// \brief Returns true if this operand uses the constant bus.
618 bool usesConstantBus(const MachineRegisterInfo &MRI,
619 const MachineOperand &MO,
620 const MCOperandInfo &OpInfo) const;
622 /// \brief Return true if this instruction has any modifiers.
623 /// e.g. src[012]_mod, omod, clamp.
624 bool hasModifiers(unsigned Opcode) const;
626 bool hasModifiersSet(const MachineInstr &MI,
627 unsigned OpName) const;
628 bool hasAnyModifiersSet(const MachineInstr &MI) const;
630 bool verifyInstruction(const MachineInstr &MI,
631 StringRef &ErrInfo) const override;
633 static unsigned getVALUOp(const MachineInstr &MI);
635 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
637 /// \brief Return the correct register class for \p OpNo. For target-specific
638 /// instructions, this will return the register class that has been defined
639 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
640 /// the register class of its machine operand.
641 /// to infer the correct register class base on the other operands.
642 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
643 unsigned OpNo) const;
645 /// \brief Return the size in bytes of the operand OpNo on the given
646 // instruction opcode.
647 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
648 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
650 if (OpInfo.RegClass == -1) {
651 // If this is an immediate operand, this must be a 32-bit literal.
652 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
656 return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
659 /// \brief This form should usually be preferred since it handles operands
660 /// with unknown register classes.
661 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
662 return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
665 /// \returns true if it is legal for the operand at index \p OpNo
667 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
669 /// \brief Legalize the \p OpIndex operand of this instruction by inserting
670 /// a MOV. For example:
671 /// ADD_I32_e32 VGPR0, 15
674 /// ADD_I32_e32 VGPR0, VGPR1
676 /// If the operand being legalized is a register, then a COPY will be used
678 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
680 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
682 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
683 const MachineOperand *MO = nullptr) const;
685 /// \brief Check if \p MO would be a valid operand for the given operand
686 /// definition \p OpInfo. Note this does not attempt to validate constant bus
687 /// restrictions (e.g. literal constant usage).
688 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
689 const MCOperandInfo &OpInfo,
690 const MachineOperand &MO) const;
692 /// \brief Check if \p MO (a register operand) is a legal register for the
693 /// given operand description.
694 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
695 const MCOperandInfo &OpInfo,
696 const MachineOperand &MO) const;
698 /// \brief Legalize operands in \p MI by either commuting it or inserting a
700 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
702 /// \brief Fix operands in \p MI to satisfy constant bus requirements.
703 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
705 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
706 /// be used when it is know that the value in SrcReg is same across all
707 /// threads in the wave.
708 /// \returns The SGPR register that \p SrcReg was copied to.
709 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
710 MachineRegisterInfo &MRI) const;
712 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
714 void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
715 MachineBasicBlock::iterator I,
716 const TargetRegisterClass *DstRC,
717 MachineOperand &Op, MachineRegisterInfo &MRI,
718 const DebugLoc &DL) const;
720 /// \brief Legalize all operands in this instruction. This function may
721 /// create new instruction and insert them before \p MI.
722 void legalizeOperands(MachineInstr &MI) const;
724 /// \brief Replace this instruction's opcode with the equivalent VALU
725 /// opcode. This function will also move the users of \p MI to the
726 /// VALU if necessary.
727 void moveToVALU(MachineInstr &MI) const;
729 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
732 void insertNoop(MachineBasicBlock &MBB,
733 MachineBasicBlock::iterator MI) const override;
735 void insertReturn(MachineBasicBlock &MBB) const;
736 /// \brief Return the number of wait states that result from executing this
738 unsigned getNumWaitStates(const MachineInstr &MI) const;
740 /// \brief Returns the operand named \p Op. If \p MI does not have an
741 /// operand named \c Op, this function returns nullptr.
743 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
746 const MachineOperand *getNamedOperand(const MachineInstr &MI,
747 unsigned OpName) const {
748 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
751 /// Get required immediate operand
752 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
753 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
754 return MI.getOperand(Idx).getImm();
757 uint64_t getDefaultRsrcDataFormat() const;
758 uint64_t getScratchRsrcWords23() const;
760 bool isLowLatencyInstruction(const MachineInstr &MI) const;
761 bool isHighLatencyInstruction(const MachineInstr &MI) const;
763 /// \brief Return the descriptor of the target-specific machine instruction
764 /// that corresponds to the specified pseudo or native opcode.
765 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
766 return get(pseudoToMCOpcode(Opcode));
769 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
770 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
772 unsigned isLoadFromStackSlot(const MachineInstr &MI,
773 int &FrameIndex) const override;
774 unsigned isStoreToStackSlot(const MachineInstr &MI,
775 int &FrameIndex) const override;
777 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
779 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
781 bool isNonUniformBranchInstr(MachineInstr &Instr) const;
783 void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
784 MachineBasicBlock *IfEnd) const;
786 void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
787 MachineBasicBlock *LoopEnd) const;
789 std::pair<unsigned, unsigned>
790 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
792 ArrayRef<std::pair<int, const char *>>
793 getSerializableTargetIndices() const override;
795 ArrayRef<std::pair<unsigned, const char *>>
796 getSerializableDirectMachineOperandTargetFlags() const override;
798 ScheduleHazardRecognizer *
799 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
800 const ScheduleDAG *DAG) const override;
802 ScheduleHazardRecognizer *
803 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
805 bool isBasicBlockPrologue(const MachineInstr &MI) const override;
807 /// \brief Return a partially built integer add instruction without carry.
808 /// Caller must add source operands.
809 /// For pre-GFX9 it will generate unused carry destination operand.
810 /// TODO: After GFX9 it should return a no-carry operation.
811 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
812 MachineBasicBlock::iterator I,
814 unsigned DestReg) const;
819 int getVOPe64(uint16_t Opcode);
822 int getVOPe32(uint16_t Opcode);
825 int getSDWAOp(uint16_t Opcode);
828 int getBasicFromSDWAOp(uint16_t Opcode);
831 int getCommuteRev(uint16_t Opcode);
834 int getCommuteOrig(uint16_t Opcode);
837 int getAddr64Inst(uint16_t Opcode);
840 int getAtomicRetOp(uint16_t Opcode);
843 int getAtomicNoRetOp(uint16_t Opcode);
846 int getSOPKOp(uint16_t Opcode);
848 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
849 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
850 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
851 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
853 // For MachineOperands.
855 TF_LONG_BRANCH_FORWARD = 1 << 0,
856 TF_LONG_BRANCH_BACKWARD = 1 << 1
858 } // End namespace AMDGPU
861 namespace KernelInputOffsets {
863 /// Offsets in bytes from the start of the input buffer
876 } // End namespace KernelInputOffsets
877 } // End namespace SI
879 } // End namespace llvm