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