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/IndexedMap.h"
14#include "llvm/ADT/STLExtras.h"
17#include "llvm/MC/LaneBitmask.h"
18#include "llvm/MC/MCRegister.h"
19#include <cassert>
20#include <cstdint>
21#include <map>
22#include <set>
23#include <vector>
24
25namespace llvm {
26
27class MachineFunction;
28class raw_ostream;
29
30namespace rdf {
31struct RegisterAggr;
32
34
35template <typename T>
36bool disjoint(const std::set<T> &A, const std::set<T> &B) {
37 auto ItA = A.begin(), EndA = A.end();
38 auto ItB = B.begin(), EndB = B.end();
39 while (ItA != EndA && ItB != EndB) {
40 if (*ItA < *ItB)
41 ++ItA;
42 else if (*ItB < *ItA)
43 ++ItB;
44 else
45 return false;
46 }
47 return true;
48}
49
50// Template class for a map translating uint32_t into arbitrary types.
51// The map will act like an indexed set: upon insertion of a new object,
52// it will automatically assign a new index to it. Index of 0 is treated
53// as invalid and is never allocated.
54template <typename T, unsigned N = 32> struct IndexedSet {
55 IndexedSet() { Map.reserve(N); }
56
57 T get(uint32_t Idx) const {
58 // Index Idx corresponds to Map[Idx-1].
59 assert(Idx != 0 && !Map.empty() && Idx - 1 < Map.size());
60 return Map[Idx - 1];
61 }
62
64 // Linear search.
65 auto F = llvm::find(Map, Val);
66 if (F != Map.end())
67 return F - Map.begin() + 1;
68 Map.push_back(Val);
69 return Map.size(); // Return actual_index + 1.
70 }
71
72 uint32_t find(T Val) const {
73 auto F = llvm::find(Map, Val);
74 assert(F != Map.end());
75 return F - Map.begin() + 1;
76 }
77
78 uint32_t size() const { return Map.size(); }
79
80 using const_iterator = typename std::vector<T>::const_iterator;
81
82 const_iterator begin() const { return Map.begin(); }
83 const_iterator end() const { return Map.end(); }
84
85private:
86 std::vector<T> Map;
87};
88
90private:
91 static constexpr RegisterId MaskFlag = 1u << 30;
92 static constexpr RegisterId UnitFlag = 1u << 31;
93
94public:
96 LaneBitmask Mask = LaneBitmask::getNone(); // Only for registers.
97
98 constexpr RegisterRef() = default;
99 constexpr explicit RegisterRef(RegisterId R,
101 : Id(R), Mask(isRegId(R) && R != 0 ? M : LaneBitmask::getNone()) {}
102
103 // Classify null register as a "register".
104 constexpr bool isReg() const { return Id == 0 || isRegId(Id); }
105 constexpr bool isUnit() const { return isUnitId(Id); }
106 constexpr bool isMask() const { return isMaskId(Id); }
107
108 constexpr MCRegister asMCReg() const {
109 assert(isReg());
110 return Id;
111 }
112
113 constexpr MCRegUnit asMCRegUnit() const {
114 assert(isUnit());
115 return static_cast<MCRegUnit>(Id & ~UnitFlag);
116 }
117
118 constexpr unsigned asMaskIdx() const {
119 assert(isMask());
120 return Id & ~MaskFlag;
121 }
122
123 explicit constexpr operator bool() const {
124 return !isReg() || (Id != 0 && Mask.any());
125 }
126
127 size_t hash() const {
128 return std::hash<RegisterId>{}(Id) ^
129 std::hash<LaneBitmask::Type>{}(Mask.getAsInteger());
130 }
131
132 static constexpr bool isRegId(RegisterId Id) {
133 return Id != 0 && !(Id & UnitFlag) && !(Id & MaskFlag);
134 }
135 static constexpr bool isUnitId(RegisterId Id) { return Id & UnitFlag; }
136 static constexpr bool isMaskId(RegisterId Id) { return Id & MaskFlag; }
137
138 static constexpr RegisterId toUnitId(unsigned Idx) { return Idx | UnitFlag; }
139
140 static constexpr RegisterId toMaskId(unsigned Idx) { return Idx | MaskFlag; }
141
142 bool operator<(RegisterRef) const = delete;
143 bool operator==(RegisterRef) const = delete;
144 bool operator!=(RegisterRef) const = delete;
145};
146
149 const MachineFunction &mf);
150
152 return RegisterRef::toMaskId(RegMasks.find(RM));
153 }
154
156 return RegMasks.get(RR.asMaskIdx());
157 }
158
159 bool alias(RegisterRef RA, RegisterRef RB) const;
160
161 // Returns the set of aliased physical registers.
162 std::set<RegisterId> getAliasSet(RegisterRef RR) const;
163
164 RegisterRef getRefForUnit(MCRegUnit U) const {
165 return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
166 }
167
169 return MaskInfos[RR.asMaskIdx()].Units;
170 }
171
172 std::set<RegisterId> getUnits(RegisterRef RR) const;
173
174 const BitVector &getUnitAliases(MCRegUnit U) const {
175 return AliasInfos[U].Regs;
176 }
177
179 const TargetRegisterInfo &getTRI() const { return TRI; }
180
181 bool equal_to(RegisterRef A, RegisterRef B) const;
182 bool less(RegisterRef A, RegisterRef B) const;
183
184 void print(raw_ostream &OS, RegisterRef A) const;
185 void print(raw_ostream &OS, const RegisterAggr &A) const;
186
187private:
188 struct RegInfo {
189 const TargetRegisterClass *RegClass = nullptr;
190 };
191 struct UnitInfo {
192 RegisterId Reg = 0;
193 LaneBitmask Mask;
194 };
195 struct MaskInfo {
196 BitVector Units;
197 };
198 struct AliasInfo {
199 BitVector Regs;
200 };
201
202 const TargetRegisterInfo &TRI;
203 IndexedSet<const uint32_t *> RegMasks;
204 std::vector<RegInfo> RegInfos;
205 IndexedMap<UnitInfo, MCRegUnitToIndex> UnitInfos;
206 std::vector<MaskInfo> MaskInfos;
207 IndexedMap<AliasInfo, MCRegUnitToIndex> AliasInfos;
208};
209
212 : PRI(&pri) {}
213
215 return PRI->equal_to(A, B);
216 }
217
218private:
219 // Make it a pointer just in case. See comment in `RegisterRefLess` below.
221};
222
225 : PRI(&pri) {}
226
228 return PRI->less(A, B);
229 }
230
231private:
232 // Make it a pointer because apparently some versions of MSVC use std::swap
233 // on the comparator object.
235};
236
239 : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
240 RegisterAggr(const RegisterAggr &RG) = default;
241
242 unsigned size() const { return Units.count(); }
243 bool empty() const { return Units.none(); }
244 bool hasAliasOf(RegisterRef RR) const;
245 bool hasCoverOf(RegisterRef RR) const;
246
247 const PhysicalRegisterInfo &getPRI() const { return PRI; }
248
249 bool operator==(const RegisterAggr &A) const {
250 return DenseMapInfo<BitVector>::isEqual(Units, A.Units);
251 }
252
254 const PhysicalRegisterInfo &PRI) {
255 return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
256 }
257
259 RegisterAggr &insert(const RegisterAggr &RG);
263 RegisterAggr &clear(const RegisterAggr &RG);
264
267 RegisterRef makeRegRef() const;
268
269 size_t hash() const { return DenseMapInfo<BitVector>::getHashValue(Units); }
270
272 using MapType = std::map<RegisterId, LaneBitmask>;
273
274 private:
275 MapType Masks;
276 MapType::iterator Pos;
277 unsigned Index;
278 const RegisterAggr *Owner;
279
280 public:
281 ref_iterator(const RegisterAggr &RG, bool End);
282
284 return RegisterRef(Pos->first, Pos->second);
285 }
286
288 ++Pos;
289 ++Index;
290 return *this;
291 }
292
293 bool operator==(const ref_iterator &I) const {
294 assert(Owner == I.Owner);
295 (void)Owner;
296 return Index == I.Index;
297 }
298
299 bool operator!=(const ref_iterator &I) const { return !(*this == I); }
300 };
301
302 ref_iterator ref_begin() const { return ref_iterator(*this, false); }
303 ref_iterator ref_end() const { return ref_iterator(*this, true); }
304
306 unit_iterator unit_begin() const { return Units.set_bits_begin(); }
307 unit_iterator unit_end() const { return Units.set_bits_end(); }
308
315
316private:
317 BitVector Units;
318 const PhysicalRegisterInfo &PRI;
319};
320
321// This is really a std::map, except that it provides a non-trivial
322// default constructor to the element accessed via [].
323template <typename KeyType> struct RegisterAggrMap {
324 RegisterAggrMap(const PhysicalRegisterInfo &pri) : Empty(pri) {}
325
327 return Map.emplace(Key, Empty).first->second;
328 }
329
330 auto begin() { return Map.begin(); }
331 auto end() { return Map.end(); }
332 auto begin() const { return Map.begin(); }
333 auto end() const { return Map.end(); }
334 auto find(const KeyType &Key) const { return Map.find(Key); }
335
336private:
338 std::map<KeyType, RegisterAggr> Map;
339
340public:
341 using key_type = typename decltype(Map)::key_type;
342 using mapped_type = typename decltype(Map)::mapped_type;
343 using value_type = typename decltype(Map)::value_type;
344};
345
347
348// Print the lane mask in a short form (or not at all if all bits are set).
354
355} // end namespace rdf
356} // end namespace llvm
357
358namespace std {
359
360template <> struct hash<llvm::rdf::RegisterRef> {
362 return A.hash();
363 }
364};
365
366template <> struct hash<llvm::rdf::RegisterAggr> {
367 size_t operator()(const llvm::rdf::RegisterAggr &A) const { //
368 return A.hash();
369 }
370};
371
372} // namespace std
373
374namespace llvm::rdf {
375using RegisterSet = std::set<RegisterRef, RegisterRefLess>;
376} // namespace llvm::rdf
377
378#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")
This file implements an indexed map.
A common definition of LaneBitmask for use in TableGen and CodeGen.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
#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 physical registers. Should be passed by value.
Definition MCRegister.h:41
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:1751
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:867
#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
RegisterRef getRefForUnit(MCRegUnit U) 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 BitVector & getMaskUnits(RegisterRef RR) const
bool equal_to(RegisterRef A, RegisterRef B) const
const uint32_t * getRegMaskBits(RegisterRef RR) const
bool alias(RegisterRef RA, RegisterRef RB) const
std::set< RegisterId > getAliasSet(RegisterRef RR) const
bool less(RegisterRef A, RegisterRef B) const
RegisterRef mapTo(RegisterRef RR, RegisterId R) const
const BitVector & getUnitAliases(MCRegUnit U) const
std::set< RegisterId > getUnits(RegisterRef RR) 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
BitVector::const_set_bits_iterator unit_iterator
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
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 RegisterRef(RegisterId R, LaneBitmask M=LaneBitmask::getAll())
bool operator!=(RegisterRef) const =delete
static constexpr RegisterId toUnitId(unsigned Idx)
constexpr unsigned asMaskIdx() const
constexpr RegisterRef()=default
constexpr bool isReg() const
constexpr bool isMask() const
static constexpr bool isMaskId(RegisterId Id)
static constexpr bool isUnitId(RegisterId Id)
static constexpr bool isRegId(RegisterId Id)
constexpr MCRegUnit asMCRegUnit() const
static constexpr RegisterId toMaskId(unsigned Idx)
constexpr bool isUnit() const
bool operator<(RegisterRef) const =delete
constexpr MCRegister asMCReg() const
bool operator==(RegisterRef) const =delete
size_t operator()(const llvm::rdf::RegisterAggr &A) const
size_t operator()(llvm::rdf::RegisterRef A) const