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