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 
16 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
17 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
18 
19 #include "AMDGPUInstrInfo.h"
20 #include "SIDefines.h"
21 #include "SIRegisterInfo.h"
22 
23 namespace llvm {
24 
25 class SIInstrInfo final : public AMDGPUInstrInfo {
26 private:
27   const SIRegisterInfo RI;
28   const SISubtarget &ST;
29 
30   // The the inverse predicate should have the negative value.
31   enum BranchPredicate {
32     INVALID_BR = 0,
33     SCC_TRUE = 1,
34     SCC_FALSE = -1,
35     VCCNZ = 2,
36     VCCZ = -2,
37     EXECNZ = -3,
38     EXECZ = 3
39   };
40 
41   static unsigned getBranchOpcode(BranchPredicate Cond);
42   static BranchPredicate getBranchPredicate(unsigned Opcode);
43 
44   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
45                               MachineRegisterInfo &MRI,
46                               MachineOperand &SuperReg,
47                               const TargetRegisterClass *SuperRC,
48                               unsigned SubIdx,
49                               const TargetRegisterClass *SubRC) const;
50   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
51                                          MachineRegisterInfo &MRI,
52                                          MachineOperand &SuperReg,
53                                          const TargetRegisterClass *SuperRC,
54                                          unsigned SubIdx,
55                                          const TargetRegisterClass *SubRC) const;
56 
57   void swapOperands(MachineBasicBlock::iterator Inst) const;
58 
59   void lowerScalarAbs(SmallVectorImpl<MachineInstr *> &Worklist,
60                       MachineInstr *Inst) const;
61 
62   void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
63                                MachineInstr *Inst, unsigned Opcode) const;
64 
65   void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
66                                 MachineInstr *Inst, unsigned Opcode) const;
67 
68   void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
69                             MachineInstr *Inst) const;
70   void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
71                            MachineInstr *Inst) const;
72 
73   void addUsersToMoveToVALUWorklist(
74     unsigned Reg, MachineRegisterInfo &MRI,
75     SmallVectorImpl<MachineInstr *> &Worklist) const;
76 
77   void addSCCDefUsersToVALUWorklist(
78     MachineInstr *SCCDefInst, SmallVectorImpl<MachineInstr *> &Worklist) const;
79 
80   const TargetRegisterClass *
81   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
82 
83   bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
84                                     MachineInstr *MIb) const;
85 
86   unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
87 
88 protected:
89   MachineInstr *commuteInstructionImpl(MachineInstr *MI,
90                                        bool NewMI,
91                                        unsigned OpIdx0,
92                                        unsigned OpIdx1) const override;
93 
94 public:
95   explicit SIInstrInfo(const SISubtarget &);
96 
97   const SIRegisterInfo &getRegisterInfo() const {
98     return RI;
99   }
100 
101   bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
102                                          AliasAnalysis *AA) const override;
103 
104   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
105                                int64_t &Offset1,
106                                int64_t &Offset2) const override;
107 
108   bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
109                              int64_t &Offset,
110                              const TargetRegisterInfo *TRI) const final;
111 
112   bool shouldClusterMemOps(MachineInstr *FirstLdSt,
113                            MachineInstr *SecondLdSt,
114                            unsigned NumLoads) const final;
115 
116   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
117                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
118                    bool KillSrc) const override;
119 
120   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
121                                     MachineBasicBlock::iterator MI,
122                                     RegScavenger *RS,
123                                     unsigned TmpReg,
124                                     unsigned Offset,
125                                     unsigned Size) const;
126 
127   void storeRegToStackSlot(MachineBasicBlock &MBB,
128                            MachineBasicBlock::iterator MI,
129                            unsigned SrcReg, bool isKill, int FrameIndex,
130                            const TargetRegisterClass *RC,
131                            const TargetRegisterInfo *TRI) const override;
132 
133   void loadRegFromStackSlot(MachineBasicBlock &MBB,
134                             MachineBasicBlock::iterator MI,
135                             unsigned DestReg, int FrameIndex,
136                             const TargetRegisterClass *RC,
137                             const TargetRegisterInfo *TRI) const override;
138 
139   bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
140 
141   // \brief Returns an opcode that can be used to move a value to a \p DstRC
142   // register.  If there is no hardware instruction that can store to \p
143   // DstRC, then AMDGPU::COPY is returned.
144   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
145 
146   LLVM_READONLY
147   int commuteOpcode(const MachineInstr &MI) const;
148 
149   bool findCommutedOpIndices(MachineInstr *MI,
150                              unsigned &SrcOpIdx1,
151                              unsigned &SrcOpIdx2) const override;
152 
153   bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
154                      MachineBasicBlock *&FBB,
155                      SmallVectorImpl<MachineOperand> &Cond,
156                      bool AllowModify) const override;
157 
158   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
159 
160   unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
161                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
162                         const DebugLoc &DL) const override;
163 
164   bool ReverseBranchCondition(
165     SmallVectorImpl<MachineOperand> &Cond) const override;
166 
167   bool areMemAccessesTriviallyDisjoint(
168     MachineInstr *MIa, MachineInstr *MIb,
169     AliasAnalysis *AA = nullptr) const override;
170 
171   bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
172                      unsigned Reg, MachineRegisterInfo *MRI) const final;
173 
174   unsigned getMachineCSELookAheadLimit() const override { return 500; }
175 
176   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
177                                       MachineBasicBlock::iterator &MI,
178                                       LiveVariables *LV) const override;
179 
180   bool isSchedulingBoundary(const MachineInstr *MI,
181                             const MachineBasicBlock *MBB,
182                             const MachineFunction &MF) const override;
183 
184   static bool isSALU(const MachineInstr &MI) {
185     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
186   }
187 
188   bool isSALU(uint16_t Opcode) const {
189     return get(Opcode).TSFlags & SIInstrFlags::SALU;
190   }
191 
192   static bool isVALU(const MachineInstr &MI) {
193     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
194   }
195 
196   bool isVALU(uint16_t Opcode) const {
197     return get(Opcode).TSFlags & SIInstrFlags::VALU;
198   }
199 
200   static bool isVMEM(const MachineInstr &MI) {
201     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
202   }
203 
204   bool isVMEM(uint16_t Opcode) const {
205     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
206   }
207 
208   static bool isSOP1(const MachineInstr &MI) {
209     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
210   }
211 
212   bool isSOP1(uint16_t Opcode) const {
213     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
214   }
215 
216   static bool isSOP2(const MachineInstr &MI) {
217     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
218   }
219 
220   bool isSOP2(uint16_t Opcode) const {
221     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
222   }
223 
224   static bool isSOPC(const MachineInstr &MI) {
225     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
226   }
227 
228   bool isSOPC(uint16_t Opcode) const {
229     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
230   }
231 
232   static bool isSOPK(const MachineInstr &MI) {
233     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
234   }
235 
236   bool isSOPK(uint16_t Opcode) const {
237     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
238   }
239 
240   static bool isSOPP(const MachineInstr &MI) {
241     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
242   }
243 
244   bool isSOPP(uint16_t Opcode) const {
245     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
246   }
247 
248   static bool isVOP1(const MachineInstr &MI) {
249     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
250   }
251 
252   bool isVOP1(uint16_t Opcode) const {
253     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
254   }
255 
256   static bool isVOP2(const MachineInstr &MI) {
257     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
258   }
259 
260   bool isVOP2(uint16_t Opcode) const {
261     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
262   }
263 
264   static bool isVOP3(const MachineInstr &MI) {
265     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
266   }
267 
268   bool isVOP3(uint16_t Opcode) const {
269     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
270   }
271 
272   static bool isVOPC(const MachineInstr &MI) {
273     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
274   }
275 
276   bool isVOPC(uint16_t Opcode) const {
277     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
278   }
279 
280   static bool isMUBUF(const MachineInstr &MI) {
281     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
282   }
283 
284   bool isMUBUF(uint16_t Opcode) const {
285     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
286   }
287 
288   static bool isMTBUF(const MachineInstr &MI) {
289     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
290   }
291 
292   bool isMTBUF(uint16_t Opcode) const {
293     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
294   }
295 
296   static bool isSMRD(const MachineInstr &MI) {
297     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
298   }
299 
300   bool isSMRD(uint16_t Opcode) const {
301     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
302   }
303 
304   static bool isDS(const MachineInstr &MI) {
305     return MI.getDesc().TSFlags & SIInstrFlags::DS;
306   }
307 
308   bool isDS(uint16_t Opcode) const {
309     return get(Opcode).TSFlags & SIInstrFlags::DS;
310   }
311 
312   static bool isMIMG(const MachineInstr &MI) {
313     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
314   }
315 
316   bool isMIMG(uint16_t Opcode) const {
317     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
318   }
319 
320   static bool isFLAT(const MachineInstr &MI) {
321     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
322   }
323 
324   bool isFLAT(uint16_t Opcode) const {
325     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
326   }
327 
328   static bool isWQM(const MachineInstr &MI) {
329     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
330   }
331 
332   bool isWQM(uint16_t Opcode) const {
333     return get(Opcode).TSFlags & SIInstrFlags::WQM;
334   }
335 
336   static bool isVGPRSpill(const MachineInstr &MI) {
337     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
338   }
339 
340   bool isVGPRSpill(uint16_t Opcode) const {
341     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
342   }
343 
344   static bool isDPP(const MachineInstr &MI) {
345     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
346   }
347 
348   bool isDPP(uint16_t Opcode) const {
349     return get(Opcode).TSFlags & SIInstrFlags::DPP;
350   }
351 
352   bool isVGPRCopy(const MachineInstr &MI) const {
353     assert(MI.isCopy());
354     unsigned Dest = MI.getOperand(0).getReg();
355     const MachineFunction &MF = *MI.getParent()->getParent();
356     const MachineRegisterInfo &MRI = MF.getRegInfo();
357     return !RI.isSGPRReg(MRI, Dest);
358   }
359 
360   bool isInlineConstant(const APInt &Imm) const;
361   bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
362   bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
363 
364   bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
365                          const MachineOperand &MO) const;
366 
367   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
368   /// This function will return false if you pass it a 32-bit instruction.
369   bool hasVALU32BitEncoding(unsigned Opcode) const;
370 
371   /// \brief Returns true if this operand uses the constant bus.
372   bool usesConstantBus(const MachineRegisterInfo &MRI,
373                        const MachineOperand &MO,
374                        unsigned OpSize) const;
375 
376   /// \brief Return true if this instruction has any modifiers.
377   ///  e.g. src[012]_mod, omod, clamp.
378   bool hasModifiers(unsigned Opcode) const;
379 
380   bool hasModifiersSet(const MachineInstr &MI,
381                        unsigned OpName) const;
382 
383   bool verifyInstruction(const MachineInstr *MI,
384                          StringRef &ErrInfo) const override;
385 
386   static unsigned getVALUOp(const MachineInstr &MI);
387 
388   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
389 
390   /// \brief Return the correct register class for \p OpNo.  For target-specific
391   /// instructions, this will return the register class that has been defined
392   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
393   /// the register class of its machine operand.
394   /// to infer the correct register class base on the other operands.
395   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
396                                            unsigned OpNo) const;
397 
398   /// \brief Return the size in bytes of the operand OpNo on the given
399   // instruction opcode.
400   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
401     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
402 
403     if (OpInfo.RegClass == -1) {
404       // If this is an immediate operand, this must be a 32-bit literal.
405       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
406       return 4;
407     }
408 
409     return RI.getRegClass(OpInfo.RegClass)->getSize();
410   }
411 
412   /// \brief This form should usually be preferred since it handles operands
413   /// with unknown register classes.
414   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
415     return getOpRegClass(MI, OpNo)->getSize();
416   }
417 
418   /// \returns true if it is legal for the operand at index \p OpNo
419   /// to read a VGPR.
420   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
421 
422   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
423   /// a MOV.  For example:
424   /// ADD_I32_e32 VGPR0, 15
425   /// to
426   /// MOV VGPR1, 15
427   /// ADD_I32_e32 VGPR0, VGPR1
428   ///
429   /// If the operand being legalized is a register, then a COPY will be used
430   /// instead of MOV.
431   void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
432 
433   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
434   /// for \p MI.
435   bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
436                       const MachineOperand *MO = nullptr) const;
437 
438   /// \brief Check if \p MO would be a valid operand for the given operand
439   /// definition \p OpInfo. Note this does not attempt to validate constant bus
440   /// restrictions (e.g. literal constant usage).
441   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
442                           const MCOperandInfo &OpInfo,
443                           const MachineOperand &MO) const;
444 
445   /// \brief Check if \p MO (a register operand) is a legal register for the
446   /// given operand description.
447   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
448                          const MCOperandInfo &OpInfo,
449                          const MachineOperand &MO) const;
450 
451   /// \brief Legalize operands in \p MI by either commuting it or inserting a
452   /// copy of src1.
453   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr *MI) const;
454 
455   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
456   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr *MI) const;
457 
458   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
459   /// be used when it is know that the value in SrcReg is same across all
460   /// threads in the wave.
461   /// \returns The SGPR register that \p SrcReg was copied to.
462   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr *UseMI,
463                           MachineRegisterInfo &MRI) const;
464 
465   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr *MI) const;
466 
467   /// \brief Legalize all operands in this instruction.  This function may
468   /// create new instruction and insert them before \p MI.
469   void legalizeOperands(MachineInstr *MI) const;
470 
471   /// \brief Replace this instruction's opcode with the equivalent VALU
472   /// opcode.  This function will also move the users of \p MI to the
473   /// VALU if necessary.
474   void moveToVALU(MachineInstr &MI) const;
475 
476   const TargetRegisterClass *getIndirectAddrRegClass() const override;
477 
478   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
479                         int Count) const;
480 
481   void insertNoop(MachineBasicBlock &MBB,
482                   MachineBasicBlock::iterator MI) const override;
483 
484   /// \brief Return the number of wait states that result from executing this
485   /// instruction.
486   unsigned getNumWaitStates(const MachineInstr &MI) const;
487 
488   /// \brief Returns the operand named \p Op.  If \p MI does not have an
489   /// operand named \c Op, this function returns nullptr.
490   LLVM_READONLY
491   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
492 
493   LLVM_READONLY
494   const MachineOperand *getNamedOperand(const MachineInstr &MI,
495                                         unsigned OpName) const {
496     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
497   }
498 
499   /// Get required immediate operand
500   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
501     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
502     return MI.getOperand(Idx).getImm();
503   }
504 
505   uint64_t getDefaultRsrcDataFormat() const;
506   uint64_t getScratchRsrcWords23() const;
507 
508   bool isLowLatencyInstruction(const MachineInstr *MI) const;
509   bool isHighLatencyInstruction(const MachineInstr *MI) const;
510 
511   /// \brief Return the descriptor of the target-specific machine instruction
512   /// that corresponds to the specified pseudo or native opcode.
513   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
514     return get(pseudoToMCOpcode(Opcode));
515   }
516 
517   unsigned getInstSizeInBytes(const MachineInstr &MI) const;
518 
519   ArrayRef<std::pair<int, const char *>>
520   getSerializableTargetIndices() const override;
521 
522   ScheduleHazardRecognizer *
523   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
524                                  const ScheduleDAG *DAG) const override;
525 
526   ScheduleHazardRecognizer *
527   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
528 };
529 
530 namespace AMDGPU {
531   LLVM_READONLY
532   int getVOPe64(uint16_t Opcode);
533 
534   LLVM_READONLY
535   int getVOPe32(uint16_t Opcode);
536 
537   LLVM_READONLY
538   int getCommuteRev(uint16_t Opcode);
539 
540   LLVM_READONLY
541   int getCommuteOrig(uint16_t Opcode);
542 
543   LLVM_READONLY
544   int getAddr64Inst(uint16_t Opcode);
545 
546   LLVM_READONLY
547   int getAtomicRetOp(uint16_t Opcode);
548 
549   LLVM_READONLY
550   int getAtomicNoRetOp(uint16_t Opcode);
551 
552   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
553   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
554   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
555   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
556 } // End namespace AMDGPU
557 
558 namespace SI {
559 namespace KernelInputOffsets {
560 
561 /// Offsets in bytes from the start of the input buffer
562 enum Offsets {
563   NGROUPS_X = 0,
564   NGROUPS_Y = 4,
565   NGROUPS_Z = 8,
566   GLOBAL_SIZE_X = 12,
567   GLOBAL_SIZE_Y = 16,
568   GLOBAL_SIZE_Z = 20,
569   LOCAL_SIZE_X = 24,
570   LOCAL_SIZE_Y = 28,
571   LOCAL_SIZE_Z = 32
572 };
573 
574 } // End namespace KernelInputOffsets
575 } // End namespace SI
576 
577 } // End namespace llvm
578 
579 #endif
580