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