LLVM 20.0.0git
AMDGPUInstructionSelector.h
Go to the documentation of this file.
1//===- AMDGPUInstructionSelector --------------------------------*- 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/// \file
9/// This file declares the targeting of the InstructionSelector class for
10/// AMDGPU.
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUINSTRUCTIONSELECTOR_H
14#define LLVM_LIB_TARGET_AMDGPU_AMDGPUINSTRUCTIONSELECTOR_H
15
16#include "SIDefines.h"
18#include "llvm/IR/InstrTypes.h"
19
20namespace {
21#define GET_GLOBALISEL_PREDICATE_BITSET
22#define AMDGPUSubtarget GCNSubtarget
23#include "AMDGPUGenGlobalISel.inc"
24#undef GET_GLOBALISEL_PREDICATE_BITSET
25#undef AMDGPUSubtarget
26}
27
28namespace llvm {
29
30namespace AMDGPU {
31struct ImageDimIntrinsicInfo;
32}
33
34class AMDGPURegisterBankInfo;
35class AMDGPUTargetMachine;
36class BlockFrequencyInfo;
37class ProfileSummaryInfo;
38class GCNSubtarget;
39class MachineInstr;
40class MachineIRBuilder;
41class MachineOperand;
42class MachineRegisterInfo;
43class RegisterBank;
44class SIInstrInfo;
45class SIRegisterInfo;
46class TargetRegisterClass;
47
49private:
51 const GCNSubtarget *Subtarget;
52
53public:
55 const AMDGPURegisterBankInfo &RBI,
56 const AMDGPUTargetMachine &TM);
57
58 bool select(MachineInstr &I) override;
59 static const char *getName();
60
63 BlockFrequencyInfo *BFI) override;
64
65private:
66 struct GEPInfo {
69 int64_t Imm = 0;
70 };
71
72 bool isSGPR(Register Reg) const;
73
74 bool isInstrUniform(const MachineInstr &MI) const;
75 bool isVCC(Register Reg, const MachineRegisterInfo &MRI) const;
76
77 const RegisterBank *getArtifactRegBank(
79 const TargetRegisterInfo &TRI) const;
80
81 /// tblgen-erated 'select' implementation.
82 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
83
84 MachineOperand getSubOperand64(MachineOperand &MO,
85 const TargetRegisterClass &SubRC,
86 unsigned SubIdx) const;
87
88 bool constrainCopyLikeIntrin(MachineInstr &MI, unsigned NewOpc) const;
89 bool selectCOPY(MachineInstr &I) const;
90 bool selectPHI(MachineInstr &I) const;
91 bool selectG_TRUNC(MachineInstr &I) const;
92 bool selectG_SZA_EXT(MachineInstr &I) const;
93 bool selectG_FPEXT(MachineInstr &I) const;
94 bool selectG_FNEG(MachineInstr &I) const;
95 bool selectG_FABS(MachineInstr &I) const;
96 bool selectG_AND_OR_XOR(MachineInstr &I) const;
97 bool selectG_ADD_SUB(MachineInstr &I) const;
98 bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const;
99 bool selectG_AMDGPU_MAD_64_32(MachineInstr &I) const;
100 bool selectG_EXTRACT(MachineInstr &I) const;
101 bool selectG_FMA_FMAD(MachineInstr &I) const;
102 bool selectG_MERGE_VALUES(MachineInstr &I) const;
103 bool selectG_UNMERGE_VALUES(MachineInstr &I) const;
104 bool selectG_BUILD_VECTOR(MachineInstr &I) const;
105 bool selectG_IMPLICIT_DEF(MachineInstr &I) const;
106 bool selectG_INSERT(MachineInstr &I) const;
107 bool selectG_SBFX_UBFX(MachineInstr &I) const;
108
109 bool selectInterpP1F16(MachineInstr &MI) const;
110 bool selectWritelane(MachineInstr &MI) const;
111 bool selectDivScale(MachineInstr &MI) const;
112 bool selectIntrinsicCmp(MachineInstr &MI) const;
113 bool selectBallot(MachineInstr &I) const;
114 bool selectRelocConstant(MachineInstr &I) const;
115 bool selectGroupStaticSize(MachineInstr &I) const;
116 bool selectReturnAddress(MachineInstr &I) const;
117 bool selectG_INTRINSIC(MachineInstr &I) const;
118
119 bool selectEndCfIntrinsic(MachineInstr &MI) const;
120 bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const;
121 bool selectDSGWSIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const;
122 bool selectDSAppendConsume(MachineInstr &MI, bool IsAppend) const;
123 bool selectInitWholeWave(MachineInstr &MI) const;
124 bool selectSBarrier(MachineInstr &MI) const;
125 bool selectDSBvhStackIntrinsic(MachineInstr &MI) const;
126
127 bool selectImageIntrinsic(MachineInstr &MI,
129 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const;
130 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const;
131 bool selectG_ICMP_or_FCMP(MachineInstr &I) const;
132 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const;
133 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI,
134 SmallVectorImpl<GEPInfo> &AddrInfo) const;
135
136 void initM0(MachineInstr &I) const;
137 bool selectG_LOAD_STORE_ATOMICRMW(MachineInstr &I) const;
138 bool selectG_SELECT(MachineInstr &I) const;
139 bool selectG_BRCOND(MachineInstr &I) const;
140 bool selectG_GLOBAL_VALUE(MachineInstr &I) const;
141 bool selectG_PTRMASK(MachineInstr &I) const;
142 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const;
143 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const;
144 bool selectBufferLoadLds(MachineInstr &MI) const;
145 bool selectGlobalLoadLds(MachineInstr &MI) const;
146 bool selectBVHIntrinsic(MachineInstr &I) const;
147 bool selectSMFMACIntrin(MachineInstr &I) const;
148 bool selectPermlaneSwapIntrin(MachineInstr &I, Intrinsic::ID IntrID) const;
149 bool selectWaveAddress(MachineInstr &I) const;
150 bool selectBITOP3(MachineInstr &I) const;
151 bool selectStackRestore(MachineInstr &MI) const;
152 bool selectNamedBarrierInit(MachineInstr &I, Intrinsic::ID IID) const;
153 bool selectNamedBarrierInst(MachineInstr &I, Intrinsic::ID IID) const;
154 bool selectSBarrierSignalIsfirst(MachineInstr &I, Intrinsic::ID IID) const;
155 bool selectSGetBarrierState(MachineInstr &I, Intrinsic::ID IID) const;
156 bool selectSBarrierLeave(MachineInstr &I) const;
157
158 std::pair<Register, unsigned> selectVOP3ModsImpl(Register Src,
159 bool IsCanonicalizing = true,
160 bool AllowAbs = true,
161 bool OpSel = false) const;
162
163 Register copyToVGPRIfSrcFolded(Register Src, unsigned Mods,
164 MachineOperand Root, MachineInstr *InsertPt,
165 bool ForceVGPR = false) const;
166
168 selectVCSRC(MachineOperand &Root) const;
169
171 selectVSRC0(MachineOperand &Root) const;
172
174 selectVOP3Mods0(MachineOperand &Root) const;
176 selectVOP3BMods0(MachineOperand &Root) const;
178 selectVOP3OMods(MachineOperand &Root) const;
180 selectVOP3Mods(MachineOperand &Root) const;
182 selectVOP3ModsNonCanonicalizing(MachineOperand &Root) const;
184 selectVOP3BMods(MachineOperand &Root) const;
185
186 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const;
187
188 std::pair<Register, unsigned>
189 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI,
190 bool IsDOT = false) const;
191
193 selectVOP3PMods(MachineOperand &Root) const;
194
196 selectVOP3PModsDOT(MachineOperand &Root) const;
197
199 selectVOP3PModsNeg(MachineOperand &Root) const;
200
202 selectWMMAOpSelVOP3PMods(MachineOperand &Root) const;
203
205 selectWMMAModsF32NegAbs(MachineOperand &Root) const;
207 selectWMMAModsF16Neg(MachineOperand &Root) const;
209 selectWMMAModsF16NegAbs(MachineOperand &Root) const;
211 selectWMMAVISrc(MachineOperand &Root) const;
213 selectSWMMACIndex8(MachineOperand &Root) const;
215 selectSWMMACIndex16(MachineOperand &Root) const;
216
218 selectVOP3OpSelMods(MachineOperand &Root) const;
219
221 selectVINTERPMods(MachineOperand &Root) const;
223 selectVINTERPModsHi(MachineOperand &Root) const;
224
225 bool selectSmrdOffset(MachineOperand &Root, Register &Base, Register *SOffset,
226 int64_t *Offset) const;
228 selectSmrdImm(MachineOperand &Root) const;
230 selectSmrdImm32(MachineOperand &Root) const;
232 selectSmrdSgpr(MachineOperand &Root) const;
234 selectSmrdSgprImm(MachineOperand &Root) const;
235
236 std::pair<Register, int> selectFlatOffsetImpl(MachineOperand &Root,
237 uint64_t FlatVariant) const;
238
240 selectFlatOffset(MachineOperand &Root) const;
242 selectGlobalOffset(MachineOperand &Root) const;
244 selectScratchOffset(MachineOperand &Root) const;
245
247 selectGlobalSAddr(MachineOperand &Root) const;
248
250 selectScratchSAddr(MachineOperand &Root) const;
251 bool checkFlatScratchSVSSwizzleBug(Register VAddr, Register SAddr,
252 uint64_t ImmOffset) const;
254 selectScratchSVAddr(MachineOperand &Root) const;
255
257 selectMUBUFScratchOffen(MachineOperand &Root) const;
259 selectMUBUFScratchOffset(MachineOperand &Root) const;
260
261 bool isDSOffsetLegal(Register Base, int64_t Offset) const;
262 bool isDSOffset2Legal(Register Base, int64_t Offset0, int64_t Offset1,
263 unsigned Size) const;
264 bool isFlatScratchBaseLegal(Register Addr) const;
265 bool isFlatScratchBaseLegalSV(Register Addr) const;
266 bool isFlatScratchBaseLegalSVImm(Register Addr) const;
267
268 std::pair<Register, unsigned>
269 selectDS1Addr1OffsetImpl(MachineOperand &Root) const;
271 selectDS1Addr1Offset(MachineOperand &Root) const;
272
274 selectDS64Bit4ByteAligned(MachineOperand &Root) const;
275
277 selectDS128Bit8ByteAligned(MachineOperand &Root) const;
278
279 std::pair<Register, unsigned> selectDSReadWrite2Impl(MachineOperand &Root,
280 unsigned size) const;
282 selectDSReadWrite2(MachineOperand &Root, unsigned size) const;
283
284 std::pair<Register, int64_t>
285 getPtrBaseWithConstantOffset(Register Root,
286 const MachineRegisterInfo &MRI) const;
287
288 // Parse out a chain of up to two g_ptr_add instructions.
289 // g_ptr_add (n0, _)
290 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3))
291 struct MUBUFAddressData {
292 Register N0, N2, N3;
293 int64_t Offset = 0;
294 };
295
296 bool shouldUseAddr64(MUBUFAddressData AddrData) const;
297
298 void splitIllegalMUBUFOffset(MachineIRBuilder &B,
299 Register &SOffset, int64_t &ImmOffset) const;
300
301 MUBUFAddressData parseMUBUFAddress(Register Src) const;
302
303 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr,
304 Register &RSrcReg, Register &SOffset,
305 int64_t &Offset) const;
306
307 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg,
308 Register &SOffset, int64_t &Offset) const;
309
311 selectBUFSOffset(MachineOperand &Root) const;
312
314 selectMUBUFAddr64(MachineOperand &Root) const;
315
317 selectMUBUFOffset(MachineOperand &Root) const;
318
319 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const;
320 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const;
321 ComplexRendererFns selectSMRDBufferSgprImm(MachineOperand &Root) const;
322
323 std::pair<Register, unsigned> selectVOP3PMadMixModsImpl(MachineOperand &Root,
324 bool &Matched) const;
325 ComplexRendererFns selectVOP3PMadMixModsExt(MachineOperand &Root) const;
326 ComplexRendererFns selectVOP3PMadMixMods(MachineOperand &Root) const;
327
328 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
329 int OpIdx = -1) const;
330
331 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
332 int OpIdx) const;
333 void renderZextBoolTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
334 int OpIdx) const;
335
336 void renderOpSelTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
337 int OpIdx) const;
338
339 void renderSrcAndDstSelToOpSelXForm_0_0(MachineInstrBuilder &MIB,
340 const MachineInstr &MI,
341 int OpIdx) const;
342
343 void renderSrcAndDstSelToOpSelXForm_0_1(MachineInstrBuilder &MIB,
344 const MachineInstr &MI,
345 int OpIdx) const;
346
347 void renderSrcAndDstSelToOpSelXForm_1_0(MachineInstrBuilder &MIB,
348 const MachineInstr &MI,
349 int OpIdx) const;
350
351 void renderSrcAndDstSelToOpSelXForm_1_1(MachineInstrBuilder &MIB,
352 const MachineInstr &MI,
353 int OpIdx) const;
354
355 void renderDstSelToOpSelXForm(MachineInstrBuilder &MIB,
356 const MachineInstr &MI, int OpIdx) const;
357
358 void renderSrcSelToOpSelXForm(MachineInstrBuilder &MIB,
359 const MachineInstr &MI, int OpIdx) const;
360
361 void renderSrcAndDstSelToOpSelXForm_2_0(MachineInstrBuilder &MIB,
362 const MachineInstr &MI,
363 int OpIdx) const;
364
365 void renderDstSelToOpSel3XFormXForm(MachineInstrBuilder &MIB,
366 const MachineInstr &MI, int OpIdx) const;
367
368 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
369 int OpIdx) const;
370
371 void renderBitcastFPImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
372 int OpIdx) const;
373
374 void renderBitcastFPImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
375 int OpIdx) const {
376 renderBitcastFPImm(MIB, MI, OpIdx);
377 }
378 void renderBitcastFPImm64(MachineInstrBuilder &MIB, const MachineInstr &MI,
379 int OpIdx) const {
380 renderBitcastFPImm(MIB, MI, OpIdx);
381 }
382
383 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
384 int OpIdx) const;
385 void renderExtractCPol(MachineInstrBuilder &MIB, const MachineInstr &MI,
386 int OpIdx) const;
387 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI,
388 int OpIdx) const;
389 void renderExtractCpolSetGLC(MachineInstrBuilder &MIB, const MachineInstr &MI,
390 int OpIdx) const;
391
392 void renderFrameIndex(MachineInstrBuilder &MIB, const MachineInstr &MI,
393 int OpIdx) const;
394
395 void renderFPPow2ToExponent(MachineInstrBuilder &MIB, const MachineInstr &MI,
396 int OpIdx) const;
397
398 void renderRoundMode(MachineInstrBuilder &MIB, const MachineInstr &MI,
399 int OpIdx) const;
400 void renderScaledMAIIntrinsicOperand(MachineInstrBuilder &MIB,
401 const MachineInstr &MI, int OpIdx) const;
402
403 bool isInlineImmediate(const APInt &Imm) const;
404 bool isInlineImmediate(const APFloat &Imm) const;
405
406 // Returns true if TargetOpcode::G_AND MachineInstr `MI`'s masking of the
407 // shift amount operand's `ShAmtBits` bits is unneeded.
408 bool isUnneededShiftMask(const MachineInstr &MI, unsigned ShAmtBits) const;
409
410 const SIInstrInfo &TII;
411 const SIRegisterInfo &TRI;
412 const AMDGPURegisterBankInfo &RBI;
413 const AMDGPUTargetMachine &TM;
414 const GCNSubtarget &STI;
415#define GET_GLOBALISEL_PREDICATES_DECL
416#define AMDGPUSubtarget GCNSubtarget
417#include "AMDGPUGenGlobalISel.inc"
418#undef GET_GLOBALISEL_PREDICATES_DECL
419#undef AMDGPUSubtarget
420
421#define GET_GLOBALISEL_TEMPORARIES_DECL
422#include "AMDGPUGenGlobalISel.inc"
423#undef GET_GLOBALISEL_TEMPORARIES_DECL
424};
425
426} // End llvm namespace.
427#endif
unsigned Intr
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
uint64_t Addr
uint64_t Size
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned Reg
#define P(N)
static const char * getName()
bool select(MachineInstr &I) override
Select the (possibly generic) instruction I to only use target-specific opcodes.
void setupMF(MachineFunction &MF, GISelKnownBits *KB, CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) override
Setup per-MF executor state.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:673
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Analysis providing profile information.
This class implements the register bank concept.
Definition: RegisterBank.h:28
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480