1 //===--- InfoByHwMode.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 // Classes that implement data parameterized by HW modes for instruction 9 // selection. Currently it is ValueTypeByHwMode (parameterized ValueType), 10 // and RegSizeInfoByHwMode (parameterized register/spill size and alignment 11 // data). 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H 15 #define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H 16 17 #include "CodeGenHwModes.h" 18 #include "llvm/ADT/SmallSet.h" 19 #include "llvm/Support/MachineValueType.h" 20 21 #include <map> 22 #include <string> 23 24 namespace llvm { 25 26 class Record; 27 class raw_ostream; 28 29 template <typename InfoT> struct InfoByHwMode; 30 31 std::string getModeName(unsigned Mode); 32 33 enum : unsigned { 34 DefaultMode = CodeGenHwModes::DefaultMode, 35 }; 36 37 template <typename InfoT> 38 void union_modes(const InfoByHwMode<InfoT> &A, 39 const InfoByHwMode<InfoT> &B, 40 SmallVectorImpl<unsigned> &Modes) { 41 SmallSet<unsigned, 4> U; 42 for (const auto &P : A) 43 U.insert(P.first); 44 for (const auto &P : B) 45 U.insert(P.first); 46 // Make sure that the default mode is last on the list. 47 bool HasDefault = false; 48 for (unsigned M : U) 49 if (M != DefaultMode) 50 Modes.push_back(M); 51 else 52 HasDefault = true; 53 if (HasDefault) 54 Modes.push_back(DefaultMode); 55 } 56 57 template <typename InfoT> 58 struct InfoByHwMode { 59 typedef std::map<unsigned,InfoT> MapType; 60 typedef typename MapType::value_type PairType; 61 typedef typename MapType::iterator iterator; 62 typedef typename MapType::const_iterator const_iterator; 63 64 InfoByHwMode() = default; 65 InfoByHwMode(const MapType &M) : Map(M) {} 66 67 LLVM_ATTRIBUTE_ALWAYS_INLINE 68 iterator begin() { return Map.begin(); } 69 LLVM_ATTRIBUTE_ALWAYS_INLINE 70 iterator end() { return Map.end(); } 71 LLVM_ATTRIBUTE_ALWAYS_INLINE 72 const_iterator begin() const { return Map.begin(); } 73 LLVM_ATTRIBUTE_ALWAYS_INLINE 74 const_iterator end() const { return Map.end(); } 75 LLVM_ATTRIBUTE_ALWAYS_INLINE 76 bool empty() const { return Map.empty(); } 77 78 LLVM_ATTRIBUTE_ALWAYS_INLINE 79 bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); } 80 LLVM_ATTRIBUTE_ALWAYS_INLINE 81 bool hasDefault() const { return hasMode(DefaultMode); } 82 83 InfoT &get(unsigned Mode) { 84 if (!hasMode(Mode)) { 85 assert(hasMode(DefaultMode)); 86 Map.insert({Mode, Map.at(DefaultMode)}); 87 } 88 return Map.at(Mode); 89 } 90 const InfoT &get(unsigned Mode) const { 91 auto F = Map.find(Mode); 92 if (Mode != DefaultMode && F == Map.end()) 93 F = Map.find(DefaultMode); 94 assert(F != Map.end()); 95 return F->second; 96 } 97 98 LLVM_ATTRIBUTE_ALWAYS_INLINE 99 bool isSimple() const { 100 return Map.size() == 1 && Map.begin()->first == DefaultMode; 101 } 102 LLVM_ATTRIBUTE_ALWAYS_INLINE 103 InfoT getSimple() const { 104 assert(isSimple()); 105 return Map.begin()->second; 106 } 107 void makeSimple(unsigned Mode) { 108 assert(hasMode(Mode) || hasDefault()); 109 InfoT I = get(Mode); 110 Map.clear(); 111 Map.insert(std::make_pair(DefaultMode, I)); 112 } 113 114 protected: 115 MapType Map; 116 }; 117 118 struct ValueTypeByHwMode : public InfoByHwMode<MVT> { 119 ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH); 120 ValueTypeByHwMode(Record *R, MVT T); 121 ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode,T}); } 122 ValueTypeByHwMode() = default; 123 124 bool operator== (const ValueTypeByHwMode &T) const; 125 bool operator< (const ValueTypeByHwMode &T) const; 126 127 bool isValid() const { 128 return !Map.empty(); 129 } 130 MVT getType(unsigned Mode) const { return get(Mode); } 131 MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type); 132 133 static StringRef getMVTName(MVT T); 134 void writeToStream(raw_ostream &OS) const; 135 void dump() const; 136 137 unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max(); 138 bool isPointer() const { 139 return PtrAddrSpace != std::numeric_limits<unsigned>::max(); 140 } 141 }; 142 143 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec, 144 const CodeGenHwModes &CGH); 145 146 struct RegSizeInfo { 147 unsigned RegSize; 148 unsigned SpillSize; 149 unsigned SpillAlignment; 150 151 RegSizeInfo(Record *R, const CodeGenHwModes &CGH); 152 RegSizeInfo() = default; 153 bool operator< (const RegSizeInfo &I) const; 154 bool operator== (const RegSizeInfo &I) const { 155 return std::tie(RegSize, SpillSize, SpillAlignment) == 156 std::tie(I.RegSize, I.SpillSize, I.SpillAlignment); 157 } 158 bool operator!= (const RegSizeInfo &I) const { 159 return !(*this == I); 160 } 161 162 bool isSubClassOf(const RegSizeInfo &I) const; 163 void writeToStream(raw_ostream &OS) const; 164 }; 165 166 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> { 167 RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH); 168 RegSizeInfoByHwMode() = default; 169 bool operator< (const RegSizeInfoByHwMode &VI) const; 170 bool operator== (const RegSizeInfoByHwMode &VI) const; 171 bool operator!= (const RegSizeInfoByHwMode &VI) const { 172 return !(*this == VI); 173 } 174 175 bool isSubClassOf(const RegSizeInfoByHwMode &I) const; 176 bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const; 177 178 void writeToStream(raw_ostream &OS) const; 179 180 void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) { 181 Map.insert(std::make_pair(Mode, Info)); 182 } 183 }; 184 185 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T); 186 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T); 187 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T); 188 189 struct EncodingInfoByHwMode : public InfoByHwMode<Record*> { 190 EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH); 191 EncodingInfoByHwMode() = default; 192 }; 193 194 } // namespace llvm 195 196 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H 197