Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / utils / TableGen / InfoByHwMode.h
blobb8a6645baca5863d1a8fa54942af229d2f45aaf4
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 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
15 #define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
17 #include "CodeGenHwModes.h"
18 #include "llvm/ADT/SmallSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/CodeGen/MachineValueType.h"
22 #include "llvm/Support/Compiler.h"
23 #include <cassert>
24 #include <limits>
25 #include <map>
26 #include <string>
27 #include <tuple>
28 #include <utility>
30 namespace llvm {
32 class Record;
33 class raw_ostream;
35 template <typename InfoT> struct InfoByHwMode;
37 std::string getModeName(unsigned Mode);
39 enum : unsigned {
40 DefaultMode = CodeGenHwModes::DefaultMode,
43 template <typename InfoT>
44 void union_modes(const InfoByHwMode<InfoT> &A,
45 const InfoByHwMode<InfoT> &B,
46 SmallVectorImpl<unsigned> &Modes) {
47 auto AI = A.begin();
48 auto BI = B.begin();
50 // Skip default mode, but remember if we had one.
51 bool HasDefault = false;
52 if (AI != A.end() && AI->first == DefaultMode) {
53 HasDefault = true;
54 ++AI;
56 if (BI != B.end() && BI->first == DefaultMode) {
57 HasDefault = true;
58 ++BI;
61 while (AI != A.end()) {
62 // If we're done with B, finish A.
63 if (BI == B.end()) {
64 for (; AI != A.end(); ++AI)
65 Modes.push_back(AI->first);
66 break;
69 if (BI->first < AI->first) {
70 Modes.push_back(BI->first);
71 ++BI;
72 } else {
73 Modes.push_back(AI->first);
74 if (AI->first == BI->first)
75 ++BI;
76 ++AI;
80 // Finish B.
81 for (; BI != B.end(); ++BI)
82 Modes.push_back(BI->first);
84 // Make sure that the default mode is last on the list.
85 if (HasDefault)
86 Modes.push_back(DefaultMode);
89 template <typename InfoT>
90 struct InfoByHwMode {
91 typedef std::map<unsigned,InfoT> MapType;
92 typedef typename MapType::value_type PairType;
93 typedef typename MapType::iterator iterator;
94 typedef typename MapType::const_iterator const_iterator;
96 InfoByHwMode() = default;
97 InfoByHwMode(const MapType &M) : Map(M) {}
99 LLVM_ATTRIBUTE_ALWAYS_INLINE
100 iterator begin() { return Map.begin(); }
101 LLVM_ATTRIBUTE_ALWAYS_INLINE
102 iterator end() { return Map.end(); }
103 LLVM_ATTRIBUTE_ALWAYS_INLINE
104 const_iterator begin() const { return Map.begin(); }
105 LLVM_ATTRIBUTE_ALWAYS_INLINE
106 const_iterator end() const { return Map.end(); }
107 LLVM_ATTRIBUTE_ALWAYS_INLINE
108 bool empty() const { return Map.empty(); }
110 LLVM_ATTRIBUTE_ALWAYS_INLINE
111 bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
112 LLVM_ATTRIBUTE_ALWAYS_INLINE
113 bool hasDefault() const {
114 return !Map.empty() && Map.begin()->first == DefaultMode;
117 InfoT &get(unsigned Mode) {
118 auto F = Map.find(Mode);
119 if (F != Map.end())
120 return F->second;
122 // Copy and insert the default mode which should be first.
123 assert(hasDefault());
124 auto P = Map.insert({Mode, Map.begin()->second});
125 return P.first->second;
127 const InfoT &get(unsigned Mode) const {
128 auto F = Map.find(Mode);
129 if (F != Map.end())
130 return F->second;
131 // Get the default mode which should be first.
132 F = Map.begin();
133 assert(F != Map.end() && F->first == DefaultMode);
134 return F->second;
137 LLVM_ATTRIBUTE_ALWAYS_INLINE
138 bool isSimple() const {
139 return Map.size() == 1 && Map.begin()->first == DefaultMode;
141 LLVM_ATTRIBUTE_ALWAYS_INLINE
142 const InfoT &getSimple() const {
143 assert(isSimple());
144 return Map.begin()->second;
146 void makeSimple(unsigned Mode) {
147 assert(hasMode(Mode) || hasDefault());
148 InfoT I = get(Mode);
149 Map.clear();
150 Map.insert(std::make_pair(DefaultMode, I));
153 protected:
154 MapType Map;
157 struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
158 ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
159 ValueTypeByHwMode(Record *R, MVT T);
160 ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode,T}); }
161 ValueTypeByHwMode() = default;
163 bool operator== (const ValueTypeByHwMode &T) const;
164 bool operator< (const ValueTypeByHwMode &T) const;
166 bool isValid() const {
167 return !Map.empty();
169 MVT getType(unsigned Mode) const { return get(Mode); }
170 MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);
172 static StringRef getMVTName(MVT T);
173 void writeToStream(raw_ostream &OS) const;
174 void dump() const;
176 unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
177 bool isPointer() const {
178 return PtrAddrSpace != std::numeric_limits<unsigned>::max();
182 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
183 const CodeGenHwModes &CGH);
185 struct RegSizeInfo {
186 unsigned RegSize;
187 unsigned SpillSize;
188 unsigned SpillAlignment;
190 RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
191 RegSizeInfo() = default;
192 bool operator< (const RegSizeInfo &I) const;
193 bool operator== (const RegSizeInfo &I) const {
194 return std::tie(RegSize, SpillSize, SpillAlignment) ==
195 std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
197 bool operator!= (const RegSizeInfo &I) const {
198 return !(*this == I);
201 bool isSubClassOf(const RegSizeInfo &I) const;
202 void writeToStream(raw_ostream &OS) const;
205 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
206 RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
207 RegSizeInfoByHwMode() = default;
208 bool operator< (const RegSizeInfoByHwMode &VI) const;
209 bool operator== (const RegSizeInfoByHwMode &VI) const;
210 bool operator!= (const RegSizeInfoByHwMode &VI) const {
211 return !(*this == VI);
214 bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
215 bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
217 void writeToStream(raw_ostream &OS) const;
219 void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
220 Map.insert(std::make_pair(Mode, Info));
224 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
225 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
226 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
228 struct EncodingInfoByHwMode : public InfoByHwMode<Record*> {
229 EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
230 EncodingInfoByHwMode() = default;
233 } // namespace llvm
235 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H