LLVM 22.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 LLT;
19class MachineRegisterInfo;
20class MachineInstr;
21class GCNSubtarget;
22class MachineFunction;
23template <typename T> class GenericUniformityInfo;
24template <typename T> class GenericSSAContext;
25using MachineSSAContext = GenericSSAContext<MachineFunction>;
26using MachineUniformityInfo = GenericUniformityInfo<MachineSSAContext>;
27
28namespace AMDGPU {
29
30/// \returns true if \p Ty is a pointer type with size \p Width.
31bool isAnyPtr(LLT Ty, unsigned Width);
32
33// IDs used to build predicate for RegBankLegalizeRule. Predicate can have one
34// or more IDs and each represents a check for 'uniform or divergent' + LLT or
35// just LLT on register operand.
36// Most often checking one operand is enough to decide which RegBankLLTMapping
37// to apply (see Fast Rules), IDs are useful when two or more operands need to
38// be checked.
41 // scalars
47
53
59
60 // pointers
69
78
87
88 // vectors
93
95
97
98 // B types
105
112
119};
120
121// How to apply register bank on register operand.
122// In most cases, this serves as a LLT and register bank assert.
123// Can change operands and insert copies, extends, truncs, and read-any-lanes.
124// Anything more complicated requires LoweringMethod.
131
132 // sgpr scalars, pointers, vectors and B-types
153
154 // vgpr scalars, pointers, vectors and B-types
176
177 // Dst only modifiers: read-any-lane and truncs
188
190
191 // Src only modifiers: execute in waterfall loop if divergent
194
195 // Src only modifiers: extends
202};
203
204// Instruction needs to be replaced with sequence of instructions. Lowering was
205// not done by legalizer since instructions is available in either sgpr or vgpr.
206// For example S64 AND is available on sgpr, for that reason S64 AND is legal in
207// context of Legalizer that only checks LLT. But S64 AND is not available on
208// vgpr. Lower it to two S32 vgpr ANDs.
224};
225
228 Standard, // S16, S32, S64, V2S16
229 StandardB, // B32, B64, B96, B128
230 Vector, // S32, V2S32, V3S32, V4S32
231};
232
238 std::initializer_list<RegBankLLTMappingApplyID> DstOpMappingList,
239 std::initializer_list<RegBankLLTMappingApplyID> SrcOpMappingList,
241};
242
245 std::function<bool(const MachineInstr &)> TestFunc;
247 std::initializer_list<UniformityLLTOpPredicateID> OpList,
248 std::function<bool(const MachineInstr &)> TestFunc = nullptr);
249
250 bool match(const MachineInstr &MI, const MachineUniformityInfo &MUI,
251 const MachineRegisterInfo &MRI) const;
252};
253
257};
258
260 // "Slow Rules". More complex 'Rules[i].Predicate', check them one by one.
262
263 // "Fast Rules"
264 // Instead of testing each 'Rules[i].Predicate' we do direct access to
265 // RegBankLLTMapping using getFastPredicateSlot. For example if:
266 // - FastTypes == Standard Uni[0] holds Mapping in case Op 0 is uniform S32
267 // - FastTypes == Vector Div[3] holds Mapping in case Op 0 is divergent V4S32
268 FastRulesTypes FastTypes = NoFastRules;
269#define InvMapping RegBankLLTMapping({InvalidMapping}, {InvalidMapping})
270 RegBankLLTMapping Uni[4] = {InvMapping, InvMapping, InvMapping, InvMapping};
271 RegBankLLTMapping Div[4] = {InvMapping, InvMapping, InvMapping, InvMapping};
272
273public:
276
277 const RegBankLLTMapping &
278 findMappingForMI(const MachineInstr &MI, const MachineRegisterInfo &MRI,
279 const MachineUniformityInfo &MUI) const;
280
281 void addRule(RegBankLegalizeRule Rule);
282
284 RegBankLLTMapping RuleApplyIDs);
286 RegBankLLTMapping RuleApplyIDs);
287
288private:
289 int getFastPredicateSlot(UniformityLLTOpPredicateID Ty) const;
290};
291
292// Essentially 'map<Opcode(or intrinsic_opcode), SetOfRulesForOpcode>' but a
293// little more efficient.
295 const GCNSubtarget *ST;
297 // Separate maps for G-opcodes and instrinsics since they are in different
298 // enums. Multiple opcodes can share same set of rules.
299 // RulesAlias = map<Opcode, KeyOpcode>
300 // Rules = map<KeyOpcode, SetOfRulesForOpcode>
305 class RuleSetInitializer {
306 SetOfRulesForOpcode *RuleSet;
307
308 public:
309 // Used for clang-format line breaks and to force writing all rules for
310 // opcode in same place.
311 template <class AliasMap, class RulesMap>
312 RuleSetInitializer(std::initializer_list<unsigned> OpcList,
313 AliasMap &RulesAlias, RulesMap &Rules,
314 FastRulesTypes FastTypes = NoFastRules) {
315 unsigned KeyOpcode = *OpcList.begin();
316 for (unsigned Opc : OpcList) {
317 [[maybe_unused]] auto [_, NewInput] =
318 RulesAlias.try_emplace(Opc, KeyOpcode);
319 assert(NewInput && "Can't redefine existing Rules");
320 }
321
322 auto [DenseMapIter, NewInput] = Rules.try_emplace(KeyOpcode, FastTypes);
323 assert(NewInput && "Can't redefine existing Rules");
324
325 RuleSet = &DenseMapIter->second;
326 }
327
328 RuleSetInitializer(const RuleSetInitializer &) = delete;
329 RuleSetInitializer &operator=(const RuleSetInitializer &) = delete;
330 RuleSetInitializer(RuleSetInitializer &&) = delete;
331 RuleSetInitializer &operator=(RuleSetInitializer &&) = delete;
332 ~RuleSetInitializer() = default;
333
334 RuleSetInitializer &Div(UniformityLLTOpPredicateID Ty,
335 RegBankLLTMapping RuleApplyIDs,
336 bool STPred = true) {
337 if (STPred)
338 RuleSet->addFastRuleDivergent(Ty, RuleApplyIDs);
339 return *this;
340 }
341
342 RuleSetInitializer &Uni(UniformityLLTOpPredicateID Ty,
343 RegBankLLTMapping RuleApplyIDs,
344 bool STPred = true) {
345 if (STPred)
346 RuleSet->addFastRuleUniform(Ty, RuleApplyIDs);
347 return *this;
348 }
349
350 RuleSetInitializer &Any(RegBankLegalizeRule Init, bool STPred = true) {
351 if (STPred)
352 RuleSet->addRule(Init);
353 return *this;
354 }
355 };
356
357 RuleSetInitializer addRulesForGOpcs(std::initializer_list<unsigned> OpcList,
358 FastRulesTypes FastTypes = NoFastRules);
359
360 RuleSetInitializer addRulesForIOpcs(std::initializer_list<unsigned> OpcList,
361 FastRulesTypes FastTypes = NoFastRules);
362
363public:
364 // Initialize rules for all opcodes.
366
367 // In case we don't want to regenerate same rules, we can use already
368 // generated rules but need to refresh references to objects that are
369 // created for this run.
371 ST = &_ST;
372 MRI = &_MRI;
373 };
374
376};
377
378} // end namespace AMDGPU
379} // end namespace llvm
380
381#endif
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define InvMapping
This file defines the DenseMap class.
IRTranslator LLVM IR MI
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:72
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:1197
bool isAnyPtr(LLT Ty, unsigned Width)
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