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