1 | //===-- R600InstrInfo.h - R600 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 R600InstrInfo |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H |
15 | #define LLVM_LIB_TARGET_AMDGPU_R600INSTRINFO_H |
16 | |
17 | #include "R600RegisterInfo.h" |
18 | #include "llvm/CodeGen/TargetInstrInfo.h" |
19 | |
20 | #define |
21 | #include "R600GenInstrInfo.inc" |
22 | |
23 | namespace llvm { |
24 | |
25 | namespace R600InstrFlags { |
26 | enum : uint64_t { |
27 | REGISTER_STORE = UINT64_C(1) << 62, |
28 | REGISTER_LOAD = UINT64_C(1) << 63 |
29 | }; |
30 | } |
31 | |
32 | class DFAPacketizer; |
33 | class MachineFunction; |
34 | class MachineInstr; |
35 | class MachineInstrBuilder; |
36 | class R600Subtarget; |
37 | |
38 | class R600InstrInfo final : public R600GenInstrInfo { |
39 | private: |
40 | const R600RegisterInfo RI; |
41 | const R600Subtarget &ST; |
42 | |
43 | std::vector<std::pair<int, unsigned>> |
44 | (MachineInstr &MI, const DenseMap<unsigned, unsigned> &PV, |
45 | unsigned &ConstCount) const; |
46 | |
47 | MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, |
48 | MachineBasicBlock::iterator I, |
49 | unsigned ValueReg, unsigned Address, |
50 | unsigned OffsetReg, |
51 | unsigned AddrChan) const; |
52 | |
53 | MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, |
54 | MachineBasicBlock::iterator I, |
55 | unsigned ValueReg, unsigned Address, |
56 | unsigned OffsetReg, |
57 | unsigned AddrChan) const; |
58 | public: |
59 | enum BankSwizzle { |
60 | ALU_VEC_012_SCL_210 = 0, |
61 | ALU_VEC_021_SCL_122, |
62 | ALU_VEC_120_SCL_212, |
63 | ALU_VEC_102_SCL_221, |
64 | ALU_VEC_201, |
65 | ALU_VEC_210 |
66 | }; |
67 | |
68 | explicit R600InstrInfo(const R600Subtarget &); |
69 | |
70 | const R600RegisterInfo &getRegisterInfo() const { |
71 | return RI; |
72 | } |
73 | |
74 | void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, |
75 | const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, |
76 | bool KillSrc) const override; |
77 | bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, |
78 | MachineBasicBlock::iterator MBBI) const override; |
79 | |
80 | bool isReductionOp(unsigned opcode) const; |
81 | bool isCubeOp(unsigned opcode) const; |
82 | |
83 | /// \returns true if this \p Opcode represents an ALU instruction. |
84 | bool isALUInstr(unsigned Opcode) const; |
85 | bool hasInstrModifiers(unsigned Opcode) const; |
86 | bool isLDSInstr(unsigned Opcode) const; |
87 | bool isLDSRetInstr(unsigned Opcode) const; |
88 | |
89 | /// \returns true if this \p Opcode represents an ALU instruction or an |
90 | /// instruction that will be lowered in ExpandSpecialInstrs Pass. |
91 | bool canBeConsideredALU(const MachineInstr &MI) const; |
92 | |
93 | bool isTransOnly(unsigned Opcode) const; |
94 | bool isTransOnly(const MachineInstr &MI) const; |
95 | bool isVectorOnly(unsigned Opcode) const; |
96 | bool isVectorOnly(const MachineInstr &MI) const; |
97 | bool isExport(unsigned Opcode) const; |
98 | |
99 | bool usesVertexCache(unsigned Opcode) const; |
100 | bool usesVertexCache(const MachineInstr &MI) const; |
101 | bool usesTextureCache(unsigned Opcode) const; |
102 | bool usesTextureCache(const MachineInstr &MI) const; |
103 | |
104 | bool mustBeLastInClause(unsigned Opcode) const; |
105 | bool usesAddressRegister(MachineInstr &MI) const; |
106 | bool definesAddressRegister(MachineInstr &MI) const; |
107 | bool readsLDSSrcReg(const MachineInstr &MI) const; |
108 | |
109 | /// \returns The operand Index for the Sel operand given an index to one |
110 | /// of the instruction's src operands. |
111 | int getSelIdx(unsigned Opcode, unsigned SrcIdx) const; |
112 | |
113 | /// \returns a pair for each src of an ALU instructions. |
114 | /// The first member of a pair is the register id. |
115 | /// If register is ALU_CONST, second member is SEL. |
116 | /// If register is ALU_LITERAL, second member is IMM. |
117 | /// Otherwise, second member value is undefined. |
118 | SmallVector<std::pair<MachineOperand *, int64_t>, 3> |
119 | getSrcs(MachineInstr &MI) const; |
120 | |
121 | unsigned isLegalUpTo( |
122 | const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, |
123 | const std::vector<R600InstrInfo::BankSwizzle> &Swz, |
124 | const std::vector<std::pair<int, unsigned> > &TransSrcs, |
125 | R600InstrInfo::BankSwizzle TransSwz) const; |
126 | |
127 | bool FindSwizzleForVectorSlot( |
128 | const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, |
129 | std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, |
130 | const std::vector<std::pair<int, unsigned> > &TransSrcs, |
131 | R600InstrInfo::BankSwizzle TransSwz) const; |
132 | |
133 | /// Given the order VEC_012 < VEC_021 < VEC_120 < VEC_102 < VEC_201 < VEC_210 |
134 | /// returns true and the first (in lexical order) BankSwizzle affectation |
135 | /// starting from the one already provided in the Instruction Group MIs that |
136 | /// fits Read Port limitations in BS if available. Otherwise returns false |
137 | /// and undefined content in BS. |
138 | /// isLastAluTrans should be set if the last Alu of MIs will be executed on |
139 | /// Trans ALU. In this case, ValidTSwizzle returns the BankSwizzle value to |
140 | /// apply to the last instruction. |
141 | /// PV holds GPR to PV registers in the Instruction Group MIs. |
142 | bool fitsReadPortLimitations(const std::vector<MachineInstr *> &MIs, |
143 | const DenseMap<unsigned, unsigned> &PV, |
144 | std::vector<BankSwizzle> &BS, |
145 | bool isLastAluTrans) const; |
146 | |
147 | /// An instruction group can only access 2 channel pair (either [XY] or [ZW]) |
148 | /// from KCache bank on R700+. This function check if MI set in input meet |
149 | /// this limitations |
150 | bool fitsConstReadLimitations(const std::vector<MachineInstr *> &) const; |
151 | /// Same but using const index set instead of MI set. |
152 | bool fitsConstReadLimitations(const std::vector<unsigned>&) const; |
153 | |
154 | /// Vector instructions are instructions that must fill all |
155 | /// instruction slots within an instruction group. |
156 | bool isVector(const MachineInstr &MI) const; |
157 | |
158 | bool isMov(unsigned Opcode) const; |
159 | |
160 | DFAPacketizer * |
161 | CreateTargetScheduleState(const TargetSubtargetInfo &) const override; |
162 | |
163 | bool reverseBranchCondition( |
164 | SmallVectorImpl<MachineOperand> &Cond) const override; |
165 | |
166 | bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, |
167 | MachineBasicBlock *&FBB, |
168 | SmallVectorImpl<MachineOperand> &Cond, |
169 | bool AllowModify) const override; |
170 | |
171 | unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, |
172 | MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, |
173 | const DebugLoc &DL, |
174 | int *BytesAdded = nullptr) const override; |
175 | |
176 | unsigned removeBranch(MachineBasicBlock &MBB, |
177 | int *BytesRemoved = nullptr) const override; |
178 | |
179 | bool isPredicated(const MachineInstr &MI) const override; |
180 | |
181 | bool isPredicable(const MachineInstr &MI) const override; |
182 | |
183 | bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, |
184 | BranchProbability Probability) const override; |
185 | |
186 | bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, |
187 | unsigned , |
188 | BranchProbability Probability) const override ; |
189 | |
190 | bool isProfitableToIfCvt(MachineBasicBlock &TMBB, |
191 | unsigned NumTCycles, unsigned , |
192 | MachineBasicBlock &FMBB, |
193 | unsigned NumFCycles, unsigned , |
194 | BranchProbability Probability) const override; |
195 | |
196 | bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred, |
197 | bool SkipDead) const override; |
198 | |
199 | bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, |
200 | MachineBasicBlock &FMBB) const override; |
201 | |
202 | bool PredicateInstruction(MachineInstr &MI, |
203 | ArrayRef<MachineOperand> Pred) const override; |
204 | |
205 | unsigned int getPredicationCost(const MachineInstr &) const override; |
206 | |
207 | unsigned int getInstrLatency(const InstrItineraryData *ItinData, |
208 | const MachineInstr &MI, |
209 | unsigned *PredCost = nullptr) const override; |
210 | |
211 | bool expandPostRAPseudo(MachineInstr &MI) const override; |
212 | |
213 | /// Reserve the registers that may be accessed using indirect addressing. |
214 | void reserveIndirectRegisters(BitVector &Reserved, |
215 | const MachineFunction &MF, |
216 | const R600RegisterInfo &TRI) const; |
217 | |
218 | /// Calculate the "Indirect Address" for the given \p RegIndex and |
219 | /// \p Channel |
220 | /// |
221 | /// We model indirect addressing using a virtual address space that can be |
222 | /// accessed with loads and stores. The "Indirect Address" is the memory |
223 | /// address in this virtual address space that maps to the given \p RegIndex |
224 | /// and \p Channel. |
225 | unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const; |
226 | |
227 | |
228 | /// \returns The register class to be used for loading and storing values |
229 | /// from an "Indirect Address" . |
230 | const TargetRegisterClass *getIndirectAddrRegClass() const; |
231 | |
232 | /// \returns the smallest register index that will be accessed by an indirect |
233 | /// read or write or -1 if indirect addressing is not used by this program. |
234 | int getIndirectIndexBegin(const MachineFunction &MF) const; |
235 | |
236 | /// \returns the largest register index that will be accessed by an indirect |
237 | /// read or write or -1 if indirect addressing is not used by this program. |
238 | int getIndirectIndexEnd(const MachineFunction &MF) const; |
239 | |
240 | /// Build instruction(s) for an indirect register write. |
241 | /// |
242 | /// \returns The instruction that performs the indirect register write |
243 | MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, |
244 | MachineBasicBlock::iterator I, |
245 | unsigned ValueReg, unsigned Address, |
246 | unsigned OffsetReg) const; |
247 | |
248 | /// Build instruction(s) for an indirect register read. |
249 | /// |
250 | /// \returns The instruction that performs the indirect register read |
251 | MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, |
252 | MachineBasicBlock::iterator I, |
253 | unsigned ValueReg, unsigned Address, |
254 | unsigned OffsetReg) const; |
255 | |
256 | unsigned getMaxAlusPerClause() const; |
257 | |
258 | /// buildDefaultInstruction - This function returns a MachineInstr with all |
259 | /// the instruction modifiers initialized to their default values. You can |
260 | /// use this function to avoid manually specifying each instruction modifier |
261 | /// operand when building a new instruction. |
262 | /// |
263 | /// \returns a MachineInstr with all the instruction modifiers initialized |
264 | /// to their default values. |
265 | MachineInstrBuilder buildDefaultInstruction(MachineBasicBlock &MBB, |
266 | MachineBasicBlock::iterator I, |
267 | unsigned Opcode, |
268 | unsigned DstReg, |
269 | unsigned Src0Reg, |
270 | unsigned Src1Reg = 0) const; |
271 | |
272 | MachineInstr *buildSlotOfVectorInstruction(MachineBasicBlock &MBB, |
273 | MachineInstr *MI, |
274 | unsigned Slot, |
275 | unsigned DstReg) const; |
276 | |
277 | MachineInstr *buildMovImm(MachineBasicBlock &BB, |
278 | MachineBasicBlock::iterator I, |
279 | unsigned DstReg, |
280 | uint64_t Imm) const; |
281 | |
282 | MachineInstr *buildMovInstr(MachineBasicBlock *MBB, |
283 | MachineBasicBlock::iterator I, |
284 | unsigned DstReg, unsigned SrcReg) const; |
285 | |
286 | /// Get the index of Op in the MachineInstr. |
287 | /// |
288 | /// \returns -1 if the Instruction does not contain the specified \p Op. |
289 | int getOperandIdx(const MachineInstr &MI, unsigned Op) const; |
290 | |
291 | /// Get the index of \p Op for the given Opcode. |
292 | /// |
293 | /// \returns -1 if the Instruction does not contain the specified \p Op. |
294 | int getOperandIdx(unsigned Opcode, unsigned Op) const; |
295 | |
296 | /// Helper function for setting instruction flag values. |
297 | void setImmOperand(MachineInstr &MI, unsigned Op, int64_t Imm) const; |
298 | |
299 | ///Add one of the MO_FLAG* flags to the specified \p Operand. |
300 | void addFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const; |
301 | |
302 | ///Determine if the specified \p Flag is set on this \p Operand. |
303 | bool isFlagSet(const MachineInstr &MI, unsigned Operand, unsigned Flag) const; |
304 | |
305 | /// \param SrcIdx The register source to set the flag on (e.g src0, src1, src2) |
306 | /// \param Flag The flag being set. |
307 | /// |
308 | /// \returns the operand containing the flags for this instruction. |
309 | MachineOperand &getFlagOp(MachineInstr &MI, unsigned SrcIdx = 0, |
310 | unsigned Flag = 0) const; |
311 | |
312 | /// Clear the specified flag on the instruction. |
313 | void clearFlag(MachineInstr &MI, unsigned Operand, unsigned Flag) const; |
314 | |
315 | // Helper functions that check the opcode for status information |
316 | bool isRegisterStore(const MachineInstr &MI) const { |
317 | return get(Opcode: MI.getOpcode()).TSFlags & R600InstrFlags::REGISTER_STORE; |
318 | } |
319 | |
320 | bool isRegisterLoad(const MachineInstr &MI) const { |
321 | return get(Opcode: MI.getOpcode()).TSFlags & R600InstrFlags::REGISTER_LOAD; |
322 | } |
323 | }; |
324 | |
325 | namespace R600 { |
326 | |
327 | int getLDSNoRetOp(uint16_t Opcode); |
328 | |
329 | } //End namespace AMDGPU |
330 | |
331 | } // End llvm namespace |
332 | |
333 | #endif |
334 | |