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 MachineRegisterInfo;
43 class TargetRegisterClass;
45 class SIInstrInfo final : public AMDGPUGenInstrInfo {
47 const SIRegisterInfo RI;
48 const GCNSubtarget &ST;
50 // The inverse predicate should have the negative value.
51 enum BranchPredicate {
61 using SetVectorType = SmallSetVector<MachineInstr *, 32>;
63 static unsigned getBranchOpcode(BranchPredicate Cond);
64 static BranchPredicate getBranchPredicate(unsigned Opcode);
67 unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
68 MachineRegisterInfo &MRI,
69 MachineOperand &SuperReg,
70 const TargetRegisterClass *SuperRC,
72 const TargetRegisterClass *SubRC) const;
73 MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
74 MachineRegisterInfo &MRI,
75 MachineOperand &SuperReg,
76 const TargetRegisterClass *SuperRC,
78 const TargetRegisterClass *SubRC) const;
80 void swapOperands(MachineInstr &Inst) const;
82 bool moveScalarAddSub(SetVectorType &Worklist,
83 MachineInstr &Inst) const;
85 void lowerScalarAbs(SetVectorType &Worklist,
86 MachineInstr &Inst) const;
88 void lowerScalarXnor(SetVectorType &Worklist,
89 MachineInstr &Inst) const;
91 void splitScalar64BitUnaryOp(SetVectorType &Worklist,
92 MachineInstr &Inst, unsigned Opcode) const;
94 void splitScalar64BitAddSub(SetVectorType &Worklist,
95 MachineInstr &Inst) const;
97 void splitScalar64BitBinaryOp(SetVectorType &Worklist,
98 MachineInstr &Inst, unsigned Opcode) const;
100 void splitScalar64BitBCNT(SetVectorType &Worklist,
101 MachineInstr &Inst) const;
102 void splitScalar64BitBFE(SetVectorType &Worklist,
103 MachineInstr &Inst) const;
104 void movePackToVALU(SetVectorType &Worklist,
105 MachineRegisterInfo &MRI,
106 MachineInstr &Inst) const;
108 void addUsersToMoveToVALUWorklist(unsigned Reg, MachineRegisterInfo &MRI,
109 SetVectorType &Worklist) const;
112 addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
113 SetVectorType &Worklist) const;
115 const TargetRegisterClass *
116 getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
118 bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
120 unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
123 bool swapSourceModifiers(MachineInstr &MI,
124 MachineOperand &Src0, unsigned Src0OpName,
125 MachineOperand &Src1, unsigned Src1OpName) const;
127 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
129 unsigned OpIdx1) const override;
132 enum TargetOperandFlags {
136 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
138 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
140 MO_GOTPCREL32_LO = 2,
141 // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
142 MO_GOTPCREL32_HI = 3,
143 // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
146 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
150 explicit SIInstrInfo(const GCNSubtarget &ST);
152 const SIRegisterInfo &getRegisterInfo() const {
156 bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
157 AliasAnalysis *AA) const override;
159 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
161 int64_t &Offset2) const override;
163 bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
165 const TargetRegisterInfo *TRI) const final;
167 bool shouldClusterMemOps(MachineInstr &FirstLdSt, unsigned BaseReg1,
168 MachineInstr &SecondLdSt, unsigned BaseReg2,
169 unsigned NumLoads) const override;
171 bool shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1, int64_t Offset0,
172 int64_t Offset1, unsigned NumLoads) const override;
174 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
175 const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
176 bool KillSrc) const override;
178 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
179 RegScavenger *RS, unsigned TmpReg,
180 unsigned Offset, unsigned Size) const;
182 void materializeImmediate(MachineBasicBlock &MBB,
183 MachineBasicBlock::iterator MI,
186 int64_t Value) const;
188 const TargetRegisterClass *getPreferredSelectRegClass(
189 unsigned Size) const;
191 unsigned insertNE(MachineBasicBlock *MBB,
192 MachineBasicBlock::iterator I, const DebugLoc &DL,
193 unsigned SrcReg, int Value) const;
195 unsigned insertEQ(MachineBasicBlock *MBB,
196 MachineBasicBlock::iterator I, const DebugLoc &DL,
197 unsigned SrcReg, int Value) const;
199 void storeRegToStackSlot(MachineBasicBlock &MBB,
200 MachineBasicBlock::iterator MI, unsigned SrcReg,
201 bool isKill, int FrameIndex,
202 const TargetRegisterClass *RC,
203 const TargetRegisterInfo *TRI) const override;
205 void loadRegFromStackSlot(MachineBasicBlock &MBB,
206 MachineBasicBlock::iterator MI, unsigned DestReg,
207 int FrameIndex, const TargetRegisterClass *RC,
208 const TargetRegisterInfo *TRI) const override;
210 bool expandPostRAPseudo(MachineInstr &MI) const override;
212 // Returns an opcode that can be used to move a value to a \p DstRC
213 // register. If there is no hardware instruction that can store to \p
214 // DstRC, then AMDGPU::COPY is returned.
215 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
218 int commuteOpcode(unsigned Opc) const;
221 inline int commuteOpcode(const MachineInstr &MI) const {
222 return commuteOpcode(MI.getOpcode());
225 bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
226 unsigned &SrcOpIdx2) const override;
228 bool isBranchOffsetInRange(unsigned BranchOpc,
229 int64_t BrOffset) const override;
231 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
233 unsigned insertIndirectBranch(MachineBasicBlock &MBB,
234 MachineBasicBlock &NewDestBB,
237 RegScavenger *RS = nullptr) const override;
239 bool analyzeBranchImpl(MachineBasicBlock &MBB,
240 MachineBasicBlock::iterator I,
241 MachineBasicBlock *&TBB,
242 MachineBasicBlock *&FBB,
243 SmallVectorImpl<MachineOperand> &Cond,
244 bool AllowModify) const;
246 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
247 MachineBasicBlock *&FBB,
248 SmallVectorImpl<MachineOperand> &Cond,
249 bool AllowModify = false) const override;
251 unsigned removeBranch(MachineBasicBlock &MBB,
252 int *BytesRemoved = nullptr) const override;
254 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
255 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
257 int *BytesAdded = nullptr) const override;
259 bool reverseBranchCondition(
260 SmallVectorImpl<MachineOperand> &Cond) const override;
262 bool canInsertSelect(const MachineBasicBlock &MBB,
263 ArrayRef<MachineOperand> Cond,
264 unsigned TrueReg, unsigned FalseReg,
266 int &TrueCycles, int &FalseCycles) const override;
268 void insertSelect(MachineBasicBlock &MBB,
269 MachineBasicBlock::iterator I, const DebugLoc &DL,
270 unsigned DstReg, ArrayRef<MachineOperand> Cond,
271 unsigned TrueReg, unsigned FalseReg) const override;
273 void insertVectorSelect(MachineBasicBlock &MBB,
274 MachineBasicBlock::iterator I, const DebugLoc &DL,
275 unsigned DstReg, ArrayRef<MachineOperand> Cond,
276 unsigned TrueReg, unsigned FalseReg) const;
278 unsigned getAddressSpaceForPseudoSourceKind(
279 PseudoSourceValue::PSVKind Kind) const override;
282 areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
283 AliasAnalysis *AA = nullptr) const override;
285 bool isFoldableCopy(const MachineInstr &MI) const;
287 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
288 MachineRegisterInfo *MRI) const final;
290 unsigned getMachineCSELookAheadLimit() const override { return 500; }
292 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
294 LiveVariables *LV) const override;
296 bool isSchedulingBoundary(const MachineInstr &MI,
297 const MachineBasicBlock *MBB,
298 const MachineFunction &MF) const override;
300 static bool isSALU(const MachineInstr &MI) {
301 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
304 bool isSALU(uint16_t Opcode) const {
305 return get(Opcode).TSFlags & SIInstrFlags::SALU;
308 static bool isVALU(const MachineInstr &MI) {
309 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
312 bool isVALU(uint16_t Opcode) const {
313 return get(Opcode).TSFlags & SIInstrFlags::VALU;
316 static bool isVMEM(const MachineInstr &MI) {
317 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
320 bool isVMEM(uint16_t Opcode) const {
321 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
324 static bool isSOP1(const MachineInstr &MI) {
325 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
328 bool isSOP1(uint16_t Opcode) const {
329 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
332 static bool isSOP2(const MachineInstr &MI) {
333 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
336 bool isSOP2(uint16_t Opcode) const {
337 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
340 static bool isSOPC(const MachineInstr &MI) {
341 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
344 bool isSOPC(uint16_t Opcode) const {
345 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
348 static bool isSOPK(const MachineInstr &MI) {
349 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
352 bool isSOPK(uint16_t Opcode) const {
353 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
356 static bool isSOPP(const MachineInstr &MI) {
357 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
360 bool isSOPP(uint16_t Opcode) const {
361 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
364 static bool isVOP1(const MachineInstr &MI) {
365 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
368 bool isVOP1(uint16_t Opcode) const {
369 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
372 static bool isVOP2(const MachineInstr &MI) {
373 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
376 bool isVOP2(uint16_t Opcode) const {
377 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
380 static bool isVOP3(const MachineInstr &MI) {
381 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
384 bool isVOP3(uint16_t Opcode) const {
385 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
388 static bool isSDWA(const MachineInstr &MI) {
389 return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
392 bool isSDWA(uint16_t Opcode) const {
393 return get(Opcode).TSFlags & SIInstrFlags::SDWA;
396 static bool isVOPC(const MachineInstr &MI) {
397 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
400 bool isVOPC(uint16_t Opcode) const {
401 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
404 static bool isMUBUF(const MachineInstr &MI) {
405 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
408 bool isMUBUF(uint16_t Opcode) const {
409 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
412 static bool isMTBUF(const MachineInstr &MI) {
413 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
416 bool isMTBUF(uint16_t Opcode) const {
417 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
420 static bool isSMRD(const MachineInstr &MI) {
421 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
424 bool isSMRD(uint16_t Opcode) const {
425 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
428 bool isBufferSMRD(const MachineInstr &MI) const;
430 static bool isDS(const MachineInstr &MI) {
431 return MI.getDesc().TSFlags & SIInstrFlags::DS;
434 bool isDS(uint16_t Opcode) const {
435 return get(Opcode).TSFlags & SIInstrFlags::DS;
438 static bool isMIMG(const MachineInstr &MI) {
439 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
442 bool isMIMG(uint16_t Opcode) const {
443 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
446 static bool isGather4(const MachineInstr &MI) {
447 return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
450 bool isGather4(uint16_t Opcode) const {
451 return get(Opcode).TSFlags & SIInstrFlags::Gather4;
454 static bool isFLAT(const MachineInstr &MI) {
455 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
458 // Is a FLAT encoded instruction which accesses a specific segment,
459 // i.e. global_* or scratch_*.
460 static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
461 auto Flags = MI.getDesc().TSFlags;
462 return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
465 // Any FLAT encoded instruction, including global_* and scratch_*.
466 bool isFLAT(uint16_t Opcode) const {
467 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
470 static bool isEXP(const MachineInstr &MI) {
471 return MI.getDesc().TSFlags & SIInstrFlags::EXP;
474 bool isEXP(uint16_t Opcode) const {
475 return get(Opcode).TSFlags & SIInstrFlags::EXP;
478 static bool isWQM(const MachineInstr &MI) {
479 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
482 bool isWQM(uint16_t Opcode) const {
483 return get(Opcode).TSFlags & SIInstrFlags::WQM;
486 static bool isDisableWQM(const MachineInstr &MI) {
487 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
490 bool isDisableWQM(uint16_t Opcode) const {
491 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
494 static bool isVGPRSpill(const MachineInstr &MI) {
495 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
498 bool isVGPRSpill(uint16_t Opcode) const {
499 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
502 static bool isSGPRSpill(const MachineInstr &MI) {
503 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
506 bool isSGPRSpill(uint16_t Opcode) const {
507 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
510 static bool isDPP(const MachineInstr &MI) {
511 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
514 bool isDPP(uint16_t Opcode) const {
515 return get(Opcode).TSFlags & SIInstrFlags::DPP;
518 static bool isVOP3P(const MachineInstr &MI) {
519 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
522 bool isVOP3P(uint16_t Opcode) const {
523 return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
526 static bool isVINTRP(const MachineInstr &MI) {
527 return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
530 bool isVINTRP(uint16_t Opcode) const {
531 return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
534 static bool isScalarUnit(const MachineInstr &MI) {
535 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
538 static bool usesVM_CNT(const MachineInstr &MI) {
539 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
542 static bool usesLGKM_CNT(const MachineInstr &MI) {
543 return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
546 static bool sopkIsZext(const MachineInstr &MI) {
547 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
550 bool sopkIsZext(uint16_t Opcode) const {
551 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
554 /// \returns true if this is an s_store_dword* instruction. This is more
555 /// specific than than isSMEM && mayStore.
556 static bool isScalarStore(const MachineInstr &MI) {
557 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
560 bool isScalarStore(uint16_t Opcode) const {
561 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
564 static bool isFixedSize(const MachineInstr &MI) {
565 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
568 bool isFixedSize(uint16_t Opcode) const {
569 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
572 static bool hasFPClamp(const MachineInstr &MI) {
573 return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
576 bool hasFPClamp(uint16_t Opcode) const {
577 return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
580 static bool hasIntClamp(const MachineInstr &MI) {
581 return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
584 uint64_t getClampMask(const MachineInstr &MI) const {
585 const uint64_t ClampFlags = SIInstrFlags::FPClamp |
586 SIInstrFlags::IntClamp |
587 SIInstrFlags::ClampLo |
588 SIInstrFlags::ClampHi;
589 return MI.getDesc().TSFlags & ClampFlags;
592 bool isVGPRCopy(const MachineInstr &MI) const {
594 unsigned Dest = MI.getOperand(0).getReg();
595 const MachineFunction &MF = *MI.getParent()->getParent();
596 const MachineRegisterInfo &MRI = MF.getRegInfo();
597 return !RI.isSGPRReg(MRI, Dest);
600 /// Whether we must prevent this instruction from executing with EXEC = 0.
601 bool hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const;
603 bool isInlineConstant(const APInt &Imm) const;
605 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
607 bool isInlineConstant(const MachineOperand &MO,
608 const MCOperandInfo &OpInfo) const {
609 return isInlineConstant(MO, OpInfo.OperandType);
612 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
613 /// be an inline immediate.
614 bool isInlineConstant(const MachineInstr &MI,
615 const MachineOperand &UseMO,
616 const MachineOperand &DefMO) const {
617 assert(UseMO.getParent() == &MI);
618 int OpIdx = MI.getOperandNo(&UseMO);
619 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
623 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
626 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
628 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
629 const MachineOperand &MO = MI.getOperand(OpIdx);
630 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
633 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
634 const MachineOperand &MO) const {
635 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
639 unsigned Size = getOpSize(MI, OpIdx);
640 assert(Size == 8 || Size == 4);
642 uint8_t OpType = (Size == 8) ?
643 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
644 return isInlineConstant(MO, OpType);
647 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
650 bool isInlineConstant(const MachineOperand &MO) const {
651 const MachineInstr *Parent = MO.getParent();
652 return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
655 bool isLiteralConstant(const MachineOperand &MO,
656 const MCOperandInfo &OpInfo) const {
657 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
660 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
661 const MachineOperand &MO = MI.getOperand(OpIdx);
662 return MO.isImm() && !isInlineConstant(MI, OpIdx);
665 // Returns true if this operand could potentially require a 32-bit literal
666 // operand, but not necessarily. A FrameIndex for example could resolve to an
667 // inline immediate value that will not require an additional 4-bytes; this
668 // assumes that it will.
669 bool isLiteralConstantLike(const MachineOperand &MO,
670 const MCOperandInfo &OpInfo) const;
672 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
673 const MachineOperand &MO) const;
675 /// Return true if this 64-bit VALU instruction has a 32-bit encoding.
676 /// This function will return false if you pass it a 32-bit instruction.
677 bool hasVALU32BitEncoding(unsigned Opcode) const;
679 /// Returns true if this operand uses the constant bus.
680 bool usesConstantBus(const MachineRegisterInfo &MRI,
681 const MachineOperand &MO,
682 const MCOperandInfo &OpInfo) const;
684 /// Return true if this instruction has any modifiers.
685 /// e.g. src[012]_mod, omod, clamp.
686 bool hasModifiers(unsigned Opcode) const;
688 bool hasModifiersSet(const MachineInstr &MI,
689 unsigned OpName) const;
690 bool hasAnyModifiersSet(const MachineInstr &MI) const;
692 bool verifyInstruction(const MachineInstr &MI,
693 StringRef &ErrInfo) const override;
695 unsigned getVALUOp(const MachineInstr &MI) const;
697 /// Return the correct register class for \p OpNo. For target-specific
698 /// instructions, this will return the register class that has been defined
699 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
700 /// the register class of its machine operand.
701 /// to infer the correct register class base on the other operands.
702 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
703 unsigned OpNo) const;
705 /// Return the size in bytes of the operand OpNo on the given
706 // instruction opcode.
707 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
708 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
710 if (OpInfo.RegClass == -1) {
711 // If this is an immediate operand, this must be a 32-bit literal.
712 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
716 return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
719 /// This form should usually be preferred since it handles operands
720 /// with unknown register classes.
721 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
722 return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
725 /// \returns true if it is legal for the operand at index \p OpNo
727 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
729 /// Legalize the \p OpIndex operand of this instruction by inserting
730 /// a MOV. For example:
731 /// ADD_I32_e32 VGPR0, 15
734 /// ADD_I32_e32 VGPR0, VGPR1
736 /// If the operand being legalized is a register, then a COPY will be used
738 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
740 /// Check if \p MO is a legal operand if it was the \p OpIdx Operand
742 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
743 const MachineOperand *MO = nullptr) const;
745 /// Check if \p MO would be a valid operand for the given operand
746 /// definition \p OpInfo. Note this does not attempt to validate constant bus
747 /// restrictions (e.g. literal constant usage).
748 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
749 const MCOperandInfo &OpInfo,
750 const MachineOperand &MO) const;
752 /// Check if \p MO (a register operand) is a legal register for the
753 /// given operand description.
754 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
755 const MCOperandInfo &OpInfo,
756 const MachineOperand &MO) const;
758 /// Legalize operands in \p MI by either commuting it or inserting a
760 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
762 /// Fix operands in \p MI to satisfy constant bus requirements.
763 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
765 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
766 /// be used when it is know that the value in SrcReg is same across all
767 /// threads in the wave.
768 /// \returns The SGPR register that \p SrcReg was copied to.
769 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
770 MachineRegisterInfo &MRI) const;
772 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
774 void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
775 MachineBasicBlock::iterator I,
776 const TargetRegisterClass *DstRC,
777 MachineOperand &Op, MachineRegisterInfo &MRI,
778 const DebugLoc &DL) const;
780 /// Legalize all operands in this instruction. This function may
781 /// create new instruction and insert them before \p MI.
782 void legalizeOperands(MachineInstr &MI) const;
784 /// Replace this instruction's opcode with the equivalent VALU
785 /// opcode. This function will also move the users of \p MI to the
786 /// VALU if necessary.
787 void moveToVALU(MachineInstr &MI) const;
789 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
792 void insertNoop(MachineBasicBlock &MBB,
793 MachineBasicBlock::iterator MI) const override;
795 void insertReturn(MachineBasicBlock &MBB) const;
796 /// Return the number of wait states that result from executing this
798 unsigned getNumWaitStates(const MachineInstr &MI) const;
800 /// Returns the operand named \p Op. If \p MI does not have an
801 /// operand named \c Op, this function returns nullptr.
803 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
806 const MachineOperand *getNamedOperand(const MachineInstr &MI,
807 unsigned OpName) const {
808 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
811 /// Get required immediate operand
812 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
813 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
814 return MI.getOperand(Idx).getImm();
817 uint64_t getDefaultRsrcDataFormat() const;
818 uint64_t getScratchRsrcWords23() const;
820 bool isLowLatencyInstruction(const MachineInstr &MI) const;
821 bool isHighLatencyInstruction(const MachineInstr &MI) const;
823 /// Return the descriptor of the target-specific machine instruction
824 /// that corresponds to the specified pseudo or native opcode.
825 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
826 return get(pseudoToMCOpcode(Opcode));
829 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
830 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
832 unsigned isLoadFromStackSlot(const MachineInstr &MI,
833 int &FrameIndex) const override;
834 unsigned isStoreToStackSlot(const MachineInstr &MI,
835 int &FrameIndex) const override;
837 unsigned getInstBundleSize(const MachineInstr &MI) const;
838 unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
840 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
842 bool isNonUniformBranchInstr(MachineInstr &Instr) const;
844 void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
845 MachineBasicBlock *IfEnd) const;
847 void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
848 MachineBasicBlock *LoopEnd) const;
850 std::pair<unsigned, unsigned>
851 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
853 ArrayRef<std::pair<int, const char *>>
854 getSerializableTargetIndices() const override;
856 ArrayRef<std::pair<unsigned, const char *>>
857 getSerializableDirectMachineOperandTargetFlags() const override;
859 ScheduleHazardRecognizer *
860 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
861 const ScheduleDAG *DAG) const override;
863 ScheduleHazardRecognizer *
864 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
866 bool isBasicBlockPrologue(const MachineInstr &MI) const override;
868 /// Return a partially built integer add instruction without carry.
869 /// Caller must add source operands.
870 /// For pre-GFX9 it will generate unused carry destination operand.
871 /// TODO: After GFX9 it should return a no-carry operation.
872 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
873 MachineBasicBlock::iterator I,
875 unsigned DestReg) const;
877 static bool isKillTerminator(unsigned Opcode);
878 const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
880 static bool isLegalMUBUFImmOffset(unsigned Imm) {
881 return isUInt<12>(Imm);
884 /// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
885 /// Return -1 if the target-specific opcode for the pseudo instruction does
886 /// not exist. If Opcode is not a pseudo instruction, this is identity.
887 int pseudoToMCOpcode(int Opcode) const;
894 int getVOPe64(uint16_t Opcode);
897 int getVOPe32(uint16_t Opcode);
900 int getSDWAOp(uint16_t Opcode);
903 int getBasicFromSDWAOp(uint16_t Opcode);
906 int getCommuteRev(uint16_t Opcode);
909 int getCommuteOrig(uint16_t Opcode);
912 int getAddr64Inst(uint16_t Opcode);
915 int getMUBUFNoLdsInst(uint16_t Opcode);
918 int getAtomicRetOp(uint16_t Opcode);
921 int getAtomicNoRetOp(uint16_t Opcode);
924 int getSOPKOp(uint16_t Opcode);
926 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
927 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
928 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
929 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
931 // For MachineOperands.
933 TF_LONG_BRANCH_FORWARD = 1 << 0,
934 TF_LONG_BRANCH_BACKWARD = 1 << 1
937 } // end namespace AMDGPU
940 namespace KernelInputOffsets {
942 /// Offsets in bytes from the start of the input buffer
955 } // end namespace KernelInputOffsets
956 } // end namespace SI
958 } // end namespace llvm
960 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H