blob: 7be4678f271bdc62d1d0ede6be46276da68bfccb [file] [log] [blame]
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +00001//===--- InfoByHwMode.h -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// Classes that implement data parameterized by HW modes for instruction
10// selection. Currently it is ValueTypeByHwMode (parameterized ValueType),
11// and RegSizeInfoByHwMode (parameterized register/spill size and alignment
12// data).
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
16#define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
17
18#include "CodeGenHwModes.h"
David Blaikie9d9a46a2018-03-23 23:58:25 +000019#include "llvm/Support/MachineValueType.h"
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000020
21#include <map>
22#include <set>
23#include <string>
24#include <vector>
25
26namespace llvm {
27
28struct CodeGenHwModes;
29class Record;
Krzysztof Parzyszekbbd7d722017-09-22 18:29:37 +000030class raw_ostream;
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000031
32template <typename InfoT> struct InfoByHwMode;
33
34std::string getModeName(unsigned Mode);
35
36enum : unsigned {
37 DefaultMode = CodeGenHwModes::DefaultMode,
38};
39
40template <typename InfoT>
41std::vector<unsigned> union_modes(const InfoByHwMode<InfoT> &A,
42 const InfoByHwMode<InfoT> &B) {
43 std::vector<unsigned> V;
44 std::set<unsigned> U;
45 for (const auto &P : A)
46 U.insert(P.first);
47 for (const auto &P : B)
48 U.insert(P.first);
49 // Make sure that the default mode is last on the list.
Simon Pilgrim545c5cb2018-08-17 17:45:15 +000050 bool HasDefault = false;
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000051 for (unsigned M : U)
52 if (M != DefaultMode)
53 V.push_back(M);
Simon Pilgrim545c5cb2018-08-17 17:45:15 +000054 else
55 HasDefault = true;
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000056 if (HasDefault)
57 V.push_back(DefaultMode);
58 return V;
59}
60
61template <typename InfoT>
62struct InfoByHwMode {
63 typedef std::map<unsigned,InfoT> MapType;
64 typedef typename MapType::value_type PairType;
65 typedef typename MapType::iterator iterator;
66 typedef typename MapType::const_iterator const_iterator;
67
68 InfoByHwMode() = default;
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000069 InfoByHwMode(const MapType &M) : Map(M) {}
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000070
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000071 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000072 iterator begin() { return Map.begin(); }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000073 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000074 iterator end() { return Map.end(); }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000075 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000076 const_iterator begin() const { return Map.begin(); }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000077 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000078 const_iterator end() const { return Map.end(); }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000079 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000080 bool empty() const { return Map.empty(); }
81
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000082 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000083 bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000084 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000085 bool hasDefault() const { return hasMode(DefaultMode); }
86
87 InfoT &get(unsigned Mode) {
88 if (!hasMode(Mode)) {
89 assert(hasMode(DefaultMode));
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000090 Map.insert({Mode, Map.at(DefaultMode)});
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000091 }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +000092 return Map.at(Mode);
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +000093 }
94 const InfoT &get(unsigned Mode) const {
95 auto F = Map.find(Mode);
96 if (Mode != DefaultMode && F == Map.end())
97 F = Map.find(DefaultMode);
98 assert(F != Map.end());
99 return F->second;
100 }
101
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +0000102 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +0000103 bool isSimple() const {
104 return Map.size() == 1 && Map.begin()->first == DefaultMode;
105 }
Krzysztof Parzyszek7e1bf432017-09-19 18:42:34 +0000106 LLVM_ATTRIBUTE_ALWAYS_INLINE
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +0000107 InfoT getSimple() const {
108 assert(isSimple());
109 return Map.begin()->second;
110 }
111 void makeSimple(unsigned Mode) {
112 assert(hasMode(Mode) || hasDefault());
113 InfoT I = get(Mode);
114 Map.clear();
115 Map.insert(std::make_pair(DefaultMode, I));
116 }
117
118 MapType Map;
119};
120
121struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
122 ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
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
Simon Pilgrim92500592017-09-22 13:32:26 +0000135 static StringRef getMVTName(MVT T);
Krzysztof Parzyszekbbd7d722017-09-22 18:29:37 +0000136 void writeToStream(raw_ostream &OS) const;
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +0000137 void dump() const;
138};
139
140ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
141 const CodeGenHwModes &CGH);
142
143struct RegSizeInfo {
144 unsigned RegSize;
145 unsigned SpillSize;
146 unsigned SpillAlignment;
147
148 RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
149 RegSizeInfo() = default;
150 bool operator< (const RegSizeInfo &I) const;
151 bool operator== (const RegSizeInfo &I) const {
152 return std::tie(RegSize, SpillSize, SpillAlignment) ==
153 std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
154 }
155 bool operator!= (const RegSizeInfo &I) const {
156 return !(*this == I);
157 }
158
159 bool isSubClassOf(const RegSizeInfo &I) const;
Krzysztof Parzyszekbbd7d722017-09-22 18:29:37 +0000160 void writeToStream(raw_ostream &OS) const;
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +0000161};
162
163struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
164 RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
165 RegSizeInfoByHwMode() = default;
166 bool operator< (const RegSizeInfoByHwMode &VI) const;
167 bool operator== (const RegSizeInfoByHwMode &VI) const;
168 bool operator!= (const RegSizeInfoByHwMode &VI) const {
169 return !(*this == VI);
170 }
171
172 bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
173 bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
174
Krzysztof Parzyszekbbd7d722017-09-22 18:29:37 +0000175 void writeToStream(raw_ostream &OS) const;
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +0000176};
Krzysztof Parzyszekbbd7d722017-09-22 18:29:37 +0000177
178raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
179raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
180raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
181
Krzysztof Parzyszekdb815642017-09-14 16:56:21 +0000182} // namespace llvm
183
184#endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H