• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
IndexedSetIndexedSet38     IndexedSet() { Map.reserve(N); }
39 
getIndexedSet40     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 
insertIndexedSet46     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 
findIndexedSet55     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 
sizeIndexedSet61     uint32_t size() const { return Map.size(); }
62 
63     using const_iterator = typename std::vector<T>::const_iterator;
64 
beginIndexedSet65     const_iterator begin() const { return Map.begin(); }
endIndexedSet66     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())
RegRegisterRef78       : 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 
isRegMaskIdPhysicalRegisterInfo102     static bool isRegMaskId(RegisterId R) {
103       return TargetRegisterInfo::isStackSlot(R);
104     }
105 
getRegMaskIdPhysicalRegisterInfo106     RegisterId getRegMaskId(const uint32_t *RM) const {
107       return TargetRegisterInfo::index2StackSlot(RegMasks.find(RM));
108     }
109 
getRegMaskBitsPhysicalRegisterInfo110     const uint32_t *getRegMaskBits(RegisterId R) const {
111       return RegMasks.get(TargetRegisterInfo::stackSlot2Index(R));
112     }
113 
114     RegisterRef normalize(RegisterRef RR) const;
115 
aliasPhysicalRegisterInfo116     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 
getRefForUnitPhysicalRegisterInfo124     RegisterRef getRefForUnit(uint32_t U) const {
125       return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
126     }
127 
getMaskUnitsPhysicalRegisterInfo128     const BitVector &getMaskUnits(RegisterId MaskId) const {
129       return MaskInfos[TargetRegisterInfo::stackSlot2Index(MaskId)].Units;
130     }
131 
132     RegisterRef mapTo(RegisterRef RR, unsigned R) const;
getTRIPhysicalRegisterInfo133     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 {
RegisterAggrRegisterAggr159     RegisterAggr(const PhysicalRegisterInfo &pri)
160         : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
161     RegisterAggr(const RegisterAggr &RG) = default;
162 
emptyRegisterAggr163     bool empty() const { return Units.none(); }
164     bool hasAliasOf(RegisterRef RR) const;
165     bool hasCoverOf(RegisterRef RR) const;
166 
isCoverOfRegisterAggr167     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 
rr_beginRegisterAggr218     rr_iterator rr_begin() const {
219       return rr_iterator(*this, false);
220     }
rr_endRegisterAggr221     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 {
PrintLaneMaskOptPrintLaneMaskOpt232     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
242