LLVM 21.0.0git
AMDGPURegBankLegalizeRules.h
Go to the documentation of this file.
1//===- AMDGPURegBankLegalizeRules --------------------------------*- 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
9#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUREGBANKLEGALIZERULES_H
10#define LLVM_LIB_TARGET_AMDGPU_AMDGPUREGBANKLEGALIZERULES_H
11
12#include "llvm/ADT/DenseMap.h"
14#include <functional>
15
16namespace llvm {
17
18class MachineRegisterInfo;
19class MachineInstr;
20class GCNSubtarget;
21class MachineFunction;
22template <typename T> class GenericUniformityInfo;
23template <typename T> class GenericSSAContext;
24using MachineSSAContext = GenericSSAContext<MachineFunction>;
25using MachineUniformityInfo = GenericUniformityInfo<MachineSSAContext>;
26
27namespace AMDGPU {
28
29// IDs used to build predicate for RegBankLegalizeRule. Predicate can have one
30// or more IDs and each represents a check for 'uniform or divergent' + LLT or
31// just LLT on register operand.
32// Most often checking one operand is enough to decide which RegBankLLTMapping
33// to apply (see Fast Rules), IDs are useful when two or more operands need to
34// be checked.
37 // scalars
42
47
51
52 // pointers
57
62
67
68 // vectors
73
74 // B types
81
88
95};
96
97// How to apply register bank on register operand.
98// In most cases, this serves as a LLT and register bank assert.
99// Can change operands and insert copies, extends, truncs, and read-any-lanes.
100// Anything more complicated requires LoweringMethod.
107
108 // sgpr scalars, pointers, vectors and B-types
123
124 // vgpr scalars, pointers, vectors and B-types
138
139 // Dst only modifiers: read-any-lane and truncs
149
151
152 // Src only modifiers: waterfalls, extends
156};
157
158// Instruction needs to be replaced with sequence of instructions. Lowering was
159// not done by legalizer since instructions is available in either sgpr or vgpr.
160// For example S64 AND is available on sgpr, for that reason S64 AND is legal in
161// context of Legalizer that only checks LLT. But S64 AND is not available on
162// vgpr. Lower it to two S32 vgpr ANDs.
172};
173
176 Standard, // S16, S32, S64, V2S16
177 StandardB, // B32, B64, B96, B128
178 Vector, // S32, V2S32, V3S32, V4S32
179};
180
186 std::initializer_list<RegBankLLTMappingApplyID> DstOpMappingList,
187 std::initializer_list<RegBankLLTMappingApplyID> SrcOpMappingList,
189};
190
193 std::function<bool(const MachineInstr &)> TestFunc;
195 std::initializer_list<UniformityLLTOpPredicateID> OpList,
196 std::function<bool(const MachineInstr &)> TestFunc = nullptr);
197
198 bool match(const MachineInstr &MI, const MachineUniformityInfo &MUI,
199 const MachineRegisterInfo &MRI) const;
200};
201
205};
206
208 // "Slow Rules". More complex 'Rules[i].Predicate', check them one by one.
210
211 // "Fast Rules"
212 // Instead of testing each 'Rules[i].Predicate' we do direct access to
213 // RegBankLLTMapping using getFastPredicateSlot. For example if:
214 // - FastTypes == Standard Uni[0] holds Mapping in case Op 0 is uniform S32
215 // - FastTypes == Vector Div[3] holds Mapping in case Op 0 is divergent V4S32
216 FastRulesTypes FastTypes = NoFastRules;
217#define InvMapping RegBankLLTMapping({InvalidMapping}, {InvalidMapping})
218 RegBankLLTMapping Uni[4] = {InvMapping, InvMapping, InvMapping, InvMapping};
219 RegBankLLTMapping Div[4] = {InvMapping, InvMapping, InvMapping, InvMapping};
220
221public:
224
225 const RegBankLLTMapping &
226 findMappingForMI(const MachineInstr &MI, const MachineRegisterInfo &MRI,
227 const MachineUniformityInfo &MUI) const;
228
229 void addRule(RegBankLegalizeRule Rule);
230
232 RegBankLLTMapping RuleApplyIDs);
234 RegBankLLTMapping RuleApplyIDs);
235
236private:
237 int getFastPredicateSlot(UniformityLLTOpPredicateID Ty) const;
238};
239
240// Essentially 'map<Opcode(or intrinsic_opcode), SetOfRulesForOpcode>' but a
241// little more efficient.
243 const GCNSubtarget *ST;
245 // Separate maps for G-opcodes and instrinsics since they are in different
246 // enums. Multiple opcodes can share same set of rules.
247 // RulesAlias = map<Opcode, KeyOpcode>
248 // Rules = map<KeyOpcode, SetOfRulesForOpcode>
253 class RuleSetInitializer {
254 SetOfRulesForOpcode *RuleSet;
255
256 public:
257 // Used for clang-format line breaks and to force writing all rules for
258 // opcode in same place.
259 template <class AliasMap, class RulesMap>
260 RuleSetInitializer(std::initializer_list<unsigned> OpcList,
261 AliasMap &RulesAlias, RulesMap &Rules,
262 FastRulesTypes FastTypes = NoFastRules) {
263 unsigned KeyOpcode = *OpcList.begin();
264 for (unsigned Opc : OpcList) {
265 [[maybe_unused]] auto [_, NewInput] =
266 RulesAlias.try_emplace(Opc, KeyOpcode);
267 assert(NewInput && "Can't redefine existing Rules");
268 }
269
270 auto [DenseMapIter, NewInput] = Rules.try_emplace(KeyOpcode, FastTypes);
271 assert(NewInput && "Can't redefine existing Rules");
272
273 RuleSet = &DenseMapIter->second;
274 }
275
276 RuleSetInitializer(const RuleSetInitializer &) = delete;
277 RuleSetInitializer &operator=(const RuleSetInitializer &) = delete;
278 RuleSetInitializer(RuleSetInitializer &&) = delete;
279 RuleSetInitializer &operator=(RuleSetInitializer &&) = delete;
280 ~RuleSetInitializer() = default;
281
282 RuleSetInitializer &Div(UniformityLLTOpPredicateID Ty,
283 RegBankLLTMapping RuleApplyIDs,
284 bool STPred = true) {
285 if (STPred)
286 RuleSet->addFastRuleDivergent(Ty, RuleApplyIDs);
287 return *this;
288 }
289
290 RuleSetInitializer &Uni(UniformityLLTOpPredicateID Ty,
291 RegBankLLTMapping RuleApplyIDs,
292 bool STPred = true) {
293 if (STPred)
294 RuleSet->addFastRuleUniform(Ty, RuleApplyIDs);
295 return *this;
296 }
297
298 RuleSetInitializer &Any(RegBankLegalizeRule Init, bool STPred = true) {
299 if (STPred)
300 RuleSet->addRule(Init);
301 return *this;
302 }
303 };
304
305 RuleSetInitializer addRulesForGOpcs(std::initializer_list<unsigned> OpcList,
306 FastRulesTypes FastTypes = NoFastRules);
307
308 RuleSetInitializer addRulesForIOpcs(std::initializer_list<unsigned> OpcList,
309 FastRulesTypes FastTypes = NoFastRules);
310
311public:
312 // Initialize rules for all opcodes.
314
315 // In case we don't want to regenerate same rules, we can use already
316 // generated rules but need to refresh references to objects that are
317 // created for this run.
319 ST = &_ST;
320 MRI = &_MRI;
321 };
322
324};
325
326} // end namespace AMDGPU
327} // end namespace llvm
328
329#endif
unsigned const MachineRegisterInfo * MRI
#define InvMapping
This file defines the DenseMap class.
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
const SetOfRulesForOpcode & getRulesForOpc(MachineInstr &MI) const
void refreshRefs(const GCNSubtarget &_ST, MachineRegisterInfo &_MRI)
const RegBankLLTMapping & findMappingForMI(const MachineInstr &MI, const MachineRegisterInfo &MRI, const MachineUniformityInfo &MUI) const
void addFastRuleDivergent(UniformityLLTOpPredicateID Ty, RegBankLLTMapping RuleApplyIDs)
void addFastRuleUniform(UniformityLLTOpPredicateID Ty, RegBankLLTMapping RuleApplyIDs)
Definition: Any.h:28
Representation of each machine instruction.
Definition: MachineInstr.h:71
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
GenericSSAContext< MachineFunction > MachineSSAContext
GenericUniformityInfo< MachineSSAContext > MachineUniformityInfo
SmallVector< UniformityLLTOpPredicateID, 4 > OpUniformityAndTypes
bool match(const MachineInstr &MI, const MachineUniformityInfo &MUI, const MachineRegisterInfo &MRI) const
std::function< bool(const MachineInstr &)> TestFunc
SmallVector< RegBankLLTMappingApplyID, 2 > DstOpMapping
SmallVector< RegBankLLTMappingApplyID, 4 > SrcOpMapping