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 "AMDGPU.h"
17 #include "AMDGPUArgumentUsageInfo.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/CodeGen/Register.h"
21 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
22 #include "llvm/IR/InstrTypes.h"
23 
24 namespace {
25 #define GET_GLOBALISEL_PREDICATE_BITSET
26 #define AMDGPUSubtarget GCNSubtarget
27 #include "AMDGPUGenGlobalISel.inc"
28 #undef GET_GLOBALISEL_PREDICATE_BITSET
29 #undef AMDGPUSubtarget
30 }
31 
32 namespace llvm {
33 
34 class AMDGPUInstrInfo;
35 class AMDGPURegisterBankInfo;
36 class GCNSubtarget;
37 class MachineInstr;
38 class MachineIRBuilder;
39 class MachineOperand;
40 class MachineRegisterInfo;
41 class RegisterBank;
42 class SIInstrInfo;
43 class SIMachineFunctionInfo;
44 class SIRegisterInfo;
45 
46 class AMDGPUInstructionSelector : public InstructionSelector {
47 private:
48   MachineRegisterInfo *MRI;
49 
50 public:
51   AMDGPUInstructionSelector(const GCNSubtarget &STI,
52                             const AMDGPURegisterBankInfo &RBI,
53                             const AMDGPUTargetMachine &TM);
54 
55   bool select(MachineInstr &I) override;
56   static const char *getName();
57 
58   void setupMF(MachineFunction &MF, GISelKnownBits &KB,
59                CodeGenCoverage &CoverageInfo) override;
60 
61 private:
62   struct GEPInfo {
63     const MachineInstr &GEP;
64     SmallVector<unsigned, 2> SgprParts;
65     SmallVector<unsigned, 2> VgprParts;
66     int64_t Imm;
67     GEPInfo(const MachineInstr &GEP) : GEP(GEP), Imm(0) { }
68   };
69 
70   bool isInstrUniform(const MachineInstr &MI) const;
71   bool isVCC(Register Reg, const MachineRegisterInfo &MRI) const;
72 
73   const RegisterBank *getArtifactRegBank(
74     Register Reg, const MachineRegisterInfo &MRI,
75     const TargetRegisterInfo &TRI) const;
76 
77   /// tblgen-erated 'select' implementation.
78   bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
79 
80   MachineOperand getSubOperand64(MachineOperand &MO,
81                                  const TargetRegisterClass &SubRC,
82                                  unsigned SubIdx) const;
83   bool selectCOPY(MachineInstr &I) const;
84   bool selectPHI(MachineInstr &I) const;
85   bool selectG_TRUNC(MachineInstr &I) const;
86   bool selectG_SZA_EXT(MachineInstr &I) const;
87   bool selectG_CONSTANT(MachineInstr &I) const;
88   bool selectG_AND_OR_XOR(MachineInstr &I) const;
89   bool selectG_ADD_SUB(MachineInstr &I) const;
90   bool selectG_UADDO_USUBO_UADDE_USUBE(MachineInstr &I) const;
91   bool selectG_EXTRACT(MachineInstr &I) const;
92   bool selectG_MERGE_VALUES(MachineInstr &I) const;
93   bool selectG_UNMERGE_VALUES(MachineInstr &I) const;
94   bool selectG_PTR_ADD(MachineInstr &I) const;
95   bool selectG_IMPLICIT_DEF(MachineInstr &I) const;
96   bool selectG_INSERT(MachineInstr &I) const;
97   bool selectG_INTRINSIC(MachineInstr &I) const;
98 
99   std::tuple<Register, unsigned, unsigned>
100   splitBufferOffsets(MachineIRBuilder &B, Register OrigOffset) const;
101 
102   bool selectStoreIntrinsic(MachineInstr &MI, bool IsFormat) const;
103   bool selectDSOrderedIntrinsic(MachineInstr &MI, Intrinsic::ID IID) const;
104 
105   bool selectG_INTRINSIC_W_SIDE_EFFECTS(MachineInstr &I) const;
106   int getS_CMPOpcode(CmpInst::Predicate P, unsigned Size) const;
107   bool selectG_ICMP(MachineInstr &I) const;
108   bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const;
109   void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI,
110                        SmallVectorImpl<GEPInfo> &AddrInfo) const;
111   bool selectSMRD(MachineInstr &I, ArrayRef<GEPInfo> AddrInfo) const;
112 
113   void initM0(MachineInstr &I) const;
114   bool selectG_LOAD_ATOMICRMW(MachineInstr &I) const;
115   bool selectG_STORE(MachineInstr &I) const;
116   bool selectG_SELECT(MachineInstr &I) const;
117   bool selectG_BRCOND(MachineInstr &I) const;
118   bool selectG_FRAME_INDEX(MachineInstr &I) const;
119   bool selectG_PTR_MASK(MachineInstr &I) const;
120   bool selectG_EXTRACT_VECTOR_ELT(MachineInstr &I) const;
121 
122   std::pair<Register, unsigned>
123   selectVOP3ModsImpl(Register Src) const;
124 
125   InstructionSelector::ComplexRendererFns
126   selectVCSRC(MachineOperand &Root) const;
127 
128   InstructionSelector::ComplexRendererFns
129   selectVSRC0(MachineOperand &Root) const;
130 
131   InstructionSelector::ComplexRendererFns
132   selectVOP3Mods0(MachineOperand &Root) const;
133   InstructionSelector::ComplexRendererFns
134   selectVOP3OMods(MachineOperand &Root) const;
135   InstructionSelector::ComplexRendererFns
136   selectVOP3Mods(MachineOperand &Root) const;
137   InstructionSelector::ComplexRendererFns
138   selectVOP3Mods_nnan(MachineOperand &Root) const;
139 
140   InstructionSelector::ComplexRendererFns
141   selectVOP3OpSelMods0(MachineOperand &Root) const;
142   InstructionSelector::ComplexRendererFns
143   selectVOP3OpSelMods(MachineOperand &Root) const;
144 
145   InstructionSelector::ComplexRendererFns
146   selectSmrdImm(MachineOperand &Root) const;
147   InstructionSelector::ComplexRendererFns
148   selectSmrdImm32(MachineOperand &Root) const;
149   InstructionSelector::ComplexRendererFns
150   selectSmrdSgpr(MachineOperand &Root) const;
151 
152   template <bool Signed>
153   InstructionSelector::ComplexRendererFns
154   selectFlatOffsetImpl(MachineOperand &Root) const;
155   InstructionSelector::ComplexRendererFns
156   selectFlatOffset(MachineOperand &Root) const;
157 
158   InstructionSelector::ComplexRendererFns
159   selectFlatOffsetSigned(MachineOperand &Root) const;
160 
161   InstructionSelector::ComplexRendererFns
162   selectMUBUFScratchOffen(MachineOperand &Root) const;
163   InstructionSelector::ComplexRendererFns
164   selectMUBUFScratchOffset(MachineOperand &Root) const;
165 
166   bool isDSOffsetLegal(const MachineRegisterInfo &MRI,
167                        const MachineOperand &Base,
168                        int64_t Offset, unsigned OffsetBits) const;
169 
170   InstructionSelector::ComplexRendererFns
171   selectDS1Addr1Offset(MachineOperand &Root) const;
172 
173   void renderTruncImm32(MachineInstrBuilder &MIB, const MachineInstr &MI,
174                         int OpIdx = -1) const;
175 
176   void renderTruncTImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
177                        int OpIdx) const;
178 
179   void renderNegateImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
180                        int OpIdx) const;
181 
182   void renderBitcastImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
183                         int OpIdx) const;
184 
185   void renderPopcntImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
186                        int OpIdx) const;
187 
188   bool isInlineImmediate16(int64_t Imm) const;
189   bool isInlineImmediate32(int64_t Imm) const;
190   bool isInlineImmediate64(int64_t Imm) const;
191   bool isInlineImmediate(const APFloat &Imm) const;
192 
193   const SIInstrInfo &TII;
194   const SIRegisterInfo &TRI;
195   const AMDGPURegisterBankInfo &RBI;
196   const AMDGPUTargetMachine &TM;
197   const GCNSubtarget &STI;
198   bool EnableLateStructurizeCFG;
199 #define GET_GLOBALISEL_PREDICATES_DECL
200 #define AMDGPUSubtarget GCNSubtarget
201 #include "AMDGPUGenGlobalISel.inc"
202 #undef GET_GLOBALISEL_PREDICATES_DECL
203 #undef AMDGPUSubtarget
204 
205 #define GET_GLOBALISEL_TEMPORARIES_DECL
206 #include "AMDGPUGenGlobalISel.inc"
207 #undef GET_GLOBALISEL_TEMPORARIES_DECL
208 };
209 
210 } // End llvm namespace.
211 #endif
212