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 "llvm/CodeGen/GlobalISel/InstructionSelector.h" 17#include "llvm/CodeGen/Register.h" 18#include "llvm/IR/InstrTypes.h" 19#include "llvm/IR/Intrinsics.h" 20#include "llvm/IR/IntrinsicsAMDGPU.h" 21 22namespace { 23#define GET_GLOBALISEL_PREDICATE_BITSET 24#define AMDGPUSubtarget GCNSubtarget 25#include "AMDGPUGenGlobalISel.inc" 26#undef GET_GLOBALISEL_PREDICATE_BITSET 27#undef AMDGPUSubtarget 28} 29 30namespace llvm { 31 32namespace AMDGPU { 33struct ImageDimIntrinsicInfo; 34} 35 36class AMDGPUInstrInfo; 37class AMDGPURegisterBankInfo; 38class AMDGPUTargetMachine; 39class BlockFrequencyInfo; 40class ProfileSummaryInfo; 41class GCNSubtarget; 42class MachineInstr; 43class MachineIRBuilder; 44class MachineOperand; 45class MachineRegisterInfo; 46class RegisterBank; 47class SIInstrInfo; 48class SIMachineFunctionInfo; 49class SIRegisterInfo; 50class TargetRegisterClass; 51 52class AMDGPUInstructionSelector final : public InstructionSelector { 53private: 54 MachineRegisterInfo *MRI; 55 const GCNSubtarget *Subtarget; 56 57public: 58 AMDGPUInstructionSelector(const GCNSubtarget &STI, 59 const AMDGPURegisterBankInfo &RBI, 60 const AMDGPUTargetMachine &TM); 61 62 bool select(MachineInstr &I) override; 63 static const char *getName(); 64 65 void setupMF(MachineFunction &MF, GISelKnownBits *KB, 66 CodeGenCoverage &CoverageInfo, ProfileSummaryInfo *PSI, 67 BlockFrequencyInfo *BFI) override; 68 69private: 70 struct GEPInfo { 71 const MachineInstr &GEP; 72 SmallVector<unsigned, 2> SgprParts; 73 SmallVector<unsigned, 2> VgprParts; 74 int64_t Imm; 75 GEPInfo(const MachineInstr &GEP) : GEP(GEP), Imm(0) { } 76 }; 77 78 bool isSGPR(Register Reg) const; 79 80 bool isInstrUniform(const MachineInstr &MI) const; 81 bool isVCC(Register Reg, const MachineRegisterInfo &MRI) const; 82 83 const RegisterBank *getArtifactRegBank( 84 Register Reg, const MachineRegisterInfo &MRI, 85 const TargetRegisterInfo &TRI) const; 86 87 /// tblgen-erated 'select' implementation. 88 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 89 90 MachineOperand getSubOperand64(MachineOperand &MO, 91 const TargetRegisterClass &SubRC, 92 unsigned SubIdx) const; 93 94 bool constrainCopyLikeIntrin(MachineInstr &MI, unsigned NewOpc) const; 95 bool selectCOPY(MachineInstr &I) const; 96 bool selectPHI(MachineInstr &I) const; 97 bool selectG_TRUNC(MachineInstr &I) const; 98 bool selectG_SZA_EXT(MachineInstr &I) const; 99 bool selectG_CONSTANT(MachineInstr &I) const; 100 bool selectG_FNEG(MachineInstr &I) const; 101 bool selectG_FABS(MachineInstr &I) const; 102 bool selectG_AND_OR_XOR(MachineInstr &I) const; 103 bool selectG_ADD_SUB(MachineInstr &I) const; 104 bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const; 105 bool selectG_EXTRACT(MachineInstr &I) const; 106 bool selectG_MERGE_VALUES(MachineInstr &I) const; 107 bool selectG_UNMERGE_VALUES(MachineInstr &I) const; 108 bool selectG_BUILD_VECTOR_TRUNC(MachineInstr &I) const; 109 bool selectG_PTR_ADD(MachineInstr &I) const; 110 bool selectG_IMPLICIT_DEF(MachineInstr &I) const; 111 bool selectG_INSERT(MachineInstr &I) const; 112 113 bool selectInterpP1F16(MachineInstr &MI) const; 114 bool selectWritelane(MachineInstr &MI) const; 115 bool selectDivScale(MachineInstr &MI) const; 116 bool selectIntrinsicIcmp(MachineInstr &MI) const; 117 bool selectBallot(MachineInstr &I) const; 118 bool selectRelocConstant(MachineInstr &I) const; 119 bool selectGroupStaticSize(MachineInstr &I) const; 120 bool selectReturnAddress(MachineInstr &I) const; 121 bool selectG_INTRINSIC(MachineInstr &I) const; 122 123 bool selectEndCfIntrinsic(MachineInstr &MI) const; 124 bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 125 bool selectDSGWSIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 126 bool selectDSAppendConsume(MachineInstr &MI, bool IsAppend) const; 127 bool selectSBarrier(MachineInstr &MI) const; 128 129 bool selectImageIntrinsic(MachineInstr &MI, 130 const AMDGPU::ImageDimIntrinsicInfo *Intr) const; 131 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const; 132 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const; 133 bool selectG_ICMP(MachineInstr &I) const; 134 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const; 135 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI, 136 SmallVectorImpl<GEPInfo> &AddrInfo) const; 137 bool selectSMRD(MachineInstr &I, ArrayRef<GEPInfo> AddrInfo) const; 138 139 void initM0(MachineInstr &I) const; 140 bool selectG_LOAD_STORE_ATOMICRMW(MachineInstr &I) const; 141 bool selectG_AMDGPU_ATOMIC_CMPXCHG(MachineInstr &I) const; 142 bool selectG_SELECT(MachineInstr &I) const; 143 bool selectG_BRCOND(MachineInstr &I) const; 144 bool selectG_GLOBAL_VALUE(MachineInstr &I) const; 145 bool selectG_PTRMASK(MachineInstr &I) const; 146 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const; 147 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const; 148 bool selectG_SHUFFLE_VECTOR(MachineInstr &I) const; 149 bool selectAMDGPU_BUFFER_ATOMIC_FADD(MachineInstr &I) const; 150 bool selectGlobalAtomicFadd(MachineInstr &I, MachineOperand &AddrOp, 151 MachineOperand &DataOp) const; 152 bool selectBVHIntrinsic(MachineInstr &I) const; 153 154 std::pair<Register, unsigned> selectVOP3ModsImpl(MachineOperand &Root, 155 bool AllowAbs = true) const; 156 157 InstructionSelector::ComplexRendererFns 158 selectVCSRC(MachineOperand &Root) const; 159 160 InstructionSelector::ComplexRendererFns 161 selectVSRC0(MachineOperand &Root) const; 162 163 InstructionSelector::ComplexRendererFns 164 selectVOP3Mods0(MachineOperand &Root) const; 165 InstructionSelector::ComplexRendererFns 166 selectVOP3BMods0(MachineOperand &Root) const; 167 InstructionSelector::ComplexRendererFns 168 selectVOP3OMods(MachineOperand &Root) const; 169 InstructionSelector::ComplexRendererFns 170 selectVOP3Mods(MachineOperand &Root) const; 171 InstructionSelector::ComplexRendererFns 172 selectVOP3BMods(MachineOperand &Root) const; 173 174 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const; 175 176 InstructionSelector::ComplexRendererFns 177 selectVOP3Mods_nnan(MachineOperand &Root) const; 178 179 std::pair<Register, unsigned> 180 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI) const; 181 182 InstructionSelector::ComplexRendererFns 183 selectVOP3PMods(MachineOperand &Root) const; 184 185 InstructionSelector::ComplexRendererFns 186 selectVOP3OpSelMods(MachineOperand &Root) const; 187 188 InstructionSelector::ComplexRendererFns 189 selectSmrdImm(MachineOperand &Root) const; 190 InstructionSelector::ComplexRendererFns 191 selectSmrdImm32(MachineOperand &Root) const; 192 InstructionSelector::ComplexRendererFns 193 selectSmrdSgpr(MachineOperand &Root) const; 194 195 std::pair<Register, int> selectFlatOffsetImpl(MachineOperand &Root, 196 uint64_t FlatVariant) const; 197 198 InstructionSelector::ComplexRendererFns 199 selectFlatOffset(MachineOperand &Root) const; 200 InstructionSelector::ComplexRendererFns 201 selectGlobalOffset(MachineOperand &Root) const; 202 InstructionSelector::ComplexRendererFns 203 selectScratchOffset(MachineOperand &Root) const; 204 205 InstructionSelector::ComplexRendererFns 206 selectGlobalSAddr(MachineOperand &Root) const; 207 208 InstructionSelector::ComplexRendererFns 209 selectScratchSAddr(MachineOperand &Root) const; 210 211 InstructionSelector::ComplexRendererFns 212 selectMUBUFScratchOffen(MachineOperand &Root) const; 213 InstructionSelector::ComplexRendererFns 214 selectMUBUFScratchOffset(MachineOperand &Root) const; 215 216 bool isDSOffsetLegal(Register Base, int64_t Offset) const; 217 bool isDSOffset2Legal(Register Base, int64_t Offset0, int64_t Offset1, 218 unsigned Size) const; 219 220 std::pair<Register, unsigned> 221 selectDS1Addr1OffsetImpl(MachineOperand &Root) const; 222 InstructionSelector::ComplexRendererFns 223 selectDS1Addr1Offset(MachineOperand &Root) const; 224 225 InstructionSelector::ComplexRendererFns 226 selectDS64Bit4ByteAligned(MachineOperand &Root) const; 227 228 InstructionSelector::ComplexRendererFns 229 selectDS128Bit8ByteAligned(MachineOperand &Root) const; 230 231 std::pair<Register, unsigned> selectDSReadWrite2Impl(MachineOperand &Root, 232 unsigned size) const; 233 InstructionSelector::ComplexRendererFns 234 selectDSReadWrite2(MachineOperand &Root, unsigned size) const; 235 236 std::pair<Register, int64_t> 237 getPtrBaseWithConstantOffset(Register Root, 238 const MachineRegisterInfo &MRI) const; 239 240 // Parse out a chain of up to two g_ptr_add instructions. 241 // g_ptr_add (n0, _) 242 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3)) 243 struct MUBUFAddressData { 244 Register N0, N2, N3; 245 int64_t Offset = 0; 246 }; 247 248 bool shouldUseAddr64(MUBUFAddressData AddrData) const; 249 250 void splitIllegalMUBUFOffset(MachineIRBuilder &B, 251 Register &SOffset, int64_t &ImmOffset) const; 252 253 MUBUFAddressData parseMUBUFAddress(Register Src) const; 254 255 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr, 256 Register &RSrcReg, Register &SOffset, 257 int64_t &Offset) const; 258 259 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg, 260 Register &SOffset, int64_t &Offset) const; 261 262 InstructionSelector::ComplexRendererFns 263 selectMUBUFAddr64(MachineOperand &Root) const; 264 265 InstructionSelector::ComplexRendererFns 266 selectMUBUFOffset(MachineOperand &Root) const; 267 268 InstructionSelector::ComplexRendererFns 269 selectMUBUFOffsetAtomic(MachineOperand &Root) const; 270 271 InstructionSelector::ComplexRendererFns 272 selectMUBUFAddr64Atomic(MachineOperand &Root) const; 273 274 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const; 275 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const; 276 277 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 278 int OpIdx = -1) const; 279 280 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 281 int OpIdx) const; 282 283 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 284 int OpIdx) const; 285 286 void renderBitcastImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 287 int OpIdx) const; 288 289 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 290 int OpIdx) const; 291 void renderExtractCPol(MachineInstrBuilder &MIB, const MachineInstr &MI, 292 int OpIdx) const; 293 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI, 294 int OpIdx) const; 295 void renderSetGLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 296 int OpIdx) const; 297 298 void renderFrameIndex(MachineInstrBuilder &MIB, const MachineInstr &MI, 299 int OpIdx) const; 300 301 bool isInlineImmediate16(int64_t Imm) const; 302 bool isInlineImmediate32(int64_t Imm) const; 303 bool isInlineImmediate64(int64_t Imm) const; 304 bool isInlineImmediate(const APFloat &Imm) const; 305 306 const SIInstrInfo &TII; 307 const SIRegisterInfo &TRI; 308 const AMDGPURegisterBankInfo &RBI; 309 const AMDGPUTargetMachine &TM; 310 const GCNSubtarget &STI; 311 bool EnableLateStructurizeCFG; 312#define GET_GLOBALISEL_PREDICATES_DECL 313#define AMDGPUSubtarget GCNSubtarget 314#include "AMDGPUGenGlobalISel.inc" 315#undef GET_GLOBALISEL_PREDICATES_DECL 316#undef AMDGPUSubtarget 317 318#define GET_GLOBALISEL_TEMPORARIES_DECL 319#include "AMDGPUGenGlobalISel.inc" 320#undef GET_GLOBALISEL_TEMPORARIES_DECL 321}; 322 323} // End llvm namespace. 324#endif 325