AMDGPU: Fix assert when legalizing atomic operands
[oota-llvm.git] / 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
16 #ifndef LLVM_LIB_TARGET_R600_SIINSTRINFO_H
17 #define LLVM_LIB_TARGET_R600_SIINSTRINFO_H
18
19 #include "AMDGPUInstrInfo.h"
20 #include "SIDefines.h"
21 #include "SIRegisterInfo.h"
22
23 namespace llvm {
24
25 class SIInstrInfo : public AMDGPUInstrInfo {
26 private:
27   const SIRegisterInfo RI;
28
29   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
30                               MachineRegisterInfo &MRI,
31                               MachineOperand &SuperReg,
32                               const TargetRegisterClass *SuperRC,
33                               unsigned SubIdx,
34                               const TargetRegisterClass *SubRC) const;
35   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
36                                          MachineRegisterInfo &MRI,
37                                          MachineOperand &SuperReg,
38                                          const TargetRegisterClass *SuperRC,
39                                          unsigned SubIdx,
40                                          const TargetRegisterClass *SubRC) const;
41
42   void swapOperands(MachineBasicBlock::iterator Inst) const;
43
44   void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
45                                MachineInstr *Inst, unsigned Opcode) const;
46
47   void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
48                                 MachineInstr *Inst, unsigned Opcode) const;
49
50   void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
51                             MachineInstr *Inst) const;
52   void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
53                            MachineInstr *Inst) const;
54
55   void addUsersToMoveToVALUWorklist(
56     unsigned Reg, MachineRegisterInfo &MRI,
57     SmallVectorImpl<MachineInstr *> &Worklist) const;
58
59   const TargetRegisterClass *
60   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
61
62   bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
63                                     MachineInstr *MIb) const;
64
65   unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
66
67 protected:
68   MachineInstr *commuteInstructionImpl(MachineInstr *MI,
69                                        bool NewMI,
70                                        unsigned OpIdx0,
71                                        unsigned OpIdx1) const override;
72
73 public:
74   explicit SIInstrInfo(const AMDGPUSubtarget &st);
75
76   const SIRegisterInfo &getRegisterInfo() const override {
77     return RI;
78   }
79
80   bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
81                                          AliasAnalysis *AA) const override;
82
83   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
84                                int64_t &Offset1,
85                                int64_t &Offset2) const override;
86
87   bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
88                              unsigned &Offset,
89                              const TargetRegisterInfo *TRI) const final;
90
91   bool shouldClusterLoads(MachineInstr *FirstLdSt,
92                           MachineInstr *SecondLdSt,
93                           unsigned NumLoads) const final;
94
95   void copyPhysReg(MachineBasicBlock &MBB,
96                    MachineBasicBlock::iterator MI, DebugLoc DL,
97                    unsigned DestReg, unsigned SrcReg,
98                    bool KillSrc) const override;
99
100   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
101                                     MachineBasicBlock::iterator MI,
102                                     RegScavenger *RS,
103                                     unsigned TmpReg,
104                                     unsigned Offset,
105                                     unsigned Size) const;
106
107   void storeRegToStackSlot(MachineBasicBlock &MBB,
108                            MachineBasicBlock::iterator MI,
109                            unsigned SrcReg, bool isKill, int FrameIndex,
110                            const TargetRegisterClass *RC,
111                            const TargetRegisterInfo *TRI) const override;
112
113   void loadRegFromStackSlot(MachineBasicBlock &MBB,
114                             MachineBasicBlock::iterator MI,
115                             unsigned DestReg, int FrameIndex,
116                             const TargetRegisterClass *RC,
117                             const TargetRegisterInfo *TRI) const override;
118
119   bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
120
121   // \brief Returns an opcode that can be used to move a value to a \p DstRC
122   // register.  If there is no hardware instruction that can store to \p
123   // DstRC, then AMDGPU::COPY is returned.
124   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
125
126   LLVM_READONLY
127   int commuteOpcode(const MachineInstr &MI) const;
128
129   bool findCommutedOpIndices(MachineInstr *MI,
130                              unsigned &SrcOpIdx1,
131                              unsigned &SrcOpIdx2) const override;
132
133   bool areMemAccessesTriviallyDisjoint(
134     MachineInstr *MIa, MachineInstr *MIb,
135     AliasAnalysis *AA = nullptr) const override;
136
137   MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
138                               MachineBasicBlock::iterator I,
139                               unsigned DstReg, unsigned SrcReg) const override;
140   bool isMov(unsigned Opcode) const override;
141
142   bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
143                      unsigned Reg, MachineRegisterInfo *MRI) const final;
144
145   unsigned getMachineCSELookAheadLimit() const override { return 500; }
146
147   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
148                                       MachineBasicBlock::iterator &MI,
149                                       LiveVariables *LV) const override;
150
151   static bool isSALU(const MachineInstr &MI) {
152     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
153   }
154
155   bool isSALU(uint16_t Opcode) const {
156     return get(Opcode).TSFlags & SIInstrFlags::SALU;
157   }
158
159   static bool isVALU(const MachineInstr &MI) {
160     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
161   }
162
163   bool isVALU(uint16_t Opcode) const {
164     return get(Opcode).TSFlags & SIInstrFlags::VALU;
165   }
166
167   static bool isSOP1(const MachineInstr &MI) {
168     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
169   }
170
171   bool isSOP1(uint16_t Opcode) const {
172     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
173   }
174
175   static bool isSOP2(const MachineInstr &MI) {
176     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
177   }
178
179   bool isSOP2(uint16_t Opcode) const {
180     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
181   }
182
183   static bool isSOPC(const MachineInstr &MI) {
184     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
185   }
186
187   bool isSOPC(uint16_t Opcode) const {
188     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
189   }
190
191   static bool isSOPK(const MachineInstr &MI) {
192     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
193   }
194
195   bool isSOPK(uint16_t Opcode) const {
196     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
197   }
198
199   static bool isSOPP(const MachineInstr &MI) {
200     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
201   }
202
203   bool isSOPP(uint16_t Opcode) const {
204     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
205   }
206
207   static bool isVOP1(const MachineInstr &MI) {
208     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
209   }
210
211   bool isVOP1(uint16_t Opcode) const {
212     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
213   }
214
215   static bool isVOP2(const MachineInstr &MI) {
216     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
217   }
218
219   bool isVOP2(uint16_t Opcode) const {
220     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
221   }
222
223   static bool isVOP3(const MachineInstr &MI) {
224     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
225   }
226
227   bool isVOP3(uint16_t Opcode) const {
228     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
229   }
230
231   static bool isVOPC(const MachineInstr &MI) {
232     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
233   }
234
235   bool isVOPC(uint16_t Opcode) const {
236     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
237   }
238
239   static bool isMUBUF(const MachineInstr &MI) {
240     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
241   }
242
243   bool isMUBUF(uint16_t Opcode) const {
244     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
245   }
246
247   static bool isMTBUF(const MachineInstr &MI) {
248     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
249   }
250
251   bool isMTBUF(uint16_t Opcode) const {
252     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
253   }
254
255   static bool isSMRD(const MachineInstr &MI) {
256     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
257   }
258
259   bool isSMRD(uint16_t Opcode) const {
260     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
261   }
262
263   static bool isDS(const MachineInstr &MI) {
264     return MI.getDesc().TSFlags & SIInstrFlags::DS;
265   }
266
267   bool isDS(uint16_t Opcode) const {
268     return get(Opcode).TSFlags & SIInstrFlags::DS;
269   }
270
271   static bool isMIMG(const MachineInstr &MI) {
272     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
273   }
274
275   bool isMIMG(uint16_t Opcode) const {
276     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
277   }
278
279   static bool isFLAT(const MachineInstr &MI) {
280     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
281   }
282
283   bool isFLAT(uint16_t Opcode) const {
284     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
285   }
286
287   static bool isWQM(const MachineInstr &MI) {
288     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
289   }
290
291   bool isWQM(uint16_t Opcode) const {
292     return get(Opcode).TSFlags & SIInstrFlags::WQM;
293   }
294
295   static bool isVGPRSpill(const MachineInstr &MI) {
296     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
297   }
298
299   bool isVGPRSpill(uint16_t Opcode) const {
300     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
301   }
302
303   bool isInlineConstant(const APInt &Imm) const;
304   bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
305   bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
306
307   bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
308                          const MachineOperand &MO) const;
309
310   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
311   /// This function will return false if you pass it a 32-bit instruction.
312   bool hasVALU32BitEncoding(unsigned Opcode) const;
313
314   /// \brief Returns true if this operand uses the constant bus.
315   bool usesConstantBus(const MachineRegisterInfo &MRI,
316                        const MachineOperand &MO,
317                        unsigned OpSize) const;
318
319   /// \brief Return true if this instruction has any modifiers.
320   ///  e.g. src[012]_mod, omod, clamp.
321   bool hasModifiers(unsigned Opcode) const;
322
323   bool hasModifiersSet(const MachineInstr &MI,
324                        unsigned OpName) const;
325
326   bool verifyInstruction(const MachineInstr *MI,
327                          StringRef &ErrInfo) const override;
328
329   static unsigned getVALUOp(const MachineInstr &MI);
330
331   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
332
333   /// \brief Return the correct register class for \p OpNo.  For target-specific
334   /// instructions, this will return the register class that has been defined
335   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
336   /// the register class of its machine operand.
337   /// to infer the correct register class base on the other operands.
338   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
339                                            unsigned OpNo) const;
340
341   /// \brief Return the size in bytes of the operand OpNo on the given
342   // instruction opcode.
343   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
344     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
345
346     if (OpInfo.RegClass == -1) {
347       // If this is an immediate operand, this must be a 32-bit literal.
348       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
349       return 4;
350     }
351
352     return RI.getRegClass(OpInfo.RegClass)->getSize();
353   }
354
355   /// \brief This form should usually be preferred since it handles operands
356   /// with unknown register classes.
357   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
358     return getOpRegClass(MI, OpNo)->getSize();
359   }
360
361   /// \returns true if it is legal for the operand at index \p OpNo
362   /// to read a VGPR.
363   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
364
365   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
366   /// a MOV.  For example:
367   /// ADD_I32_e32 VGPR0, 15
368   /// to
369   /// MOV VGPR1, 15
370   /// ADD_I32_e32 VGPR0, VGPR1
371   ///
372   /// If the operand being legalized is a register, then a COPY will be used
373   /// instead of MOV.
374   void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
375
376   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
377   /// for \p MI.
378   bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
379                       const MachineOperand *MO = nullptr) const;
380
381   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
382   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr *MI) const;
383
384   /// \brief Legalize all operands in this instruction.  This function may
385   /// create new instruction and insert them before \p MI.
386   void legalizeOperands(MachineInstr *MI) const;
387
388   /// \brief Split an SMRD instruction into two smaller loads of half the
389   //  size storing the results in \p Lo and \p Hi.
390   void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC,
391                  unsigned HalfImmOp, unsigned HalfSGPROp,
392                  MachineInstr *&Lo, MachineInstr *&Hi) const;
393
394   void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI,
395                       SmallVectorImpl<MachineInstr *> &Worklist) const;
396
397   /// \brief Replace this instruction's opcode with the equivalent VALU
398   /// opcode.  This function will also move the users of \p MI to the
399   /// VALU if necessary.
400   void moveToVALU(MachineInstr &MI) const;
401
402   unsigned calculateIndirectAddress(unsigned RegIndex,
403                                     unsigned Channel) const override;
404
405   const TargetRegisterClass *getIndirectAddrRegClass() const override;
406
407   MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
408                                          MachineBasicBlock::iterator I,
409                                          unsigned ValueReg,
410                                          unsigned Address,
411                                          unsigned OffsetReg) const override;
412
413   MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
414                                         MachineBasicBlock::iterator I,
415                                         unsigned ValueReg,
416                                         unsigned Address,
417                                         unsigned OffsetReg) const override;
418   void reserveIndirectRegisters(BitVector &Reserved,
419                                 const MachineFunction &MF) const;
420
421   void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I,
422               unsigned SavReg, unsigned IndexReg) const;
423
424   void insertNOPs(MachineBasicBlock::iterator MI, int Count) const;
425
426   /// \brief Returns the operand named \p Op.  If \p MI does not have an
427   /// operand named \c Op, this function returns nullptr.
428   LLVM_READONLY
429   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
430
431   LLVM_READONLY
432   const MachineOperand *getNamedOperand(const MachineInstr &MI,
433                                         unsigned OpName) const {
434     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
435   }
436
437   /// Get required immediate operand
438   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
439     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
440     return MI.getOperand(Idx).getImm();
441   }
442
443   uint64_t getDefaultRsrcDataFormat() const;
444   uint64_t getScratchRsrcWords23() const;
445 };
446
447 namespace AMDGPU {
448   LLVM_READONLY
449   int getVOPe64(uint16_t Opcode);
450
451   LLVM_READONLY
452   int getVOPe32(uint16_t Opcode);
453
454   LLVM_READONLY
455   int getCommuteRev(uint16_t Opcode);
456
457   LLVM_READONLY
458   int getCommuteOrig(uint16_t Opcode);
459
460   LLVM_READONLY
461   int getAddr64Inst(uint16_t Opcode);
462
463   LLVM_READONLY
464   int getAtomicRetOp(uint16_t Opcode);
465
466   LLVM_READONLY
467   int getAtomicNoRetOp(uint16_t Opcode);
468
469   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
470   const uint64_t RSRC_TID_ENABLE = 1LL << 55;
471
472 } // End namespace AMDGPU
473
474 namespace SI {
475 namespace KernelInputOffsets {
476
477 /// Offsets in bytes from the start of the input buffer
478 enum Offsets {
479   NGROUPS_X = 0,
480   NGROUPS_Y = 4,
481   NGROUPS_Z = 8,
482   GLOBAL_SIZE_X = 12,
483   GLOBAL_SIZE_Y = 16,
484   GLOBAL_SIZE_Z = 20,
485   LOCAL_SIZE_X = 24,
486   LOCAL_SIZE_Y = 28,
487   LOCAL_SIZE_Z = 32
488 };
489
490 } // End namespace KernelInputOffsets
491 } // End namespace SI
492
493 } // End namespace llvm
494
495 #endif