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>
union_modes(const InfoByHwMode<InfoT> & A,const InfoByHwMode<InfoT> & B,SmallVectorImpl<unsigned> & Modes)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;
InfoByHwModeInfoByHwMode65 InfoByHwMode(const MapType &M) : Map(M) {}
66
67 LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode68 iterator begin() { return Map.begin(); }
69 LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode70 iterator end() { return Map.end(); }
71 LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode72 const_iterator begin() const { return Map.begin(); }
73 LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode74 const_iterator end() const { return Map.end(); }
75 LLVM_ATTRIBUTE_ALWAYS_INLINE
emptyInfoByHwMode76 bool empty() const { return Map.empty(); }
77
78 LLVM_ATTRIBUTE_ALWAYS_INLINE
hasModeInfoByHwMode79 bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
80 LLVM_ATTRIBUTE_ALWAYS_INLINE
hasDefaultInfoByHwMode81 bool hasDefault() const { return hasMode(DefaultMode); }
82
getInfoByHwMode83 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 }
getInfoByHwMode90 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
isSimpleInfoByHwMode99 bool isSimple() const {
100 return Map.size() == 1 && Map.begin()->first == DefaultMode;
101 }
102 LLVM_ATTRIBUTE_ALWAYS_INLINE
getSimpleInfoByHwMode103 InfoT getSimple() const {
104 assert(isSimple());
105 return Map.begin()->second;
106 }
makeSimpleInfoByHwMode107 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);
ValueTypeByHwModeValueTypeByHwMode121 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
isValidValueTypeByHwMode127 bool isValid() const {
128 return !Map.empty();
129 }
getTypeValueTypeByHwMode130 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();
isPointerValueTypeByHwMode138 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
insertRegSizeForModeRegSizeInfoByHwMode180 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