1 //===- SIInstrInfo.h - SI Instruction Info Interface ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Interface definition for SIInstrInfo.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
15 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
16 
17 #include "AMDGPUMIRFormatter.h"
18 #include "SIRegisterInfo.h"
19 #include "Utils/AMDGPUBaseInfo.h"
20 #include "llvm/ADT/SetVector.h"
21 #include "llvm/CodeGen/TargetInstrInfo.h"
22 #include "llvm/CodeGen/TargetSchedule.h"
23 
24 #define GET_INSTRINFO_HEADER
25 #include "AMDGPUGenInstrInfo.inc"
26 
27 namespace llvm {
28 
29 class APInt;
30 class GCNSubtarget;
31 class LiveVariables;
32 class MachineDominatorTree;
33 class MachineRegisterInfo;
34 class RegScavenger;
35 class TargetRegisterClass;
36 class ScheduleHazardRecognizer;
37 
38 class SIInstrInfo final : public AMDGPUGenInstrInfo {
39 private:
40   const SIRegisterInfo RI;
41   const GCNSubtarget &ST;
42   TargetSchedModel SchedModel;
43   mutable std::unique_ptr<AMDGPUMIRFormatter> Formatter;
44 
45   // The inverse predicate should have the negative value.
46   enum BranchPredicate {
47     INVALID_BR = 0,
48     SCC_TRUE = 1,
49     SCC_FALSE = -1,
50     VCCNZ = 2,
51     VCCZ = -2,
52     EXECNZ = -3,
53     EXECZ = 3
54   };
55 
56   using SetVectorType = SmallSetVector<MachineInstr *, 32>;
57 
58   static unsigned getBranchOpcode(BranchPredicate Cond);
59   static BranchPredicate getBranchPredicate(unsigned Opcode);
60 
61 public:
62   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
63                               MachineRegisterInfo &MRI,
64                               MachineOperand &SuperReg,
65                               const TargetRegisterClass *SuperRC,
66                               unsigned SubIdx,
67                               const TargetRegisterClass *SubRC) const;
68   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
69                                          MachineRegisterInfo &MRI,
70                                          MachineOperand &SuperReg,
71                                          const TargetRegisterClass *SuperRC,
72                                          unsigned SubIdx,
73                                          const TargetRegisterClass *SubRC) const;
74 private:
75   void swapOperands(MachineInstr &Inst) const;
76 
77   std::pair<bool, MachineBasicBlock *>
78   moveScalarAddSub(SetVectorType &Worklist, MachineInstr &Inst,
79                    MachineDominatorTree *MDT = nullptr) const;
80 
81   void lowerSelect(SetVectorType &Worklist, MachineInstr &Inst,
82                    MachineDominatorTree *MDT = nullptr) const;
83 
84   void lowerScalarAbs(SetVectorType &Worklist,
85                       MachineInstr &Inst) const;
86 
87   void lowerScalarXnor(SetVectorType &Worklist,
88                        MachineInstr &Inst) const;
89 
90   void splitScalarNotBinop(SetVectorType &Worklist,
91                            MachineInstr &Inst,
92                            unsigned Opcode) const;
93 
94   void splitScalarBinOpN2(SetVectorType &Worklist,
95                           MachineInstr &Inst,
96                           unsigned Opcode) const;
97 
98   void splitScalar64BitUnaryOp(SetVectorType &Worklist,
99                                MachineInstr &Inst, unsigned Opcode,
100                                bool Swap = false) const;
101 
102   void splitScalar64BitAddSub(SetVectorType &Worklist, MachineInstr &Inst,
103                               MachineDominatorTree *MDT = nullptr) const;
104 
105   void splitScalar64BitBinaryOp(SetVectorType &Worklist, MachineInstr &Inst,
106                                 unsigned Opcode,
107                                 MachineDominatorTree *MDT = nullptr) const;
108 
109   void splitScalar64BitXnor(SetVectorType &Worklist, MachineInstr &Inst,
110                                 MachineDominatorTree *MDT = nullptr) const;
111 
112   void splitScalar64BitBCNT(SetVectorType &Worklist,
113                             MachineInstr &Inst) const;
114   void splitScalar64BitBFE(SetVectorType &Worklist,
115                            MachineInstr &Inst) const;
116   void movePackToVALU(SetVectorType &Worklist,
117                       MachineRegisterInfo &MRI,
118                       MachineInstr &Inst) const;
119 
120   void addUsersToMoveToVALUWorklist(Register Reg, MachineRegisterInfo &MRI,
121                                     SetVectorType &Worklist) const;
122 
123   void addSCCDefUsersToVALUWorklist(MachineOperand &Op,
124                                     MachineInstr &SCCDefInst,
125                                     SetVectorType &Worklist) const;
126 
127   const TargetRegisterClass *
128   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
129 
130   bool checkInstOffsetsDoNotOverlap(const MachineInstr &MIa,
131                                     const MachineInstr &MIb) const;
132 
133   Register 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 = 0xf,
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     MO_LONG_BRANCH_FORWARD = 6,
163     MO_LONG_BRANCH_BACKWARD = 7,
164 
165     MO_ABS32_LO = 8,
166     MO_ABS32_HI = 9,
167   };
168 
169   explicit SIInstrInfo(const GCNSubtarget &ST);
170 
171   const SIRegisterInfo &getRegisterInfo() const {
172     return RI;
173   }
174 
175   const GCNSubtarget &getSubtarget() const {
176     return ST;
177   }
178 
179   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
180                                          AAResults *AA) const override;
181 
182   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
183                                int64_t &Offset1,
184                                int64_t &Offset2) const override;
185 
186   bool getMemOperandsWithOffsetWidth(
187       const MachineInstr &LdSt,
188       SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
189       bool &OffsetIsScalable, unsigned &Width,
190       const TargetRegisterInfo *TRI) const final;
191 
192   bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,
193                            ArrayRef<const MachineOperand *> BaseOps2,
194                            unsigned NumLoads, unsigned NumBytes) const override;
195 
196   bool shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1, int64_t Offset0,
197                                int64_t Offset1, unsigned NumLoads) const override;
198 
199   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
200                    const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
201                    bool KillSrc) const override;
202 
203   void materializeImmediate(MachineBasicBlock &MBB,
204                             MachineBasicBlock::iterator MI,
205                             const DebugLoc &DL,
206                             unsigned DestReg,
207                             int64_t Value) const;
208 
209   const TargetRegisterClass *getPreferredSelectRegClass(
210                                unsigned Size) const;
211 
212   Register insertNE(MachineBasicBlock *MBB,
213                     MachineBasicBlock::iterator I, const DebugLoc &DL,
214                     Register SrcReg, int Value) const;
215 
216   Register insertEQ(MachineBasicBlock *MBB,
217                     MachineBasicBlock::iterator I, const DebugLoc &DL,
218                     Register SrcReg, int Value)  const;
219 
220   void storeRegToStackSlot(MachineBasicBlock &MBB,
221                            MachineBasicBlock::iterator MI, Register SrcReg,
222                            bool isKill, int FrameIndex,
223                            const TargetRegisterClass *RC,
224                            const TargetRegisterInfo *TRI) const override;
225 
226   void loadRegFromStackSlot(MachineBasicBlock &MBB,
227                             MachineBasicBlock::iterator MI, Register DestReg,
228                             int FrameIndex, const TargetRegisterClass *RC,
229                             const TargetRegisterInfo *TRI) const override;
230 
231   bool expandPostRAPseudo(MachineInstr &MI) const override;
232 
233   // Splits a V_MOV_B64_DPP_PSEUDO opcode into a pair of v_mov_b32_dpp
234   // instructions. Returns a pair of generated instructions.
235   // Can split either post-RA with physical registers or pre-RA with
236   // virtual registers. In latter case IR needs to be in SSA form and
237   // and a REG_SEQUENCE is produced to define original register.
238   std::pair<MachineInstr*, MachineInstr*>
239   expandMovDPP64(MachineInstr &MI) const;
240 
241   // Returns an opcode that can be used to move a value to a \p DstRC
242   // register.  If there is no hardware instruction that can store to \p
243   // DstRC, then AMDGPU::COPY is returned.
244   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
245 
246   const MCInstrDesc &getIndirectRegWriteMovRelPseudo(unsigned VecSize,
247                                                      unsigned EltSize,
248                                                      bool IsSGPR) const;
249 
250   const MCInstrDesc &getIndirectGPRIDXPseudo(unsigned VecSize,
251                                              bool IsIndirectSrc) const;
252   LLVM_READONLY
253   int commuteOpcode(unsigned Opc) const;
254 
255   LLVM_READONLY
256   inline int commuteOpcode(const MachineInstr &MI) const {
257     return commuteOpcode(MI.getOpcode());
258   }
259 
260   bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1,
261                              unsigned &SrcOpIdx2) const override;
262 
263   bool findCommutedOpIndices(MCInstrDesc Desc, unsigned & SrcOpIdx0,
264    unsigned & SrcOpIdx1) const;
265 
266   bool isBranchOffsetInRange(unsigned BranchOpc,
267                              int64_t BrOffset) const override;
268 
269   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
270 
271   unsigned insertIndirectBranch(MachineBasicBlock &MBB,
272                                 MachineBasicBlock &NewDestBB,
273                                 const DebugLoc &DL,
274                                 int64_t BrOffset,
275                                 RegScavenger *RS = nullptr) const override;
276 
277   bool analyzeBranchImpl(MachineBasicBlock &MBB,
278                          MachineBasicBlock::iterator I,
279                          MachineBasicBlock *&TBB,
280                          MachineBasicBlock *&FBB,
281                          SmallVectorImpl<MachineOperand> &Cond,
282                          bool AllowModify) const;
283 
284   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
285                      MachineBasicBlock *&FBB,
286                      SmallVectorImpl<MachineOperand> &Cond,
287                      bool AllowModify = false) const override;
288 
289   unsigned removeBranch(MachineBasicBlock &MBB,
290                         int *BytesRemoved = nullptr) const override;
291 
292   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
293                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
294                         const DebugLoc &DL,
295                         int *BytesAdded = nullptr) const override;
296 
297   bool reverseBranchCondition(
298     SmallVectorImpl<MachineOperand> &Cond) const override;
299 
300   bool canInsertSelect(const MachineBasicBlock &MBB,
301                        ArrayRef<MachineOperand> Cond, Register DstReg,
302                        Register TrueReg, Register FalseReg, int &CondCycles,
303                        int &TrueCycles, int &FalseCycles) const override;
304 
305   void insertSelect(MachineBasicBlock &MBB,
306                     MachineBasicBlock::iterator I, const DebugLoc &DL,
307                     Register DstReg, ArrayRef<MachineOperand> Cond,
308                     Register TrueReg, Register FalseReg) const override;
309 
310   void insertVectorSelect(MachineBasicBlock &MBB,
311                           MachineBasicBlock::iterator I, const DebugLoc &DL,
312                           Register DstReg, ArrayRef<MachineOperand> Cond,
313                           Register TrueReg, Register FalseReg) const;
314 
315   unsigned getAddressSpaceForPseudoSourceKind(
316              unsigned Kind) const override;
317 
318   bool
319   areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
320                                   const MachineInstr &MIb) const override;
321 
322   bool isFoldableCopy(const MachineInstr &MI) const;
323 
324   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,
325                      MachineRegisterInfo *MRI) const final;
326 
327   unsigned getMachineCSELookAheadLimit() const override { return 500; }
328 
329   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
330                                       MachineInstr &MI,
331                                       LiveVariables *LV) const override;
332 
333   bool isSchedulingBoundary(const MachineInstr &MI,
334                             const MachineBasicBlock *MBB,
335                             const MachineFunction &MF) const override;
336 
337   static bool isSALU(const MachineInstr &MI) {
338     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
339   }
340 
341   bool isSALU(uint16_t Opcode) const {
342     return get(Opcode).TSFlags & SIInstrFlags::SALU;
343   }
344 
345   static bool isVALU(const MachineInstr &MI) {
346     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
347   }
348 
349   bool isVALU(uint16_t Opcode) const {
350     return get(Opcode).TSFlags & SIInstrFlags::VALU;
351   }
352 
353   static bool isVMEM(const MachineInstr &MI) {
354     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
355   }
356 
357   bool isVMEM(uint16_t Opcode) const {
358     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
359   }
360 
361   static bool isSOP1(const MachineInstr &MI) {
362     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
363   }
364 
365   bool isSOP1(uint16_t Opcode) const {
366     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
367   }
368 
369   static bool isSOP2(const MachineInstr &MI) {
370     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
371   }
372 
373   bool isSOP2(uint16_t Opcode) const {
374     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
375   }
376 
377   static bool isSOPC(const MachineInstr &MI) {
378     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
379   }
380 
381   bool isSOPC(uint16_t Opcode) const {
382     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
383   }
384 
385   static bool isSOPK(const MachineInstr &MI) {
386     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
387   }
388 
389   bool isSOPK(uint16_t Opcode) const {
390     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
391   }
392 
393   static bool isSOPP(const MachineInstr &MI) {
394     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
395   }
396 
397   bool isSOPP(uint16_t Opcode) const {
398     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
399   }
400 
401   static bool isPacked(const MachineInstr &MI) {
402     return MI.getDesc().TSFlags & SIInstrFlags::IsPacked;
403   }
404 
405   bool isPacked(uint16_t Opcode) const {
406     return get(Opcode).TSFlags & SIInstrFlags::IsPacked;
407   }
408 
409   static bool isVOP1(const MachineInstr &MI) {
410     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
411   }
412 
413   bool isVOP1(uint16_t Opcode) const {
414     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
415   }
416 
417   static bool isVOP2(const MachineInstr &MI) {
418     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
419   }
420 
421   bool isVOP2(uint16_t Opcode) const {
422     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
423   }
424 
425   static bool isVOP3(const MachineInstr &MI) {
426     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
427   }
428 
429   bool isVOP3(uint16_t Opcode) const {
430     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
431   }
432 
433   static bool isSDWA(const MachineInstr &MI) {
434     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
435   }
436 
437   bool isSDWA(uint16_t Opcode) const {
438     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
439   }
440 
441   static bool isVOPC(const MachineInstr &MI) {
442     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
443   }
444 
445   bool isVOPC(uint16_t Opcode) const {
446     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
447   }
448 
449   static bool isMUBUF(const MachineInstr &MI) {
450     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
451   }
452 
453   bool isMUBUF(uint16_t Opcode) const {
454     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
455   }
456 
457   static bool isMTBUF(const MachineInstr &MI) {
458     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
459   }
460 
461   bool isMTBUF(uint16_t Opcode) const {
462     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
463   }
464 
465   static bool isSMRD(const MachineInstr &MI) {
466     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
467   }
468 
469   bool isSMRD(uint16_t Opcode) const {
470     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
471   }
472 
473   bool isBufferSMRD(const MachineInstr &MI) const;
474 
475   static bool isDS(const MachineInstr &MI) {
476     return MI.getDesc().TSFlags & SIInstrFlags::DS;
477   }
478 
479   bool isDS(uint16_t Opcode) const {
480     return get(Opcode).TSFlags & SIInstrFlags::DS;
481   }
482 
483   bool isAlwaysGDS(uint16_t Opcode) const;
484 
485   static bool isMIMG(const MachineInstr &MI) {
486     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
487   }
488 
489   bool isMIMG(uint16_t Opcode) const {
490     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
491   }
492 
493   static bool isGather4(const MachineInstr &MI) {
494     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
495   }
496 
497   bool isGather4(uint16_t Opcode) const {
498     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
499   }
500 
501   static bool isFLAT(const MachineInstr &MI) {
502     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
503   }
504 
505   // Is a FLAT encoded instruction which accesses a specific segment,
506   // i.e. global_* or scratch_*.
507   static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
508     auto Flags = MI.getDesc().TSFlags;
509     return Flags & (SIInstrFlags::FlatGlobal | SIInstrFlags::FlatScratch);
510   }
511 
512   bool isSegmentSpecificFLAT(uint16_t Opcode) const {
513     auto Flags = get(Opcode).TSFlags;
514     return Flags & (SIInstrFlags::FlatGlobal | SIInstrFlags::FlatScratch);
515   }
516 
517   static bool isFLATGlobal(const MachineInstr &MI) {
518     return MI.getDesc().TSFlags & SIInstrFlags::FlatGlobal;
519   }
520 
521   bool isFLATGlobal(uint16_t Opcode) const {
522     return get(Opcode).TSFlags & SIInstrFlags::FlatGlobal;
523   }
524 
525   static bool isFLATScratch(const MachineInstr &MI) {
526     return MI.getDesc().TSFlags & SIInstrFlags::FlatScratch;
527   }
528 
529   bool isFLATScratch(uint16_t Opcode) const {
530     return get(Opcode).TSFlags & SIInstrFlags::FlatScratch;
531   }
532 
533   // Any FLAT encoded instruction, including global_* and scratch_*.
534   bool isFLAT(uint16_t Opcode) const {
535     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
536   }
537 
538   static bool isEXP(const MachineInstr &MI) {
539     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
540   }
541 
542   bool isEXP(uint16_t Opcode) const {
543     return get(Opcode).TSFlags & SIInstrFlags::EXP;
544   }
545 
546   static bool isAtomicNoRet(const MachineInstr &MI) {
547     return MI.getDesc().TSFlags & SIInstrFlags::IsAtomicNoRet;
548   }
549 
550   bool isAtomicNoRet(uint16_t Opcode) const {
551     return get(Opcode).TSFlags & SIInstrFlags::IsAtomicNoRet;
552   }
553 
554   static bool isAtomicRet(const MachineInstr &MI) {
555     return MI.getDesc().TSFlags & SIInstrFlags::IsAtomicRet;
556   }
557 
558   bool isAtomicRet(uint16_t Opcode) const {
559     return get(Opcode).TSFlags & SIInstrFlags::IsAtomicRet;
560   }
561 
562   static bool isAtomic(const MachineInstr &MI) {
563     return MI.getDesc().TSFlags & (SIInstrFlags::IsAtomicRet |
564                                    SIInstrFlags::IsAtomicNoRet);
565   }
566 
567   bool isAtomic(uint16_t Opcode) const {
568     return get(Opcode).TSFlags & (SIInstrFlags::IsAtomicRet |
569                                   SIInstrFlags::IsAtomicNoRet);
570   }
571 
572   static bool isWQM(const MachineInstr &MI) {
573     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
574   }
575 
576   bool isWQM(uint16_t Opcode) const {
577     return get(Opcode).TSFlags & SIInstrFlags::WQM;
578   }
579 
580   static bool isDisableWQM(const MachineInstr &MI) {
581     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
582   }
583 
584   bool isDisableWQM(uint16_t Opcode) const {
585     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
586   }
587 
588   static bool isVGPRSpill(const MachineInstr &MI) {
589     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
590   }
591 
592   bool isVGPRSpill(uint16_t Opcode) const {
593     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
594   }
595 
596   static bool isSGPRSpill(const MachineInstr &MI) {
597     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
598   }
599 
600   bool isSGPRSpill(uint16_t Opcode) const {
601     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
602   }
603 
604   static bool isDPP(const MachineInstr &MI) {
605     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
606   }
607 
608   bool isDPP(uint16_t Opcode) const {
609     return get(Opcode).TSFlags & SIInstrFlags::DPP;
610   }
611 
612   static bool isTRANS(const MachineInstr &MI) {
613     return MI.getDesc().TSFlags & SIInstrFlags::TRANS;
614   }
615 
616   bool isTRANS(uint16_t Opcode) const {
617     return get(Opcode).TSFlags & SIInstrFlags::TRANS;
618   }
619 
620   static bool isVOP3P(const MachineInstr &MI) {
621     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
622   }
623 
624   bool isVOP3P(uint16_t Opcode) const {
625     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
626   }
627 
628   static bool isVINTRP(const MachineInstr &MI) {
629     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
630   }
631 
632   bool isVINTRP(uint16_t Opcode) const {
633     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
634   }
635 
636   static bool isMAI(const MachineInstr &MI) {
637     return MI.getDesc().TSFlags & SIInstrFlags::IsMAI;
638   }
639 
640   bool isMAI(uint16_t Opcode) const {
641     return get(Opcode).TSFlags & SIInstrFlags::IsMAI;
642   }
643 
644   static bool isDOT(const MachineInstr &MI) {
645     return MI.getDesc().TSFlags & SIInstrFlags::IsDOT;
646   }
647 
648   bool isDOT(uint16_t Opcode) const {
649     return get(Opcode).TSFlags & SIInstrFlags::IsDOT;
650   }
651 
652   static bool isScalarUnit(const MachineInstr &MI) {
653     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
654   }
655 
656   static bool usesVM_CNT(const MachineInstr &MI) {
657     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
658   }
659 
660   static bool usesLGKM_CNT(const MachineInstr &MI) {
661     return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT;
662   }
663 
664   static bool sopkIsZext(const MachineInstr &MI) {
665     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
666   }
667 
668   bool sopkIsZext(uint16_t Opcode) const {
669     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
670   }
671 
672   /// \returns true if this is an s_store_dword* instruction. This is more
673   /// specific than than isSMEM && mayStore.
674   static bool isScalarStore(const MachineInstr &MI) {
675     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
676   }
677 
678   bool isScalarStore(uint16_t Opcode) const {
679     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
680   }
681 
682   static bool isFixedSize(const MachineInstr &MI) {
683     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
684   }
685 
686   bool isFixedSize(uint16_t Opcode) const {
687     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
688   }
689 
690   static bool hasFPClamp(const MachineInstr &MI) {
691     return MI.getDesc().TSFlags & SIInstrFlags::FPClamp;
692   }
693 
694   bool hasFPClamp(uint16_t Opcode) const {
695     return get(Opcode).TSFlags & SIInstrFlags::FPClamp;
696   }
697 
698   static bool hasIntClamp(const MachineInstr &MI) {
699     return MI.getDesc().TSFlags & SIInstrFlags::IntClamp;
700   }
701 
702   uint64_t getClampMask(const MachineInstr &MI) const {
703     const uint64_t ClampFlags = SIInstrFlags::FPClamp |
704                                 SIInstrFlags::IntClamp |
705                                 SIInstrFlags::ClampLo |
706                                 SIInstrFlags::ClampHi;
707       return MI.getDesc().TSFlags & ClampFlags;
708   }
709 
710   static bool usesFPDPRounding(const MachineInstr &MI) {
711     return MI.getDesc().TSFlags & SIInstrFlags::FPDPRounding;
712   }
713 
714   bool usesFPDPRounding(uint16_t Opcode) const {
715     return get(Opcode).TSFlags & SIInstrFlags::FPDPRounding;
716   }
717 
718   static bool isFPAtomic(const MachineInstr &MI) {
719     return MI.getDesc().TSFlags & SIInstrFlags::FPAtomic;
720   }
721 
722   bool isFPAtomic(uint16_t Opcode) const {
723     return get(Opcode).TSFlags & SIInstrFlags::FPAtomic;
724   }
725 
726   bool isVGPRCopy(const MachineInstr &MI) const {
727     assert(MI.isCopy());
728     Register Dest = MI.getOperand(0).getReg();
729     const MachineFunction &MF = *MI.getParent()->getParent();
730     const MachineRegisterInfo &MRI = MF.getRegInfo();
731     return !RI.isSGPRReg(MRI, Dest);
732   }
733 
734   bool hasVGPRUses(const MachineInstr &MI) const {
735     const MachineFunction &MF = *MI.getParent()->getParent();
736     const MachineRegisterInfo &MRI = MF.getRegInfo();
737     return llvm::any_of(MI.explicit_uses(),
738                         [&MRI, this](const MachineOperand &MO) {
739       return MO.isReg() && RI.isVGPR(MRI, MO.getReg());});
740   }
741 
742   /// Return true if the instruction modifies the mode register.q
743   static bool modifiesModeRegister(const MachineInstr &MI);
744 
745   /// Whether we must prevent this instruction from executing with EXEC = 0.
746   bool hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const;
747 
748   /// Returns true if the instruction could potentially depend on the value of
749   /// exec. If false, exec dependencies may safely be ignored.
750   bool mayReadEXEC(const MachineRegisterInfo &MRI, const MachineInstr &MI) const;
751 
752   bool isInlineConstant(const APInt &Imm) const;
753 
754   bool isInlineConstant(const APFloat &Imm) const {
755     return isInlineConstant(Imm.bitcastToAPInt());
756   }
757 
758   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
759 
760   bool isInlineConstant(const MachineOperand &MO,
761                         const MCOperandInfo &OpInfo) const {
762     return isInlineConstant(MO, OpInfo.OperandType);
763   }
764 
765   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
766   /// be an inline immediate.
767   bool isInlineConstant(const MachineInstr &MI,
768                         const MachineOperand &UseMO,
769                         const MachineOperand &DefMO) const {
770     assert(UseMO.getParent() == &MI);
771     int OpIdx = MI.getOperandNo(&UseMO);
772     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
773       return false;
774     }
775 
776     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
777   }
778 
779   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
780   /// immediate.
781   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
782     const MachineOperand &MO = MI.getOperand(OpIdx);
783     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
784   }
785 
786   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
787                         const MachineOperand &MO) const {
788     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
789       return false;
790 
791     if (MI.isCopy()) {
792       unsigned Size = getOpSize(MI, OpIdx);
793       assert(Size == 8 || Size == 4);
794 
795       uint8_t OpType = (Size == 8) ?
796         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
797       return isInlineConstant(MO, OpType);
798     }
799 
800     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
801   }
802 
803   bool isInlineConstant(const MachineOperand &MO) const {
804     const MachineInstr *Parent = MO.getParent();
805     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
806   }
807 
808   bool isLiteralConstant(const MachineOperand &MO,
809                          const MCOperandInfo &OpInfo) const {
810     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
811   }
812 
813   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
814     const MachineOperand &MO = MI.getOperand(OpIdx);
815     return MO.isImm() && !isInlineConstant(MI, OpIdx);
816   }
817 
818   // Returns true if this operand could potentially require a 32-bit literal
819   // operand, but not necessarily. A FrameIndex for example could resolve to an
820   // inline immediate value that will not require an additional 4-bytes; this
821   // assumes that it will.
822   bool isLiteralConstantLike(const MachineOperand &MO,
823                              const MCOperandInfo &OpInfo) const;
824 
825   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
826                          const MachineOperand &MO) const;
827 
828   /// Return true if this 64-bit VALU instruction has a 32-bit encoding.
829   /// This function will return false if you pass it a 32-bit instruction.
830   bool hasVALU32BitEncoding(unsigned Opcode) const;
831 
832   /// Returns true if this operand uses the constant bus.
833   bool usesConstantBus(const MachineRegisterInfo &MRI,
834                        const MachineOperand &MO,
835                        const MCOperandInfo &OpInfo) const;
836 
837   /// Return true if this instruction has any modifiers.
838   ///  e.g. src[012]_mod, omod, clamp.
839   bool hasModifiers(unsigned Opcode) const;
840 
841   bool hasModifiersSet(const MachineInstr &MI,
842                        unsigned OpName) const;
843   bool hasAnyModifiersSet(const MachineInstr &MI) const;
844 
845   bool canShrink(const MachineInstr &MI,
846                  const MachineRegisterInfo &MRI) const;
847 
848   MachineInstr *buildShrunkInst(MachineInstr &MI,
849                                 unsigned NewOpcode) const;
850 
851   bool verifyInstruction(const MachineInstr &MI,
852                          StringRef &ErrInfo) const override;
853 
854   unsigned getVALUOp(const MachineInstr &MI) const;
855 
856   /// Return the correct register class for \p OpNo.  For target-specific
857   /// instructions, this will return the register class that has been defined
858   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
859   /// the register class of its machine operand.
860   /// to infer the correct register class base on the other operands.
861   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
862                                            unsigned OpNo) const;
863 
864   /// Return the size in bytes of the operand OpNo on the given
865   // instruction opcode.
866   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
867     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
868 
869     if (OpInfo.RegClass == -1) {
870       // If this is an immediate operand, this must be a 32-bit literal.
871       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
872       return 4;
873     }
874 
875     return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8;
876   }
877 
878   /// This form should usually be preferred since it handles operands
879   /// with unknown register classes.
880   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
881     const MachineOperand &MO = MI.getOperand(OpNo);
882     if (MO.isReg()) {
883       if (unsigned SubReg = MO.getSubReg()) {
884         return RI.getSubRegIdxSize(SubReg) / 8;
885       }
886     }
887     return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8;
888   }
889 
890   /// Legalize the \p OpIndex operand of this instruction by inserting
891   /// a MOV.  For example:
892   /// ADD_I32_e32 VGPR0, 15
893   /// to
894   /// MOV VGPR1, 15
895   /// ADD_I32_e32 VGPR0, VGPR1
896   ///
897   /// If the operand being legalized is a register, then a COPY will be used
898   /// instead of MOV.
899   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
900 
901   /// Check if \p MO is a legal operand if it was the \p OpIdx Operand
902   /// for \p MI.
903   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
904                       const MachineOperand *MO = nullptr) const;
905 
906   /// Check if \p MO would be a valid operand for the given operand
907   /// definition \p OpInfo. Note this does not attempt to validate constant bus
908   /// restrictions (e.g. literal constant usage).
909   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
910                           const MCOperandInfo &OpInfo,
911                           const MachineOperand &MO) const;
912 
913   /// Check if \p MO (a register operand) is a legal register for the
914   /// given operand description.
915   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
916                          const MCOperandInfo &OpInfo,
917                          const MachineOperand &MO) const;
918 
919   /// Legalize operands in \p MI by either commuting it or inserting a
920   /// copy of src1.
921   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
922 
923   /// Fix operands in \p MI to satisfy constant bus requirements.
924   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
925 
926   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
927   /// be used when it is know that the value in SrcReg is same across all
928   /// threads in the wave.
929   /// \returns The SGPR register that \p SrcReg was copied to.
930   Register readlaneVGPRToSGPR(Register SrcReg, MachineInstr &UseMI,
931                               MachineRegisterInfo &MRI) const;
932 
933   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
934   void legalizeOperandsFLAT(MachineRegisterInfo &MRI, MachineInstr &MI) const;
935 
936   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
937                               MachineBasicBlock::iterator I,
938                               const TargetRegisterClass *DstRC,
939                               MachineOperand &Op, MachineRegisterInfo &MRI,
940                               const DebugLoc &DL) const;
941 
942   /// Legalize all operands in this instruction.  This function may create new
943   /// instructions and control-flow around \p MI.  If present, \p MDT is
944   /// updated.
945   /// \returns A new basic block that contains \p MI if new blocks were created.
946   MachineBasicBlock *
947   legalizeOperands(MachineInstr &MI, MachineDominatorTree *MDT = nullptr) const;
948 
949   /// Replace this instruction's opcode with the equivalent VALU
950   /// opcode.  This function will also move the users of \p MI to the
951   /// VALU if necessary. If present, \p MDT is updated.
952   MachineBasicBlock *moveToVALU(MachineInstr &MI,
953                                 MachineDominatorTree *MDT = nullptr) const;
954 
955   void insertNoop(MachineBasicBlock &MBB,
956                   MachineBasicBlock::iterator MI) const override;
957 
958   void insertNoops(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
959                    unsigned Quantity) const override;
960 
961   void insertReturn(MachineBasicBlock &MBB) const;
962   /// Return the number of wait states that result from executing this
963   /// instruction.
964   static unsigned getNumWaitStates(const MachineInstr &MI);
965 
966   /// Returns the operand named \p Op.  If \p MI does not have an
967   /// operand named \c Op, this function returns nullptr.
968   LLVM_READONLY
969   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
970 
971   LLVM_READONLY
972   const MachineOperand *getNamedOperand(const MachineInstr &MI,
973                                         unsigned OpName) const {
974     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
975   }
976 
977   /// Get required immediate operand
978   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
979     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
980     return MI.getOperand(Idx).getImm();
981   }
982 
983   uint64_t getDefaultRsrcDataFormat() const;
984   uint64_t getScratchRsrcWords23() const;
985 
986   bool isLowLatencyInstruction(const MachineInstr &MI) const;
987   bool isHighLatencyDef(int Opc) const override;
988 
989   /// Return the descriptor of the target-specific machine instruction
990   /// that corresponds to the specified pseudo or native opcode.
991   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
992     return get(pseudoToMCOpcode(Opcode));
993   }
994 
995   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
996   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
997 
998   unsigned isLoadFromStackSlot(const MachineInstr &MI,
999                                int &FrameIndex) const override;
1000   unsigned isStoreToStackSlot(const MachineInstr &MI,
1001                               int &FrameIndex) const override;
1002 
1003   unsigned getInstBundleSize(const MachineInstr &MI) const;
1004   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
1005 
1006   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
1007 
1008   bool isNonUniformBranchInstr(MachineInstr &Instr) const;
1009 
1010   void convertNonUniformIfRegion(MachineBasicBlock *IfEntry,
1011                                  MachineBasicBlock *IfEnd) const;
1012 
1013   void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry,
1014                                    MachineBasicBlock *LoopEnd) const;
1015 
1016   std::pair<unsigned, unsigned>
1017   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
1018 
1019   ArrayRef<std::pair<int, const char *>>
1020   getSerializableTargetIndices() const override;
1021 
1022   ArrayRef<std::pair<unsigned, const char *>>
1023   getSerializableDirectMachineOperandTargetFlags() const override;
1024 
1025   ScheduleHazardRecognizer *
1026   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
1027                                  const ScheduleDAG *DAG) const override;
1028 
1029   ScheduleHazardRecognizer *
1030   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
1031 
1032   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
1033 
1034   MachineInstr *createPHIDestinationCopy(MachineBasicBlock &MBB,
1035                                          MachineBasicBlock::iterator InsPt,
1036                                          const DebugLoc &DL, Register Src,
1037                                          Register Dst) const override;
1038 
1039   MachineInstr *createPHISourceCopy(MachineBasicBlock &MBB,
1040                                     MachineBasicBlock::iterator InsPt,
1041                                     const DebugLoc &DL, Register Src,
1042                                     unsigned SrcSubReg,
1043                                     Register Dst) const override;
1044 
1045   bool isWave32() const;
1046 
1047   /// Return a partially built integer add instruction without carry.
1048   /// Caller must add source operands.
1049   /// For pre-GFX9 it will generate unused carry destination operand.
1050   /// TODO: After GFX9 it should return a no-carry operation.
1051   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
1052                                     MachineBasicBlock::iterator I,
1053                                     const DebugLoc &DL,
1054                                     Register DestReg) const;
1055 
1056   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
1057                                     MachineBasicBlock::iterator I,
1058                                     const DebugLoc &DL,
1059                                     Register DestReg,
1060                                     RegScavenger &RS) const;
1061 
1062   static bool isKillTerminator(unsigned Opcode);
1063   const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const;
1064 
1065   static bool isLegalMUBUFImmOffset(unsigned Imm) {
1066     return isUInt<12>(Imm);
1067   }
1068 
1069   /// Returns if \p Offset is legal for the subtarget as the offset to a FLAT
1070   /// encoded instruction. If \p Signed, this is for an instruction that
1071   /// interprets the offset as signed.
1072   bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
1073                          uint64_t FlatVariant) const;
1074 
1075   /// Split \p COffsetVal into {immediate offset field, remainder offset}
1076   /// values.
1077   std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal,
1078                                               unsigned AddrSpace,
1079                                               uint64_t FlatVariant) const;
1080 
1081   /// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
1082   /// Return -1 if the target-specific opcode for the pseudo instruction does
1083   /// not exist. If Opcode is not a pseudo instruction, this is identity.
1084   int pseudoToMCOpcode(int Opcode) const;
1085 
1086   /// \brief Check if this instruction should only be used by assembler.
1087   /// Return true if this opcode should not be used by codegen.
1088   bool isAsmOnlyOpcode(int MCOp) const;
1089 
1090   const TargetRegisterClass *getRegClass(const MCInstrDesc &TID, unsigned OpNum,
1091                                          const TargetRegisterInfo *TRI,
1092                                          const MachineFunction &MF)
1093     const override;
1094 
1095   void fixImplicitOperands(MachineInstr &MI) const;
1096 
1097   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
1098                                       ArrayRef<unsigned> Ops,
1099                                       MachineBasicBlock::iterator InsertPt,
1100                                       int FrameIndex,
1101                                       LiveIntervals *LIS = nullptr,
1102                                       VirtRegMap *VRM = nullptr) const override;
1103 
1104   unsigned getInstrLatency(const InstrItineraryData *ItinData,
1105                            const MachineInstr &MI,
1106                            unsigned *PredCost = nullptr) const override;
1107 
1108   const MIRFormatter *getMIRFormatter() const override {
1109     if (!Formatter.get())
1110       Formatter = std::make_unique<AMDGPUMIRFormatter>();
1111     return Formatter.get();
1112   }
1113 
1114   static unsigned getDSShaderTypeValue(const MachineFunction &MF);
1115 };
1116 
1117 /// \brief Returns true if a reg:subreg pair P has a TRC class
1118 inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P,
1119                          const TargetRegisterClass &TRC,
1120                          MachineRegisterInfo &MRI) {
1121   auto *RC = MRI.getRegClass(P.Reg);
1122   if (!P.SubReg)
1123     return RC == &TRC;
1124   auto *TRI = MRI.getTargetRegisterInfo();
1125   return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg);
1126 }
1127 
1128 /// \brief Create RegSubRegPair from a register MachineOperand
1129 inline
1130 TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O) {
1131   assert(O.isReg());
1132   return TargetInstrInfo::RegSubRegPair(O.getReg(), O.getSubReg());
1133 }
1134 
1135 /// \brief Return the SubReg component from REG_SEQUENCE
1136 TargetInstrInfo::RegSubRegPair getRegSequenceSubReg(MachineInstr &MI,
1137                                                     unsigned SubReg);
1138 
1139 /// \brief Return the defining instruction for a given reg:subreg pair
1140 /// skipping copy like instructions and subreg-manipulation pseudos.
1141 /// Following another subreg of a reg:subreg isn't supported.
1142 MachineInstr *getVRegSubRegDef(const TargetInstrInfo::RegSubRegPair &P,
1143                                MachineRegisterInfo &MRI);
1144 
1145 /// \brief Return false if EXEC is not changed between the def of \p VReg at \p
1146 /// DefMI and the use at \p UseMI. Should be run on SSA. Currently does not
1147 /// attempt to track between blocks.
1148 bool execMayBeModifiedBeforeUse(const MachineRegisterInfo &MRI,
1149                                 Register VReg,
1150                                 const MachineInstr &DefMI,
1151                                 const MachineInstr &UseMI);
1152 
1153 /// \brief Return false if EXEC is not changed between the def of \p VReg at \p
1154 /// DefMI and all its uses. Should be run on SSA. Currently does not attempt to
1155 /// track between blocks.
1156 bool execMayBeModifiedBeforeAnyUse(const MachineRegisterInfo &MRI,
1157                                    Register VReg,
1158                                    const MachineInstr &DefMI);
1159 
1160 namespace AMDGPU {
1161 
1162   LLVM_READONLY
1163   int getVOPe64(uint16_t Opcode);
1164 
1165   LLVM_READONLY
1166   int getVOPe32(uint16_t Opcode);
1167 
1168   LLVM_READONLY
1169   int getSDWAOp(uint16_t Opcode);
1170 
1171   LLVM_READONLY
1172   int getDPPOp32(uint16_t Opcode);
1173 
1174   LLVM_READONLY
1175   int getBasicFromSDWAOp(uint16_t Opcode);
1176 
1177   LLVM_READONLY
1178   int getCommuteRev(uint16_t Opcode);
1179 
1180   LLVM_READONLY
1181   int getCommuteOrig(uint16_t Opcode);
1182 
1183   LLVM_READONLY
1184   int getAddr64Inst(uint16_t Opcode);
1185 
1186   /// Check if \p Opcode is an Addr64 opcode.
1187   ///
1188   /// \returns \p Opcode if it is an Addr64 opcode, otherwise -1.
1189   LLVM_READONLY
1190   int getIfAddr64Inst(uint16_t Opcode);
1191 
1192   LLVM_READONLY
1193   int getMUBUFNoLdsInst(uint16_t Opcode);
1194 
1195   LLVM_READONLY
1196   int getAtomicNoRetOp(uint16_t Opcode);
1197 
1198   LLVM_READONLY
1199   int getSOPKOp(uint16_t Opcode);
1200 
1201   LLVM_READONLY
1202   int getGlobalSaddrOp(uint16_t Opcode);
1203 
1204   LLVM_READONLY
1205   int getVCMPXNoSDstOp(uint16_t Opcode);
1206 
1207   LLVM_READONLY
1208   int getFlatScratchInstSTfromSS(uint16_t Opcode);
1209 
1210   LLVM_READONLY
1211   int getFlatScratchInstSSfromSV(uint16_t Opcode);
1212 
1213   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
1214   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
1215   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
1216   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
1217 
1218 } // end namespace AMDGPU
1219 
1220 namespace SI {
1221 namespace KernelInputOffsets {
1222 
1223 /// Offsets in bytes from the start of the input buffer
1224 enum Offsets {
1225   NGROUPS_X = 0,
1226   NGROUPS_Y = 4,
1227   NGROUPS_Z = 8,
1228   GLOBAL_SIZE_X = 12,
1229   GLOBAL_SIZE_Y = 16,
1230   GLOBAL_SIZE_Z = 20,
1231   LOCAL_SIZE_X = 24,
1232   LOCAL_SIZE_Y = 28,
1233   LOCAL_SIZE_Z = 32
1234 };
1235 
1236 } // end namespace KernelInputOffsets
1237 } // end namespace SI
1238 
1239 } // end namespace llvm
1240 
1241 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
1242