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/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/CodeGenTypes/MachineValueType.h"
21 #include "llvm/Support/Compiler.h"
22 #include <cassert>
23 #include <limits>
24 #include <map>
25 #include <string>
26 #include <tuple>
27 #include <utility>
28
29 namespace llvm {
30
31 class Record;
32 class raw_ostream;
33
34 template <typename InfoT> struct InfoByHwMode;
35
36 std::string getModeName(unsigned Mode);
37
38 enum : unsigned {
39 DefaultMode = CodeGenHwModes::DefaultMode,
40 };
41
42 template <typename InfoT>
union_modes(const InfoByHwMode<InfoT> & A,const InfoByHwMode<InfoT> & B,SmallVectorImpl<unsigned> & Modes)43 void union_modes(const InfoByHwMode<InfoT> &A, const InfoByHwMode<InfoT> &B,
44 SmallVectorImpl<unsigned> &Modes) {
45 auto AI = A.begin();
46 auto BI = B.begin();
47
48 // Skip default mode, but remember if we had one.
49 bool HasDefault = false;
50 if (AI != A.end() && AI->first == DefaultMode) {
51 HasDefault = true;
52 ++AI;
53 }
54 if (BI != B.end() && BI->first == DefaultMode) {
55 HasDefault = true;
56 ++BI;
57 }
58
59 while (AI != A.end()) {
60 // If we're done with B, finish A.
61 if (BI == B.end()) {
62 for (; AI != A.end(); ++AI)
63 Modes.push_back(AI->first);
64 break;
65 }
66
67 if (BI->first < AI->first) {
68 Modes.push_back(BI->first);
69 ++BI;
70 } else {
71 Modes.push_back(AI->first);
72 if (AI->first == BI->first)
73 ++BI;
74 ++AI;
75 }
76 }
77
78 // Finish B.
79 for (; BI != B.end(); ++BI)
80 Modes.push_back(BI->first);
81
82 // Make sure that the default mode is last on the list.
83 if (HasDefault)
84 Modes.push_back(DefaultMode);
85 }
86
87 template <typename InfoT> struct InfoByHwMode {
88 typedef std::map<unsigned, InfoT> MapType;
89 typedef typename MapType::value_type PairType;
90 typedef typename MapType::iterator iterator;
91 typedef typename MapType::const_iterator const_iterator;
92
93 InfoByHwMode() = default;
InfoByHwModeInfoByHwMode94 InfoByHwMode(const MapType &M) : Map(M) {}
95
96 LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode97 iterator begin() { return Map.begin(); }
98 LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode99 iterator end() { return Map.end(); }
100 LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode101 const_iterator begin() const { return Map.begin(); }
102 LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode103 const_iterator end() const { return Map.end(); }
104 LLVM_ATTRIBUTE_ALWAYS_INLINE
emptyInfoByHwMode105 bool empty() const { return Map.empty(); }
106
107 LLVM_ATTRIBUTE_ALWAYS_INLINE
hasModeInfoByHwMode108 bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
109 LLVM_ATTRIBUTE_ALWAYS_INLINE
hasDefaultInfoByHwMode110 bool hasDefault() const {
111 return !Map.empty() && Map.begin()->first == DefaultMode;
112 }
113
getInfoByHwMode114 InfoT &get(unsigned Mode) {
115 auto F = Map.find(Mode);
116 if (F != Map.end())
117 return F->second;
118
119 // Copy and insert the default mode which should be first.
120 assert(hasDefault());
121 auto P = Map.insert({Mode, Map.begin()->second});
122 return P.first->second;
123 }
getInfoByHwMode124 const InfoT &get(unsigned Mode) const {
125 auto F = Map.find(Mode);
126 if (F != Map.end())
127 return F->second;
128 // Get the default mode which should be first.
129 F = Map.begin();
130 assert(F != Map.end() && F->first == DefaultMode);
131 return F->second;
132 }
133
134 LLVM_ATTRIBUTE_ALWAYS_INLINE
isSimpleInfoByHwMode135 bool isSimple() const {
136 return Map.size() == 1 && Map.begin()->first == DefaultMode;
137 }
138 LLVM_ATTRIBUTE_ALWAYS_INLINE
getSimpleInfoByHwMode139 const InfoT &getSimple() const {
140 assert(isSimple());
141 return Map.begin()->second;
142 }
makeSimpleInfoByHwMode143 void makeSimple(unsigned Mode) {
144 assert(hasMode(Mode) || hasDefault());
145 InfoT I = get(Mode);
146 Map.clear();
147 Map.insert(std::pair(DefaultMode, I));
148 }
149
150 protected:
151 MapType Map;
152 };
153
154 struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
155 ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
156 ValueTypeByHwMode(Record *R, MVT T);
ValueTypeByHwModeValueTypeByHwMode157 ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode, T}); }
158 ValueTypeByHwMode() = default;
159
160 bool operator==(const ValueTypeByHwMode &T) const;
161 bool operator<(const ValueTypeByHwMode &T) const;
162
isValidValueTypeByHwMode163 bool isValid() const { return !Map.empty(); }
getTypeValueTypeByHwMode164 MVT getType(unsigned Mode) const { return get(Mode); }
165 MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);
166
167 static StringRef getMVTName(MVT T);
168 void writeToStream(raw_ostream &OS) const;
169 void dump() const;
170
171 unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
isPointerValueTypeByHwMode172 bool isPointer() const {
173 return PtrAddrSpace != std::numeric_limits<unsigned>::max();
174 }
175 };
176
177 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec, const CodeGenHwModes &CGH);
178
179 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
180
181 struct RegSizeInfo {
182 unsigned RegSize;
183 unsigned SpillSize;
184 unsigned SpillAlignment;
185
186 RegSizeInfo(Record *R);
187 RegSizeInfo() = default;
188 bool operator<(const RegSizeInfo &I) const;
189 bool operator==(const RegSizeInfo &I) const {
190 return std::tie(RegSize, SpillSize, SpillAlignment) ==
191 std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
192 }
193 bool operator!=(const RegSizeInfo &I) const { return !(*this == I); }
194
195 bool isSubClassOf(const RegSizeInfo &I) const;
196 void writeToStream(raw_ostream &OS) const;
197 };
198
199 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
200 RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
201 RegSizeInfoByHwMode() = default;
202 bool operator<(const RegSizeInfoByHwMode &VI) const;
203 bool operator==(const RegSizeInfoByHwMode &VI) const;
204 bool operator!=(const RegSizeInfoByHwMode &VI) const {
205 return !(*this == VI);
206 }
207
208 bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
209 bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
210
211 void writeToStream(raw_ostream &OS) const;
212
insertRegSizeForModeRegSizeInfoByHwMode213 void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
214 Map.insert(std::pair(Mode, Info));
215 }
216 };
217
218 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
219 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
220
221 struct SubRegRange {
222 uint16_t Size;
223 uint16_t Offset;
224
225 SubRegRange(Record *R);
SubRegRangeSubRegRange226 SubRegRange(uint16_t Size, uint16_t Offset) : Size(Size), Offset(Offset) {}
227 };
228
229 struct SubRegRangeByHwMode : public InfoByHwMode<SubRegRange> {
230 SubRegRangeByHwMode(Record *R, const CodeGenHwModes &CGH);
SubRegRangeByHwModeSubRegRangeByHwMode231 SubRegRangeByHwMode(SubRegRange Range) { Map.insert({DefaultMode, Range}); }
232 SubRegRangeByHwMode() = default;
233
insertSubRegRangeForModeSubRegRangeByHwMode234 void insertSubRegRangeForMode(unsigned Mode, SubRegRange Info) {
235 Map.insert(std::pair(Mode, Info));
236 }
237 };
238
239 struct EncodingInfoByHwMode : public InfoByHwMode<Record *> {
240 EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
241 EncodingInfoByHwMode() = default;
242 };
243
244 } // namespace llvm
245
246 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
247