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