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