]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/RDFRegisters.h
dts: Update our copy to Linux 4.17
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / RDFRegisters.h
1 //===- RDFRegisters.h -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
11 #define LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
12
13 #include "llvm/ADT/BitVector.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/CodeGen/TargetRegisterInfo.h"
16 #include "llvm/MC/LaneBitmask.h"
17 #include <cassert>
18 #include <cstdint>
19 #include <map>
20 #include <set>
21 #include <vector>
22
23 namespace llvm {
24
25 class MachineFunction;
26 class raw_ostream;
27
28 namespace rdf {
29
30   using RegisterId = uint32_t;
31
32   // Template class for a map translating uint32_t into arbitrary types.
33   // The map will act like an indexed set: upon insertion of a new object,
34   // it will automatically assign a new index to it. Index of 0 is treated
35   // as invalid and is never allocated.
36   template <typename T, unsigned N = 32>
37   struct IndexedSet {
38     IndexedSet() { Map.reserve(N); }
39
40     T get(uint32_t Idx) const {
41       // Index Idx corresponds to Map[Idx-1].
42       assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
43       return Map[Idx-1];
44     }
45
46     uint32_t insert(T Val) {
47       // Linear search.
48       auto F = llvm::find(Map, Val);
49       if (F != Map.end())
50         return F - Map.begin() + 1;
51       Map.push_back(Val);
52       return Map.size();  // Return actual_index + 1.
53     }
54
55     uint32_t find(T Val) const {
56       auto F = llvm::find(Map, Val);
57       assert(F != Map.end());
58       return F - Map.begin() + 1;
59     }
60
61     uint32_t size() const { return Map.size(); }
62
63     using const_iterator = typename std::vector<T>::const_iterator;
64
65     const_iterator begin() const { return Map.begin(); }
66     const_iterator end() const { return Map.end(); }
67
68   private:
69     std::vector<T> Map;
70   };
71
72   struct RegisterRef {
73     RegisterId Reg = 0;
74     LaneBitmask Mask = LaneBitmask::getNone();
75
76     RegisterRef() = default;
77     explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
78       : Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}
79
80     operator bool() const {
81       return Reg != 0 && Mask.any();
82     }
83
84     bool operator== (const RegisterRef &RR) const {
85       return Reg == RR.Reg && Mask == RR.Mask;
86     }
87
88     bool operator!= (const RegisterRef &RR) const {
89       return !operator==(RR);
90     }
91
92     bool operator< (const RegisterRef &RR) const {
93       return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
94     }
95   };
96
97
98   struct PhysicalRegisterInfo {
99     PhysicalRegisterInfo(const TargetRegisterInfo &tri,
100                          const MachineFunction &mf);
101
102     static bool isRegMaskId(RegisterId R) {
103       return TargetRegisterInfo::isStackSlot(R);
104     }
105
106     RegisterId getRegMaskId(const uint32_t *RM) const {
107       return TargetRegisterInfo::index2StackSlot(RegMasks.find(RM));
108     }
109
110     const uint32_t *getRegMaskBits(RegisterId R) const {
111       return RegMasks.get(TargetRegisterInfo::stackSlot2Index(R));
112     }
113
114     RegisterRef normalize(RegisterRef RR) const;
115
116     bool alias(RegisterRef RA, RegisterRef RB) const {
117       if (!isRegMaskId(RA.Reg))
118         return !isRegMaskId(RB.Reg) ? aliasRR(RA, RB) : aliasRM(RA, RB);
119       return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB);
120     }
121
122     std::set<RegisterId> getAliasSet(RegisterId Reg) const;
123
124     RegisterRef getRefForUnit(uint32_t U) const {
125       return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
126     }
127
128     const BitVector &getMaskUnits(RegisterId MaskId) const {
129       return MaskInfos[TargetRegisterInfo::stackSlot2Index(MaskId)].Units;
130     }
131
132     RegisterRef mapTo(RegisterRef RR, unsigned R) const;
133     const TargetRegisterInfo &getTRI() const { return TRI; }
134
135   private:
136     struct RegInfo {
137       const TargetRegisterClass *RegClass = nullptr;
138     };
139     struct UnitInfo {
140       RegisterId Reg = 0;
141       LaneBitmask Mask;
142     };
143     struct MaskInfo {
144       BitVector Units;
145     };
146
147     const TargetRegisterInfo &TRI;
148     IndexedSet<const uint32_t*> RegMasks;
149     std::vector<RegInfo> RegInfos;
150     std::vector<UnitInfo> UnitInfos;
151     std::vector<MaskInfo> MaskInfos;
152
153     bool aliasRR(RegisterRef RA, RegisterRef RB) const;
154     bool aliasRM(RegisterRef RR, RegisterRef RM) const;
155     bool aliasMM(RegisterRef RM, RegisterRef RN) const;
156   };
157
158   struct RegisterAggr {
159     RegisterAggr(const PhysicalRegisterInfo &pri)
160         : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
161     RegisterAggr(const RegisterAggr &RG) = default;
162
163     bool empty() const { return Units.none(); }
164     bool hasAliasOf(RegisterRef RR) const;
165     bool hasCoverOf(RegisterRef RR) const;
166
167     static bool isCoverOf(RegisterRef RA, RegisterRef RB,
168                           const PhysicalRegisterInfo &PRI) {
169       return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
170     }
171
172     RegisterAggr &insert(RegisterRef RR);
173     RegisterAggr &insert(const RegisterAggr &RG);
174     RegisterAggr &intersect(RegisterRef RR);
175     RegisterAggr &intersect(const RegisterAggr &RG);
176     RegisterAggr &clear(RegisterRef RR);
177     RegisterAggr &clear(const RegisterAggr &RG);
178
179     RegisterRef intersectWith(RegisterRef RR) const;
180     RegisterRef clearIn(RegisterRef RR) const;
181     RegisterRef makeRegRef() const;
182
183     void print(raw_ostream &OS) const;
184
185     struct rr_iterator {
186       using MapType = std::map<RegisterId, LaneBitmask>;
187
188     private:
189       MapType Masks;
190       MapType::iterator Pos;
191       unsigned Index;
192       const RegisterAggr *Owner;
193
194     public:
195       rr_iterator(const RegisterAggr &RG, bool End);
196
197       RegisterRef operator*() const {
198         return RegisterRef(Pos->first, Pos->second);
199       }
200
201       rr_iterator &operator++() {
202         ++Pos;
203         ++Index;
204         return *this;
205       }
206
207       bool operator==(const rr_iterator &I) const {
208         assert(Owner == I.Owner);
209         (void)Owner;
210         return Index == I.Index;
211       }
212
213       bool operator!=(const rr_iterator &I) const {
214         return !(*this == I);
215       }
216     };
217
218     rr_iterator rr_begin() const {
219       return rr_iterator(*this, false);
220     }
221     rr_iterator rr_end() const {
222       return rr_iterator(*this, true);
223     }
224
225   private:
226     BitVector Units;
227     const PhysicalRegisterInfo &PRI;
228   };
229
230   // Optionally print the lane mask, if it is not ~0.
231   struct PrintLaneMaskOpt {
232     PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
233     LaneBitmask Mask;
234   };
235   raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);
236
237 } // end namespace rdf
238
239 } // end namespace llvm
240
241 #endif // LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H