xref: /llvm-project/llvm/utils/TableGen/Common/CodeGenRegisters.h (revision 4e8c9d28132039a98feb97cec2759cddeb37d934)
1fa3d789dSPierre van Houtryve //===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===//
2fa3d789dSPierre van Houtryve //
3fa3d789dSPierre van Houtryve // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fa3d789dSPierre van Houtryve // See https://llvm.org/LICENSE.txt for license information.
5fa3d789dSPierre van Houtryve // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fa3d789dSPierre van Houtryve //
7fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===//
8fa3d789dSPierre van Houtryve //
9fa3d789dSPierre van Houtryve // This file defines structures to encapsulate information gleaned from the
10fa3d789dSPierre van Houtryve // target register and register class definitions.
11fa3d789dSPierre van Houtryve //
12fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===//
13fa3d789dSPierre van Houtryve 
148a61bfcfSRahul Joshi #ifndef LLVM_UTILS_TABLEGEN_COMMON_CODEGENREGISTERS_H
158a61bfcfSRahul Joshi #define LLVM_UTILS_TABLEGEN_COMMON_CODEGENREGISTERS_H
16fa3d789dSPierre van Houtryve 
17fa3d789dSPierre van Houtryve #include "CodeGenHwModes.h"
18fa3d789dSPierre van Houtryve #include "InfoByHwMode.h"
19fa3d789dSPierre van Houtryve #include "llvm/ADT/ArrayRef.h"
20fa3d789dSPierre van Houtryve #include "llvm/ADT/BitVector.h"
21fa3d789dSPierre van Houtryve #include "llvm/ADT/DenseMap.h"
22fa3d789dSPierre van Houtryve #include "llvm/ADT/STLExtras.h"
23fa3d789dSPierre van Houtryve #include "llvm/ADT/SetVector.h"
24fa3d789dSPierre van Houtryve #include "llvm/ADT/SmallPtrSet.h"
25fa3d789dSPierre van Houtryve #include "llvm/ADT/SmallVector.h"
26fa3d789dSPierre van Houtryve #include "llvm/ADT/SparseBitVector.h"
27fa3d789dSPierre van Houtryve #include "llvm/ADT/StringMap.h"
28fa3d789dSPierre van Houtryve #include "llvm/ADT/StringRef.h"
29fa3d789dSPierre van Houtryve #include "llvm/MC/LaneBitmask.h"
30fa3d789dSPierre van Houtryve #include "llvm/Support/ErrorHandling.h"
31fa3d789dSPierre van Houtryve #include "llvm/TableGen/Record.h"
32fa3d789dSPierre van Houtryve #include "llvm/TableGen/SetTheory.h"
33fa3d789dSPierre van Houtryve #include <cassert>
34fa3d789dSPierre van Houtryve #include <cstdint>
35fa3d789dSPierre van Houtryve #include <deque>
36fa3d789dSPierre van Houtryve #include <functional>
37fa3d789dSPierre van Houtryve #include <list>
38fa3d789dSPierre van Houtryve #include <map>
39fa3d789dSPierre van Houtryve #include <memory>
40fa3d789dSPierre van Houtryve #include <optional>
41fa3d789dSPierre van Houtryve #include <string>
42fa3d789dSPierre van Houtryve #include <utility>
43fa3d789dSPierre van Houtryve #include <vector>
44fa3d789dSPierre van Houtryve 
45fa3d789dSPierre van Houtryve namespace llvm {
46fa3d789dSPierre van Houtryve 
47fa3d789dSPierre van Houtryve class CodeGenRegBank;
48fa3d789dSPierre van Houtryve 
49fa3d789dSPierre van Houtryve /// Used to encode a step in a register lane mask transformation.
50fa3d789dSPierre van Houtryve /// Mask the bits specified in Mask, then rotate them Rol bits to the left
51fa3d789dSPierre van Houtryve /// assuming a wraparound at 32bits.
52fa3d789dSPierre van Houtryve struct MaskRolPair {
53fa3d789dSPierre van Houtryve   LaneBitmask Mask;
54fa3d789dSPierre van Houtryve   uint8_t RotateLeft;
55fa3d789dSPierre van Houtryve 
56fa3d789dSPierre van Houtryve   bool operator==(const MaskRolPair Other) const {
57fa3d789dSPierre van Houtryve     return Mask == Other.Mask && RotateLeft == Other.RotateLeft;
58fa3d789dSPierre van Houtryve   }
59fa3d789dSPierre van Houtryve   bool operator!=(const MaskRolPair Other) const {
60fa3d789dSPierre van Houtryve     return Mask != Other.Mask || RotateLeft != Other.RotateLeft;
61fa3d789dSPierre van Houtryve   }
62fa3d789dSPierre van Houtryve };
63fa3d789dSPierre van Houtryve 
64fa3d789dSPierre van Houtryve /// CodeGenSubRegIndex - Represents a sub-register index.
65fa3d789dSPierre van Houtryve class CodeGenSubRegIndex {
667c6592f5SRahul Joshi   const Record *const TheDef;
67fa3d789dSPierre van Houtryve   std::string Name;
68fa3d789dSPierre van Houtryve   std::string Namespace;
69fa3d789dSPierre van Houtryve 
70fa3d789dSPierre van Houtryve public:
71baf66ec0SCraig Topper   SubRegRangeByHwMode Range;
72fa3d789dSPierre van Houtryve   const unsigned EnumValue;
73fa3d789dSPierre van Houtryve   mutable LaneBitmask LaneMask;
74fa3d789dSPierre van Houtryve   mutable SmallVector<MaskRolPair, 1> CompositionLaneMaskTransform;
75fa3d789dSPierre van Houtryve 
76fa3d789dSPierre van Houtryve   /// A list of subregister indexes concatenated resulting in this
77fa3d789dSPierre van Houtryve   /// subregister index. This is the reverse of CodeGenRegBank::ConcatIdx.
78fa3d789dSPierre van Houtryve   SmallVector<CodeGenSubRegIndex *, 4> ConcatenationOf;
79fa3d789dSPierre van Houtryve 
80fa3d789dSPierre van Houtryve   // Are all super-registers containing this SubRegIndex covered by their
81fa3d789dSPierre van Houtryve   // sub-registers?
82fa3d789dSPierre van Houtryve   bool AllSuperRegsCovered;
83fa3d789dSPierre van Houtryve   // A subregister index is "artificial" if every subregister obtained
84fa3d789dSPierre van Houtryve   // from applying this index is artificial. Artificial subregister
85fa3d789dSPierre van Houtryve   // indexes are not used to create new register classes.
86fa3d789dSPierre van Houtryve   bool Artificial;
87fa3d789dSPierre van Houtryve 
887c6592f5SRahul Joshi   CodeGenSubRegIndex(const Record *R, unsigned Enum, const CodeGenHwModes &CGH);
89fa3d789dSPierre van Houtryve   CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
90fa3d789dSPierre van Houtryve   CodeGenSubRegIndex(CodeGenSubRegIndex &) = delete;
91fa3d789dSPierre van Houtryve 
92fa3d789dSPierre van Houtryve   const std::string &getName() const { return Name; }
93fa3d789dSPierre van Houtryve   const std::string &getNamespace() const { return Namespace; }
94fa3d789dSPierre van Houtryve   std::string getQualifiedName() const;
95fa3d789dSPierre van Houtryve 
96fa3d789dSPierre van Houtryve   // Map of composite subreg indices.
97fa3d789dSPierre van Houtryve   typedef std::map<CodeGenSubRegIndex *, CodeGenSubRegIndex *,
98fa3d789dSPierre van Houtryve                    deref<std::less<>>>
99fa3d789dSPierre van Houtryve       CompMap;
100fa3d789dSPierre van Houtryve 
101fa3d789dSPierre van Houtryve   // Returns the subreg index that results from composing this with Idx.
102fa3d789dSPierre van Houtryve   // Returns NULL if this and Idx don't compose.
103fa3d789dSPierre van Houtryve   CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const {
104fa3d789dSPierre van Houtryve     CompMap::const_iterator I = Composed.find(Idx);
105fa3d789dSPierre van Houtryve     return I == Composed.end() ? nullptr : I->second;
106fa3d789dSPierre van Houtryve   }
107fa3d789dSPierre van Houtryve 
108fa3d789dSPierre van Houtryve   // Add a composite subreg index: this+A = B.
109fa3d789dSPierre van Houtryve   // Return a conflicting composite, or NULL
110baf66ec0SCraig Topper   CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, CodeGenSubRegIndex *B,
111baf66ec0SCraig Topper                                    const CodeGenHwModes &CGH) {
112fa3d789dSPierre van Houtryve     assert(A && B);
113*4e8c9d28SJay Foad     std::pair<CompMap::iterator, bool> Ins = Composed.try_emplace(A, B);
114baf66ec0SCraig Topper 
115fa3d789dSPierre van Houtryve     // Synthetic subreg indices that aren't contiguous (for instance ARM
116fa3d789dSPierre van Houtryve     // register tuples) don't have a bit range, so it's OK to let
117fa3d789dSPierre van Houtryve     // B->Offset == -1. For the other cases, accumulate the offset and set
118fa3d789dSPierre van Houtryve     // the size here. Only do so if there is no offset yet though.
119baf66ec0SCraig Topper     unsigned NumModes = CGH.getNumModeIds();
120baf66ec0SCraig Topper     // Skip default mode.
121baf66ec0SCraig Topper     for (unsigned M = 0; M < NumModes; ++M) {
122baf66ec0SCraig Topper       // Handle DefaultMode last.
123baf66ec0SCraig Topper       if (M == DefaultMode)
124baf66ec0SCraig Topper         continue;
125baf66ec0SCraig Topper       SubRegRange &Range = this->Range.get(M);
126baf66ec0SCraig Topper       SubRegRange &ARange = A->Range.get(M);
127baf66ec0SCraig Topper       SubRegRange &BRange = B->Range.get(M);
128baf66ec0SCraig Topper 
129baf66ec0SCraig Topper       if (Range.Offset != (uint16_t)-1 && ARange.Offset != (uint16_t)-1 &&
130baf66ec0SCraig Topper           BRange.Offset == (uint16_t)-1) {
131baf66ec0SCraig Topper         BRange.Offset = Range.Offset + ARange.Offset;
132baf66ec0SCraig Topper         BRange.Size = ARange.Size;
133fa3d789dSPierre van Houtryve       }
134baf66ec0SCraig Topper     }
135baf66ec0SCraig Topper 
136baf66ec0SCraig Topper     // Now handle default.
137baf66ec0SCraig Topper     SubRegRange &Range = this->Range.get(DefaultMode);
138baf66ec0SCraig Topper     SubRegRange &ARange = A->Range.get(DefaultMode);
139baf66ec0SCraig Topper     SubRegRange &BRange = B->Range.get(DefaultMode);
140baf66ec0SCraig Topper     if (Range.Offset != (uint16_t)-1 && ARange.Offset != (uint16_t)-1 &&
141baf66ec0SCraig Topper         BRange.Offset == (uint16_t)-1) {
142baf66ec0SCraig Topper       BRange.Offset = Range.Offset + ARange.Offset;
143baf66ec0SCraig Topper       BRange.Size = ARange.Size;
144baf66ec0SCraig Topper     }
145baf66ec0SCraig Topper 
146fa3d789dSPierre van Houtryve     return (Ins.second || Ins.first->second == B) ? nullptr : Ins.first->second;
147fa3d789dSPierre van Houtryve   }
148fa3d789dSPierre van Houtryve 
149fa3d789dSPierre van Houtryve   // Update the composite maps of components specified in 'ComposedOf'.
150fa3d789dSPierre van Houtryve   void updateComponents(CodeGenRegBank &);
151fa3d789dSPierre van Houtryve 
152fa3d789dSPierre van Houtryve   // Return the map of composites.
153fa3d789dSPierre van Houtryve   const CompMap &getComposites() const { return Composed; }
154fa3d789dSPierre van Houtryve 
155fa3d789dSPierre van Houtryve   // Compute LaneMask from Composed. Return LaneMask.
156fa3d789dSPierre van Houtryve   LaneBitmask computeLaneMask() const;
157fa3d789dSPierre van Houtryve 
158fa3d789dSPierre van Houtryve   void setConcatenationOf(ArrayRef<CodeGenSubRegIndex *> Parts);
159fa3d789dSPierre van Houtryve 
160fa3d789dSPierre van Houtryve   /// Replaces subregister indexes in the `ConcatenationOf` list with
161fa3d789dSPierre van Houtryve   /// list of subregisters they are composed of (if any). Do this recursively.
162fa3d789dSPierre van Houtryve   void computeConcatTransitiveClosure();
163fa3d789dSPierre van Houtryve 
164fa3d789dSPierre van Houtryve   bool operator<(const CodeGenSubRegIndex &RHS) const {
165fa3d789dSPierre van Houtryve     return this->EnumValue < RHS.EnumValue;
166fa3d789dSPierre van Houtryve   }
167fa3d789dSPierre van Houtryve 
168fa3d789dSPierre van Houtryve private:
169fa3d789dSPierre van Houtryve   CompMap Composed;
170fa3d789dSPierre van Houtryve };
171fa3d789dSPierre van Houtryve 
172fa3d789dSPierre van Houtryve /// CodeGenRegister - Represents a register definition.
173fa3d789dSPierre van Houtryve class CodeGenRegister {
174fa3d789dSPierre van Houtryve public:
17516510149SRahul Joshi   const Record *TheDef;
176fa3d789dSPierre van Houtryve   unsigned EnumValue;
177fa3d789dSPierre van Houtryve   std::vector<int64_t> CostPerUse;
178fa3d789dSPierre van Houtryve   bool CoveredBySubRegs = true;
179fa3d789dSPierre van Houtryve   bool HasDisjunctSubRegs = false;
180fa3d789dSPierre van Houtryve   bool Artificial = true;
181fa3d789dSPierre van Houtryve   bool Constant = false;
182fa3d789dSPierre van Houtryve 
183fa3d789dSPierre van Houtryve   // Map SubRegIndex -> Register.
184fa3d789dSPierre van Houtryve   typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, deref<std::less<>>>
185fa3d789dSPierre van Houtryve       SubRegMap;
186fa3d789dSPierre van Houtryve 
18716510149SRahul Joshi   CodeGenRegister(const Record *R, unsigned Enum);
188fa3d789dSPierre van Houtryve 
189fa3d789dSPierre van Houtryve   StringRef getName() const;
190fa3d789dSPierre van Houtryve 
191fa3d789dSPierre van Houtryve   // Extract more information from TheDef. This is used to build an object
192fa3d789dSPierre van Houtryve   // graph after all CodeGenRegister objects have been created.
193fa3d789dSPierre van Houtryve   void buildObjectGraph(CodeGenRegBank &);
194fa3d789dSPierre van Houtryve 
195fa3d789dSPierre van Houtryve   // Lazily compute a map of all sub-registers.
196fa3d789dSPierre van Houtryve   // This includes unique entries for all sub-sub-registers.
197fa3d789dSPierre van Houtryve   const SubRegMap &computeSubRegs(CodeGenRegBank &);
198fa3d789dSPierre van Houtryve 
199fa3d789dSPierre van Houtryve   // Compute extra sub-registers by combining the existing sub-registers.
200fa3d789dSPierre van Houtryve   void computeSecondarySubRegs(CodeGenRegBank &);
201fa3d789dSPierre van Houtryve 
202fa3d789dSPierre van Houtryve   // Add this as a super-register to all sub-registers after the sub-register
203fa3d789dSPierre van Houtryve   // graph has been built.
204fa3d789dSPierre van Houtryve   void computeSuperRegs(CodeGenRegBank &);
205fa3d789dSPierre van Houtryve 
206fa3d789dSPierre van Houtryve   const SubRegMap &getSubRegs() const {
207fa3d789dSPierre van Houtryve     assert(SubRegsComplete && "Must precompute sub-registers");
208fa3d789dSPierre van Houtryve     return SubRegs;
209fa3d789dSPierre van Houtryve   }
210fa3d789dSPierre van Houtryve 
211fa3d789dSPierre van Houtryve   // Add sub-registers to OSet following a pre-order defined by the .td file.
212fa3d789dSPierre van Houtryve   void addSubRegsPreOrder(SetVector<const CodeGenRegister *> &OSet,
213fa3d789dSPierre van Houtryve                           CodeGenRegBank &) const;
214fa3d789dSPierre van Houtryve 
215fa3d789dSPierre van Houtryve   // Return the sub-register index naming Reg as a sub-register of this
216fa3d789dSPierre van Houtryve   // register. Returns NULL if Reg is not a sub-register.
217fa3d789dSPierre van Houtryve   CodeGenSubRegIndex *getSubRegIndex(const CodeGenRegister *Reg) const {
218fa3d789dSPierre van Houtryve     return SubReg2Idx.lookup(Reg);
219fa3d789dSPierre van Houtryve   }
220fa3d789dSPierre van Houtryve 
221fa3d789dSPierre van Houtryve   typedef std::vector<const CodeGenRegister *> SuperRegList;
222fa3d789dSPierre van Houtryve 
223fa3d789dSPierre van Houtryve   // Get the list of super-registers in topological order, small to large.
224fa3d789dSPierre van Houtryve   // This is valid after computeSubRegs visits all registers during RegBank
225fa3d789dSPierre van Houtryve   // construction.
226fa3d789dSPierre van Houtryve   const SuperRegList &getSuperRegs() const {
227fa3d789dSPierre van Houtryve     assert(SubRegsComplete && "Must precompute sub-registers");
228fa3d789dSPierre van Houtryve     return SuperRegs;
229fa3d789dSPierre van Houtryve   }
230fa3d789dSPierre van Houtryve 
231fa3d789dSPierre van Houtryve   // Get the list of ad hoc aliases. The graph is symmetric, so the list
232fa3d789dSPierre van Houtryve   // contains all registers in 'Aliases', and all registers that mention this
233fa3d789dSPierre van Houtryve   // register in 'Aliases'.
234fa3d789dSPierre van Houtryve   ArrayRef<CodeGenRegister *> getExplicitAliases() const {
235fa3d789dSPierre van Houtryve     return ExplicitAliases;
236fa3d789dSPierre van Houtryve   }
237fa3d789dSPierre van Houtryve 
238fa3d789dSPierre van Houtryve   // Get the topological signature of this register. This is a small integer
239fa3d789dSPierre van Houtryve   // less than RegBank.getNumTopoSigs(). Registers with the same TopoSig have
240fa3d789dSPierre van Houtryve   // identical sub-register structure. That is, they support the same set of
241fa3d789dSPierre van Houtryve   // sub-register indices mapping to the same kind of sub-registers
242fa3d789dSPierre van Houtryve   // (TopoSig-wise).
243fa3d789dSPierre van Houtryve   unsigned getTopoSig() const {
244fa3d789dSPierre van Houtryve     assert(SuperRegsComplete && "TopoSigs haven't been computed yet.");
245fa3d789dSPierre van Houtryve     return TopoSig;
246fa3d789dSPierre van Houtryve   }
247fa3d789dSPierre van Houtryve 
248fa3d789dSPierre van Houtryve   // List of register units in ascending order.
249fa3d789dSPierre van Houtryve   typedef SparseBitVector<> RegUnitList;
250fa3d789dSPierre van Houtryve   typedef SmallVector<LaneBitmask, 16> RegUnitLaneMaskList;
251fa3d789dSPierre van Houtryve 
252fa3d789dSPierre van Houtryve   // How many entries in RegUnitList are native?
253fa3d789dSPierre van Houtryve   RegUnitList NativeRegUnits;
254fa3d789dSPierre van Houtryve 
255fa3d789dSPierre van Houtryve   // Get the list of register units.
256fa3d789dSPierre van Houtryve   // This is only valid after computeSubRegs() completes.
257fa3d789dSPierre van Houtryve   const RegUnitList &getRegUnits() const { return RegUnits; }
258fa3d789dSPierre van Houtryve 
259fa3d789dSPierre van Houtryve   ArrayRef<LaneBitmask> getRegUnitLaneMasks() const {
260fa3d789dSPierre van Houtryve     return ArrayRef(RegUnitLaneMasks).slice(0, NativeRegUnits.count());
261fa3d789dSPierre van Houtryve   }
262fa3d789dSPierre van Houtryve 
263fa3d789dSPierre van Houtryve   // Get the native register units. This is a prefix of getRegUnits().
264fa3d789dSPierre van Houtryve   RegUnitList getNativeRegUnits() const { return NativeRegUnits; }
265fa3d789dSPierre van Houtryve 
266fa3d789dSPierre van Houtryve   void setRegUnitLaneMasks(const RegUnitLaneMaskList &LaneMasks) {
267fa3d789dSPierre van Houtryve     RegUnitLaneMasks = LaneMasks;
268fa3d789dSPierre van Houtryve   }
269fa3d789dSPierre van Houtryve 
270fa3d789dSPierre van Houtryve   // Inherit register units from subregisters.
271fa3d789dSPierre van Houtryve   // Return true if the RegUnits changed.
272fa3d789dSPierre van Houtryve   bool inheritRegUnits(CodeGenRegBank &RegBank);
273fa3d789dSPierre van Houtryve 
274fa3d789dSPierre van Houtryve   // Adopt a register unit for pressure tracking.
275fa3d789dSPierre van Houtryve   // A unit is adopted iff its unit number is >= NativeRegUnits.count().
276fa3d789dSPierre van Houtryve   void adoptRegUnit(unsigned RUID) { RegUnits.set(RUID); }
277fa3d789dSPierre van Houtryve 
278fa3d789dSPierre van Houtryve   // Get the sum of this register's register unit weights.
279fa3d789dSPierre van Houtryve   unsigned getWeight(const CodeGenRegBank &RegBank) const;
280fa3d789dSPierre van Houtryve 
281fa3d789dSPierre van Houtryve   // Canonically ordered set.
282fa3d789dSPierre van Houtryve   typedef std::vector<const CodeGenRegister *> Vec;
283fa3d789dSPierre van Houtryve 
284fa3d789dSPierre van Houtryve private:
285fa3d789dSPierre van Houtryve   bool SubRegsComplete;
286fa3d789dSPierre van Houtryve   bool SuperRegsComplete;
287fa3d789dSPierre van Houtryve   unsigned TopoSig;
288fa3d789dSPierre van Houtryve 
289fa3d789dSPierre van Houtryve   // The sub-registers explicit in the .td file form a tree.
290fa3d789dSPierre van Houtryve   SmallVector<CodeGenSubRegIndex *, 8> ExplicitSubRegIndices;
291fa3d789dSPierre van Houtryve   SmallVector<CodeGenRegister *, 8> ExplicitSubRegs;
292fa3d789dSPierre van Houtryve 
293fa3d789dSPierre van Houtryve   // Explicit ad hoc aliases, symmetrized to form an undirected graph.
294fa3d789dSPierre van Houtryve   SmallVector<CodeGenRegister *, 8> ExplicitAliases;
295fa3d789dSPierre van Houtryve 
296fa3d789dSPierre van Houtryve   // Super-registers where this is the first explicit sub-register.
297fa3d789dSPierre van Houtryve   SuperRegList LeadingSuperRegs;
298fa3d789dSPierre van Houtryve 
299fa3d789dSPierre van Houtryve   SubRegMap SubRegs;
300fa3d789dSPierre van Houtryve   SuperRegList SuperRegs;
301fa3d789dSPierre van Houtryve   DenseMap<const CodeGenRegister *, CodeGenSubRegIndex *> SubReg2Idx;
302fa3d789dSPierre van Houtryve   RegUnitList RegUnits;
303fa3d789dSPierre van Houtryve   RegUnitLaneMaskList RegUnitLaneMasks;
304fa3d789dSPierre van Houtryve };
305fa3d789dSPierre van Houtryve 
306fa3d789dSPierre van Houtryve inline bool operator<(const CodeGenRegister &A, const CodeGenRegister &B) {
307fa3d789dSPierre van Houtryve   return A.EnumValue < B.EnumValue;
308fa3d789dSPierre van Houtryve }
309fa3d789dSPierre van Houtryve 
310fa3d789dSPierre van Houtryve inline bool operator==(const CodeGenRegister &A, const CodeGenRegister &B) {
311fa3d789dSPierre van Houtryve   return A.EnumValue == B.EnumValue;
312fa3d789dSPierre van Houtryve }
313fa3d789dSPierre van Houtryve 
314fa3d789dSPierre van Houtryve class CodeGenRegisterClass {
315fa3d789dSPierre van Houtryve   CodeGenRegister::Vec Members;
316fa3d789dSPierre van Houtryve   // Allocation orders. Order[0] always contains all registers in Members.
31716510149SRahul Joshi   std::vector<SmallVector<const Record *, 16>> Orders;
318fa3d789dSPierre van Houtryve   // Bit mask of sub-classes including this, indexed by their EnumValue.
319fa3d789dSPierre van Houtryve   BitVector SubClasses;
320fa3d789dSPierre van Houtryve   // List of super-classes, topologocally ordered to have the larger classes
321fa3d789dSPierre van Houtryve   // first.  This is the same as sorting by EnumValue.
322fa3d789dSPierre van Houtryve   SmallVector<CodeGenRegisterClass *, 4> SuperClasses;
3237c6592f5SRahul Joshi   const Record *TheDef;
324fa3d789dSPierre van Houtryve   std::string Name;
325fa3d789dSPierre van Houtryve 
326fa3d789dSPierre van Houtryve   // For a synthesized class, inherit missing properties from the nearest
327fa3d789dSPierre van Houtryve   // super-class.
328fa3d789dSPierre van Houtryve   void inheritProperties(CodeGenRegBank &);
329fa3d789dSPierre van Houtryve 
330fa3d789dSPierre van Houtryve   // Map SubRegIndex -> sub-class.  This is the largest sub-class where all
331fa3d789dSPierre van Houtryve   // registers have a SubRegIndex sub-register.
332fa3d789dSPierre van Houtryve   DenseMap<const CodeGenSubRegIndex *, CodeGenRegisterClass *>
333fa3d789dSPierre van Houtryve       SubClassWithSubReg;
334fa3d789dSPierre van Houtryve 
335fa3d789dSPierre van Houtryve   // Map SubRegIndex -> set of super-reg classes.  This is all register
336fa3d789dSPierre van Houtryve   // classes SuperRC such that:
337fa3d789dSPierre van Houtryve   //
338fa3d789dSPierre van Houtryve   //   R:SubRegIndex in this RC for all R in SuperRC.
339fa3d789dSPierre van Houtryve   //
340fa3d789dSPierre van Houtryve   DenseMap<const CodeGenSubRegIndex *, SmallPtrSet<CodeGenRegisterClass *, 8>>
341fa3d789dSPierre van Houtryve       SuperRegClasses;
342fa3d789dSPierre van Houtryve 
343fa3d789dSPierre van Houtryve   // Bit vector of TopoSigs for the registers in this class. This will be
344fa3d789dSPierre van Houtryve   // very sparse on regular architectures.
345fa3d789dSPierre van Houtryve   BitVector TopoSigs;
346fa3d789dSPierre van Houtryve 
347fa3d789dSPierre van Houtryve public:
348fa3d789dSPierre van Houtryve   unsigned EnumValue;
349fa3d789dSPierre van Houtryve   StringRef Namespace;
350fa3d789dSPierre van Houtryve   SmallVector<ValueTypeByHwMode, 4> VTs;
351fa3d789dSPierre van Houtryve   RegSizeInfoByHwMode RSI;
352fa3d789dSPierre van Houtryve   int CopyCost;
353fa3d789dSPierre van Houtryve   bool Allocatable;
354fa3d789dSPierre van Houtryve   StringRef AltOrderSelect;
355fa3d789dSPierre van Houtryve   uint8_t AllocationPriority;
356fa3d789dSPierre van Houtryve   bool GlobalPriority;
357fa3d789dSPierre van Houtryve   uint8_t TSFlags;
358fa3d789dSPierre van Houtryve   /// Contains the combination of the lane masks of all subregisters.
359fa3d789dSPierre van Houtryve   LaneBitmask LaneMask;
360fa3d789dSPierre van Houtryve   /// True if there are at least 2 subregisters which do not interfere.
361fa3d789dSPierre van Houtryve   bool HasDisjunctSubRegs;
362fa3d789dSPierre van Houtryve   bool CoveredBySubRegs;
363fa3d789dSPierre van Houtryve   /// A register class is artificial if all its members are artificial.
364fa3d789dSPierre van Houtryve   bool Artificial;
365fa3d789dSPierre van Houtryve   /// Generate register pressure set for this register class and any class
366fa3d789dSPierre van Houtryve   /// synthesized from it.
367fa3d789dSPierre van Houtryve   bool GeneratePressureSet;
368fa3d789dSPierre van Houtryve 
369fa3d789dSPierre van Houtryve   // Return the Record that defined this class, or NULL if the class was
370fa3d789dSPierre van Houtryve   // created by TableGen.
3717c6592f5SRahul Joshi   const Record *getDef() const { return TheDef; }
372fa3d789dSPierre van Houtryve 
373fa3d789dSPierre van Houtryve   std::string getNamespaceQualification() const;
374fa3d789dSPierre van Houtryve   const std::string &getName() const { return Name; }
375fa3d789dSPierre van Houtryve   std::string getQualifiedName() const;
376fa3d789dSPierre van Houtryve   std::string getIdName() const;
377fa3d789dSPierre van Houtryve   std::string getQualifiedIdName() const;
378fa3d789dSPierre van Houtryve   ArrayRef<ValueTypeByHwMode> getValueTypes() const { return VTs; }
379fa3d789dSPierre van Houtryve   unsigned getNumValueTypes() const { return VTs.size(); }
380fa3d789dSPierre van Houtryve   bool hasType(const ValueTypeByHwMode &VT) const;
381fa3d789dSPierre van Houtryve 
382fa3d789dSPierre van Houtryve   const ValueTypeByHwMode &getValueTypeNum(unsigned VTNum) const {
383fa3d789dSPierre van Houtryve     if (VTNum < VTs.size())
384fa3d789dSPierre van Houtryve       return VTs[VTNum];
385fa3d789dSPierre van Houtryve     llvm_unreachable("VTNum greater than number of ValueTypes in RegClass!");
386fa3d789dSPierre van Houtryve   }
387fa3d789dSPierre van Houtryve 
388fa3d789dSPierre van Houtryve   // Return true if this class contains the register.
389fa3d789dSPierre van Houtryve   bool contains(const CodeGenRegister *) const;
390fa3d789dSPierre van Houtryve 
391fa3d789dSPierre van Houtryve   // Returns true if RC is a subclass.
392fa3d789dSPierre van Houtryve   // RC is a sub-class of this class if it is a valid replacement for any
393fa3d789dSPierre van Houtryve   // instruction operand where a register of this classis required. It must
394fa3d789dSPierre van Houtryve   // satisfy these conditions:
395fa3d789dSPierre van Houtryve   //
396fa3d789dSPierre van Houtryve   // 1. All RC registers are also in this.
397fa3d789dSPierre van Houtryve   // 2. The RC spill size must not be smaller than our spill size.
398fa3d789dSPierre van Houtryve   // 3. RC spill alignment must be compatible with ours.
399fa3d789dSPierre van Houtryve   //
400fa3d789dSPierre van Houtryve   bool hasSubClass(const CodeGenRegisterClass *RC) const {
401fa3d789dSPierre van Houtryve     return SubClasses.test(RC->EnumValue);
402fa3d789dSPierre van Houtryve   }
403fa3d789dSPierre van Houtryve 
404fa3d789dSPierre van Houtryve   // getSubClassWithSubReg - Returns the largest sub-class where all
405fa3d789dSPierre van Houtryve   // registers have a SubIdx sub-register.
406fa3d789dSPierre van Houtryve   CodeGenRegisterClass *
407fa3d789dSPierre van Houtryve   getSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx) const {
408fa3d789dSPierre van Houtryve     return SubClassWithSubReg.lookup(SubIdx);
409fa3d789dSPierre van Houtryve   }
410fa3d789dSPierre van Houtryve 
411fa3d789dSPierre van Houtryve   /// Find largest subclass where all registers have SubIdx subregisters in
412fa3d789dSPierre van Houtryve   /// SubRegClass and the largest subregister class that contains those
413fa3d789dSPierre van Houtryve   /// subregisters without (as far as possible) also containing additional
414fa3d789dSPierre van Houtryve   /// registers.
415fa3d789dSPierre van Houtryve   ///
416fa3d789dSPierre van Houtryve   /// This can be used to find a suitable pair of classes for subregister
417fa3d789dSPierre van Houtryve   /// copies. \return std::pair<SubClass, SubRegClass> where SubClass is a
418fa3d789dSPierre van Houtryve   /// SubClass is a class where every register has SubIdx and SubRegClass is a
419fa3d789dSPierre van Houtryve   /// class where every register is covered by the SubIdx subregister of
420fa3d789dSPierre van Houtryve   /// SubClass.
421fa3d789dSPierre van Houtryve   std::optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
422fa3d789dSPierre van Houtryve   getMatchingSubClassWithSubRegs(CodeGenRegBank &RegBank,
423fa3d789dSPierre van Houtryve                                  const CodeGenSubRegIndex *SubIdx) const;
424fa3d789dSPierre van Houtryve 
425fa3d789dSPierre van Houtryve   void setSubClassWithSubReg(const CodeGenSubRegIndex *SubIdx,
426fa3d789dSPierre van Houtryve                              CodeGenRegisterClass *SubRC) {
427fa3d789dSPierre van Houtryve     SubClassWithSubReg[SubIdx] = SubRC;
428fa3d789dSPierre van Houtryve   }
429fa3d789dSPierre van Houtryve 
430fa3d789dSPierre van Houtryve   // getSuperRegClasses - Returns a bit vector of all register classes
431fa3d789dSPierre van Houtryve   // containing only SubIdx super-registers of this class.
432fa3d789dSPierre van Houtryve   void getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
433fa3d789dSPierre van Houtryve                           BitVector &Out) const;
434fa3d789dSPierre van Houtryve 
435fa3d789dSPierre van Houtryve   // addSuperRegClass - Add a class containing only SubIdx super-registers.
436fa3d789dSPierre van Houtryve   void addSuperRegClass(CodeGenSubRegIndex *SubIdx,
437fa3d789dSPierre van Houtryve                         CodeGenRegisterClass *SuperRC) {
438fa3d789dSPierre van Houtryve     SuperRegClasses[SubIdx].insert(SuperRC);
439fa3d789dSPierre van Houtryve   }
440fa3d789dSPierre van Houtryve 
441fa3d789dSPierre van Houtryve   // getSubClasses - Returns a constant BitVector of subclasses indexed by
442fa3d789dSPierre van Houtryve   // EnumValue.
443fa3d789dSPierre van Houtryve   // The SubClasses vector includes an entry for this class.
444fa3d789dSPierre van Houtryve   const BitVector &getSubClasses() const { return SubClasses; }
445fa3d789dSPierre van Houtryve 
446fa3d789dSPierre van Houtryve   // getSuperClasses - Returns a list of super classes ordered by EnumValue.
447fa3d789dSPierre van Houtryve   // The array does not include an entry for this class.
448fa3d789dSPierre van Houtryve   ArrayRef<CodeGenRegisterClass *> getSuperClasses() const {
449fa3d789dSPierre van Houtryve     return SuperClasses;
450fa3d789dSPierre van Houtryve   }
451fa3d789dSPierre van Houtryve 
452fa3d789dSPierre van Houtryve   // Returns an ordered list of class members.
453fa3d789dSPierre van Houtryve   // The order of registers is the same as in the .td file.
454fa3d789dSPierre van Houtryve   // No = 0 is the default allocation order, No = 1 is the first alternative.
45516510149SRahul Joshi   ArrayRef<const Record *> getOrder(unsigned No = 0) const {
45616510149SRahul Joshi     return Orders[No];
45716510149SRahul Joshi   }
458fa3d789dSPierre van Houtryve 
459fa3d789dSPierre van Houtryve   // Return the total number of allocation orders available.
460fa3d789dSPierre van Houtryve   unsigned getNumOrders() const { return Orders.size(); }
461fa3d789dSPierre van Houtryve 
462fa3d789dSPierre van Houtryve   // Get the set of registers.  This set contains the same registers as
463fa3d789dSPierre van Houtryve   // getOrder(0).
464fa3d789dSPierre van Houtryve   const CodeGenRegister::Vec &getMembers() const { return Members; }
465fa3d789dSPierre van Houtryve 
466fa3d789dSPierre van Houtryve   // Get a bit vector of TopoSigs present in this register class.
467fa3d789dSPierre van Houtryve   const BitVector &getTopoSigs() const { return TopoSigs; }
468fa3d789dSPierre van Houtryve 
469fa3d789dSPierre van Houtryve   // Get a weight of this register class.
470fa3d789dSPierre van Houtryve   unsigned getWeight(const CodeGenRegBank &) const;
471fa3d789dSPierre van Houtryve 
472fa3d789dSPierre van Houtryve   // Populate a unique sorted list of units from a register set.
473fa3d789dSPierre van Houtryve   void buildRegUnitSet(const CodeGenRegBank &RegBank,
474fa3d789dSPierre van Houtryve                        std::vector<unsigned> &RegUnits) const;
475fa3d789dSPierre van Houtryve 
4767c6592f5SRahul Joshi   CodeGenRegisterClass(CodeGenRegBank &, const Record *R);
477fa3d789dSPierre van Houtryve   CodeGenRegisterClass(CodeGenRegisterClass &) = delete;
478fa3d789dSPierre van Houtryve 
479fa3d789dSPierre van Houtryve   // A key representing the parts of a register class used for forming
480fa3d789dSPierre van Houtryve   // sub-classes.  Note the ordering provided by this key is not the same as
481fa3d789dSPierre van Houtryve   // the topological order used for the EnumValues.
482fa3d789dSPierre van Houtryve   struct Key {
483fa3d789dSPierre van Houtryve     const CodeGenRegister::Vec *Members;
484fa3d789dSPierre van Houtryve     RegSizeInfoByHwMode RSI;
485fa3d789dSPierre van Houtryve 
486fa3d789dSPierre van Houtryve     Key(const CodeGenRegister::Vec *M, const RegSizeInfoByHwMode &I)
487fa3d789dSPierre van Houtryve         : Members(M), RSI(I) {}
488fa3d789dSPierre van Houtryve 
489fa3d789dSPierre van Houtryve     Key(const CodeGenRegisterClass &RC)
490fa3d789dSPierre van Houtryve         : Members(&RC.getMembers()), RSI(RC.RSI) {}
491fa3d789dSPierre van Houtryve 
492fa3d789dSPierre van Houtryve     // Lexicographical order of (Members, RegSizeInfoByHwMode).
493fa3d789dSPierre van Houtryve     bool operator<(const Key &) const;
494fa3d789dSPierre van Houtryve   };
495fa3d789dSPierre van Houtryve 
496fa3d789dSPierre van Houtryve   // Create a non-user defined register class.
497fa3d789dSPierre van Houtryve   CodeGenRegisterClass(CodeGenRegBank &, StringRef Name, Key Props);
498fa3d789dSPierre van Houtryve 
499fa3d789dSPierre van Houtryve   // Called by CodeGenRegBank::CodeGenRegBank().
500fa3d789dSPierre van Houtryve   static void computeSubClasses(CodeGenRegBank &);
501fa3d789dSPierre van Houtryve 
502fa3d789dSPierre van Houtryve   // Get ordering value among register base classes.
503fa3d789dSPierre van Houtryve   std::optional<int> getBaseClassOrder() const {
504fa3d789dSPierre van Houtryve     if (TheDef && !TheDef->isValueUnset("BaseClassOrder"))
505fa3d789dSPierre van Houtryve       return TheDef->getValueAsInt("BaseClassOrder");
506fa3d789dSPierre van Houtryve     return {};
507fa3d789dSPierre van Houtryve   }
508fa3d789dSPierre van Houtryve };
509fa3d789dSPierre van Houtryve 
510fa3d789dSPierre van Houtryve // Register categories are used when we need to deterine the category a
511fa3d789dSPierre van Houtryve // register falls into (GPR, vector, fixed, etc.) without having to know
512fa3d789dSPierre van Houtryve // specific information about the target architecture.
513fa3d789dSPierre van Houtryve class CodeGenRegisterCategory {
5147c6592f5SRahul Joshi   const Record *TheDef;
515fa3d789dSPierre van Houtryve   std::string Name;
516fa3d789dSPierre van Houtryve   std::list<CodeGenRegisterClass *> Classes;
517fa3d789dSPierre van Houtryve 
518fa3d789dSPierre van Houtryve public:
5197c6592f5SRahul Joshi   CodeGenRegisterCategory(CodeGenRegBank &, const Record *R);
520fa3d789dSPierre van Houtryve   CodeGenRegisterCategory(CodeGenRegisterCategory &) = delete;
521fa3d789dSPierre van Houtryve 
522fa3d789dSPierre van Houtryve   // Return the Record that defined this class, or NULL if the class was
523fa3d789dSPierre van Houtryve   // created by TableGen.
5247c6592f5SRahul Joshi   const Record *getDef() const { return TheDef; }
525fa3d789dSPierre van Houtryve 
526fa3d789dSPierre van Houtryve   std::string getName() const { return Name; }
527fa3d789dSPierre van Houtryve   std::list<CodeGenRegisterClass *> getClasses() const { return Classes; }
528fa3d789dSPierre van Houtryve };
529fa3d789dSPierre van Houtryve 
530fa3d789dSPierre van Houtryve // Register units are used to model interference and register pressure.
531fa3d789dSPierre van Houtryve // Every register is assigned one or more register units such that two
532fa3d789dSPierre van Houtryve // registers overlap if and only if they have a register unit in common.
533fa3d789dSPierre van Houtryve //
534fa3d789dSPierre van Houtryve // Normally, one register unit is created per leaf register. Non-leaf
535fa3d789dSPierre van Houtryve // registers inherit the units of their sub-registers.
536fa3d789dSPierre van Houtryve struct RegUnit {
537fa3d789dSPierre van Houtryve   // Weight assigned to this RegUnit for estimating register pressure.
538fa3d789dSPierre van Houtryve   // This is useful when equalizing weights in register classes with mixed
539fa3d789dSPierre van Houtryve   // register topologies.
540fa3d789dSPierre van Houtryve   unsigned Weight;
541fa3d789dSPierre van Houtryve 
542fa3d789dSPierre van Houtryve   // Each native RegUnit corresponds to one or two root registers. The full
543fa3d789dSPierre van Houtryve   // set of registers containing this unit can be computed as the union of
544fa3d789dSPierre van Houtryve   // these two registers and their super-registers.
545fa3d789dSPierre van Houtryve   const CodeGenRegister *Roots[2];
546fa3d789dSPierre van Houtryve 
547fa3d789dSPierre van Houtryve   // Index into RegClassUnitSets where we can find the list of UnitSets that
548fa3d789dSPierre van Houtryve   // contain this unit.
549fa3d789dSPierre van Houtryve   unsigned RegClassUnitSetsIdx;
550fa3d789dSPierre van Houtryve   // A register unit is artificial if at least one of its roots is
551fa3d789dSPierre van Houtryve   // artificial.
552fa3d789dSPierre van Houtryve   bool Artificial;
553fa3d789dSPierre van Houtryve 
554fa3d789dSPierre van Houtryve   RegUnit() : Weight(0), RegClassUnitSetsIdx(0), Artificial(false) {
555fa3d789dSPierre van Houtryve     Roots[0] = Roots[1] = nullptr;
556fa3d789dSPierre van Houtryve   }
557fa3d789dSPierre van Houtryve 
558fa3d789dSPierre van Houtryve   ArrayRef<const CodeGenRegister *> getRoots() const {
559fa3d789dSPierre van Houtryve     assert(!(Roots[1] && !Roots[0]) && "Invalid roots array");
560fa3d789dSPierre van Houtryve     return ArrayRef(Roots, !!Roots[0] + !!Roots[1]);
561fa3d789dSPierre van Houtryve   }
562fa3d789dSPierre van Houtryve };
563fa3d789dSPierre van Houtryve 
564fa3d789dSPierre van Houtryve // Each RegUnitSet is a sorted vector with a name.
565fa3d789dSPierre van Houtryve struct RegUnitSet {
566fa3d789dSPierre van Houtryve   typedef std::vector<unsigned>::const_iterator iterator;
567fa3d789dSPierre van Houtryve 
568fa3d789dSPierre van Houtryve   std::string Name;
569fa3d789dSPierre van Houtryve   std::vector<unsigned> Units;
570fa3d789dSPierre van Houtryve   unsigned Weight = 0; // Cache the sum of all unit weights.
571fa3d789dSPierre van Houtryve   unsigned Order = 0;  // Cache the sort key.
572fa3d789dSPierre van Houtryve 
573358593baSCraig Topper   RegUnitSet(std::string Name) : Name(std::move(Name)) {}
574fa3d789dSPierre van Houtryve };
575fa3d789dSPierre van Houtryve 
576fa3d789dSPierre van Houtryve // Base vector for identifying TopoSigs. The contents uniquely identify a
577fa3d789dSPierre van Houtryve // TopoSig, only computeSuperRegs needs to know how.
578fa3d789dSPierre van Houtryve typedef SmallVector<unsigned, 16> TopoSigId;
579fa3d789dSPierre van Houtryve 
580fa3d789dSPierre van Houtryve // CodeGenRegBank - Represent a target's registers and the relations between
581fa3d789dSPierre van Houtryve // them.
582fa3d789dSPierre van Houtryve class CodeGenRegBank {
583fa3d789dSPierre van Houtryve   SetTheory Sets;
584fa3d789dSPierre van Houtryve 
585fa3d789dSPierre van Houtryve   const CodeGenHwModes &CGH;
586fa3d789dSPierre van Houtryve 
587fa3d789dSPierre van Houtryve   std::deque<CodeGenSubRegIndex> SubRegIndices;
5887c6592f5SRahul Joshi   DenseMap<const Record *, CodeGenSubRegIndex *> Def2SubRegIdx;
589fa3d789dSPierre van Houtryve 
590fa3d789dSPierre van Houtryve   CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace);
591fa3d789dSPierre van Houtryve 
592fa3d789dSPierre van Houtryve   typedef std::map<SmallVector<CodeGenSubRegIndex *, 8>, CodeGenSubRegIndex *>
593fa3d789dSPierre van Houtryve       ConcatIdxMap;
594fa3d789dSPierre van Houtryve   ConcatIdxMap ConcatIdx;
595fa3d789dSPierre van Houtryve 
596fa3d789dSPierre van Houtryve   // Registers.
597fa3d789dSPierre van Houtryve   std::deque<CodeGenRegister> Registers;
598fa3d789dSPierre van Houtryve   StringMap<CodeGenRegister *> RegistersByName;
59916510149SRahul Joshi   DenseMap<const Record *, CodeGenRegister *> Def2Reg;
600fa3d789dSPierre van Houtryve   unsigned NumNativeRegUnits;
601fa3d789dSPierre van Houtryve 
602fa3d789dSPierre van Houtryve   std::map<TopoSigId, unsigned> TopoSigs;
603fa3d789dSPierre van Houtryve 
604fa3d789dSPierre van Houtryve   // Includes native (0..NumNativeRegUnits-1) and adopted register units.
605fa3d789dSPierre van Houtryve   SmallVector<RegUnit, 8> RegUnits;
606fa3d789dSPierre van Houtryve 
607fa3d789dSPierre van Houtryve   // Register classes.
608fa3d789dSPierre van Houtryve   std::list<CodeGenRegisterClass> RegClasses;
609bdf02249SRahul Joshi   DenseMap<const Record *, CodeGenRegisterClass *> Def2RC;
610fa3d789dSPierre van Houtryve   typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass *> RCKeyMap;
611fa3d789dSPierre van Houtryve   RCKeyMap Key2RC;
612fa3d789dSPierre van Houtryve 
613fa3d789dSPierre van Houtryve   // Register categories.
614fa3d789dSPierre van Houtryve   std::list<CodeGenRegisterCategory> RegCategories;
615fa3d789dSPierre van Houtryve   using RCatKeyMap =
616fa3d789dSPierre van Houtryve       std::map<CodeGenRegisterClass::Key, CodeGenRegisterCategory *>;
617fa3d789dSPierre van Houtryve   RCatKeyMap Key2RCat;
618fa3d789dSPierre van Houtryve 
619fa3d789dSPierre van Houtryve   // Remember each unique set of register units. Initially, this contains a
620fa3d789dSPierre van Houtryve   // unique set for each register class. Simliar sets are coalesced with
621fa3d789dSPierre van Houtryve   // pruneUnitSets and new supersets are inferred during computeRegUnitSets.
622fa3d789dSPierre van Houtryve   std::vector<RegUnitSet> RegUnitSets;
623fa3d789dSPierre van Houtryve 
624fa3d789dSPierre van Houtryve   // Map RegisterClass index to the index of the RegUnitSet that contains the
625fa3d789dSPierre van Houtryve   // class's units and any inferred RegUnit supersets.
626fa3d789dSPierre van Houtryve   //
627fa3d789dSPierre van Houtryve   // NOTE: This could grow beyond the number of register classes when we map
628fa3d789dSPierre van Houtryve   // register units to lists of unit sets. If the list of unit sets does not
629fa3d789dSPierre van Houtryve   // already exist for a register class, we create a new entry in this vector.
630fa3d789dSPierre van Houtryve   std::vector<std::vector<unsigned>> RegClassUnitSets;
631fa3d789dSPierre van Houtryve 
632fa3d789dSPierre van Houtryve   // Give each register unit set an order based on sorting criteria.
633fa3d789dSPierre van Houtryve   std::vector<unsigned> RegUnitSetOrder;
634fa3d789dSPierre van Houtryve 
635fa3d789dSPierre van Houtryve   // Keep track of synthesized definitions generated in TupleExpander.
636fa3d789dSPierre van Houtryve   std::vector<std::unique_ptr<Record>> SynthDefs;
637fa3d789dSPierre van Houtryve 
638fa3d789dSPierre van Houtryve   // Add RC to *2RC maps.
639fa3d789dSPierre van Houtryve   void addToMaps(CodeGenRegisterClass *);
640fa3d789dSPierre van Houtryve 
641fa3d789dSPierre van Houtryve   // Create a synthetic sub-class if it is missing.
642fa3d789dSPierre van Houtryve   CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC,
643fa3d789dSPierre van Houtryve                                             const CodeGenRegister::Vec *Membs,
644fa3d789dSPierre van Houtryve                                             StringRef Name);
645fa3d789dSPierre van Houtryve 
646fa3d789dSPierre van Houtryve   // Infer missing register classes.
647fa3d789dSPierre van Houtryve   void computeInferredRegisterClasses();
648fa3d789dSPierre van Houtryve   void inferCommonSubClass(CodeGenRegisterClass *RC);
649fa3d789dSPierre van Houtryve   void inferSubClassWithSubReg(CodeGenRegisterClass *RC);
650fa3d789dSPierre van Houtryve 
651fa3d789dSPierre van Houtryve   void inferMatchingSuperRegClass(CodeGenRegisterClass *RC) {
652fa3d789dSPierre van Houtryve     inferMatchingSuperRegClass(RC, RegClasses.begin());
653fa3d789dSPierre van Houtryve   }
654fa3d789dSPierre van Houtryve 
655fa3d789dSPierre van Houtryve   void inferMatchingSuperRegClass(
656fa3d789dSPierre van Houtryve       CodeGenRegisterClass *RC,
657fa3d789dSPierre van Houtryve       std::list<CodeGenRegisterClass>::iterator FirstSubRegRC);
658fa3d789dSPierre van Houtryve 
659fa3d789dSPierre van Houtryve   // Iteratively prune unit sets.
660fa3d789dSPierre van Houtryve   void pruneUnitSets();
661fa3d789dSPierre van Houtryve 
662fa3d789dSPierre van Houtryve   // Compute a weight for each register unit created during getSubRegs.
663fa3d789dSPierre van Houtryve   void computeRegUnitWeights();
664fa3d789dSPierre van Houtryve 
665fa3d789dSPierre van Houtryve   // Create a RegUnitSet for each RegClass and infer superclasses.
666fa3d789dSPierre van Houtryve   void computeRegUnitSets();
667fa3d789dSPierre van Houtryve 
668fa3d789dSPierre van Houtryve   // Populate the Composite map from sub-register relationships.
669fa3d789dSPierre van Houtryve   void computeComposites();
670fa3d789dSPierre van Houtryve 
671fa3d789dSPierre van Houtryve   // Compute a lane mask for each sub-register index.
672fa3d789dSPierre van Houtryve   void computeSubRegLaneMasks();
673fa3d789dSPierre van Houtryve 
674fa3d789dSPierre van Houtryve   /// Computes a lane mask for each register unit enumerated by a physical
675fa3d789dSPierre van Houtryve   /// register.
676fa3d789dSPierre van Houtryve   void computeRegUnitLaneMasks();
677fa3d789dSPierre van Houtryve 
678fa3d789dSPierre van Houtryve public:
6797c6592f5SRahul Joshi   CodeGenRegBank(const RecordKeeper &, const CodeGenHwModes &);
680fa3d789dSPierre van Houtryve   CodeGenRegBank(CodeGenRegBank &) = delete;
681fa3d789dSPierre van Houtryve 
682fa3d789dSPierre van Houtryve   SetTheory &getSets() { return Sets; }
683fa3d789dSPierre van Houtryve 
684fa3d789dSPierre van Houtryve   const CodeGenHwModes &getHwModes() const { return CGH; }
685fa3d789dSPierre van Houtryve 
686fa3d789dSPierre van Houtryve   // Sub-register indices. The first NumNamedIndices are defined by the user
687fa3d789dSPierre van Houtryve   // in the .td files. The rest are synthesized such that all sub-registers
688fa3d789dSPierre van Houtryve   // have a unique name.
689fa3d789dSPierre van Houtryve   const std::deque<CodeGenSubRegIndex> &getSubRegIndices() const {
690fa3d789dSPierre van Houtryve     return SubRegIndices;
691fa3d789dSPierre van Houtryve   }
692fa3d789dSPierre van Houtryve 
693fa3d789dSPierre van Houtryve   // Find a SubRegIndex from its Record def or add to the list if it does
694fa3d789dSPierre van Houtryve   // not exist there yet.
6957c6592f5SRahul Joshi   CodeGenSubRegIndex *getSubRegIdx(const Record *);
696fa3d789dSPierre van Houtryve 
697fa3d789dSPierre van Houtryve   // Find a SubRegIndex from its Record def.
698fa3d789dSPierre van Houtryve   const CodeGenSubRegIndex *findSubRegIdx(const Record *Def) const;
699fa3d789dSPierre van Houtryve 
700fa3d789dSPierre van Houtryve   // Find or create a sub-register index representing the A+B composition.
701fa3d789dSPierre van Houtryve   CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A,
702fa3d789dSPierre van Houtryve                                               CodeGenSubRegIndex *B);
703fa3d789dSPierre van Houtryve 
704fa3d789dSPierre van Houtryve   // Find or create a sub-register index representing the concatenation of
705fa3d789dSPierre van Houtryve   // non-overlapping sibling indices.
706fa3d789dSPierre van Houtryve   CodeGenSubRegIndex *
707baf66ec0SCraig Topper   getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &,
708baf66ec0SCraig Topper                        const CodeGenHwModes &CGH);
709fa3d789dSPierre van Houtryve 
710fa3d789dSPierre van Houtryve   const std::deque<CodeGenRegister> &getRegisters() const { return Registers; }
711fa3d789dSPierre van Houtryve 
712fa3d789dSPierre van Houtryve   const StringMap<CodeGenRegister *> &getRegistersByName() const {
713fa3d789dSPierre van Houtryve     return RegistersByName;
714fa3d789dSPierre van Houtryve   }
715fa3d789dSPierre van Houtryve 
716fa3d789dSPierre van Houtryve   // Find a register from its Record def.
71716510149SRahul Joshi   CodeGenRegister *getReg(const Record *);
718fa3d789dSPierre van Houtryve 
719fa3d789dSPierre van Houtryve   // Get a Register's index into the Registers array.
720fa3d789dSPierre van Houtryve   unsigned getRegIndex(const CodeGenRegister *Reg) const {
721fa3d789dSPierre van Houtryve     return Reg->EnumValue - 1;
722fa3d789dSPierre van Houtryve   }
723fa3d789dSPierre van Houtryve 
724fa3d789dSPierre van Houtryve   // Return the number of allocated TopoSigs. The first TopoSig representing
725fa3d789dSPierre van Houtryve   // leaf registers is allocated number 0.
726fa3d789dSPierre van Houtryve   unsigned getNumTopoSigs() const { return TopoSigs.size(); }
727fa3d789dSPierre van Houtryve 
728fa3d789dSPierre van Houtryve   // Find or create a TopoSig for the given TopoSigId.
729fa3d789dSPierre van Houtryve   // This function is only for use by CodeGenRegister::computeSuperRegs().
730fa3d789dSPierre van Houtryve   // Others should simply use Reg->getTopoSig().
731fa3d789dSPierre van Houtryve   unsigned getTopoSig(const TopoSigId &Id) {
732*4e8c9d28SJay Foad     return TopoSigs.try_emplace(Id, TopoSigs.size()).first->second;
733fa3d789dSPierre van Houtryve   }
734fa3d789dSPierre van Houtryve 
735fa3d789dSPierre van Houtryve   // Create a native register unit that is associated with one or two root
736fa3d789dSPierre van Houtryve   // registers.
737fa3d789dSPierre van Houtryve   unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = nullptr) {
738fa3d789dSPierre van Houtryve     RegUnit &RU = RegUnits.emplace_back();
739fa3d789dSPierre van Houtryve     RU.Roots[0] = R0;
740fa3d789dSPierre van Houtryve     RU.Roots[1] = R1;
741fa3d789dSPierre van Houtryve     RU.Artificial = R0->Artificial;
742fa3d789dSPierre van Houtryve     if (R1)
743fa3d789dSPierre van Houtryve       RU.Artificial |= R1->Artificial;
744fa3d789dSPierre van Houtryve     return RegUnits.size() - 1;
745fa3d789dSPierre van Houtryve   }
746fa3d789dSPierre van Houtryve 
747fa3d789dSPierre van Houtryve   // Create a new non-native register unit that can be adopted by a register
748fa3d789dSPierre van Houtryve   // to increase its pressure. Note that NumNativeRegUnits is not increased.
749fa3d789dSPierre van Houtryve   unsigned newRegUnit(unsigned Weight) {
750fa3d789dSPierre van Houtryve     RegUnit &RU = RegUnits.emplace_back();
751fa3d789dSPierre van Houtryve     RU.Weight = Weight;
752fa3d789dSPierre van Houtryve     return RegUnits.size() - 1;
753fa3d789dSPierre van Houtryve   }
754fa3d789dSPierre van Houtryve 
755fa3d789dSPierre van Houtryve   // Native units are the singular unit of a leaf register. Register aliasing
756fa3d789dSPierre van Houtryve   // is completely characterized by native units. Adopted units exist to give
757fa3d789dSPierre van Houtryve   // register additional weight but don't affect aliasing.
758fa3d789dSPierre van Houtryve   bool isNativeUnit(unsigned RUID) const { return RUID < NumNativeRegUnits; }
759fa3d789dSPierre van Houtryve 
760fa3d789dSPierre van Houtryve   unsigned getNumNativeRegUnits() const { return NumNativeRegUnits; }
761fa3d789dSPierre van Houtryve 
762fa3d789dSPierre van Houtryve   RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
763fa3d789dSPierre van Houtryve   const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
764fa3d789dSPierre van Houtryve 
765fa3d789dSPierre van Houtryve   std::list<CodeGenRegisterClass> &getRegClasses() { return RegClasses; }
766fa3d789dSPierre van Houtryve 
767fa3d789dSPierre van Houtryve   const std::list<CodeGenRegisterClass> &getRegClasses() const {
768fa3d789dSPierre van Houtryve     return RegClasses;
769fa3d789dSPierre van Houtryve   }
770fa3d789dSPierre van Houtryve 
771fa3d789dSPierre van Houtryve   std::list<CodeGenRegisterCategory> &getRegCategories() {
772fa3d789dSPierre van Houtryve     return RegCategories;
773fa3d789dSPierre van Houtryve   }
774fa3d789dSPierre van Houtryve 
775fa3d789dSPierre van Houtryve   const std::list<CodeGenRegisterCategory> &getRegCategories() const {
776fa3d789dSPierre van Houtryve     return RegCategories;
777fa3d789dSPierre van Houtryve   }
778fa3d789dSPierre van Houtryve 
779fa3d789dSPierre van Houtryve   // Find a register class from its def.
780fa3d789dSPierre van Houtryve   CodeGenRegisterClass *getRegClass(const Record *) const;
781fa3d789dSPierre van Houtryve 
782fa3d789dSPierre van Houtryve   /// getRegisterClassForRegister - Find the register class that contains the
783fa3d789dSPierre van Houtryve   /// specified physical register.  If the register is not in a register
784fa3d789dSPierre van Houtryve   /// class, return null. If the register is in multiple classes, and the
785fa3d789dSPierre van Houtryve   /// classes have a superset-subset relationship and the same set of types,
786fa3d789dSPierre van Houtryve   /// return the superclass.  Otherwise return null.
7877c6592f5SRahul Joshi   const CodeGenRegisterClass *getRegClassForRegister(const Record *R);
788fa3d789dSPierre van Houtryve 
789fa3d789dSPierre van Houtryve   // Analog of TargetRegisterInfo::getMinimalPhysRegClass. Unlike
790fa3d789dSPierre van Houtryve   // getRegClassForRegister, this tries to find the smallest class containing
791fa3d789dSPierre van Houtryve   // the physical register. If \p VT is specified, it will only find classes
792fa3d789dSPierre van Houtryve   // with a matching type
793fa3d789dSPierre van Houtryve   const CodeGenRegisterClass *
7947c6592f5SRahul Joshi   getMinimalPhysRegClass(const Record *RegRecord,
7957c6592f5SRahul Joshi                          ValueTypeByHwMode *VT = nullptr);
796fa3d789dSPierre van Houtryve 
797fa3d789dSPierre van Houtryve   // Get the sum of unit weights.
798fa3d789dSPierre van Houtryve   unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const {
799fa3d789dSPierre van Houtryve     unsigned Weight = 0;
800fa3d789dSPierre van Houtryve     for (unsigned Unit : Units)
801fa3d789dSPierre van Houtryve       Weight += getRegUnit(Unit).Weight;
802fa3d789dSPierre van Houtryve     return Weight;
803fa3d789dSPierre van Houtryve   }
804fa3d789dSPierre van Houtryve 
805fa3d789dSPierre van Houtryve   unsigned getRegSetIDAt(unsigned Order) const {
806fa3d789dSPierre van Houtryve     return RegUnitSetOrder[Order];
807fa3d789dSPierre van Houtryve   }
808fa3d789dSPierre van Houtryve 
809fa3d789dSPierre van Houtryve   const RegUnitSet &getRegSetAt(unsigned Order) const {
810fa3d789dSPierre van Houtryve     return RegUnitSets[RegUnitSetOrder[Order]];
811fa3d789dSPierre van Houtryve   }
812fa3d789dSPierre van Houtryve 
813fa3d789dSPierre van Houtryve   // Increase a RegUnitWeight.
814fa3d789dSPierre van Houtryve   void increaseRegUnitWeight(unsigned RUID, unsigned Inc) {
815fa3d789dSPierre van Houtryve     getRegUnit(RUID).Weight += Inc;
816fa3d789dSPierre van Houtryve   }
817fa3d789dSPierre van Houtryve 
818fa3d789dSPierre van Houtryve   // Get the number of register pressure dimensions.
819fa3d789dSPierre van Houtryve   unsigned getNumRegPressureSets() const { return RegUnitSets.size(); }
820fa3d789dSPierre van Houtryve 
821fa3d789dSPierre van Houtryve   // Get a set of register unit IDs for a given dimension of pressure.
822fa3d789dSPierre van Houtryve   const RegUnitSet &getRegPressureSet(unsigned Idx) const {
823fa3d789dSPierre van Houtryve     return RegUnitSets[Idx];
824fa3d789dSPierre van Houtryve   }
825fa3d789dSPierre van Houtryve 
826fa3d789dSPierre van Houtryve   // The number of pressure set lists may be larget than the number of
827fa3d789dSPierre van Houtryve   // register classes if some register units appeared in a list of sets that
828fa3d789dSPierre van Houtryve   // did not correspond to an existing register class.
829fa3d789dSPierre van Houtryve   unsigned getNumRegClassPressureSetLists() const {
830fa3d789dSPierre van Houtryve     return RegClassUnitSets.size();
831fa3d789dSPierre van Houtryve   }
832fa3d789dSPierre van Houtryve 
833fa3d789dSPierre van Houtryve   // Get a list of pressure set IDs for a register class. Liveness of a
834fa3d789dSPierre van Houtryve   // register in this class impacts each pressure set in this list by the
835fa3d789dSPierre van Houtryve   // weight of the register. An exact solution requires all registers in a
836fa3d789dSPierre van Houtryve   // class to have the same class, but it is not strictly guaranteed.
837fa3d789dSPierre van Houtryve   ArrayRef<unsigned> getRCPressureSetIDs(unsigned RCIdx) const {
838fa3d789dSPierre van Houtryve     return RegClassUnitSets[RCIdx];
839fa3d789dSPierre van Houtryve   }
840fa3d789dSPierre van Houtryve 
841fa3d789dSPierre van Houtryve   // Computed derived records such as missing sub-register indices.
842fa3d789dSPierre van Houtryve   void computeDerivedInfo();
843fa3d789dSPierre van Houtryve 
844fa3d789dSPierre van Houtryve   // Compute the set of registers completely covered by the registers in Regs.
845fa3d789dSPierre van Houtryve   // The returned BitVector will have a bit set for each register in Regs,
846fa3d789dSPierre van Houtryve   // all sub-registers, and all super-registers that are covered by the
847fa3d789dSPierre van Houtryve   // registers in Regs.
848fa3d789dSPierre van Houtryve   //
849fa3d789dSPierre van Houtryve   // This is used to compute the mask of call-preserved registers from a list
850fa3d789dSPierre van Houtryve   // of callee-saves.
85116510149SRahul Joshi   BitVector computeCoveredRegisters(ArrayRef<const Record *> Regs);
852fa3d789dSPierre van Houtryve 
853fa3d789dSPierre van Houtryve   // Bit mask of lanes that cover their registers. A sub-register index whose
854fa3d789dSPierre van Houtryve   // LaneMask is contained in CoveringLanes will be completely covered by
855fa3d789dSPierre van Houtryve   // another sub-register with the same or larger lane mask.
856fa3d789dSPierre van Houtryve   LaneBitmask CoveringLanes;
857fa3d789dSPierre van Houtryve 
858fa3d789dSPierre van Houtryve   // Helper function for printing debug information. Handles artificial
859fa3d789dSPierre van Houtryve   // (non-native) reg units.
860fa3d789dSPierre van Houtryve   void printRegUnitName(unsigned Unit) const;
861fa3d789dSPierre van Houtryve };
862fa3d789dSPierre van Houtryve 
863fa3d789dSPierre van Houtryve } // end namespace llvm
864fa3d789dSPierre van Houtryve 
8658a61bfcfSRahul Joshi #endif // LLVM_UTILS_TABLEGEN_COMMON_CODEGENREGISTERS_H
866