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   static bool usesFPDPRounding(const MachineInstr &MI) {
608     return MI.getDesc().TSFlags & SIInstrFlags::FPDPRounding;
609   }
610 
611   bool usesFPDPRounding(uint16_t Opcode) const {
612     return get(Opcode).TSFlags & SIInstrFlags::FPDPRounding;
613   }
614 
615   bool isVGPRCopy(const MachineInstr &MI) const {
616     assert(MI.isCopy());
617     unsigned Dest = MI.getOperand(0).getReg();
618     const MachineFunction &MF = *MI.getParent()->getParent();
619     const MachineRegisterInfo &MRI = MF.getRegInfo();
620     return !RI.isSGPRReg(MRI, Dest);
621   }
622 
623   /// Whether we must prevent this instruction from executing with EXEC = 0.
624   bool hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const;
625 
626   bool isInlineConstant(const APInt &Imm) const;
627 
628   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
629 
630   bool isInlineConstant(const MachineOperand &MO,
631                         const MCOperandInfo &OpInfo) const {
632     return isInlineConstant(MO, OpInfo.OperandType);
633   }
634 
635   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
636   /// be an inline immediate.
637   bool isInlineConstant(const MachineInstr &MI,
638                         const MachineOperand &UseMO,
639                         const MachineOperand &DefMO) const {
640     assert(UseMO.getParent() == &MI);
641     int OpIdx = MI.getOperandNo(&UseMO);
642     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
643       return false;
644     }
645 
646     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
647   }
648 
649   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
650   /// immediate.
651   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
652     const MachineOperand &MO = MI.getOperand(OpIdx);
653     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
654   }
655 
656   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
657                         const MachineOperand &MO) const {
658     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
659       return false;
660 
661     if (MI.isCopy()) {
662       unsigned Size = getOpSize(MI, OpIdx);
663       assert(Size == 8 || Size == 4);
664 
665       uint8_t OpType = (Size == 8) ?
666         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
667       return isInlineConstant(MO, OpType);
668     }
669 
670     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
671   }
672 
673   bool isInlineConstant(const MachineOperand &MO) const {
674     const MachineInstr *Parent = MO.getParent();
675     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
676   }
677 
678   bool isLiteralConstant(const MachineOperand &MO,
679                          const MCOperandInfo &OpInfo) const {
680     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
681   }
682 
683   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
684     const MachineOperand &MO = MI.getOperand(OpIdx);
685     return MO.isImm() && !isInlineConstant(MI, OpIdx);
686   }
687 
688   // Returns true if this operand could potentially require a 32-bit literal
689   // operand, but not necessarily. A FrameIndex for example could resolve to an
690   // inline immediate value that will not require an additional 4-bytes; this
691   // assumes that it will.
692   bool isLiteralConstantLike(const MachineOperand &MO,
693                              const MCOperandInfo &OpInfo) const;
694 
695   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
696                          const MachineOperand &MO) const;
697 
698   /// Return true if this 64-bit VALU instruction has a 32-bit encoding.
699   /// This function will return false if you pass it a 32-bit instruction.
700   bool hasVALU32BitEncoding(unsigned Opcode) const;
701 
702   /// Returns true if this operand uses the constant bus.
703   bool usesConstantBus(const MachineRegisterInfo &MRI,
704                        const MachineOperand &MO,
705                        const MCOperandInfo &OpInfo) const;
706 
707   /// Return true if this instruction has any modifiers.
708   ///  e.g. src[012]_mod, omod, clamp.
709   bool hasModifiers(unsigned Opcode) const;
710 
711   bool hasModifiersSet(const MachineInstr &MI,
712                        unsigned OpName) const;
713   bool hasAnyModifiersSet(const MachineInstr &MI) const;
714 
715   bool canShrink(const MachineInstr &MI,
716                  const MachineRegisterInfo &MRI) const;
717 
718   MachineInstr *buildShrunkInst(MachineInstr &MI,
719                                 unsigned NewOpcode) const;
720 
721   bool verifyInstruction(const MachineInstr &MI,
722                          StringRef &ErrInfo) const override;
723 
724   unsigned getVALUOp(const MachineInstr &MI) const;
725 
726   /// Return the correct register class for \p OpNo.  For target-specific
727   /// instructions, this will return the register class that has been defined
728   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
729   /// the register class of its machine operand.
730   /// to infer the correct register class base on the other operands.
731   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
732                                            unsigned OpNo) const;
733 
734   /// Return the size in bytes of the operand OpNo on the given
735   // instruction opcode.
736   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
737     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
738 
739     if (OpInfo.RegClass == -1) {
740       // If this is an immediate operand, this must be a 32-bit literal.
741       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
742       return 4;
743     }
744 
745     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
746   }
747 
748   /// This form should usually be preferred since it handles operands
749   /// with unknown register classes.
750   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
751     const MachineOperand &MO = MI.getOperand(OpNo);
752     if (MO.isReg()) {
753       if (unsigned SubReg = MO.getSubReg()) {
754         assert(RI.getRegSizeInBits(*RI.getSubClassWithSubReg(
755                                    MI.getParent()->getParent()->getRegInfo().
756                                      getRegClass(MO.getReg()), SubReg)) >= 32 &&
757                "Sub-dword subregs are not supported");
758         return RI.getSubRegIndexLaneMask(SubReg).getNumLanes() * 4;
759       }
760     }
761     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
762   }
763 
764   /// \returns true if it is legal for the operand at index \p OpNo
765   /// to read a VGPR.
766   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
767 
768   /// Legalize the \p OpIndex operand of this instruction by inserting
769   /// a MOV.  For example:
770   /// ADD_I32_e32 VGPR0, 15
771   /// to
772   /// MOV VGPR1, 15
773   /// ADD_I32_e32 VGPR0, VGPR1
774   ///
775   /// If the operand being legalized is a register, then a COPY will be used
776   /// instead of MOV.
777   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
778 
779   /// Check if \p MO is a legal operand if it was the \p OpIdx Operand
780   /// for \p MI.
781   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
782                       const MachineOperand *MO = nullptr) const;
783 
784   /// Check if \p MO would be a valid operand for the given operand
785   /// definition \p OpInfo. Note this does not attempt to validate constant bus
786   /// restrictions (e.g. literal constant usage).
787   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
788                           const MCOperandInfo &OpInfo,
789                           const MachineOperand &MO) const;
790 
791   /// Check if \p MO (a register operand) is a legal register for the
792   /// given operand description.
793   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
794                          const MCOperandInfo &OpInfo,
795                          const MachineOperand &MO) const;
796 
797   /// Legalize operands in \p MI by either commuting it or inserting a
798   /// copy of src1.
799   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
800 
801   /// Fix operands in \p MI to satisfy constant bus requirements.
802   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
803 
804   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
805   /// be used when it is know that the value in SrcReg is same across all
806   /// threads in the wave.
807   /// \returns The SGPR register that \p SrcReg was copied to.
808   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
809                               MachineRegisterInfo &MRI) const;
810 
811   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
812 
813   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
814                               MachineBasicBlock::iterator I,
815                               const TargetRegisterClass *DstRC,
816                               MachineOperand &Op, MachineRegisterInfo &MRI,
817                               const DebugLoc &DL) const;
818 
819   /// Legalize all operands in this instruction.  This function may create new
820   /// instructions and control-flow around \p MI.  If present, \p MDT is
821   /// updated.
822   void legalizeOperands(MachineInstr &MI,
823                         MachineDominatorTree *MDT = nullptr) const;
824 
825   /// Replace this instruction's opcode with the equivalent VALU
826   /// opcode.  This function will also move the users of \p MI to the
827   /// VALU if necessary. If present, \p MDT is updated.
828   void moveToVALU(MachineInstr &MI, MachineDominatorTree *MDT = nullptr) const;
829 
830   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
831                         int Count) const;
832 
833   void insertNoop(MachineBasicBlock &MBB,
834                   MachineBasicBlock::iterator MI) const override;
835 
836   void insertReturn(MachineBasicBlock &MBB) const;
837   /// Return the number of wait states that result from executing this
838   /// instruction.
839   unsigned getNumWaitStates(const MachineInstr &MI) const;
840 
841   /// Returns the operand named \p Op.  If \p MI does not have an
842   /// operand named \c Op, this function returns nullptr.
843   LLVM_READONLY
844   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
845 
846   LLVM_READONLY
847   const MachineOperand *getNamedOperand(const MachineInstr &MI,
848                                         unsigned OpName) const {
849     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
850   }
851 
852   /// Get required immediate operand
853   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
854     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
855     return MI.getOperand(Idx).getImm();
856   }
857 
858   uint64_t getDefaultRsrcDataFormat() const;
859   uint64_t getScratchRsrcWords23() const;
860 
861   bool isLowLatencyInstruction(const MachineInstr &MI) const;
862   bool isHighLatencyInstruction(const MachineInstr &MI) const;
863 
864   /// Return the descriptor of the target-specific machine instruction
865   /// that corresponds to the specified pseudo or native opcode.
866   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
867     return get(pseudoToMCOpcode(Opcode));
868   }
869 
870   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
871   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
872 
873   unsigned isLoadFromStackSlot(const MachineInstr &MI,
874                                int &FrameIndex) const override;
875   unsigned isStoreToStackSlot(const MachineInstr &MI,
876                               int &FrameIndex) const override;
877 
878   unsigned getInstBundleSize(const MachineInstr &MI) const;
879   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
880 
881   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
882 
883   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
884 
885   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
886                                  MachineBasicBlock *IfEnd) const;
887 
888   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
889                                    MachineBasicBlock *LoopEnd) const;
890 
891   std::pair<unsigned, unsigned>
892   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
893 
894   ArrayRef<std::pair<int, const char *>>
895   getSerializableTargetIndices() const override;
896 
897   ArrayRef<std::pair<unsigned, const char *>>
898   getSerializableDirectMachineOperandTargetFlags() const override;
899 
900   ScheduleHazardRecognizer *
901   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
902                                  const ScheduleDAG *DAG) const override;
903 
904   ScheduleHazardRecognizer *
905   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
906 
907   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
908 
909   /// Return a partially built integer add instruction without carry.
910   /// Caller must add source operands.
911   /// For pre-GFX9 it will generate unused carry destination operand.
912   /// TODO: After GFX9 it should return a no-carry operation.
913   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
914                                     MachineBasicBlock::iterator I,
915                                     const DebugLoc &DL,
916                                     unsigned DestReg) const;
917 
918   static bool isKillTerminator(unsigned Opcode);
919   const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
920 
921   static bool isLegalMUBUFImmOffset(unsigned Imm) {
922     return isUInt<12>(Imm);
923   }
924 
925   /// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
926   /// Return -1 if the target-specific opcode for the pseudo instruction does
927   /// not exist. If Opcode is not a pseudo instruction, this is identity.
928   int pseudoToMCOpcode(int Opcode) const;
929 };
930 
931 /// \brief Returns true if a reg:subreg pair P has a TRC class
932 inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P,
933                          const TargetRegisterClass &TRC,
934                          MachineRegisterInfo &MRI) {
935   auto *RC = MRI.getRegClass(P.Reg);
936   if (!P.SubReg)
937     return RC == &TRC;
938   auto *TRI = MRI.getTargetRegisterInfo();
939   return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg);
940 }
941 
942 /// \brief Create RegSubRegPair from a register MachineOperand
943 inline
944 TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O) {
945   assert(O.isReg());
946   return TargetInstrInfo::RegSubRegPair(O.getReg(), O.getSubReg());
947 }
948 
949 /// \brief Return the SubReg component from REG_SEQUENCE
950 TargetInstrInfo::RegSubRegPair getRegSequenceSubReg(MachineInstr &MI,
951                                                     unsigned SubReg);
952 
953 /// \brief Return the defining instruction for a given reg:subreg pair
954 /// skipping copy like instructions and subreg-manipulation pseudos.
955 /// Following another subreg of a reg:subreg isn't supported.
956 MachineInstr *getVRegSubRegDef(const TargetInstrInfo::RegSubRegPair &P,
957                                MachineRegisterInfo &MRI);
958 
959 namespace AMDGPU {
960 
961   LLVM_READONLY
962   int getVOPe64(uint16_t Opcode);
963 
964   LLVM_READONLY
965   int getVOPe32(uint16_t Opcode);
966 
967   LLVM_READONLY
968   int getSDWAOp(uint16_t Opcode);
969 
970   LLVM_READONLY
971   int getDPPOp32(uint16_t Opcode);
972 
973   LLVM_READONLY
974   int getBasicFromSDWAOp(uint16_t Opcode);
975 
976   LLVM_READONLY
977   int getCommuteRev(uint16_t Opcode);
978 
979   LLVM_READONLY
980   int getCommuteOrig(uint16_t Opcode);
981 
982   LLVM_READONLY
983   int getAddr64Inst(uint16_t Opcode);
984 
985   /// Check if \p Opcode is an Addr64 opcode.
986   ///
987   /// \returns \p Opcode if it is an Addr64 opcode, otherwise -1.
988   LLVM_READONLY
989   int getIfAddr64Inst(uint16_t Opcode);
990 
991   LLVM_READONLY
992   int getMUBUFNoLdsInst(uint16_t Opcode);
993 
994   LLVM_READONLY
995   int getAtomicRetOp(uint16_t Opcode);
996 
997   LLVM_READONLY
998   int getAtomicNoRetOp(uint16_t Opcode);
999 
1000   LLVM_READONLY
1001   int getSOPKOp(uint16_t Opcode);
1002 
1003   LLVM_READONLY
1004   int getGlobalSaddrOp(uint16_t Opcode);
1005 
1006   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
1007   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
1008   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
1009   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
1010 
1011   // For MachineOperands.
1012   enum TargetFlags {
1013     TF_LONG_BRANCH_FORWARD = 1 << 0,
1014     TF_LONG_BRANCH_BACKWARD = 1 << 1
1015   };
1016 
1017 } // end namespace AMDGPU
1018 
1019 namespace SI {
1020 namespace KernelInputOffsets {
1021 
1022 /// Offsets in bytes from the start of the input buffer
1023 enum Offsets {
1024   NGROUPS_X = 0,
1025   NGROUPS_Y = 4,
1026   NGROUPS_Z = 8,
1027   GLOBAL_SIZE_X = 12,
1028   GLOBAL_SIZE_Y = 16,
1029   GLOBAL_SIZE_Z = 20,
1030   LOCAL_SIZE_X = 24,
1031   LOCAL_SIZE_Y = 28,
1032   LOCAL_SIZE_Z = 32
1033 };
1034 
1035 } // end namespace KernelInputOffsets
1036 } // end namespace SI
1037 
1038 } // end namespace llvm
1039 
1040 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
1041