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 /// Interface definition for SIInstrInfo.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
16 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
18 #include "AMDGPUInstrInfo.h"
19 #include "SIDefines.h"
20 #include "SIRegisterInfo.h"
21 #include "Utils/AMDGPUBaseInfo.h"
22 #include "llvm/ADT/ArrayRef.h"
23 #include "llvm/ADT/SetVector.h"
24 #include "llvm/CodeGen/MachineBasicBlock.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstr.h"
27 #include "llvm/CodeGen/MachineInstrBuilder.h"
28 #include "llvm/CodeGen/MachineOperand.h"
29 #include "llvm/MC/MCInstrDesc.h"
30 #include "llvm/Support/Compiler.h"
34 #define GET_INSTRINFO_HEADER
35 #include "AMDGPUGenInstrInfo.inc"
40 class MachineDominatorTree;
41 class MachineRegisterInfo;
44 class TargetRegisterClass;
46 class SIInstrInfo final : public AMDGPUGenInstrInfo {
48 const SIRegisterInfo RI;
49 const GCNSubtarget &ST;
51 // The inverse predicate should have the negative value.
52 enum BranchPredicate {
62 using SetVectorType = SmallSetVector<MachineInstr *, 32>;
64 static unsigned getBranchOpcode(BranchPredicate Cond);
65 static BranchPredicate getBranchPredicate(unsigned Opcode);
68 unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
69 MachineRegisterInfo &MRI,
70 MachineOperand &SuperReg,
71 const TargetRegisterClass *SuperRC,
73 const TargetRegisterClass *SubRC) const;
74 MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
75 MachineRegisterInfo &MRI,
76 MachineOperand &SuperReg,
77 const TargetRegisterClass *SuperRC,
79 const TargetRegisterClass *SubRC) const;
81 void swapOperands(MachineInstr &Inst) const;
83 bool moveScalarAddSub(SetVectorType &Worklist, MachineInstr &Inst,
84 MachineDominatorTree *MDT = nullptr) const;
86 void lowerScalarAbs(SetVectorType &Worklist,
87 MachineInstr &Inst) const;
89 void lowerScalarXnor(SetVectorType &Worklist,
90 MachineInstr &Inst) const;
92 void splitScalarNotBinop(SetVectorType &Worklist,
94 unsigned Opcode) const;
96 void splitScalarBinOpN2(SetVectorType &Worklist,
98 unsigned Opcode) const;
100 void splitScalar64BitUnaryOp(SetVectorType &Worklist,
101 MachineInstr &Inst, unsigned Opcode) const;
103 void splitScalar64BitAddSub(SetVectorType &Worklist, MachineInstr &Inst,
104 MachineDominatorTree *MDT = nullptr) const;
106 void splitScalar64BitBinaryOp(SetVectorType &Worklist, MachineInstr &Inst,
108 MachineDominatorTree *MDT = nullptr) const;
110 void splitScalar64BitXnor(SetVectorType &Worklist, MachineInstr &Inst,
111 MachineDominatorTree *MDT = nullptr) const;
113 void splitScalar64BitBCNT(SetVectorType &Worklist,
114 MachineInstr &Inst) const;
115 void splitScalar64BitBFE(SetVectorType &Worklist,
116 MachineInstr &Inst) const;
117 void movePackToVALU(SetVectorType &Worklist,
118 MachineRegisterInfo &MRI,
119 MachineInstr &Inst) const;
121 void addUsersToMoveToVALUWorklist(unsigned Reg, MachineRegisterInfo &MRI,
122 SetVectorType &Worklist) const;
125 addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
126 SetVectorType &Worklist) const;
128 const TargetRegisterClass *
129 getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
131 bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
133 unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
136 bool swapSourceModifiers(MachineInstr &MI,
137 MachineOperand &Src0, unsigned Src0OpName,
138 MachineOperand &Src1, unsigned Src1OpName) const;
140 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
142 unsigned OpIdx1) const override;
145 enum TargetOperandFlags {
149 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
151 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
153 MO_GOTPCREL32_LO = 2,
154 // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
155 MO_GOTPCREL32_HI = 3,
156 // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
159 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
163 explicit SIInstrInfo(const GCNSubtarget &ST);
165 const SIRegisterInfo &getRegisterInfo() const {
169 bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
170 AliasAnalysis *AA) const override;
172 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
174 int64_t &Offset2) const override;
176 bool getMemOperandWithOffset(MachineInstr &LdSt, MachineOperand *&BaseOp,
178 const TargetRegisterInfo *TRI) const final;
180 bool shouldClusterMemOps(MachineOperand &BaseOp1, MachineOperand &BaseOp2,
181 unsigned NumLoads) const override;
183 bool shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1, int64_t Offset0,
184 int64_t Offset1, unsigned NumLoads) const override;
186 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
187 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
188 bool KillSrc) const override;
190 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
191 RegScavenger *RS, unsigned TmpReg,
192 unsigned Offset, unsigned Size) const;
194 void materializeImmediate(MachineBasicBlock &MBB,
195 MachineBasicBlock::iterator MI,
198 int64_t Value) const;
200 const TargetRegisterClass *getPreferredSelectRegClass(
201 unsigned Size) const;
203 unsigned insertNE(MachineBasicBlock *MBB,
204 MachineBasicBlock::iterator I, const DebugLoc &DL,
205 unsigned SrcReg, int Value) const;
207 unsigned insertEQ(MachineBasicBlock *MBB,
208 MachineBasicBlock::iterator I, const DebugLoc &DL,
209 unsigned SrcReg, int Value) const;
211 void storeRegToStackSlot(MachineBasicBlock &MBB,
212 MachineBasicBlock::iterator MI, unsigned SrcReg,
213 bool isKill, int FrameIndex,
214 const TargetRegisterClass *RC,
215 const TargetRegisterInfo *TRI) const override;
217 void loadRegFromStackSlot(MachineBasicBlock &MBB,
218 MachineBasicBlock::iterator MI, unsigned DestReg,
219 int FrameIndex, const TargetRegisterClass *RC,
220 const TargetRegisterInfo *TRI) const override;
222 bool expandPostRAPseudo(MachineInstr &MI) const override;
224 // Returns an opcode that can be used to move a value to a \p DstRC
225 // register. If there is no hardware instruction that can store to \p
226 // DstRC, then AMDGPU::COPY is returned.
227 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
230 int commuteOpcode(unsigned Opc) const;
233 inline int commuteOpcode(const MachineInstr &MI) const {
234 return commuteOpcode(MI.getOpcode());
237 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
238 unsigned &SrcOpIdx2) const override;
240 bool findCommutedOpIndices(MCInstrDesc Desc, unsigned & SrcOpIdx0,
241 unsigned & SrcOpIdx1) const;
243 bool isBranchOffsetInRange(unsigned BranchOpc,
244 int64_t BrOffset) const override;
246 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
248 unsigned insertIndirectBranch(MachineBasicBlock &MBB,
249 MachineBasicBlock &NewDestBB,
252 RegScavenger *RS = nullptr) const override;
254 bool analyzeBranchImpl(MachineBasicBlock &MBB,
255 MachineBasicBlock::iterator I,
256 MachineBasicBlock *&TBB,
257 MachineBasicBlock *&FBB,
258 SmallVectorImpl<MachineOperand> &Cond,
259 bool AllowModify) const;
261 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
262 MachineBasicBlock *&FBB,
263 SmallVectorImpl<MachineOperand> &Cond,
264 bool AllowModify = false) const override;
266 unsigned removeBranch(MachineBasicBlock &MBB,
267 int *BytesRemoved = nullptr) const override;
269 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
270 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
272 int *BytesAdded = nullptr) const override;
274 bool reverseBranchCondition(
275 SmallVectorImpl<MachineOperand> &Cond) const override;
277 bool canInsertSelect(const MachineBasicBlock &MBB,
278 ArrayRef<MachineOperand> Cond,
279 unsigned TrueReg, unsigned FalseReg,
281 int &TrueCycles, int &FalseCycles) const override;
283 void insertSelect(MachineBasicBlock &MBB,
284 MachineBasicBlock::iterator I, const DebugLoc &DL,
285 unsigned DstReg, ArrayRef<MachineOperand> Cond,
286 unsigned TrueReg, unsigned FalseReg) const override;
288 void insertVectorSelect(MachineBasicBlock &MBB,
289 MachineBasicBlock::iterator I, const DebugLoc &DL,
290 unsigned DstReg, ArrayRef<MachineOperand> Cond,
291 unsigned TrueReg, unsigned FalseReg) const;
293 unsigned getAddressSpaceForPseudoSourceKind(
294 unsigned Kind) const override;
297 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
298 AliasAnalysis *AA = nullptr) const override;
300 bool isFoldableCopy(const MachineInstr &MI) const;
302 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
303 MachineRegisterInfo *MRI) const final;
305 unsigned getMachineCSELookAheadLimit() const override { return 500; }
307 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
309 LiveVariables *LV) const override;
311 bool isSchedulingBoundary(const MachineInstr &MI,
312 const MachineBasicBlock *MBB,
313 const MachineFunction &MF) const override;
315 static bool isSALU(const MachineInstr &MI) {
316 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
319 bool isSALU(uint16_t Opcode) const {
320 return get(Opcode).TSFlags & SIInstrFlags::SALU;
323 static bool isVALU(const MachineInstr &MI) {
324 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
327 bool isVALU(uint16_t Opcode) const {
328 return get(Opcode).TSFlags & SIInstrFlags::VALU;
331 static bool isVMEM(const MachineInstr &MI) {
332 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
335 bool isVMEM(uint16_t Opcode) const {
336 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
339 static bool isSOP1(const MachineInstr &MI) {
340 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
343 bool isSOP1(uint16_t Opcode) const {
344 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
347 static bool isSOP2(const MachineInstr &MI) {
348 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
351 bool isSOP2(uint16_t Opcode) const {
352 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
355 static bool isSOPC(const MachineInstr &MI) {
356 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
359 bool isSOPC(uint16_t Opcode) const {
360 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
363 static bool isSOPK(const MachineInstr &MI) {
364 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
367 bool isSOPK(uint16_t Opcode) const {
368 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
371 static bool isSOPP(const MachineInstr &MI) {
372 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
375 bool isSOPP(uint16_t Opcode) const {
376 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
379 static bool isVOP1(const MachineInstr &MI) {
380 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
383 bool isVOP1(uint16_t Opcode) const {
384 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
387 static bool isVOP2(const MachineInstr &MI) {
388 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
391 bool isVOP2(uint16_t Opcode) const {
392 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
395 static bool isVOP3(const MachineInstr &MI) {
396 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
399 bool isVOP3(uint16_t Opcode) const {
400 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
403 static bool isSDWA(const MachineInstr &MI) {
404 return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
407 bool isSDWA(uint16_t Opcode) const {
408 return get(Opcode).TSFlags & SIInstrFlags::SDWA;
411 static bool isVOPC(const MachineInstr &MI) {
412 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
415 bool isVOPC(uint16_t Opcode) const {
416 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
419 static bool isMUBUF(const MachineInstr &MI) {
420 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
423 bool isMUBUF(uint16_t Opcode) const {
424 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
427 static bool isMTBUF(const MachineInstr &MI) {
428 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
431 bool isMTBUF(uint16_t Opcode) const {
432 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
435 static bool isSMRD(const MachineInstr &MI) {
436 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
439 bool isSMRD(uint16_t Opcode) const {
440 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
443 bool isBufferSMRD(const MachineInstr &MI) const;
445 static bool isDS(const MachineInstr &MI) {
446 return MI.getDesc().TSFlags & SIInstrFlags::DS;
449 bool isDS(uint16_t Opcode) const {
450 return get(Opcode).TSFlags & SIInstrFlags::DS;
453 bool isAlwaysGDS(uint16_t Opcode) const;
455 static bool isMIMG(const MachineInstr &MI) {
456 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
459 bool isMIMG(uint16_t Opcode) const {
460 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
463 static bool isGather4(const MachineInstr &MI) {
464 return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
467 bool isGather4(uint16_t Opcode) const {
468 return get(Opcode).TSFlags & SIInstrFlags::Gather4;
471 static bool isFLAT(const MachineInstr &MI) {
472 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
475 // Is a FLAT encoded instruction which accesses a specific segment,
476 // i.e. global_* or scratch_*.
477 static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
478 auto Flags = MI.getDesc().TSFlags;
479 return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
482 // Any FLAT encoded instruction, including global_* and scratch_*.
483 bool isFLAT(uint16_t Opcode) const {
484 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
487 static bool isEXP(const MachineInstr &MI) {
488 return MI.getDesc().TSFlags & SIInstrFlags::EXP;
491 bool isEXP(uint16_t Opcode) const {
492 return get(Opcode).TSFlags & SIInstrFlags::EXP;
495 static bool isWQM(const MachineInstr &MI) {
496 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
499 bool isWQM(uint16_t Opcode) const {
500 return get(Opcode).TSFlags & SIInstrFlags::WQM;
503 static bool isDisableWQM(const MachineInstr &MI) {
504 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
507 bool isDisableWQM(uint16_t Opcode) const {
508 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
511 static bool isVGPRSpill(const MachineInstr &MI) {
512 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
515 bool isVGPRSpill(uint16_t Opcode) const {
516 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
519 static bool isSGPRSpill(const MachineInstr &MI) {
520 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
523 bool isSGPRSpill(uint16_t Opcode) const {
524 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
527 static bool isDPP(const MachineInstr &MI) {
528 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
531 bool isDPP(uint16_t Opcode) const {
532 return get(Opcode).TSFlags & SIInstrFlags::DPP;
535 static bool isVOP3P(const MachineInstr &MI) {
536 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
539 bool isVOP3P(uint16_t Opcode) const {
540 return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
543 static bool isVINTRP(const MachineInstr &MI) {
544 return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
547 bool isVINTRP(uint16_t Opcode) const {
548 return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
551 static bool isScalarUnit(const MachineInstr &MI) {
552 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
555 static bool usesVM_CNT(const MachineInstr &MI) {
556 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
559 static bool usesLGKM_CNT(const MachineInstr &MI) {
560 return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
563 static bool sopkIsZext(const MachineInstr &MI) {
564 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
567 bool sopkIsZext(uint16_t Opcode) const {
568 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
571 /// \returns true if this is an s_store_dword* instruction. This is more
572 /// specific than than isSMEM && mayStore.
573 static bool isScalarStore(const MachineInstr &MI) {
574 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
577 bool isScalarStore(uint16_t Opcode) const {
578 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
581 static bool isFixedSize(const MachineInstr &MI) {
582 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
585 bool isFixedSize(uint16_t Opcode) const {
586 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
589 static bool hasFPClamp(const MachineInstr &MI) {
590 return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
593 bool hasFPClamp(uint16_t Opcode) const {
594 return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
597 static bool hasIntClamp(const MachineInstr &MI) {
598 return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
601 uint64_t getClampMask(const MachineInstr &MI) const {
602 const uint64_t ClampFlags = SIInstrFlags::FPClamp |
603 SIInstrFlags::IntClamp |
604 SIInstrFlags::ClampLo |
605 SIInstrFlags::ClampHi;
606 return MI.getDesc().TSFlags & ClampFlags;
609 static bool usesFPDPRounding(const MachineInstr &MI) {
610 return MI.getDesc().TSFlags & SIInstrFlags::FPDPRounding;
613 bool usesFPDPRounding(uint16_t Opcode) const {
614 return get(Opcode).TSFlags & SIInstrFlags::FPDPRounding;
617 bool isVGPRCopy(const MachineInstr &MI) const {
619 unsigned Dest = MI.getOperand(0).getReg();
620 const MachineFunction &MF = *MI.getParent()->getParent();
621 const MachineRegisterInfo &MRI = MF.getRegInfo();
622 return !RI.isSGPRReg(MRI, Dest);
625 /// Whether we must prevent this instruction from executing with EXEC = 0.
626 bool hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const;
628 bool isInlineConstant(const APInt &Imm) const;
630 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
632 bool isInlineConstant(const MachineOperand &MO,
633 const MCOperandInfo &OpInfo) const {
634 return isInlineConstant(MO, OpInfo.OperandType);
637 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
638 /// be an inline immediate.
639 bool isInlineConstant(const MachineInstr &MI,
640 const MachineOperand &UseMO,
641 const MachineOperand &DefMO) const {
642 assert(UseMO.getParent() == &MI);
643 int OpIdx = MI.getOperandNo(&UseMO);
644 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
648 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
651 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
653 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
654 const MachineOperand &MO = MI.getOperand(OpIdx);
655 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
658 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
659 const MachineOperand &MO) const {
660 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
664 unsigned Size = getOpSize(MI, OpIdx);
665 assert(Size == 8 || Size == 4);
667 uint8_t OpType = (Size == 8) ?
668 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
669 return isInlineConstant(MO, OpType);
672 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
675 bool isInlineConstant(const MachineOperand &MO) const {
676 const MachineInstr *Parent = MO.getParent();
677 return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
680 bool isLiteralConstant(const MachineOperand &MO,
681 const MCOperandInfo &OpInfo) const {
682 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
685 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
686 const MachineOperand &MO = MI.getOperand(OpIdx);
687 return MO.isImm() && !isInlineConstant(MI, OpIdx);
690 // Returns true if this operand could potentially require a 32-bit literal
691 // operand, but not necessarily. A FrameIndex for example could resolve to an
692 // inline immediate value that will not require an additional 4-bytes; this
693 // assumes that it will.
694 bool isLiteralConstantLike(const MachineOperand &MO,
695 const MCOperandInfo &OpInfo) const;
697 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
698 const MachineOperand &MO) const;
700 /// Return true if this 64-bit VALU instruction has a 32-bit encoding.
701 /// This function will return false if you pass it a 32-bit instruction.
702 bool hasVALU32BitEncoding(unsigned Opcode) const;
704 /// Returns true if this operand uses the constant bus.
705 bool usesConstantBus(const MachineRegisterInfo &MRI,
706 const MachineOperand &MO,
707 const MCOperandInfo &OpInfo) const;
709 /// Return true if this instruction has any modifiers.
710 /// e.g. src[012]_mod, omod, clamp.
711 bool hasModifiers(unsigned Opcode) const;
713 bool hasModifiersSet(const MachineInstr &MI,
714 unsigned OpName) const;
715 bool hasAnyModifiersSet(const MachineInstr &MI) const;
717 bool canShrink(const MachineInstr &MI,
718 const MachineRegisterInfo &MRI) const;
720 MachineInstr *buildShrunkInst(MachineInstr &MI,
721 unsigned NewOpcode) const;
723 bool verifyInstruction(const MachineInstr &MI,
724 StringRef &ErrInfo) const override;
726 unsigned getVALUOp(const MachineInstr &MI) const;
728 /// Return the correct register class for \p OpNo. For target-specific
729 /// instructions, this will return the register class that has been defined
730 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
731 /// the register class of its machine operand.
732 /// to infer the correct register class base on the other operands.
733 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
734 unsigned OpNo) const;
736 /// Return the size in bytes of the operand OpNo on the given
737 // instruction opcode.
738 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
739 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
741 if (OpInfo.RegClass == -1) {
742 // If this is an immediate operand, this must be a 32-bit literal.
743 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
747 return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
750 /// This form should usually be preferred since it handles operands
751 /// with unknown register classes.
752 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
753 const MachineOperand &MO = MI.getOperand(OpNo);
755 if (unsigned SubReg = MO.getSubReg()) {
756 assert(RI.getRegSizeInBits(*RI.getSubClassWithSubReg(
757 MI.getParent()->getParent()->getRegInfo().
758 getRegClass(MO.getReg()), SubReg)) >= 32 &&
759 "Sub-dword subregs are not supported");
760 return RI.getSubRegIndexLaneMask(SubReg).getNumLanes() * 4;
763 return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
766 /// \returns true if it is legal for the operand at index \p OpNo
768 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
770 /// Legalize the \p OpIndex operand of this instruction by inserting
771 /// a MOV. For example:
772 /// ADD_I32_e32 VGPR0, 15
775 /// ADD_I32_e32 VGPR0, VGPR1
777 /// If the operand being legalized is a register, then a COPY will be used
779 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
781 /// Check if \p MO is a legal operand if it was the \p OpIdx Operand
783 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
784 const MachineOperand *MO = nullptr) const;
786 /// Check if \p MO would be a valid operand for the given operand
787 /// definition \p OpInfo. Note this does not attempt to validate constant bus
788 /// restrictions (e.g. literal constant usage).
789 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
790 const MCOperandInfo &OpInfo,
791 const MachineOperand &MO) const;
793 /// Check if \p MO (a register operand) is a legal register for the
794 /// given operand description.
795 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
796 const MCOperandInfo &OpInfo,
797 const MachineOperand &MO) const;
799 /// Legalize operands in \p MI by either commuting it or inserting a
801 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
803 /// Fix operands in \p MI to satisfy constant bus requirements.
804 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
806 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
807 /// be used when it is know that the value in SrcReg is same across all
808 /// threads in the wave.
809 /// \returns The SGPR register that \p SrcReg was copied to.
810 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
811 MachineRegisterInfo &MRI) const;
813 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
815 void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
816 MachineBasicBlock::iterator I,
817 const TargetRegisterClass *DstRC,
818 MachineOperand &Op, MachineRegisterInfo &MRI,
819 const DebugLoc &DL) const;
821 /// Legalize all operands in this instruction. This function may create new
822 /// instructions and control-flow around \p MI. If present, \p MDT is
824 void legalizeOperands(MachineInstr &MI,
825 MachineDominatorTree *MDT = nullptr) const;
827 /// Replace this instruction's opcode with the equivalent VALU
828 /// opcode. This function will also move the users of \p MI to the
829 /// VALU if necessary. If present, \p MDT is updated.
830 void moveToVALU(MachineInstr &MI, MachineDominatorTree *MDT = nullptr) const;
832 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
835 void insertNoop(MachineBasicBlock &MBB,
836 MachineBasicBlock::iterator MI) const override;
838 void insertReturn(MachineBasicBlock &MBB) const;
839 /// Return the number of wait states that result from executing this
841 unsigned getNumWaitStates(const MachineInstr &MI) const;
843 /// Returns the operand named \p Op. If \p MI does not have an
844 /// operand named \c Op, this function returns nullptr.
846 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
849 const MachineOperand *getNamedOperand(const MachineInstr &MI,
850 unsigned OpName) const {
851 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
854 /// Get required immediate operand
855 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
856 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
857 return MI.getOperand(Idx).getImm();
860 uint64_t getDefaultRsrcDataFormat() const;
861 uint64_t getScratchRsrcWords23() const;
863 bool isLowLatencyInstruction(const MachineInstr &MI) const;
864 bool isHighLatencyInstruction(const MachineInstr &MI) const;
866 /// Return the descriptor of the target-specific machine instruction
867 /// that corresponds to the specified pseudo or native opcode.
868 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
869 return get(pseudoToMCOpcode(Opcode));
872 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
873 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
875 unsigned isLoadFromStackSlot(const MachineInstr &MI,
876 int &FrameIndex) const override;
877 unsigned isStoreToStackSlot(const MachineInstr &MI,
878 int &FrameIndex) const override;
880 unsigned getInstBundleSize(const MachineInstr &MI) const;
881 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
883 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
885 bool isNonUniformBranchInstr(MachineInstr &Instr) const;
887 void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
888 MachineBasicBlock *IfEnd) const;
890 void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
891 MachineBasicBlock *LoopEnd) const;
893 std::pair<unsigned, unsigned>
894 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
896 ArrayRef<std::pair<int, const char *>>
897 getSerializableTargetIndices() const override;
899 ArrayRef<std::pair<unsigned, const char *>>
900 getSerializableDirectMachineOperandTargetFlags() const override;
902 ScheduleHazardRecognizer *
903 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
904 const ScheduleDAG *DAG) const override;
906 ScheduleHazardRecognizer *
907 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
909 bool isBasicBlockPrologue(const MachineInstr &MI) const override;
911 /// Return a partially built integer add instruction without carry.
912 /// Caller must add source operands.
913 /// For pre-GFX9 it will generate unused carry destination operand.
914 /// TODO: After GFX9 it should return a no-carry operation.
915 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
916 MachineBasicBlock::iterator I,
918 unsigned DestReg) const;
920 static bool isKillTerminator(unsigned Opcode);
921 const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
923 static bool isLegalMUBUFImmOffset(unsigned Imm) {
924 return isUInt<12>(Imm);
927 /// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
928 /// Return -1 if the target-specific opcode for the pseudo instruction does
929 /// not exist. If Opcode is not a pseudo instruction, this is identity.
930 int pseudoToMCOpcode(int Opcode) const;
933 /// \brief Returns true if a reg:subreg pair P has a TRC class
934 inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P,
935 const TargetRegisterClass &TRC,
936 MachineRegisterInfo &MRI) {
937 auto *RC = MRI.getRegClass(P.Reg);
940 auto *TRI = MRI.getTargetRegisterInfo();
941 return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg);
944 /// \brief Create RegSubRegPair from a register MachineOperand
946 TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O) {
948 return TargetInstrInfo::RegSubRegPair(O.getReg(), O.getSubReg());
951 /// \brief Return the SubReg component from REG_SEQUENCE
952 TargetInstrInfo::RegSubRegPair getRegSequenceSubReg(MachineInstr &MI,
955 /// \brief Return the defining instruction for a given reg:subreg pair
956 /// skipping copy like instructions and subreg-manipulation pseudos.
957 /// Following another subreg of a reg:subreg isn't supported.
958 MachineInstr *getVRegSubRegDef(const TargetInstrInfo::RegSubRegPair &P,
959 MachineRegisterInfo &MRI);
964 int getVOPe64(uint16_t Opcode);
967 int getVOPe32(uint16_t Opcode);
970 int getSDWAOp(uint16_t Opcode);
973 int getDPPOp32(uint16_t Opcode);
976 int getBasicFromSDWAOp(uint16_t Opcode);
979 int getCommuteRev(uint16_t Opcode);
982 int getCommuteOrig(uint16_t Opcode);
985 int getAddr64Inst(uint16_t Opcode);
987 /// Check if \p Opcode is an Addr64 opcode.
989 /// \returns \p Opcode if it is an Addr64 opcode, otherwise -1.
991 int getIfAddr64Inst(uint16_t Opcode);
994 int getMUBUFNoLdsInst(uint16_t Opcode);
997 int getAtomicRetOp(uint16_t Opcode);
1000 int getAtomicNoRetOp(uint16_t Opcode);
1003 int getSOPKOp(uint16_t Opcode);
1006 int getGlobalSaddrOp(uint16_t Opcode);
1008 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
1009 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
1010 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
1011 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
1013 // For MachineOperands.
1015 TF_LONG_BRANCH_FORWARD = 1 << 0,
1016 TF_LONG_BRANCH_BACKWARD = 1 << 1
1019 } // end namespace AMDGPU
1022 namespace KernelInputOffsets {
1024 /// Offsets in bytes from the start of the input buffer
1037 } // end namespace KernelInputOffsets
1038 } // end namespace SI
1040 } // end namespace llvm
1042 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H