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 22 namespace { 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 30 namespace llvm { 31 32 namespace AMDGPU { 33 struct ImageDimIntrinsicInfo; 34 } 35 36 class AMDGPUInstrInfo; 37 class AMDGPURegisterBankInfo; 38 class AMDGPUTargetMachine; 39 class BlockFrequencyInfo; 40 class ProfileSummaryInfo; 41 class GCNSubtarget; 42 class MachineInstr; 43 class MachineIRBuilder; 44 class MachineOperand; 45 class MachineRegisterInfo; 46 class RegisterBank; 47 class SIInstrInfo; 48 class SIMachineFunctionInfo; 49 class SIRegisterInfo; 50 class TargetRegisterClass; 51 52 class AMDGPUInstructionSelector final : public InstructionSelector { 53 private: 54 MachineRegisterInfo *MRI; 55 const GCNSubtarget *Subtarget; 56 57 public: 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 69 private: 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 bool selectG_SBFX_UBFX(MachineInstr &I) const; 113 114 bool selectInterpP1F16(MachineInstr &MI) const; 115 bool selectWritelane(MachineInstr &MI) const; 116 bool selectDivScale(MachineInstr &MI) const; 117 bool selectIntrinsicIcmp(MachineInstr &MI) const; 118 bool selectBallot(MachineInstr &I) const; 119 bool selectRelocConstant(MachineInstr &I) const; 120 bool selectGroupStaticSize(MachineInstr &I) const; 121 bool selectReturnAddress(MachineInstr &I) const; 122 bool selectG_INTRINSIC(MachineInstr &I) const; 123 124 bool selectEndCfIntrinsic(MachineInstr &MI) const; 125 bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 126 bool selectDSGWSIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const; 127 bool selectDSAppendConsume(MachineInstr &MI, bool IsAppend) const; 128 bool selectSBarrier(MachineInstr &MI) const; 129 130 bool selectImageIntrinsic(MachineInstr &MI, 131 const AMDGPU::ImageDimIntrinsicInfo *Intr) const; 132 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const; 133 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const; 134 bool selectG_ICMP(MachineInstr &I) const; 135 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const; 136 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI, 137 SmallVectorImpl<GEPInfo> &AddrInfo) const; 138 bool selectSMRD(MachineInstr &I, ArrayRef<GEPInfo> AddrInfo) const; 139 140 void initM0(MachineInstr &I) const; 141 bool selectG_LOAD_STORE_ATOMICRMW(MachineInstr &I) const; 142 bool selectG_AMDGPU_ATOMIC_CMPXCHG(MachineInstr &I) const; 143 bool selectG_SELECT(MachineInstr &I) const; 144 bool selectG_BRCOND(MachineInstr &I) const; 145 bool selectG_GLOBAL_VALUE(MachineInstr &I) const; 146 bool selectG_PTRMASK(MachineInstr &I) const; 147 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const; 148 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const; 149 bool selectG_SHUFFLE_VECTOR(MachineInstr &I) const; 150 bool selectAMDGPU_BUFFER_ATOMIC_FADD(MachineInstr &I) const; 151 bool selectGlobalAtomicFadd(MachineInstr &I, MachineOperand &AddrOp, 152 MachineOperand &DataOp) const; 153 bool selectBVHIntrinsic(MachineInstr &I) const; 154 155 std::pair<Register, unsigned> selectVOP3ModsImpl(MachineOperand &Root, 156 bool AllowAbs = true) const; 157 158 InstructionSelector::ComplexRendererFns 159 selectVCSRC(MachineOperand &Root) const; 160 161 InstructionSelector::ComplexRendererFns 162 selectVSRC0(MachineOperand &Root) const; 163 164 InstructionSelector::ComplexRendererFns 165 selectVOP3Mods0(MachineOperand &Root) const; 166 InstructionSelector::ComplexRendererFns 167 selectVOP3BMods0(MachineOperand &Root) const; 168 InstructionSelector::ComplexRendererFns 169 selectVOP3OMods(MachineOperand &Root) const; 170 InstructionSelector::ComplexRendererFns 171 selectVOP3Mods(MachineOperand &Root) const; 172 InstructionSelector::ComplexRendererFns 173 selectVOP3BMods(MachineOperand &Root) const; 174 175 ComplexRendererFns selectVOP3NoMods(MachineOperand &Root) const; 176 177 InstructionSelector::ComplexRendererFns 178 selectVOP3Mods_nnan(MachineOperand &Root) const; 179 180 std::pair<Register, unsigned> 181 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI) const; 182 183 InstructionSelector::ComplexRendererFns 184 selectVOP3PMods(MachineOperand &Root) const; 185 186 InstructionSelector::ComplexRendererFns 187 selectVOP3OpSelMods(MachineOperand &Root) const; 188 189 InstructionSelector::ComplexRendererFns 190 selectSmrdImm(MachineOperand &Root) const; 191 InstructionSelector::ComplexRendererFns 192 selectSmrdImm32(MachineOperand &Root) const; 193 InstructionSelector::ComplexRendererFns 194 selectSmrdSgpr(MachineOperand &Root) const; 195 196 std::pair<Register, int> selectFlatOffsetImpl(MachineOperand &Root, 197 uint64_t FlatVariant) const; 198 199 InstructionSelector::ComplexRendererFns 200 selectFlatOffset(MachineOperand &Root) const; 201 InstructionSelector::ComplexRendererFns 202 selectGlobalOffset(MachineOperand &Root) const; 203 InstructionSelector::ComplexRendererFns 204 selectScratchOffset(MachineOperand &Root) const; 205 206 InstructionSelector::ComplexRendererFns 207 selectGlobalSAddr(MachineOperand &Root) const; 208 209 InstructionSelector::ComplexRendererFns 210 selectScratchSAddr(MachineOperand &Root) const; 211 212 InstructionSelector::ComplexRendererFns 213 selectMUBUFScratchOffen(MachineOperand &Root) const; 214 InstructionSelector::ComplexRendererFns 215 selectMUBUFScratchOffset(MachineOperand &Root) const; 216 217 bool isDSOffsetLegal(Register Base, int64_t Offset) const; 218 bool isDSOffset2Legal(Register Base, int64_t Offset0, int64_t Offset1, 219 unsigned Size) const; 220 221 std::pair<Register, unsigned> 222 selectDS1Addr1OffsetImpl(MachineOperand &Root) const; 223 InstructionSelector::ComplexRendererFns 224 selectDS1Addr1Offset(MachineOperand &Root) const; 225 226 InstructionSelector::ComplexRendererFns 227 selectDS64Bit4ByteAligned(MachineOperand &Root) const; 228 229 InstructionSelector::ComplexRendererFns 230 selectDS128Bit8ByteAligned(MachineOperand &Root) const; 231 232 std::pair<Register, unsigned> selectDSReadWrite2Impl(MachineOperand &Root, 233 unsigned size) const; 234 InstructionSelector::ComplexRendererFns 235 selectDSReadWrite2(MachineOperand &Root, unsigned size) const; 236 237 std::pair<Register, int64_t> 238 getPtrBaseWithConstantOffset(Register Root, 239 const MachineRegisterInfo &MRI) const; 240 241 // Parse out a chain of up to two g_ptr_add instructions. 242 // g_ptr_add (n0, _) 243 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3)) 244 struct MUBUFAddressData { 245 Register N0, N2, N3; 246 int64_t Offset = 0; 247 }; 248 249 bool shouldUseAddr64(MUBUFAddressData AddrData) const; 250 251 void splitIllegalMUBUFOffset(MachineIRBuilder &B, 252 Register &SOffset, int64_t &ImmOffset) const; 253 254 MUBUFAddressData parseMUBUFAddress(Register Src) const; 255 256 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr, 257 Register &RSrcReg, Register &SOffset, 258 int64_t &Offset) const; 259 260 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg, 261 Register &SOffset, int64_t &Offset) const; 262 263 InstructionSelector::ComplexRendererFns 264 selectMUBUFAddr64(MachineOperand &Root) const; 265 266 InstructionSelector::ComplexRendererFns 267 selectMUBUFOffset(MachineOperand &Root) const; 268 269 InstructionSelector::ComplexRendererFns 270 selectMUBUFOffsetAtomic(MachineOperand &Root) const; 271 272 InstructionSelector::ComplexRendererFns 273 selectMUBUFAddr64Atomic(MachineOperand &Root) const; 274 275 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const; 276 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const; 277 278 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 279 int OpIdx = -1) const; 280 281 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 282 int OpIdx) const; 283 284 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 285 int OpIdx) const; 286 287 void renderBitcastImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 288 int OpIdx) const; 289 290 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 291 int OpIdx) const; 292 void renderExtractCPol(MachineInstrBuilder &MIB, const MachineInstr &MI, 293 int OpIdx) const; 294 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI, 295 int OpIdx) const; 296 void renderSetGLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 297 int OpIdx) const; 298 299 void renderFrameIndex(MachineInstrBuilder &MIB, const MachineInstr &MI, 300 int OpIdx) const; 301 302 bool isInlineImmediate16(int64_t Imm) const; 303 bool isInlineImmediate32(int64_t Imm) const; 304 bool isInlineImmediate64(int64_t Imm) const; 305 bool isInlineImmediate(const APFloat &Imm) const; 306 307 const SIInstrInfo &TII; 308 const SIRegisterInfo &TRI; 309 const AMDGPURegisterBankInfo &RBI; 310 const AMDGPUTargetMachine &TM; 311 const GCNSubtarget &STI; 312 bool EnableLateStructurizeCFG; 313 #define GET_GLOBALISEL_PREDICATES_DECL 314 #define AMDGPUSubtarget GCNSubtarget 315 #include "AMDGPUGenGlobalISel.inc" 316 #undef GET_GLOBALISEL_PREDICATES_DECL 317 #undef AMDGPUSubtarget 318 319 #define GET_GLOBALISEL_TEMPORARIES_DECL 320 #include "AMDGPUGenGlobalISel.inc" 321 #undef GET_GLOBALISEL_TEMPORARIES_DECL 322 }; 323 324 } // End llvm namespace. 325 #endif 326