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 AMDGPURegisterBankInfo; 34 class AMDGPUTargetMachine; 35 class BlockFrequencyInfo; 36 class ProfileSummaryInfo; 37 class GCNSubtarget; 38 class MachineInstr; 39 class MachineIRBuilder; 40 class MachineOperand; 41 class MachineRegisterInfo; 42 class RegisterBank; 43 class SIInstrInfo; 44 class SIRegisterInfo; 45 class TargetRegisterClass; 46 47 class AMDGPUInstructionSelector final : public InstructionSelector { 48 private: 49 MachineRegisterInfo *MRI; 50 const GCNSubtarget *Subtarget; 51 52 public: 53 AMDGPUInstructionSelector(const GCNSubtarget &STI, 54 const AMDGPURegisterBankInfo &RBI, 55 const AMDGPUTargetMachine &TM); 56 57 bool select(MachineInstr &I) override; 58 static const char *getName(); 59 60 void setupMF(MachineFunction &MF, GISelKnownBits *KB, 61 CodeGenCoverage &CoverageInfo, ProfileSummaryInfo *PSI, 62 BlockFrequencyInfo *BFI) override; 63 64 private: 65 struct GEPInfo { 66 SmallVector<unsigned, 2> SgprParts; 67 SmallVector<unsigned, 2> VgprParts; 68 int64_t Imm = 0; 69 }; 70 71 bool isSGPR(Register Reg) const; 72 73 bool isInstrUniform(const MachineInstr &MI) const; 74 bool isVCC(Register Reg, const MachineRegisterInfo &MRI) const; 75 76 const RegisterBank *getArtifactRegBank( 77 Register Reg, const MachineRegisterInfo &MRI, 78 const TargetRegisterInfo &TRI) const; 79 80 /// tblgen-erated 'select' implementation. 81 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 82 83 MachineOperand getSubOperand64(MachineOperand &MO, 84 const TargetRegisterClass &SubRC, 85 unsigned SubIdx) const; 86 87 bool constrainCopyLikeIntrin(MachineInstr &MI, unsigned NewOpc) const; 88 bool selectCOPY(MachineInstr &I) const; 89 bool selectPHI(MachineInstr &I) const; 90 bool selectG_TRUNC(MachineInstr &I) const; 91 bool selectG_SZA_EXT(MachineInstr &I) const; 92 bool selectG_CONSTANT(MachineInstr &I) const; 93 bool selectG_FNEG(MachineInstr &I) const; 94 bool selectG_FABS(MachineInstr &I) const; 95 bool selectG_AND_OR_XOR(MachineInstr &I) const; 96 bool selectG_ADD_SUB(MachineInstr &I) const; 97 bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const; 98 bool selectG_AMDGPU_MAD_64_32(MachineInstr &I) const; 99 bool selectG_EXTRACT(MachineInstr &I) const; 100 bool selectG_FMA_FMAD(MachineInstr &I) const; 101 bool selectG_MERGE_VALUES(MachineInstr &I) const; 102 bool selectG_UNMERGE_VALUES(MachineInstr &I) const; 103 bool selectG_BUILD_VECTOR(MachineInstr &I) const; 104 bool selectG_PTR_ADD(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 selectSBarrier(MachineInstr &MI) const; 124 bool selectDSBvhStackIntrinsic(MachineInstr &MI) const; 125 126 bool selectImageIntrinsic(MachineInstr &MI, 127 const AMDGPU::ImageDimIntrinsicInfo *Intr) const; 128 bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const; 129 int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const; 130 bool selectG_ICMP(MachineInstr &I) const; 131 bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const; 132 void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI, 133 SmallVectorImpl<GEPInfo> &AddrInfo) const; 134 135 void initM0(MachineInstr &I) const; 136 bool selectG_LOAD_STORE_ATOMICRMW(MachineInstr &I) const; 137 bool selectG_SELECT(MachineInstr &I) const; 138 bool selectG_BRCOND(MachineInstr &I) const; 139 bool selectG_GLOBAL_VALUE(MachineInstr &I) const; 140 bool selectG_PTRMASK(MachineInstr &I) const; 141 bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const; 142 bool selectG_INSERT_VECTOR_ELT(MachineInstr &I) const; 143 bool selectBufferLoadLds(MachineInstr &MI) const; 144 bool selectGlobalLoadLds(MachineInstr &MI) const; 145 bool selectBVHIntrinsic(MachineInstr &I) const; 146 bool selectSMFMACIntrin(MachineInstr &I) const; 147 bool selectWaveAddress(MachineInstr &I) const; 148 149 std::pair<Register, unsigned> 150 selectVOP3ModsImpl(MachineOperand &Root, bool AllowAbs = true, 151 bool OpSel = false) const; 152 153 Register copyToVGPRIfSrcFolded(Register Src, unsigned Mods, 154 MachineOperand Root, MachineInstr *InsertPt, 155 bool ForceVGPR = false) 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 std::pair<Register, unsigned> 177 selectVOP3PModsImpl(Register Src, const MachineRegisterInfo &MRI, 178 bool IsDOT = false) const; 179 180 InstructionSelector::ComplexRendererFns 181 selectVOP3PMods(MachineOperand &Root) const; 182 183 InstructionSelector::ComplexRendererFns 184 selectVOP3PModsDOT(MachineOperand &Root) const; 185 186 InstructionSelector::ComplexRendererFns 187 selectDotIUVOP3PMods(MachineOperand &Root) const; 188 189 InstructionSelector::ComplexRendererFns 190 selectWMMAOpSelVOP3PMods(MachineOperand &Root) const; 191 192 InstructionSelector::ComplexRendererFns 193 selectVOP3OpSelMods(MachineOperand &Root) const; 194 195 InstructionSelector::ComplexRendererFns 196 selectVINTERPMods(MachineOperand &Root) const; 197 InstructionSelector::ComplexRendererFns 198 selectVINTERPModsHi(MachineOperand &Root) const; 199 200 bool selectSmrdOffset(MachineOperand &Root, Register &Base, Register *SOffset, 201 int64_t *Offset) const; 202 InstructionSelector::ComplexRendererFns 203 selectSmrdImm(MachineOperand &Root) const; 204 InstructionSelector::ComplexRendererFns 205 selectSmrdImm32(MachineOperand &Root) const; 206 InstructionSelector::ComplexRendererFns 207 selectSmrdSgpr(MachineOperand &Root) const; 208 InstructionSelector::ComplexRendererFns 209 selectSmrdSgprImm(MachineOperand &Root) const; 210 211 std::pair<Register, int> selectFlatOffsetImpl(MachineOperand &Root, 212 uint64_t FlatVariant) const; 213 214 InstructionSelector::ComplexRendererFns 215 selectFlatOffset(MachineOperand &Root) const; 216 InstructionSelector::ComplexRendererFns 217 selectGlobalOffset(MachineOperand &Root) const; 218 InstructionSelector::ComplexRendererFns 219 selectScratchOffset(MachineOperand &Root) const; 220 221 InstructionSelector::ComplexRendererFns 222 selectGlobalSAddr(MachineOperand &Root) const; 223 224 InstructionSelector::ComplexRendererFns 225 selectScratchSAddr(MachineOperand &Root) const; 226 bool checkFlatScratchSVSSwizzleBug(Register VAddr, Register SAddr, 227 uint64_t ImmOffset) const; 228 InstructionSelector::ComplexRendererFns 229 selectScratchSVAddr(MachineOperand &Root) const; 230 231 InstructionSelector::ComplexRendererFns 232 selectMUBUFScratchOffen(MachineOperand &Root) const; 233 InstructionSelector::ComplexRendererFns 234 selectMUBUFScratchOffset(MachineOperand &Root) const; 235 236 bool isDSOffsetLegal(Register Base, int64_t Offset) const; 237 bool isDSOffset2Legal(Register Base, int64_t Offset0, int64_t Offset1, 238 unsigned Size) const; 239 240 std::pair<Register, unsigned> 241 selectDS1Addr1OffsetImpl(MachineOperand &Root) const; 242 InstructionSelector::ComplexRendererFns 243 selectDS1Addr1Offset(MachineOperand &Root) const; 244 245 InstructionSelector::ComplexRendererFns 246 selectDS64Bit4ByteAligned(MachineOperand &Root) const; 247 248 InstructionSelector::ComplexRendererFns 249 selectDS128Bit8ByteAligned(MachineOperand &Root) const; 250 251 std::pair<Register, unsigned> selectDSReadWrite2Impl(MachineOperand &Root, 252 unsigned size) const; 253 InstructionSelector::ComplexRendererFns 254 selectDSReadWrite2(MachineOperand &Root, unsigned size) const; 255 256 std::pair<Register, int64_t> 257 getPtrBaseWithConstantOffset(Register Root, 258 const MachineRegisterInfo &MRI) const; 259 260 // Parse out a chain of up to two g_ptr_add instructions. 261 // g_ptr_add (n0, _) 262 // g_ptr_add (n0, (n1 = g_ptr_add n2, n3)) 263 struct MUBUFAddressData { 264 Register N0, N2, N3; 265 int64_t Offset = 0; 266 }; 267 268 bool shouldUseAddr64(MUBUFAddressData AddrData) const; 269 270 void splitIllegalMUBUFOffset(MachineIRBuilder &B, 271 Register &SOffset, int64_t &ImmOffset) const; 272 273 MUBUFAddressData parseMUBUFAddress(Register Src) const; 274 275 bool selectMUBUFAddr64Impl(MachineOperand &Root, Register &VAddr, 276 Register &RSrcReg, Register &SOffset, 277 int64_t &Offset) const; 278 279 bool selectMUBUFOffsetImpl(MachineOperand &Root, Register &RSrcReg, 280 Register &SOffset, int64_t &Offset) const; 281 282 InstructionSelector::ComplexRendererFns 283 selectMUBUFAddr64(MachineOperand &Root) const; 284 285 InstructionSelector::ComplexRendererFns 286 selectMUBUFOffset(MachineOperand &Root) const; 287 288 InstructionSelector::ComplexRendererFns 289 selectMUBUFOffsetAtomic(MachineOperand &Root) const; 290 291 InstructionSelector::ComplexRendererFns 292 selectMUBUFAddr64Atomic(MachineOperand &Root) const; 293 294 ComplexRendererFns selectSMRDBufferImm(MachineOperand &Root) const; 295 ComplexRendererFns selectSMRDBufferImm32(MachineOperand &Root) const; 296 ComplexRendererFns selectSMRDBufferSgprImm(MachineOperand &Root) const; 297 298 std::pair<Register, unsigned> selectVOP3PMadMixModsImpl(MachineOperand &Root, 299 bool &Matched) const; 300 ComplexRendererFns selectVOP3PMadMixMods(MachineOperand &Root) const; 301 302 void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI, 303 int OpIdx = -1) const; 304 305 void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 306 int OpIdx) const; 307 308 void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 309 int OpIdx) const; 310 311 void renderBitcastImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 312 int OpIdx) const; 313 314 void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI, 315 int OpIdx) const; 316 void renderExtractCPol(MachineInstrBuilder &MIB, const MachineInstr &MI, 317 int OpIdx) const; 318 void renderExtractSWZ(MachineInstrBuilder &MIB, const MachineInstr &MI, 319 int OpIdx) const; 320 void renderSetGLC(MachineInstrBuilder &MIB, const MachineInstr &MI, 321 int OpIdx) const; 322 323 void renderFrameIndex(MachineInstrBuilder &MIB, const MachineInstr &MI, 324 int OpIdx) const; 325 326 bool isInlineImmediate16(int64_t Imm) const; 327 bool isInlineImmediate32(int64_t Imm) const; 328 bool isInlineImmediate64(int64_t Imm) const; 329 bool isInlineImmediate(const APFloat &Imm) const; 330 331 // Returns true if TargetOpcode::G_AND MachineInstr `MI`'s masking of the 332 // shift amount operand's `ShAmtBits` bits is unneeded. 333 bool isUnneededShiftMask(const MachineInstr &MI, unsigned ShAmtBits) const; 334 335 const SIInstrInfo &TII; 336 const SIRegisterInfo &TRI; 337 const AMDGPURegisterBankInfo &RBI; 338 const AMDGPUTargetMachine &TM; 339 const GCNSubtarget &STI; 340 bool EnableLateStructurizeCFG; 341 #define GET_GLOBALISEL_PREDICATES_DECL 342 #define AMDGPUSubtarget GCNSubtarget 343 #include "AMDGPUGenGlobalISel.inc" 344 #undef GET_GLOBALISEL_PREDICATES_DECL 345 #undef AMDGPUSubtarget 346 347 #define GET_GLOBALISEL_TEMPORARIES_DECL 348 #include "AMDGPUGenGlobalISel.inc" 349 #undef GET_GLOBALISEL_TEMPORARIES_DECL 350 }; 351 352 } // End llvm namespace. 353 #endif 354