1 //===- SIInstrInfo.h - SI Instruction Info Interface ------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief Interface definition for SIInstrInfo.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
16 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
17 
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"
31 #include <cassert>
32 #include <cstdint>
33 
34 namespace llvm {
35 
36 class APInt;
37 class MachineRegisterInfo;
38 class RegScavenger;
39 class SISubtarget;
40 class TargetRegisterClass;
41 
42 class SIInstrInfo final : public AMDGPUInstrInfo {
43 private:
44   const SIRegisterInfo RI;
45   const SISubtarget &ST;
46 
47   // The the inverse predicate should have the negative value.
48   enum BranchPredicate {
49     INVALID_BR = 0,
50     SCC_TRUE = 1,
51     SCC_FALSE = -1,
52     VCCNZ = 2,
53     VCCZ = -2,
54     EXECNZ = -3,
55     EXECZ = 3
56   };
57 
58   using SetVectorType = SmallSetVector<MachineInstr *, 32>;
59 
60   static unsigned getBranchOpcode(BranchPredicate Cond);
61   static BranchPredicate getBranchPredicate(unsigned Opcode);
62 
63   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
64                               MachineRegisterInfo &MRI,
65                               MachineOperand &SuperReg,
66                               const TargetRegisterClass *SuperRC,
67                               unsigned SubIdx,
68                               const TargetRegisterClass *SubRC) const;
69   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
70                                          MachineRegisterInfo &MRI,
71                                          MachineOperand &SuperReg,
72                                          const TargetRegisterClass *SuperRC,
73                                          unsigned SubIdx,
74                                          const TargetRegisterClass *SubRC) const;
75 
76   void swapOperands(MachineInstr &Inst) const;
77 
78   void lowerScalarAbs(SetVectorType &Worklist,
79                       MachineInstr &Inst) const;
80 
81   void lowerScalarXnor(SetVectorType &Worklist,
82                        MachineInstr &Inst) const;
83 
84   void splitScalar64BitUnaryOp(SetVectorType &Worklist,
85                                MachineInstr &Inst, unsigned Opcode) const;
86 
87   void splitScalar64BitBinaryOp(SetVectorType &Worklist,
88                                 MachineInstr &Inst, unsigned Opcode) const;
89 
90   void splitScalar64BitBCNT(SetVectorType &Worklist,
91                             MachineInstr &Inst) const;
92   void splitScalar64BitBFE(SetVectorType &Worklist,
93                            MachineInstr &Inst) const;
94   void movePackToVALU(SetVectorType &Worklist,
95                       MachineRegisterInfo &MRI,
96                       MachineInstr &Inst) const;
97 
98   void addUsersToMoveToVALUWorklist(unsigned Reg, MachineRegisterInfo &MRI,
99                                     SetVectorType &Worklist) const;
100 
101   void
102   addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
103                                SetVectorType &Worklist) const;
104 
105   const TargetRegisterClass *
106   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
107 
108   bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
109 
110   unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
111 
112 protected:
113   bool swapSourceModifiers(MachineInstr &MI,
114                            MachineOperand &Src0, unsigned Src0OpName,
115                            MachineOperand &Src1, unsigned Src1OpName) const;
116 
117   MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
118                                        unsigned OpIdx0,
119                                        unsigned OpIdx1) const override;
120 
121 public:
122   enum TargetOperandFlags {
123     MO_MASK = 0x7,
124 
125     MO_NONE = 0,
126     // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
127     MO_GOTPCREL = 1,
128     // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
129     MO_GOTPCREL32 = 2,
130     MO_GOTPCREL32_LO = 2,
131     // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
132     MO_GOTPCREL32_HI = 3,
133     // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
134     MO_REL32 = 4,
135     MO_REL32_LO = 4,
136     // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
137     MO_REL32_HI = 5
138   };
139 
140   explicit SIInstrInfo(const SISubtarget &ST);
141 
142   const SIRegisterInfo &getRegisterInfo() const {
143     return RI;
144   }
145 
146   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
147                                          AliasAnalysis *AA) const override;
148 
149   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
150                                int64_t &Offset1,
151                                int64_t &Offset2) const override;
152 
153   bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
154                              int64_t &Offset,
155                              const TargetRegisterInfo *TRI) const final;
156 
157   bool shouldClusterMemOps(MachineInstr &FirstLdSt, unsigned BaseReg1,
158                            MachineInstr &SecondLdSt, unsigned BaseReg2,
159                            unsigned NumLoads) const final;
160 
161   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
162                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
163                    bool KillSrc) const override;
164 
165   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
166                                     RegScavenger *RS, unsigned TmpReg,
167                                     unsigned Offset, unsigned Size) const;
168 
169   void materializeImmediate(MachineBasicBlock &MBB,
170                             MachineBasicBlock::iterator MI,
171                             const DebugLoc &DL,
172                             unsigned DestReg,
173                             int64_t Value) const;
174 
175   const TargetRegisterClass *getPreferredSelectRegClass(
176                                unsigned Size) const;
177 
178   unsigned insertNE(MachineBasicBlock *MBB,
179                     MachineBasicBlock::iterator I, const DebugLoc &DL,
180                     unsigned SrcReg, int Value) const;
181 
182   unsigned insertEQ(MachineBasicBlock *MBB,
183                     MachineBasicBlock::iterator I, const DebugLoc &DL,
184                     unsigned SrcReg, int Value)  const;
185 
186   void storeRegToStackSlot(MachineBasicBlock &MBB,
187                            MachineBasicBlock::iterator MI, unsigned SrcReg,
188                            bool isKill, int FrameIndex,
189                            const TargetRegisterClass *RC,
190                            const TargetRegisterInfo *TRI) const override;
191 
192   void loadRegFromStackSlot(MachineBasicBlock &MBB,
193                             MachineBasicBlock::iterator MI, unsigned DestReg,
194                             int FrameIndex, const TargetRegisterClass *RC,
195                             const TargetRegisterInfo *TRI) const override;
196 
197   bool expandPostRAPseudo(MachineInstr &MI) const override;
198 
199   // \brief Returns an opcode that can be used to move a value to a \p DstRC
200   // register.  If there is no hardware instruction that can store to \p
201   // DstRC, then AMDGPU::COPY is returned.
202   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
203 
204   LLVM_READONLY
205   int commuteOpcode(unsigned Opc) const;
206 
207   LLVM_READONLY
208   inline int commuteOpcode(const MachineInstr &MI) const {
209     return commuteOpcode(MI.getOpcode());
210   }
211 
212   bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
213                              unsigned &SrcOpIdx2) const override;
214 
215   bool isBranchOffsetInRange(unsigned BranchOpc,
216                              int64_t BrOffset) const override;
217 
218   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
219 
220   unsigned insertIndirectBranch(MachineBasicBlock &MBB,
221                                 MachineBasicBlock &NewDestBB,
222                                 const DebugLoc &DL,
223                                 int64_t BrOffset,
224                                 RegScavenger *RS = nullptr) const override;
225 
226   bool analyzeBranchImpl(MachineBasicBlock &MBB,
227                          MachineBasicBlock::iterator I,
228                          MachineBasicBlock *&TBB,
229                          MachineBasicBlock *&FBB,
230                          SmallVectorImpl<MachineOperand> &Cond,
231                          bool AllowModify) const;
232 
233   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
234                      MachineBasicBlock *&FBB,
235                      SmallVectorImpl<MachineOperand> &Cond,
236                      bool AllowModify = false) const override;
237 
238   unsigned removeBranch(MachineBasicBlock &MBB,
239                         int *BytesRemoved = nullptr) const override;
240 
241   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
242                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
243                         const DebugLoc &DL,
244                         int *BytesAdded = nullptr) const override;
245 
246   bool reverseBranchCondition(
247     SmallVectorImpl<MachineOperand> &Cond) const override;
248 
249   bool canInsertSelect(const MachineBasicBlock &MBB,
250                        ArrayRef<MachineOperand> Cond,
251                        unsigned TrueReg, unsigned FalseReg,
252                        int &CondCycles,
253                        int &TrueCycles, int &FalseCycles) const override;
254 
255   void insertSelect(MachineBasicBlock &MBB,
256                     MachineBasicBlock::iterator I, const DebugLoc &DL,
257                     unsigned DstReg, ArrayRef<MachineOperand> Cond,
258                     unsigned TrueReg, unsigned FalseReg) const override;
259 
260   void insertVectorSelect(MachineBasicBlock &MBB,
261                           MachineBasicBlock::iterator I, const DebugLoc &DL,
262                           unsigned DstReg, ArrayRef<MachineOperand> Cond,
263                           unsigned TrueReg, unsigned FalseReg) const;
264 
265   unsigned getAddressSpaceForPseudoSourceKind(
266              PseudoSourceValue::PSVKind Kind) const override;
267 
268   bool
269   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
270                                   AliasAnalysis *AA = nullptr) const override;
271 
272   bool isFoldableCopy(const MachineInstr &MI) const;
273 
274   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
275                      MachineRegisterInfo *MRI) const final;
276 
277   unsigned getMachineCSELookAheadLimit() const override { return 500; }
278 
279   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
280                                       MachineInstr &MI,
281                                       LiveVariables *LV) const override;
282 
283   bool isSchedulingBoundary(const MachineInstr &MI,
284                             const MachineBasicBlock *MBB,
285                             const MachineFunction &MF) const override;
286 
287   static bool isSALU(const MachineInstr &MI) {
288     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
289   }
290 
291   bool isSALU(uint16_t Opcode) const {
292     return get(Opcode).TSFlags & SIInstrFlags::SALU;
293   }
294 
295   static bool isVALU(const MachineInstr &MI) {
296     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
297   }
298 
299   bool isVALU(uint16_t Opcode) const {
300     return get(Opcode).TSFlags & SIInstrFlags::VALU;
301   }
302 
303   static bool isVMEM(const MachineInstr &MI) {
304     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
305   }
306 
307   bool isVMEM(uint16_t Opcode) const {
308     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
309   }
310 
311   static bool isSOP1(const MachineInstr &MI) {
312     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
313   }
314 
315   bool isSOP1(uint16_t Opcode) const {
316     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
317   }
318 
319   static bool isSOP2(const MachineInstr &MI) {
320     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
321   }
322 
323   bool isSOP2(uint16_t Opcode) const {
324     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
325   }
326 
327   static bool isSOPC(const MachineInstr &MI) {
328     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
329   }
330 
331   bool isSOPC(uint16_t Opcode) const {
332     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
333   }
334 
335   static bool isSOPK(const MachineInstr &MI) {
336     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
337   }
338 
339   bool isSOPK(uint16_t Opcode) const {
340     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
341   }
342 
343   static bool isSOPP(const MachineInstr &MI) {
344     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
345   }
346 
347   bool isSOPP(uint16_t Opcode) const {
348     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
349   }
350 
351   static bool isVOP1(const MachineInstr &MI) {
352     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
353   }
354 
355   bool isVOP1(uint16_t Opcode) const {
356     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
357   }
358 
359   static bool isVOP2(const MachineInstr &MI) {
360     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
361   }
362 
363   bool isVOP2(uint16_t Opcode) const {
364     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
365   }
366 
367   static bool isVOP3(const MachineInstr &MI) {
368     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
369   }
370 
371   bool isVOP3(uint16_t Opcode) const {
372     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
373   }
374 
375   static bool isSDWA(const MachineInstr &MI) {
376     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
377   }
378 
379   bool isSDWA(uint16_t Opcode) const {
380     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
381   }
382 
383   static bool isVOPC(const MachineInstr &MI) {
384     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
385   }
386 
387   bool isVOPC(uint16_t Opcode) const {
388     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
389   }
390 
391   static bool isMUBUF(const MachineInstr &MI) {
392     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
393   }
394 
395   bool isMUBUF(uint16_t Opcode) const {
396     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
397   }
398 
399   static bool isMTBUF(const MachineInstr &MI) {
400     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
401   }
402 
403   bool isMTBUF(uint16_t Opcode) const {
404     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
405   }
406 
407   static bool isSMRD(const MachineInstr &MI) {
408     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
409   }
410 
411   bool isSMRD(uint16_t Opcode) const {
412     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
413   }
414 
415   static bool isDS(const MachineInstr &MI) {
416     return MI.getDesc().TSFlags & SIInstrFlags::DS;
417   }
418 
419   bool isDS(uint16_t Opcode) const {
420     return get(Opcode).TSFlags & SIInstrFlags::DS;
421   }
422 
423   static bool isMIMG(const MachineInstr &MI) {
424     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
425   }
426 
427   bool isMIMG(uint16_t Opcode) const {
428     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
429   }
430 
431   static bool isGather4(const MachineInstr &MI) {
432     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
433   }
434 
435   bool isGather4(uint16_t Opcode) const {
436     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
437   }
438 
439   static bool isFLAT(const MachineInstr &MI) {
440     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
441   }
442 
443   // Is a FLAT encoded instruction which accesses a specific segment,
444   // i.e. global_* or scratch_*.
445   static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
446     auto Flags = MI.getDesc().TSFlags;
447     return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
448   }
449 
450   // Any FLAT encoded instruction, including global_* and scratch_*.
451   bool isFLAT(uint16_t Opcode) const {
452     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
453   }
454 
455   static bool isEXP(const MachineInstr &MI) {
456     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
457   }
458 
459   bool isEXP(uint16_t Opcode) const {
460     return get(Opcode).TSFlags & SIInstrFlags::EXP;
461   }
462 
463   static bool isWQM(const MachineInstr &MI) {
464     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
465   }
466 
467   bool isWQM(uint16_t Opcode) const {
468     return get(Opcode).TSFlags & SIInstrFlags::WQM;
469   }
470 
471   static bool isDisableWQM(const MachineInstr &MI) {
472     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
473   }
474 
475   bool isDisableWQM(uint16_t Opcode) const {
476     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
477   }
478 
479   static bool isVGPRSpill(const MachineInstr &MI) {
480     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
481   }
482 
483   bool isVGPRSpill(uint16_t Opcode) const {
484     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
485   }
486 
487   static bool isSGPRSpill(const MachineInstr &MI) {
488     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
489   }
490 
491   bool isSGPRSpill(uint16_t Opcode) const {
492     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
493   }
494 
495   static bool isDPP(const MachineInstr &MI) {
496     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
497   }
498 
499   bool isDPP(uint16_t Opcode) const {
500     return get(Opcode).TSFlags & SIInstrFlags::DPP;
501   }
502 
503   static bool isVOP3P(const MachineInstr &MI) {
504     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
505   }
506 
507   bool isVOP3P(uint16_t Opcode) const {
508     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
509   }
510 
511   static bool isVINTRP(const MachineInstr &MI) {
512     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
513   }
514 
515   bool isVINTRP(uint16_t Opcode) const {
516     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
517   }
518 
519   static bool isScalarUnit(const MachineInstr &MI) {
520     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
521   }
522 
523   static bool usesVM_CNT(const MachineInstr &MI) {
524     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
525   }
526 
527   static bool usesLGKM_CNT(const MachineInstr &MI) {
528     return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
529   }
530 
531   static bool sopkIsZext(const MachineInstr &MI) {
532     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
533   }
534 
535   bool sopkIsZext(uint16_t Opcode) const {
536     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
537   }
538 
539   /// \returns true if this is an s_store_dword* instruction. This is more
540   /// specific than than isSMEM && mayStore.
541   static bool isScalarStore(const MachineInstr &MI) {
542     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
543   }
544 
545   bool isScalarStore(uint16_t Opcode) const {
546     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
547   }
548 
549   static bool isFixedSize(const MachineInstr &MI) {
550     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
551   }
552 
553   bool isFixedSize(uint16_t Opcode) const {
554     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
555   }
556 
557   static bool hasFPClamp(const MachineInstr &MI) {
558     return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
559   }
560 
561   bool hasFPClamp(uint16_t Opcode) const {
562     return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
563   }
564 
565   static bool hasIntClamp(const MachineInstr &MI) {
566     return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
567   }
568 
569   uint64_t getClampMask(const MachineInstr &MI) const {
570     const uint64_t ClampFlags = SIInstrFlags::FPClamp |
571                                 SIInstrFlags::IntClamp |
572                                 SIInstrFlags::ClampLo |
573                                 SIInstrFlags::ClampHi;
574       return MI.getDesc().TSFlags & ClampFlags;
575   }
576 
577   bool isVGPRCopy(const MachineInstr &MI) const {
578     assert(MI.isCopy());
579     unsigned Dest = MI.getOperand(0).getReg();
580     const MachineFunction &MF = *MI.getParent()->getParent();
581     const MachineRegisterInfo &MRI = MF.getRegInfo();
582     return !RI.isSGPRReg(MRI, Dest);
583   }
584 
585   bool isInlineConstant(const APInt &Imm) const;
586 
587   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
588 
589   bool isInlineConstant(const MachineOperand &MO,
590                         const MCOperandInfo &OpInfo) const {
591     return isInlineConstant(MO, OpInfo.OperandType);
592   }
593 
594   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
595   /// be an inline immediate.
596   bool isInlineConstant(const MachineInstr &MI,
597                         const MachineOperand &UseMO,
598                         const MachineOperand &DefMO) const {
599     assert(UseMO.getParent() == &MI);
600     int OpIdx = MI.getOperandNo(&UseMO);
601     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
602       return false;
603     }
604 
605     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
606   }
607 
608   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
609   /// immediate.
610   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
611     const MachineOperand &MO = MI.getOperand(OpIdx);
612     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
613   }
614 
615   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
616                         const MachineOperand &MO) const {
617     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
618       return false;
619 
620     if (MI.isCopy()) {
621       unsigned Size = getOpSize(MI, OpIdx);
622       assert(Size == 8 || Size == 4);
623 
624       uint8_t OpType = (Size == 8) ?
625         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
626       return isInlineConstant(MO, OpType);
627     }
628 
629     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
630   }
631 
632   bool isInlineConstant(const MachineOperand &MO) const {
633     const MachineInstr *Parent = MO.getParent();
634     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
635   }
636 
637   bool isLiteralConstant(const MachineOperand &MO,
638                          const MCOperandInfo &OpInfo) const {
639     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
640   }
641 
642   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
643     const MachineOperand &MO = MI.getOperand(OpIdx);
644     return MO.isImm() && !isInlineConstant(MI, OpIdx);
645   }
646 
647   // Returns true if this operand could potentially require a 32-bit literal
648   // operand, but not necessarily. A FrameIndex for example could resolve to an
649   // inline immediate value that will not require an additional 4-bytes; this
650   // assumes that it will.
651   bool isLiteralConstantLike(const MachineOperand &MO,
652                              const MCOperandInfo &OpInfo) const;
653 
654   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
655                          const MachineOperand &MO) const;
656 
657   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
658   /// This function will return false if you pass it a 32-bit instruction.
659   bool hasVALU32BitEncoding(unsigned Opcode) const;
660 
661   /// \brief Returns true if this operand uses the constant bus.
662   bool usesConstantBus(const MachineRegisterInfo &MRI,
663                        const MachineOperand &MO,
664                        const MCOperandInfo &OpInfo) const;
665 
666   /// \brief Return true if this instruction has any modifiers.
667   ///  e.g. src[012]_mod, omod, clamp.
668   bool hasModifiers(unsigned Opcode) const;
669 
670   bool hasModifiersSet(const MachineInstr &MI,
671                        unsigned OpName) const;
672   bool hasAnyModifiersSet(const MachineInstr &MI) const;
673 
674   bool verifyInstruction(const MachineInstr &MI,
675                          StringRef &ErrInfo) const override;
676 
677   static unsigned getVALUOp(const MachineInstr &MI);
678 
679   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
680 
681   /// \brief Return the correct register class for \p OpNo.  For target-specific
682   /// instructions, this will return the register class that has been defined
683   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
684   /// the register class of its machine operand.
685   /// to infer the correct register class base on the other operands.
686   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
687                                            unsigned OpNo) const;
688 
689   /// \brief Return the size in bytes of the operand OpNo on the given
690   // instruction opcode.
691   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
692     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
693 
694     if (OpInfo.RegClass == -1) {
695       // If this is an immediate operand, this must be a 32-bit literal.
696       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
697       return 4;
698     }
699 
700     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
701   }
702 
703   /// \brief This form should usually be preferred since it handles operands
704   /// with unknown register classes.
705   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
706     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
707   }
708 
709   /// \returns true if it is legal for the operand at index \p OpNo
710   /// to read a VGPR.
711   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
712 
713   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
714   /// a MOV.  For example:
715   /// ADD_I32_e32 VGPR0, 15
716   /// to
717   /// MOV VGPR1, 15
718   /// ADD_I32_e32 VGPR0, VGPR1
719   ///
720   /// If the operand being legalized is a register, then a COPY will be used
721   /// instead of MOV.
722   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
723 
724   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
725   /// for \p MI.
726   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
727                       const MachineOperand *MO = nullptr) const;
728 
729   /// \brief Check if \p MO would be a valid operand for the given operand
730   /// definition \p OpInfo. Note this does not attempt to validate constant bus
731   /// restrictions (e.g. literal constant usage).
732   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
733                           const MCOperandInfo &OpInfo,
734                           const MachineOperand &MO) const;
735 
736   /// \brief Check if \p MO (a register operand) is a legal register for the
737   /// given operand description.
738   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
739                          const MCOperandInfo &OpInfo,
740                          const MachineOperand &MO) const;
741 
742   /// \brief Legalize operands in \p MI by either commuting it or inserting a
743   /// copy of src1.
744   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
745 
746   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
747   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
748 
749   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
750   /// be used when it is know that the value in SrcReg is same across all
751   /// threads in the wave.
752   /// \returns The SGPR register that \p SrcReg was copied to.
753   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
754                               MachineRegisterInfo &MRI) const;
755 
756   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
757 
758   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
759                               MachineBasicBlock::iterator I,
760                               const TargetRegisterClass *DstRC,
761                               MachineOperand &Op, MachineRegisterInfo &MRI,
762                               const DebugLoc &DL) const;
763 
764   /// \brief Legalize all operands in this instruction.  This function may
765   /// create new instruction and insert them before \p MI.
766   void legalizeOperands(MachineInstr &MI) const;
767 
768   /// \brief Replace this instruction's opcode with the equivalent VALU
769   /// opcode.  This function will also move the users of \p MI to the
770   /// VALU if necessary.
771   void moveToVALU(MachineInstr &MI) const;
772 
773   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
774                         int Count) const;
775 
776   void insertNoop(MachineBasicBlock &MBB,
777                   MachineBasicBlock::iterator MI) const override;
778 
779   void insertReturn(MachineBasicBlock &MBB) const;
780   /// \brief Return the number of wait states that result from executing this
781   /// instruction.
782   unsigned getNumWaitStates(const MachineInstr &MI) const;
783 
784   /// \brief Returns the operand named \p Op.  If \p MI does not have an
785   /// operand named \c Op, this function returns nullptr.
786   LLVM_READONLY
787   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
788 
789   LLVM_READONLY
790   const MachineOperand *getNamedOperand(const MachineInstr &MI,
791                                         unsigned OpName) const {
792     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
793   }
794 
795   /// Get required immediate operand
796   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
797     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
798     return MI.getOperand(Idx).getImm();
799   }
800 
801   uint64_t getDefaultRsrcDataFormat() const;
802   uint64_t getScratchRsrcWords23() const;
803 
804   bool isLowLatencyInstruction(const MachineInstr &MI) const;
805   bool isHighLatencyInstruction(const MachineInstr &MI) const;
806 
807   /// \brief Return the descriptor of the target-specific machine instruction
808   /// that corresponds to the specified pseudo or native opcode.
809   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
810     return get(pseudoToMCOpcode(Opcode));
811   }
812 
813   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
814   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
815 
816   unsigned isLoadFromStackSlot(const MachineInstr &MI,
817                                int &FrameIndex) const override;
818   unsigned isStoreToStackSlot(const MachineInstr &MI,
819                               int &FrameIndex) const override;
820 
821   unsigned getInstBundleSize(const MachineInstr &MI) const;
822   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
823 
824   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
825 
826   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
827 
828   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
829                                  MachineBasicBlock *IfEnd) const;
830 
831   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
832                                    MachineBasicBlock *LoopEnd) const;
833 
834   std::pair<unsigned, unsigned>
835   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
836 
837   ArrayRef<std::pair<int, const char *>>
838   getSerializableTargetIndices() const override;
839 
840   ArrayRef<std::pair<unsigned, const char *>>
841   getSerializableDirectMachineOperandTargetFlags() const override;
842 
843   ScheduleHazardRecognizer *
844   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
845                                  const ScheduleDAG *DAG) const override;
846 
847   ScheduleHazardRecognizer *
848   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
849 
850   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
851 
852   /// \brief Return a partially built integer add instruction without carry.
853   /// Caller must add source operands.
854   /// For pre-GFX9 it will generate unused carry destination operand.
855   /// TODO: After GFX9 it should return a no-carry operation.
856   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
857                                     MachineBasicBlock::iterator I,
858                                     const DebugLoc &DL,
859                                     unsigned DestReg) const;
860 
861   static bool isKillTerminator(unsigned Opcode);
862   const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
863 };
864 
865 namespace AMDGPU {
866 
867   LLVM_READONLY
868   int getVOPe64(uint16_t Opcode);
869 
870   LLVM_READONLY
871   int getVOPe32(uint16_t Opcode);
872 
873   LLVM_READONLY
874   int getSDWAOp(uint16_t Opcode);
875 
876   LLVM_READONLY
877   int getBasicFromSDWAOp(uint16_t Opcode);
878 
879   LLVM_READONLY
880   int getCommuteRev(uint16_t Opcode);
881 
882   LLVM_READONLY
883   int getCommuteOrig(uint16_t Opcode);
884 
885   LLVM_READONLY
886   int getAddr64Inst(uint16_t Opcode);
887 
888   LLVM_READONLY
889   int getAtomicRetOp(uint16_t Opcode);
890 
891   LLVM_READONLY
892   int getAtomicNoRetOp(uint16_t Opcode);
893 
894   LLVM_READONLY
895   int getSOPKOp(uint16_t Opcode);
896 
897   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
898   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
899   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
900   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
901 
902   // For MachineOperands.
903   enum TargetFlags {
904     TF_LONG_BRANCH_FORWARD = 1 << 0,
905     TF_LONG_BRANCH_BACKWARD = 1 << 1
906   };
907 
908 } // end namespace AMDGPU
909 
910 namespace SI {
911 namespace KernelInputOffsets {
912 
913 /// Offsets in bytes from the start of the input buffer
914 enum Offsets {
915   NGROUPS_X = 0,
916   NGROUPS_Y = 4,
917   NGROUPS_Z = 8,
918   GLOBAL_SIZE_X = 12,
919   GLOBAL_SIZE_Y = 16,
920   GLOBAL_SIZE_Z = 20,
921   LOCAL_SIZE_X = 24,
922   LOCAL_SIZE_Y = 28,
923   LOCAL_SIZE_Z = 32
924 };
925 
926 } // end namespace KernelInputOffsets
927 } // end namespace SI
928 
929 } // end namespace llvm
930 
931 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
932