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>
union_modes(const InfoByHwMode<InfoT> & A,const InfoByHwMode<InfoT> & B)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;
InfoByHwModeInfoByHwMode68 InfoByHwMode(const MapType &M) : Map(M) {}
69
70 LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode71 iterator begin() { return Map.begin(); }
72 LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode73 iterator end() { return Map.end(); }
74 LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode75 const_iterator begin() const { return Map.begin(); }
76 LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode77 const_iterator end() const { return Map.end(); }
78 LLVM_ATTRIBUTE_ALWAYS_INLINE
emptyInfoByHwMode79 bool empty() const { return Map.empty(); }
80
81 LLVM_ATTRIBUTE_ALWAYS_INLINE
hasModeInfoByHwMode82 bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
83 LLVM_ATTRIBUTE_ALWAYS_INLINE
hasDefaultInfoByHwMode84 bool hasDefault() const { return hasMode(DefaultMode); }
85
getInfoByHwMode86 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 }
getInfoByHwMode93 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
isSimpleInfoByHwMode102 bool isSimple() const {
103 return Map.size() == 1 && Map.begin()->first == DefaultMode;
104 }
105 LLVM_ATTRIBUTE_ALWAYS_INLINE
getSimpleInfoByHwMode106 InfoT getSimple() const {
107 assert(isSimple());
108 return Map.begin()->second;
109 }
makeSimpleInfoByHwMode110 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);
ValueTypeByHwModeValueTypeByHwMode123 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
isValidValueTypeByHwMode129 bool isValid() const {
130 return !Map.empty();
131 }
getTypeValueTypeByHwMode132 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();
isPointerValueTypeByHwMode140 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