Home | History | Annotate | Line # | Download | only in AMDGPU
      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 
    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