LLVM 22.0.0git
RDFRegisters.h
Go to the documentation of this file.
1//===- RDFRegisters.h -------------------------------------------*- 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_CODEGEN_RDFREGISTERS_H
10#define LLVM_CODEGEN_RDFREGISTERS_H
11
12#include "llvm/ADT/BitVector.h"
13#include "llvm/ADT/STLExtras.h"
16#include "llvm/MC/LaneBitmask.h"
17#include "llvm/MC/MCRegister.h"
18#include <cassert>
19#include <cstdint>
20#include <map>
21#include <set>
22#include <vector>
23
24namespace llvm {
25
26class MachineFunction;
27class raw_ostream;
28
29namespace rdf {
30struct RegisterAggr;
31
33
34template <typename T>
35bool disjoint(const std::set<T> &A, const std::set<T> &B) {
36 auto ItA = A.begin(), EndA = A.end();
37 auto ItB = B.begin(), EndB = B.end();
38 while (ItA != EndA && ItB != EndB) {
39 if (*ItA < *ItB)
40 ++ItA;
41 else if (*ItB < *ItA)
42 ++ItB;
43 else
44 return false;
45 }
46 return true;
47}
48
49// Template class for a map translating uint32_t into arbitrary types.
50// The map will act like an indexed set: upon insertion of a new object,
51// it will automatically assign a new index to it. Index of 0 is treated
52// as invalid and is never allocated.
53template <typename T, unsigned N = 32> struct IndexedSet {
54 IndexedSet() { Map.reserve(N); }
55
56 T get(uint32_t Idx) const {
57 // Index Idx corresponds to Map[Idx-1].
58 assert(Idx != 0 && !Map.empty() && Idx - 1 < Map.size());
59 return Map[Idx - 1];
60 }
61
63 // Linear search.
64 auto F = llvm::find(Map, Val);
65 if (F != Map.end())
66 return F - Map.begin() + 1;
67 Map.push_back(Val);
68 return Map.size(); // Return actual_index + 1.
69 }
70
71 uint32_t find(T Val) const {
72 auto F = llvm::find(Map, Val);
73 assert(F != Map.end());
74 return F - Map.begin() + 1;
75 }
76
77 uint32_t size() const { return Map.size(); }
78
79 using const_iterator = typename std::vector<T>::const_iterator;
80
81 const_iterator begin() const { return Map.begin(); }
82 const_iterator end() const { return Map.end(); }
83
84private:
85 std::vector<T> Map;
86};
87
90 LaneBitmask Mask = LaneBitmask::getNone(); // Only for registers.
91
92 constexpr RegisterRef() = default;
93 constexpr explicit RegisterRef(RegisterId R,
95 : Reg(R), Mask(isRegId(R) && R != 0 ? M : LaneBitmask::getNone()) {}
96
97 // Classify null register as a "register".
98 constexpr bool isReg() const { return Reg == 0 || isRegId(Reg); }
99 constexpr bool isUnit() const { return isUnitId(Reg); }
100 constexpr bool isMask() const { return isMaskId(Reg); }
101
102 constexpr unsigned idx() const { return toIdx(Reg); }
103
104 constexpr operator bool() const {
105 return !isReg() || (Reg != 0 && Mask.any());
106 }
107
108 size_t hash() const {
109 return std::hash<RegisterId>{}(Reg) ^
110 std::hash<LaneBitmask::Type>{}(Mask.getAsInteger());
111 }
112
113 static constexpr bool isRegId(unsigned Id) {
115 }
116 static constexpr bool isUnitId(unsigned Id) {
118 }
119 static constexpr bool isMaskId(unsigned Id) { return Register(Id).isStack(); }
120
121 static constexpr RegisterId toUnitId(unsigned Idx) {
122 return Idx | Register::VirtualRegFlag;
123 }
124
125 static constexpr unsigned toIdx(RegisterId Id) {
126 // Not using virtReg2Index or stackSlot2Index, because they are
127 // not constexpr.
128 if (isUnitId(Id))
129 return Id & ~Register::VirtualRegFlag;
130 // RegId and MaskId are unchanged.
131 return Id;
132 }
133
134 bool operator<(RegisterRef) const = delete;
135 bool operator==(RegisterRef) const = delete;
136 bool operator!=(RegisterRef) const = delete;
137};
138
141 const MachineFunction &mf);
142
144 return Register::index2StackSlot(RegMasks.find(RM));
145 }
146
148 return RegMasks.get(Register(R).stackSlotIndex());
149 }
150
151 bool alias(RegisterRef RA, RegisterRef RB) const;
152
153 // Returns the set of aliased physical registers.
154 std::set<RegisterId> getAliasSet(RegisterId Reg) const;
155
157 return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
158 }
159
160 const BitVector &getMaskUnits(RegisterId MaskId) const {
161 return MaskInfos[Register(MaskId).stackSlotIndex()].Units;
162 }
163
164 std::set<RegisterId> getUnits(RegisterRef RR) const;
165
167 return AliasInfos[U].Regs;
168 }
169
170 RegisterRef mapTo(RegisterRef RR, unsigned R) const;
171 const TargetRegisterInfo &getTRI() const { return TRI; }
172
173 bool equal_to(RegisterRef A, RegisterRef B) const;
174 bool less(RegisterRef A, RegisterRef B) const;
175
176 void print(raw_ostream &OS, RegisterRef A) const;
177 void print(raw_ostream &OS, const RegisterAggr &A) const;
178
179private:
180 struct RegInfo {
181 const TargetRegisterClass *RegClass = nullptr;
182 };
183 struct UnitInfo {
184 RegisterId Reg = 0;
185 LaneBitmask Mask;
186 };
187 struct MaskInfo {
188 BitVector Units;
189 };
190 struct AliasInfo {
191 BitVector Regs;
192 };
193
194 const TargetRegisterInfo &TRI;
195 IndexedSet<const uint32_t *> RegMasks;
196 std::vector<RegInfo> RegInfos;
197 std::vector<UnitInfo> UnitInfos;
198 std::vector<MaskInfo> MaskInfos;
199 std::vector<AliasInfo> AliasInfos;
200};
201
204 : PRI(&pri) {}
205
207 return PRI->equal_to(A, B);
208 }
209
210private:
211 // Make it a pointer just in case. See comment in `RegisterRefLess` below.
213};
214
217 : PRI(&pri) {}
218
220 return PRI->less(A, B);
221 }
222
223private:
224 // Make it a pointer because apparently some versions of MSVC use std::swap
225 // on the comparator object.
227};
228
231 : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
232 RegisterAggr(const RegisterAggr &RG) = default;
233
234 unsigned size() const { return Units.count(); }
235 bool empty() const { return Units.none(); }
236 bool hasAliasOf(RegisterRef RR) const;
237 bool hasCoverOf(RegisterRef RR) const;
238
239 const PhysicalRegisterInfo &getPRI() const { return PRI; }
240
241 bool operator==(const RegisterAggr &A) const {
242 return DenseMapInfo<BitVector>::isEqual(Units, A.Units);
243 }
244
246 const PhysicalRegisterInfo &PRI) {
247 return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
248 }
249
251 RegisterAggr &insert(const RegisterAggr &RG);
255 RegisterAggr &clear(const RegisterAggr &RG);
256
259 RegisterRef makeRegRef() const;
260
261 size_t hash() const { return DenseMapInfo<BitVector>::getHashValue(Units); }
262
264 using MapType = std::map<RegisterId, LaneBitmask>;
265
266 private:
267 MapType Masks;
268 MapType::iterator Pos;
269 unsigned Index;
270 const RegisterAggr *Owner;
271
272 public:
273 ref_iterator(const RegisterAggr &RG, bool End);
274
276 return RegisterRef(Pos->first, Pos->second);
277 }
278
280 ++Pos;
281 ++Index;
282 return *this;
283 }
284
285 bool operator==(const ref_iterator &I) const {
286 assert(Owner == I.Owner);
287 (void)Owner;
288 return Index == I.Index;
289 }
290
291 bool operator!=(const ref_iterator &I) const { return !(*this == I); }
292 };
293
294 ref_iterator ref_begin() const { return ref_iterator(*this, false); }
295 ref_iterator ref_end() const { return ref_iterator(*this, true); }
296
298 unit_iterator unit_begin() const { return Units.set_bits_begin(); }
299 unit_iterator unit_end() const { return Units.set_bits_end(); }
300
307
308private:
309 BitVector Units;
310 const PhysicalRegisterInfo &PRI;
311};
312
313// This is really a std::map, except that it provides a non-trivial
314// default constructor to the element accessed via [].
315template <typename KeyType> struct RegisterAggrMap {
316 RegisterAggrMap(const PhysicalRegisterInfo &pri) : Empty(pri) {}
317
319 return Map.emplace(Key, Empty).first->second;
320 }
321
322 auto begin() { return Map.begin(); }
323 auto end() { return Map.end(); }
324 auto begin() const { return Map.begin(); }
325 auto end() const { return Map.end(); }
326 auto find(const KeyType &Key) const { return Map.find(Key); }
327
328private:
330 std::map<KeyType, RegisterAggr> Map;
331
332public:
333 using key_type = typename decltype(Map)::key_type;
334 using mapped_type = typename decltype(Map)::mapped_type;
335 using value_type = typename decltype(Map)::value_type;
336};
337
339
340// Print the lane mask in a short form (or not at all if all bits are set).
346
347} // end namespace rdf
348} // end namespace llvm
349
350namespace std {
351
352template <> struct hash<llvm::rdf::RegisterRef> {
354 return A.hash();
355 }
356};
357
358template <> struct hash<llvm::rdf::RegisterAggr> {
359 size_t operator()(const llvm::rdf::RegisterAggr &A) const { //
360 return A.hash();
361 }
362};
363
364template <> struct equal_to<llvm::rdf::RegisterAggr> {
366 const llvm::rdf::RegisterAggr &B) const {
367 return A == B;
368 }
369};
370
371} // namespace std
372
373namespace llvm::rdf {
374using RegisterSet = std::set<RegisterRef, RegisterRefLess>;
375} // namespace llvm::rdf
376
377#endif // LLVM_CODEGEN_RDFREGISTERS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A common definition of LaneBitmask for use in TableGen and CodeGen.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
#define P(N)
SI optimize exec mask operations pre RA
This file contains some templates that are useful if you are working with the STL at all.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
const_set_bits_iterator_impl< BitVector > const_set_bits_iterator
Definition BitVector.h:150
Wrapper class representing virtual and physical registers.
Definition Register.h:19
static Register index2StackSlot(int FI)
Convert a non-negative frame index to a stack slot register value.
Definition Register.h:48
static constexpr unsigned VirtualRegFlag
Definition Register.h:40
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:61
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition Register.h:55
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
std::set< RegisterRef, RegisterRefLess > RegisterSet
Definition RDFGraph.h:450
uint32_t RegisterId
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
Definition RDFGraph.cpp:44
bool disjoint(const std::set< T > &A, const std::set< T > &B)
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1731
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
An information struct used to provide DenseMap with the various necessary components for a given valu...
static constexpr LaneBitmask getAll()
Definition LaneBitmask.h:82
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81
const_iterator end() const
typename std::vector< T >::const_iterator const_iterator
T get(uint32_t Idx) const
uint32_t size() const
uint32_t insert(T Val)
const_iterator begin() const
uint32_t find(T Val) const
const BitVector & getMaskUnits(RegisterId MaskId) const
RegisterId getRegMaskId(const uint32_t *RM) const
PhysicalRegisterInfo(const TargetRegisterInfo &tri, const MachineFunction &mf)
void print(raw_ostream &OS, RegisterRef A) const
const TargetRegisterInfo & getTRI() const
const uint32_t * getRegMaskBits(RegisterId R) const
std::set< RegisterId > getAliasSet(RegisterId Reg) const
const BitVector & getUnitAliases(uint32_t U) const
bool equal_to(RegisterRef A, RegisterRef B) const
bool alias(RegisterRef RA, RegisterRef RB) const
RegisterRef mapTo(RegisterRef RR, unsigned R) const
bool less(RegisterRef A, RegisterRef B) const
std::set< RegisterId > getUnits(RegisterRef RR) const
RegisterRef getRefForUnit(uint32_t U) const
RegisterAggrMap(const PhysicalRegisterInfo &pri)
auto find(const KeyType &Key) const
typename decltype(Map)::mapped_type mapped_type
typename decltype(Map)::key_type key_type
RegisterAggr & operator[](KeyType Key)
typename decltype(Map)::value_type value_type
ref_iterator(const RegisterAggr &RG, bool End)
std::map< RegisterId, LaneBitmask > MapType
bool operator!=(const ref_iterator &I) const
bool operator==(const ref_iterator &I) const
iterator_range< ref_iterator > refs() const
RegisterAggr & insert(RegisterRef RR)
iterator_range< unit_iterator > units() const
RegisterAggr(const PhysicalRegisterInfo &pri)
unsigned size() const
const PhysicalRegisterInfo & getPRI() const
RegisterRef clearIn(RegisterRef RR) const
unit_iterator unit_end() const
RegisterAggr(const RegisterAggr &RG)=default
RegisterAggr & clear(RegisterRef RR)
ref_iterator ref_begin() const
RegisterRef makeRegRef() const
RegisterAggr & intersect(RegisterRef RR)
bool hasAliasOf(RegisterRef RR) const
RegisterRef intersectWith(RegisterRef RR) const
bool operator==(const RegisterAggr &A) const
bool hasCoverOf(RegisterRef RR) const
unit_iterator unit_begin() const
static bool isCoverOf(RegisterRef RA, RegisterRef RB, const PhysicalRegisterInfo &PRI)
ref_iterator ref_end() const
typename BitVector::const_set_bits_iterator unit_iterator
bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const
constexpr RegisterRefEqualTo(const llvm::rdf::PhysicalRegisterInfo &pri)
constexpr RegisterRefLess(const llvm::rdf::PhysicalRegisterInfo &pri)
bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const
constexpr unsigned idx() const
constexpr RegisterRef(RegisterId R, LaneBitmask M=LaneBitmask::getAll())
bool operator!=(RegisterRef) const =delete
static constexpr RegisterId toUnitId(unsigned Idx)
constexpr RegisterRef()=default
constexpr bool isReg() const
constexpr bool isMask() const
static constexpr bool isMaskId(unsigned Id)
static constexpr bool isRegId(unsigned Id)
static constexpr bool isUnitId(unsigned Id)
constexpr bool isUnit() const
static constexpr unsigned toIdx(RegisterId Id)
bool operator<(RegisterRef) const =delete
bool operator==(RegisterRef) const =delete
bool operator()(const llvm::rdf::RegisterAggr &A, const llvm::rdf::RegisterAggr &B) const
size_t operator()(const llvm::rdf::RegisterAggr &A) const
size_t operator()(llvm::rdf::RegisterRef A) const